Как ссылаться на ресурс CSS / JS / изображения в шаблоне Facelets? - PullRequest
52 голосов
/ 03 декабря 2011

Я сделал учебник по шаблонам Facelets .

Теперь я попытался создать страницу, которая не находится в том же каталоге, что и шаблон. У меня проблемы со стилем страницы, потому что на стили ссылается относительный путь, например:

<link rel="stylesheet" href="style_resource_path.css" />

Я могу использовать абсолютные ссылки, начиная с /:

<link rel="stylesheet" href="/project_root_path/style_resource_path.css" />

Но это доставит мне неприятности, когда я перенесу приложение в другой контекст.

Так что мне интересно, как лучше всего ссылаться на ресурсы CSS (и JS и изображения) в Facelets?

Ответы [ 4 ]

108 голосов
/ 03 декабря 2011

Введение

Правильный способ JSF 2.x использует <h:outputStylesheet>, <h:outputScript> и <h:graphicImage> сname ссылается на путь относительно папки /resources веб-приложения.Таким образом, вам не нужно беспокоиться о пути к контексту, как в JSF 1.x.См. Также Как включить CSS относительно пути к контексту в JSF 1.x?

Структура папки

Перетащите файлы CSS / JS / image в папку /resourcesобщедоступный веб-контент, как показано ниже (просто создайте его, если он еще не существует на том же уровне, что и /WEB-INF и /META-INF).

WebContent
 |-- resources
 |    |-- css
 |    |    |-- other.css
 |    |    `-- style.css
 |    |-- js
 |    |    `-- script.js
 |    `-- images
 |         |-- background.png
 |         |-- favicon.ico
 |         `-- logo.png
 |-- META-INF
 |    `-- MANIFEST.MF
 |-- WEB-INF
 |    |-- faces-config.xml
 |    `-- web.xml
 |-- page.xhtml
 :

В случае Maven он должен быть в /main/webapp/resources и, таким образом, not /main/resources (это для ресурсов Java (файлы свойств / xml / text / config), которые должны заканчиваться в пути к классам времени выполнения, а не в веб-контенте).См. Также Структура веб-приложения Maven и JSF, куда именно помещать ресурсы JSF .

Ссылки в Facelets

В конечном счете, эти ресурсы доступны, как показано ниже, повсюду без необходимости возитьсяс относительными путями:

<h:head>
    ...
    <h:outputStylesheet name="css/style.css" />
    <h:outputScript name="js/script.js" />
</h:head>
<h:body>
    ...
    <h:graphicImage name="images/logo.png" />
    ...
</h:body>

Атрибут name должен представлять полный путь относительно папки /resources.Не нужно начинать с /.Вы не нуждаетесь в атрибуте library, если вы не разрабатываете библиотеку компонентов, такую ​​как PrimeFaces, или файл JAR общего модуля, который используется несколькими веб-приложениями.

Вы можете ссылаться<h:outputStylesheet> где угодно, а также <ui:define> шаблонных клиентов без необходимости дополнительного <h:head>.Он будет через <h:head> компонент основного шаблона автоматически попадать в сгенерированный <head>.

<ui:define name="...">
    <h:outputStylesheet name="css/style.css" />
    ...
</ui:define>

Вы также можете ссылаться на <h:outputScript> в любом месте, но по умолчанию он окажется в HTML именно там, где вы его объявили.Если вы хотите, чтобы он заканчивался <head> через <h:head>, добавьте атрибут target="head".

<ui:define name="...">
    <h:outputScript name="js/script.js" target="head" />
    ...
</ui:define>

Или, если вы хотите, чтобы он заканчивался в конце <body> (прямо перед </body>, так что, например, window.onload и $(document).ready() и т. Д. Не требуется) через <h:body>, затем добавьте атрибут target="body".

<ui:define name="...">
    <h:outputScript name="js/script.js" target="body" />
    ...
</ui:define>

PrimeFaces HeadRenderer

Если вы используете PrimeFaces, его HeadRenderer испортит порядок сценариев по умолчанию <h:head>как описано выше.По сути, вы вынуждены форсировать ордер с помощью <f:facet name="first|middle|last">, специфичного для PrimeFaces, что может привести к грязному и «беспорядочному» коду.Вы можете отключить его, как описано в этот ответ .

Упаковка в JAR

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

Ссылки в EL

В EL можно использовать отображение #{resource}, чтобы позволить JSF в основном печатать URL ресурса.как /context/javax.faces.resource/folder/file.ext.xhtml?ln=library, чтобы вы могли использовать его, например, как фоновое изображение CSS или favicon.Единственное требование заключается в том, что сам CSS-файл также должен служить ресурсом JSF, иначе выражения EL не будут оцениваться.См. Также Как ссылаться на ресурс изображения JSF как на фоновое изображение CSS url .

.some {
    background-image: url("#{resource['images/background.png']}");
}

Вот пример @import.

@import url("#{resource['css/other.css']}");

Вот пример favicon.См. Также Добавить значок в проект JSF и сослаться на него в .

<link rel="shortcut icon" href="#{resource['images/favicon.ico']}" />

Если вы используете компилятор SCSS (например, Sass Compiler Plugin для Maven ), имейте в виду, что процессор SCSS может интерпретировать # как специальный символ.В этом случае вам потребуется экранировать его с помощью \.

.some {
    background-image: url("\#{resource['images/background.png']}");
}

Ссылка на сторонние CSS-файлы

Сторонние CSS-файлы, загруженные с помощью <h:outputStylesheet>, которые, в свою очередь, ссылаются на шрифты и/ или изображения, возможно, придется изменить, чтобы использовать выражения #{resource}, как описано в предыдущем разделе, в противном случае необходимо установить UnmappedResourceHandler, чтобы иметь возможность обслуживать тех, кто использует JSF.См. Также ao Страница Bootsfaces отображается в браузере без каких-либо стилей и Как использовать Font Awesome 4.x CSS-файл с JSF?Браузер не может найти файлы шрифтов .

Скрытие в / WEB-INF

Если вы намереваетесь скрыть ресурсы от общего доступа, переместив всю папку /resources в /WEB-INF, тогда вы можете, начиная с JSF 2.2, по желанию изменить путь относительно веб-контента с помощью нового параметра контекста web.xml следующим образом:

<context-param>
    <param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
    <param-value>/WEB-INF/resources</param-value>
</context-param>

В старых версиях JSF это невозможно.

См. Также:

7 голосов
/ 03 декабря 2011

Предположим, что вы работаете в подкаталогах веб-приложения.Вы можете попробовать вот так:

 <link href="${facesContext.externalContext.requestContextPath}/css/style.css" rel="stylesheet" type="text/css"/>

Ссылка '${facesContext.externalContext.requestContextPath}/' поможет вам немедленно вернуться к корню контекста.

В относительных URL-адресах косая черта / указывает наКорень домена.Так, если страница JSF, например, запрашивается http://example.com/context/page.jsf,, URL-адрес CSS будет абсолютно указывать на http://example.com/styles/decoration.css. Чтобы узнать действительный относительный URL-адрес, необходимо знать абсолютный URL-адрес как страницы JSF, так иCSS-файл и извлеките один из другого.

Давайте догадаемся, что ваш CSS-файл действительно расположен в http://example.com/context/styles/decoration.css,, тогда вам нужно удалить начальную косую черту, чтобы она относилась к текущему контексту (один из page.jsp):

<link rel="stylesheet" type="text/css" href="styles/decoration.css" />
2 голосов
/ 25 июня 2017

Эти ответы помогли мне решить ту же проблему. Хотя моя проблема была более сложной, так как я использовал SASS и GULP.

Я должен был измениться (обратите внимание на "\" перед #. Вероятно, побочный эффект от gulp:

 <h:outputStylesheet library="my_theme" name="css/default.css"/>  

 background: $blue url("\#{resource['my_theme/images/background-homepage-h1.png']}");
0 голосов
/ 25 декабря 2018

resourcehandlers.UnmappedResourceHandler помогает сопоставлять ресурсы JSF по шаблону URL-адреса /javax.faces.resource/*.

Для меня эти 2 xml-конфига в face-config.xml: org.omnifaces.resourcehandler.UnmappedResourceHandler

и в файле web.xml:

<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>/javax.faces.resource/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

помогли с CSS и изображениями.

...