Как включить другой XHTML в XHTML, используя Facelet JSF 2.0?

218

Как наиболее правильно включить другую страницу XHTML в страницу XHTML? Я пробовал разные способы, ни один из них не работает.

Ikthiander
источник

Ответы:

423

<ui:include>

Самый простой способ <ui:include>. Содержимое должно быть размещено внутри <ui:composition>.

Пример запуска главной страницы /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>

Страница включения /WEB-INF/include.xhtml(да, это файл целиком, любые внешние теги <ui:composition>не нужны, так как они все равно игнорируются 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>
  

Это должно быть открыто /page.xhtml. Обратите внимание, что вам не нужно повторять <html>, <h:head>и <h:body>внутри файла включения, так как в противном случае это приведет к неверному HTML .

Вы можете использовать динамическое выражение EL в <ui:include src>. Смотрите также Как ajax-refresh динамически включать контент с помощью меню навигации? (JSF SPA) .


<ui:define>/<ui:insert>

Более продвинутый способ включения - шаблонизация . Это включает в основном наоборот. Главную страницу шаблона следует использовать <ui:insert>для объявления мест для вставки определенного содержимого шаблона. Страница клиента шаблона, которая использует главную страницу шаблона, должна использовать <ui:define>для определения содержимого шаблона, которое должно быть вставлено.

Основная страница шаблона /WEB-INF/template.xhtml(как подсказка для дизайна: верхний колонтитул, меню и нижний колонтитул, в свою очередь, могут быть даже <ui:include>файлами)

<!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.xhtml(обратите внимание на templateатрибут; также здесь, это файл целиком):

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

Это должно быть открыто /page.xhtml. Если нет <ui:define>, то по умолчанию <ui:insert>будет отображаться содержимое по умолчанию , если оно есть.


<ui:param>

Вы можете передать параметры <ui:include>или <ui:composition template>путем <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 >

Внутри файла include / template он будет доступен как #{foo}. В случае, если вам нужно передать «много» параметров <ui:include>, вам лучше зарегистрировать включаемый файл как файл тегов, чтобы в конечном итоге вы могли использовать его вот так <my:tagname foo="#{bean.foo}">. См. Также Когда использовать <ui: include>, файлы тегов, составные компоненты и / или пользовательские компоненты?

Вы даже можете передать целые бины, методы и параметры через <ui:param>. См. Также JSF 2: как передать действие, включающее в себя аргумент, который будет вызван, к вложенному представлению Facelets (используя ui: include и ui: param)?


Советы по дизайну

Файлы, которые не должны быть общедоступными, просто вводя / угадывая его URL, должны быть помещены в /WEB-INFпапку, например, как файл включения и файл шаблона в приведенном выше примере. Смотрите также Какие файлы XHTML мне нужно поместить в / WEB-INF, а какие нет?

Там не должно быть никакой разметки (HTML-код) снаружи <ui:composition>и <ui:define>. Вы можете поставить любой, но они будут игнорироваться Facelets. Размещение разметки полезно только для веб-дизайнеров. См. Также Есть ли способ запустить страницу JSF без создания всего проекта?

В настоящее время тип документа HTML5 является рекомендуемым типом документа, несмотря на то, что это файл XHTML. Вы должны увидеть XHTML как язык, который позволяет вам выводить HTML, используя инструмент на основе XML. См. Также Можно ли использовать JSF + Facelets с HTML 4/5? поддержка JavaServer Faces 2.2 и HTML5, почему XHTML все еще используется .

Файлы CSS / JS / изображения могут быть включены в качестве динамически перемещаемых / локализованных / версионных ресурсов. См. Также Как ссылаться на ресурс CSS / JS / image в шаблоне Facelets?

Вы можете поместить файлы Facelets в повторно используемый файл JAR. См. Также Структура для нескольких проектов JSF с общим кодом .

Для реальных примеров передовых Facelets мира шаблонирования, проверьте src/main/webappпапку Java EE Kickoff App исходного кода и OmniFaces Showcase исходного кода сайта .

BalusC
источник
1
Привет Балус, относительно: Самый простой способ - это <ui: include>. Содержимое должно быть размещено внутри <ui: состав>. Я думаю, что включенный контент может быть просто в <p> </ p>, он будет работать.
Корай Тугай
1
@KorayTugay: Да, это правильно. ui: состав необходим только для: а) использования шаблона (см. выше) или б) для переноса всего в <html> <body>, чтобы вы могли загрузить файл с помощью браузера или редактора HTML.
слеске
Привет, можешь решить эту загадку для меня? Я бьюсь головой последние 3 дня. stackoverflow.com/questions/24738079/…
Кишор Пракаш
1
@ Одиссей: нет, если это на самом деле композиция.
BalusC
1
Afaik, если вы объявляете только <ui:composition ...>внутри facelet, вы должны также объявить doctype <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">, иначе вы получите entity referenced but not declaredошибку при использовании сущностей HTML.
ChristophS
24

Включенная страница:

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

Включая страницу:

<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
  • Вы начинаете свой включенный файл xhtml ui:compositionкак показано выше.
  • Вы включаете этот файл ui:includeво включающий файл xhtml, как показано выше.
Венчик
источник
Иногда недостаточно указать путь, когда вы используете только имя файла. Для тех, кто пытался включить файл выше, и он не работал. Вы можете попробовать добавить символ косой черты перед именем файла или каталогом / WEB-INF. Так выглядит <ui:include src="/yourFile.xhtml"/>или<ui:include src="/WEB-INF/yourFile.xhtml"/>
Лефан