Comment inclure un autre XHTML dans XHTML en utilisant des facettes JSF 2.0?

218

Quelle est la façon la plus correcte d'inclure une autre page XHTML dans une page XHTML? J'ai essayé différentes manières, aucune ne fonctionne.

Ikthiander
la source

Réponses:

423

<ui:include>

La façon la plus élémentaire est <ui:include>. Le contenu inclus doit être placé à l'intérieur <ui:composition>.

Exemple de lancement de la page maître /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>

La page d'inclusion /WEB-INF/include.xhtml(oui, c'est le fichier dans son intégralité, toutes les balises à l'extérieur <ui:composition>sont inutiles car elles sont de toute façon ignorées par 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>
  

Cela doit être ouvert par /page.xhtml. Notez que vous n'avez pas besoin de répéter <html>, <h:head>et <h:body>à l'intérieur du fichier include car cela entraînerait sinon un code HTML non valide .

Vous pouvez utiliser une expression EL dynamique dans <ui:include src>. Voir aussi Comment ajax-refresh dynamic inclure du contenu par le menu de navigation? (JSF SPA) .


<ui:define>/<ui:insert>

Une manière plus avancée d'inclure est la création de modèles . Cela comprend essentiellement l'inverse. La page de modèle principal doit utiliser <ui:insert>pour déclarer des emplacements pour insérer le contenu de modèle défini. La page client de modèle qui utilise la page de modèle principale doit utiliser <ui:define>pour définir le contenu du modèle à insérer.

Page de modèle principale /WEB-INF/template.xhtml(à titre indicatif: l'en-tête, le menu et le pied de page peuvent à leur tour même être des <ui:include>fichiers):

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

Page client du modèle /page.xhtml(notez l' templateattribut; ici aussi, c'est le fichier dans son intégralité):

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

Cela doit être ouvert par /page.xhtml. S'il n'y en a pas <ui:define>, le contenu par défaut à l'intérieur <ui:insert>sera affiché à la place, le cas échéant.


<ui:param>

Vous pouvez passer des paramètres à <ui:include>ou <ui:composition template>par <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 >

Dans le fichier include / template, il sera disponible en tant que #{foo}. Dans le cas où vous devez passer "plusieurs" paramètres à <ui:include>, alors vous feriez mieux d'envisager d'enregistrer le fichier inclus en tant que fichier de balises, afin de pouvoir finalement l'utiliser comme tel <my:tagname foo="#{bean.foo}">. Voir aussi Quand utiliser <ui: include>, fichiers de balises, composants composites et / ou composants personnalisés?

Vous pouvez même transmettre des beans entiers, des méthodes et des paramètres via <ui:param>. Voir aussi JSF 2: comment passer une action incluant un argument à appeler à une sous-vue Facelets (en utilisant ui: include et ui: param)?


Conseils de conception

Les fichiers qui ne sont pas censés être accessibles au public en entrant / devinant simplement son URL, doivent être placés dans le /WEB-INFdossier, comme le fichier inclus et le fichier modèle dans l'exemple ci-dessus. Voir aussi Quels fichiers XHTML dois-je mettre dans / WEB-INF et lesquels non?

Il n'y a pas besoin de balisage (code HTML) à l'extérieur <ui:composition>et <ui:define>. Vous pouvez en mettre, mais ils seront ignorés par Facelets. Le balisage n'est utile que pour les concepteurs de sites Web. Voir aussi Existe-t-il un moyen d'exécuter une page JSF sans générer l'intégralité du projet?

Le doctype HTML5 est le doctype recommandé de nos jours, "malgré" qu'il s'agit d'un fichier XHTML. Vous devriez voir XHTML comme un langage qui vous permet de produire une sortie HTML à l'aide d'un outil basé sur XML. Voir aussi Est-il possible d'utiliser des facettes JSF + avec HTML 4/5? et JavaServer Faces 2.2 et HTML5, pourquoi XHTML est-il toujours utilisé ?

Les fichiers CSS / JS / image peuvent être inclus en tant que ressources déplaçables / localisées / versionnées dynamiquement. Voir aussi Comment référencer une ressource CSS / JS / image dans le modèle Facelets?

Vous pouvez placer les fichiers Facelets dans un fichier JAR réutilisable. Voir aussi Structure pour plusieurs projets JSF avec code partagé .

Pour des exemples concrets de modèles avancés de Facelets, consultez le src/main/webappdossier du code source de l'application Java EE Kickoff et du code source du site vitrine OmniFaces .

BalusC
la source
1
Salut Balus, concernant: La manière la plus basique est <ui: include>. Le contenu inclus doit être placé dans <ui: composition>. Je pense que le contenu inclus peut simplement être dans <p> </p> cela fonctionnera.
Koray Tugay
1
@KorayTugay: Oui, c'est exact. ui: la composition n'est nécessaire que pour a) utiliser un modèle (voir ci-dessus), ou b) pour tout envelopper dans <html> <body> afin que vous puissiez charger le fichier avec un navigateur ou un éditeur HTML.
sleske
Salut, peux-tu résoudre cette énigme pour moi? Je me tape la tête depuis 3 jours. stackoverflow.com/questions/24738079/…
Kishor Prakash
1
@Odysseus: pas si c'est en fait une composition.
BalusC
1
Afaik, si vous déclarez uniquement à l' <ui:composition ...>intérieur de la facette, vous devez également déclarer le doctype <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">, sinon vous obtenez une entity referenced but not declarederreur lors de l'utilisation d'entités HTML.
ChristophS
24

Page incluse:

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

Y compris la page:

<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
  • Vous démarrez votre fichier xhtml inclus avec ui:compositioncomme indiqué ci-dessus.
  • Vous incluez ce fichier avec ui:includedans le fichier xhtml inclus, comme indiqué ci-dessus.
Benchik
la source
Parfois, il ne suffit pas d'identifier le chemin lorsque vous utilisez uniquement un nom de fichier. Pour ceux qui ont essayé l'inclusion de fichiers ci-dessus et cela n'a pas fonctionné. Vous pouvez essayer d'ajouter un symbole de barre oblique avant le nom de fichier ou le répertoire / WEB-INF. Il ressemble donc à <ui:include src="/yourFile.xhtml"/>ou<ui:include src="/WEB-INF/yourFile.xhtml"/>
Lefan