Как ссылаться на ресурс CSS / JS / image в шаблоне Facelets?
Я сделал учебник по шаблонам Facelets.
Теперь я попытался создать страницу, которая не находится в том же каталоге, что и шаблон. У меня проблемы со стилем страницы, потому что на стили ссылается относительный путь, например:
<link rel="stylesheet" href="style_resource_path.css" />
Я могу использовать абсолютные ссылки, начиная с /
:
<link rel="stylesheet" href="/project_root_path/style_resource_path.css" />
Но это доставит мне неприятности, когда я перенесу приложение в другой контекст.
Поэтому мне интересно, как лучше всего ссылаться на ресурсы CSS (и JS и изображения) в Facelets?
3 ответа
Вступление
Правильный способ JSF 2.x использует <h:outputStylesheet>
, <h:outputScript>
а также <h:graphicImage>
с name
ссылаясь на путь относительно веб-приложения /resources
папка. Таким образом, вам не нужно беспокоиться о пути к контексту, как в JSF 1.x. Смотрите также Как включить CSS относительно контекстного пути в JSF 1.x?
Структура папок
Удалите файлы CSS/JS/ изображения в /resources
папка общедоступного веб-контента, как показано ниже (просто создайте ее, если она еще не существует на том же уровне, что и /WEB-INF
а также /META-INF
).
WebContent
|-- META-INF
|-- WEB-INF
|-- resources
| |-- css
| | |-- other.css
| | `-- style.css
| |-- js
| | `-- script.js
| `-- images
| |-- background.png
| |-- favicon.ico
| `-- logo.png
|-- page.xhtml
:
В случае Maven, это должно быть в /main/webapp/resources
и, следовательно, нет /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>
Сценарий заказа, как описано выше. Вы в основном вынуждены форсировать заказ через PrimeFaces-only <f:facet name="first|middle|last">
, что может привести к беспорядочному и "беспорядочному" коду. Вы можете отключить его, как описано в этом ответе.
Упаковка в банке
Вы даже можете упаковать ресурсы в файл JAR. См. Также Структура для нескольких проектов JSF с общим кодом.
Ссылка в EL
Вы можете в EL использовать #{resource}
отображение, чтобы позволить JSF в основном печатать URL ресурса, как /context/javax.faces.resource/folder/file.ext.xhtml?ln=library
так что вы можете использовать его как, например, фоновое изображение CSS или favicon. Единственное требование состоит в том, что сам CSS-файл также должен служить ресурсом JSF, иначе выражения EL не будут оцениваться. См. Также Как ссылаться на ресурс изображения JSF как URL фонового изображения CSS.
.some {
background-image: url("#{resource['images/background.png']}");
}
Вот @import
пример.
@import url("#{resource['css/other.css']}");
Вот пример иконки См. Также Добавить значок в проект JSF и сослаться на него в ;.
<link rel="shortcut icon" href="#{resource['images/favicon.ico']}" />
Ссылки на сторонние CSS-файлы
CSS-файлы сторонних производителей, загруженные через <h:outputStylesheet>
которые, в свою очередь, могут потребовать изменения эталонных шрифтов и / или изображений для использования #{resource}
выражения, как описано в предыдущем разделе, в противном случае UnmappedResourceHandler
должен быть установлен, чтобы иметь возможность обслуживать тех, кто использует JSF. См. Также Страница 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 это невозможно.
Смотрите также:
Предположим, что вы работаете в подкаталогах веб-приложения. Вы можете попробовать вот так:
<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, тогда вам нужно удалить начальную косую черту, чтобы она относилась к текущему контексту (одному из страниц). JSP):
<link rel="stylesheet" type="text/css" href="styles/decoration.css" />
Эти ответы помогли мне решить ту же проблему. Хотя моя проблема была более сложной, так как я использовал SASS и GULP.
Я должен был изменить (пожалуйста, обратите внимание на "\" перед #. Вероятно, побочный эффект от глотка:
<h:outputStylesheet library="my_theme" name="css/default.css"/>
background: $blue url("\#{resource['my_theme/images/background-homepage-h1.png']}");
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 и изображениями.