Wie kann ich mit JSF 2.0 Facelets ein weiteres XHTML in XHTML einbinden?

218

Was ist der korrekteste Weg, um eine andere XHTML-Seite in eine XHTML-Seite aufzunehmen? Ich habe verschiedene Wege ausprobiert, keiner von ihnen funktioniert.

Ikthiander
quelle

Antworten:

423

<ui:include>

Der einfachste Weg ist <ui:include>. Der enthaltene Inhalt muss darin platziert werden <ui:composition>.

Kickoff-Beispiel der Masterseite /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>

Die Include-Seite /WEB-INF/include.xhtml(ja, dies ist die Datei in ihrer Gesamtheit, alle Tags außerhalb <ui:composition>sind nicht erforderlich, da sie von Facelets sowieso ignoriert werden):

<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>
  

Dies muss von geöffnet werden /page.xhtml. Beachten Sie, dass Sie dies nicht wiederholen <html>müssen <h:head>und sich <h:body>in der Include-Datei befinden, da dies sonst zu ungültigem HTML führen würde .

Sie können einen dynamischen EL-Ausdruck in verwenden <ui:include src>. Siehe auch Wie kann ich dynamische Include-Inhalte über das Navigationsmenü aktualisieren? (JSF SPA) .


<ui:define>/.<ui:insert>

Eine fortgeschrittenere Art der Aufnahme ist das Templating . Dies schließt grundsätzlich umgekehrt ein. Auf der Master-Vorlagenseite sollten <ui:insert>Orte deklariert werden, an denen definierter Vorlageninhalt eingefügt werden soll. Die Vorlagen-Client-Seite, die die Master-Vorlagenseite verwendet, sollte <ui:define>zum Definieren des Vorlageninhalts verwendet werden, der eingefügt werden soll.

Master-Vorlagenseite /WEB-INF/template.xhtml(als Design-Hinweis: Kopf-, Menü- und Fußzeile können wiederum sogar <ui:include>Dateien sein):

<!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>

Vorlagen-Client-Seite /page.xhtml(beachten Sie das templateAttribut; auch hier ist dies die Datei in ihrer Gesamtheit):

<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>

Dies muss von geöffnet werden /page.xhtml. Wenn dies nicht <ui:define>der <ui:insert>Fall ist, wird stattdessen der Standardinhalt angezeigt, falls vorhanden.


<ui:param>

Sie können Parameter an <ui:include>oder <ui:composition template>von übergeben <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 >

In der Include- / Vorlagendatei ist sie als verfügbar #{foo}. <ui:include>Wenn Sie "viele" Parameter übergeben müssen, sollten Sie die Include-Datei als Tag-Datei registrieren, damit Sie sie letztendlich so verwenden können <my:tagname foo="#{bean.foo}">. Siehe auch Wann werden <ui: include>, Tag-Dateien, zusammengesetzte Komponenten und / oder benutzerdefinierte Komponenten verwendet?

Sie können sogar ganze Beans, Methoden und Parameter über übergeben <ui:param>. Siehe auch JSF 2: Wie übergebe ich eine Aktion mit einem Argument, das aufgerufen werden soll, an eine Facelets-Unteransicht (mit ui: include und ui: param)?


Design-Tipps

Die Dateien, auf die nicht nur durch Eingabe / Erraten der URL öffentlich zugegriffen werden soll, müssen in einem /WEB-INFOrdner abgelegt werden, z. B. als Include-Datei und als Vorlagendatei im obigen Beispiel. Siehe auch Welche XHTML-Dateien muss ich in / WEB-INF einfügen und welche nicht?

Es muss kein Markup (HTML-Code) außerhalb von <ui:composition>und geben <ui:define>. Sie können alle setzen, aber sie werden von Facelets ignoriert . Das Einfügen von Markups ist nur für Webdesigner nützlich. Siehe auch Gibt es eine Möglichkeit, eine JSF-Seite auszuführen, ohne das gesamte Projekt zu erstellen?

Der HTML5-Doctype ist heutzutage der empfohlene Doctype, "obwohl" es sich um eine XHTML-Datei handelt. Sie sollten XHTML als eine Sprache sehen, mit der Sie HTML-Ausgaben mit einem XML-basierten Tool erstellen können. Siehe auch Ist es möglich, JSF + Facelets mit HTML 4/5 zu verwenden? und JavaServer Faces 2.2 und HTML5 unterstützen, warum wird XHTML immer noch verwendet .

CSS / JS / Image-Dateien können als dynamisch verschiebbare / lokalisierte / versionierte Ressourcen enthalten sein. Siehe auch Verweisen auf CSS / JS / Bildressourcen in der Facelets-Vorlage.

Sie können Facelets-Dateien in eine wiederverwendbare JAR-Datei einfügen. Siehe auch Struktur für mehrere JSF-Projekte mit gemeinsam genutztem Code .

Beispiele für erweiterte Facelets-Vorlagen aus der Praxis finden Sie im src/main/webappOrdner mit dem Java EE Kickoff App-Quellcode und im OmniFaces-Showcase-Site-Quellcode .

BalusC
quelle
1
Hallo Balus, bezüglich: Der grundlegendste Weg ist <ui: include>. Der enthaltene Inhalt muss in <ui: Komposition> platziert werden. Ich denke, der enthaltene Inhalt kann einfach in <p> </ p> sein, es wird funktionieren.
Koray Tugay
1
@KorayTugay: Ja, das ist richtig. ui: Komposition ist nur erforderlich, um a) eine Vorlage (siehe oben) zu verwenden oder b) alles in <html> <body> zu verpacken, damit Sie die Datei mit einem Browser oder HTML-Editor laden können.
Sleske
Hallo, kannst du bitte dieses Rätsel für mich lösen? Ich habe mir in den letzten 3 Tagen den Kopf geschlagen. stackoverflow.com/questions/24738079/…
Kishor Prakash
1
@ Odysseus: nicht wenn es sich tatsächlich um eine Komposition handelt.
BalusC
1
Afaik, wenn Sie nur <ui:composition ...>innerhalb von facelet deklarieren, müssen Sie den Doctype wie <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">auch deklarieren , sonst erhalten Sie eine entity referenced but not declaredFehlermeldung, wenn Sie HTML-Entitäten verwenden.
ChristophS
24

Enthaltene Seite:

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

Einschließlich Seite:

<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
  • Sie starten Ihre enthaltene XML-Datei mit ui:compositionwie oben gezeigt.
  • Sie ui:includefügen diese Datei wie oben gezeigt in die enthaltende xhtml-Datei ein.
Benchik
quelle
Manchmal reicht es nicht aus, den Pfad zu identifizieren, während Sie nur einen Dateinamen verwenden. Für diejenigen, die versucht haben, die Datei oben aufzunehmen, und es hat nicht funktioniert. Sie können versuchen, vor dem Dateinamen oder dem Verzeichnis / WEB-INF ein Schrägstrichsymbol hinzuzufügen. So sieht es aus wie <ui:include src="/yourFile.xhtml"/>oder<ui:include src="/WEB-INF/yourFile.xhtml"/>
Lefan