Jak dołączyć kolejny XHTML do XHTML za pomocą JSF 2.0 Facelets?

218

Jaki jest najbardziej poprawny sposób umieszczenia innej strony XHTML na stronie XHTML? Próbowałem na różne sposoby, żaden z nich nie działa.

Ikthiander
źródło

Odpowiedzi:

423

<ui:include>

Najbardziej podstawowym sposobem jest <ui:include>. Zawarta zawartość musi być umieszczona w środku <ui:composition>.

Przykładowy początek strony wzorcowej /page.xhtml:

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <title>Include demo</title>
    </h:head>
    <h:body>
        <h1>Master page</h1>
        <p>Master page blah blah lorem ipsum</p>
        <ui:include src="/WEB-INF/include.xhtml" />
    </h:body>
</html>

Strona dołączania /WEB-INF/include.xhtml(tak, jest to plik w całości, wszelkie zewnętrzne tagi <ui:composition>są niepotrzebne, ponieważ i tak są ignorowane przez Facelets):

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h2>Include page</h2>
    <p>Include page blah blah lorem ipsum</p>
</ui:composition>
  

To musi zostać otwarte przez /page.xhtml. Należy pamiętać, że nie trzeba powtarzać <html>, <h:head>a <h:body>wewnątrz pliku dołączania, ponieważ w przeciwnym razie spowodowałoby to nieprawidłowy kod HTML .

Możesz użyć dynamicznego wyrażenia EL w <ui:include src>. Zobacz także Jak odświeżyć dynamicznie ajax dołączyć zawartość według menu nawigacji? (JSF SPA) .


<ui:define>/<ui:insert>

Bardziej zaawansowanym sposobem włączenia jest tworzenie szablonów . Obejmuje to w zasadzie na odwrót. Strona szablonu wzorcowego powinna służyć <ui:insert>do deklarowania miejsc wstawienia zdefiniowanej zawartości szablonu. Strona klienta szablonu, która korzysta ze strony szablonu głównego, powinna posłużyć <ui:define>do zdefiniowania treści szablonu, która ma zostać wstawiona.

Strona szablonu wzorcowego /WEB-INF/template.xhtml(jako wskazówka dotycząca projektu: nagłówek, menu i stopka mogą z kolei być nawet <ui:include>plikami):

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <title><ui:insert name="title">Default title</ui:insert></title>
    </h:head>
    <h:body>
        <div id="header">Header</div>
        <div id="menu">Menu</div>
        <div id="content"><ui:insert name="content">Default content</ui:insert></div>
        <div id="footer">Footer</div>
    </h:body>
</html>

Szablon strony klienta /page.xhtml(zwróć uwagę na templateatrybut; tutaj również jest to plik w całości):

<ui:composition template="/WEB-INF/template.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

    <ui:define name="title">
        New page title here
    </ui:define>

    <ui:define name="content">
        <h1>New content here</h1>
        <p>Blah blah</p>
    </ui:define>
</ui:composition>

To musi zostać otwarte przez /page.xhtml. Jeśli nie <ui:define>, <ui:insert>pojawi się domyślna zawartość , jeśli taka istnieje.


<ui:param>

Możesz przekazać parametry do <ui:include>lub <ui:composition template>przez <ui:param>.

<ui:include ...>
    <ui:param name="foo" value="#{bean.foo}" />
</ui:include>
<ui:composition template="...">
    <ui:param name="foo" value="#{bean.foo}" />
    ...
</ui:composition >

W pliku dołączania / szablonu będzie dostępny jako #{foo}. Jeśli musisz przekazać „wiele” parametrów <ui:include>, lepiej zastanów się nad zarejestrowaniem pliku dołączanego jako pliku tagów, abyś mógł z niego w ten sposób korzystać <my:tagname foo="#{bean.foo}">. Zobacz także Kiedy używać <ui: include>, oznaczać pliki, komponenty kompozytowe i / lub komponenty niestandardowe?

Możesz nawet przekazać całą fasolę, metody i parametry <ui:param>. Zobacz także JSF 2: jak przekazać akcję zawierającą argument, który ma zostać wywołany do widoku podrzędnego Facelets (przy użyciu ui: include i ui: param)?


Wskazówki dotyczące projektowania

Pliki, które nie powinny być publicznie dostępne po prostu wpisując / zgadując ich adres URL, muszą być umieszczone w /WEB-INFfolderze, podobnie jak plik dołączania i plik szablonu w powyższym przykładzie. Zobacz także Które pliki XHTML muszę umieścić w / WEB-INF, a które nie?

Nie musi być żadnych znaczników (kodu HTML) na zewnątrz <ui:composition>i <ui:define>. Możesz umieścić dowolne, ale zostaną one zignorowane przez Facelety. Umieszczenie tam znaczników jest przydatne tylko dla projektantów stron internetowych. Zobacz także Czy istnieje sposób na uruchomienie strony JSF bez budowania całego projektu?

Doctype HTML5 jest obecnie zalecanym typem dokumentu, „mimo że” jest to plik XHTML. Powinieneś widzieć XHTML jako język, który pozwala na tworzenie danych wyjściowych HTML za pomocą narzędzia opartego na XML. Zobacz także Czy można używać JSF + Facelets z HTML 4/5? oraz obsługa JavaServer Faces 2.2 i HTML5, dlaczego XHTML jest nadal używany .

Pliki CSS / JS / obrazu można dołączać jako zasoby dynamicznie relokowalne / zlokalizowane / wersjonowane. Zobacz także Jak odwoływać się do zasobu CSS / JS / image w szablonie Facelets?

Możesz umieścić pliki Facelets w pliku JAR wielokrotnego użytku. Zobacz także Struktura wielu projektów JSF ze wspólnym kodem .

Aby zapoznać się z przykładami zaawansowanych szablonów Facelets w świecie rzeczywistym, sprawdź src/main/webappfolder kodu źródłowego aplikacji Java EE Kickoff i kod źródłowy witryny OmniFaces .

BalusC
źródło
1
Cześć Balus, w odniesieniu do: Najbardziej podstawowym sposobem jest <ui: include>. Zawarta treść musi być umieszczona wewnątrz <ui: composition>. Wydaje mi się, że zawarta zawartość może po prostu znajdować się w <p> </p>, będzie działać.
Koray Tugay
1
@KorayTugay: Tak, zgadza się. ui: kompozycja jest konieczna tylko do a) użycia szablonu (patrz wyżej) lub b) do zawinięcia wszystkiego w <html> <body>, aby można było załadować plik za pomocą przeglądarki lub edytora HTML.
sleske
Cześć, proszę, możesz rozwiązać dla mnie tę zagadkę? Walę głową w ostatnie 3 dni. stackoverflow.com/questions/24738079/…
Kishor Prakash
1
@Odysseus: nie, jeśli tak naprawdę jest to kompozycja.
BalusC
1
Afaik, jeśli tylko deklarujesz <ui:composition ...>wewnątrz facelet, musisz zadeklarować <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">również typ dokumentu , w przeciwnym razie pojawi się entity referenced but not declaredbłąd podczas używania encji HTML.
ChristophS,
24

Zawarta strona:

<!-- opening and closing tags of included page -->
<ui:composition ...>
</ui:composition>

W tym strona:

<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
  • Zaczynasz dołączony plik xhtml w ui:compositionsposób pokazany powyżej.
  • Uwzględniasz ten plik w dołączonym ui:includepliku xhtml, jak pokazano również powyżej.
Benchik
źródło
Czasami nie wystarczy zidentyfikować ścieżkę, gdy używasz tylko nazwy pliku. Dla tych, którzy próbowali dołączyć plik powyżej i nie działało. Możesz spróbować dodać symbol ukośnika przed nazwą pliku lub katalogiem / WEB-INF. Wygląda to na: <ui:include src="/yourFile.xhtml"/>lub<ui:include src="/WEB-INF/yourFile.xhtml"/>
Lefan