Jak odwołać się do CSS / JS / image resource w szablonie Facelets?

Zrobiłem tutorial o template Facelets .

Teraz próbowałem stworzyć stronę, która nie jest w tym samym katalogu co szablon. Mam problemy ze stylem strony, ponieważ Style odwołują się do ścieżki względnej w ten sposób:

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

Mogę użyć referencji bezwzględnej zaczynając od /:

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

Ale to przyniesie mi kłopoty, kiedy będę przenosić aplikację do innego kontekstu.

Więc zastanawiam się, jaki jest najlepszy sposób na odwołanie się do CSS (i JS i image) zasoby w Facelets?

Author: BalusC, 2011-12-03

3 answers

Wprowadzenie

Właściwe JSF 2.X sposób jest za pomocą <h:outputStylesheet>, <h:outputScript> oraz <h:graphicImage> Z name odnoszenie ścieżki względem folderu /resources webapp. W ten sposób nie musisz martwić się o ścieżkę kontekstową, tak jak w JSF 1.X. Zobacz także jak włączyć CSS względem ścieżki kontekstowej w JSF 1.x?

Struktura folderów

Upuść pliki CSS / JS / image w folderze /resources publicznego webcontent jak poniżej (po prostu utwórz je, jeśli nie istnieją już na tym samym poziomie co /WEB-INF i /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
 :

W przypadku Mavena powinno być w /main/webapp/resources a zatem Nie /main/resources (są one przeznaczone dla zasobów Java (pliki properties / xml / text / config), które muszą znajdować się w runtime classpath, a nie w webcontent). Zobacz także Maven i struktura webapp JSF, gdzie dokładnie umieścić zasoby JSF .

Referowanie w Faktach

Ostatecznie te zasoby są dostępne jak poniżej wszędzie bez potrzeby fiddle ze ścieżkami względnymi:

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

Atrybut name musi reprezentować pełną ścieżkę względem folderu /resources. Nie musi zaczynać się od /. Nie potrzebujesz atrybutu library, o ile nie tworzysz biblioteki komponentów, takiej jak PrimeFaces lub plik JAR wspólnego modułu, który jest współdzielony przez wiele aplikacji webowych.

Możesz odwoływać się do <h:outputStylesheet> w dowolnym miejscu, również w <ui:define> klientów szablonów bez potrzeby stosowania dodatkowego <h:head>. Będzie przez <h:head> komponent szablonu głównego automatycznie kończy się w wygenerowanym <head>.

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

Możesz odwołać się do <h:outputScript> również w dowolnym miejscu, ale domyślnie skończy się w HTML dokładnie tam, gdzie go zadeklarowałeś. Jeśli chcesz, aby skończyło się na <head> poprzez <h:head>, Dodaj atrybut target="head".

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

Lub, jeśli chcesz, aby skończyło się na końcu <body> (tuż przed </body>, tak że np. window.onload i $(document).ready() itp. nie jest konieczne) poprzez <h:body>, dodaj target="body" atrybut.

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

PrimeFaces HeadRenderer

W przypadku, gdy używasz PrimeFaces, jej HeadRenderer spowoduje błąd w domyślnej kolejności skryptów <h:head>, jak opisano powyżej. W zasadzie jesteś zmuszony do wymuszenia kolejności za pomocą specyficznego dla PrimeFaces <f:facet name="first|middle|last">, co może skończyć się bałaganem i" niewykonalnym " kodem. Możesz wyłączyć go zgodnie z opisem w ta odpowiedź .

Opakowanie w słoiku

Możesz nawet spakować zasoby do pliku JAR. Zobacz też Struktura dla wiele projektów JSF ze współdzielonym kodem .

Odwołanie do EL

Możesz w EL użyć mapowania #{resource}, aby JSF w zasadzie wydrukował adres URL zasobu, taki jak /context/javax.faces.resource/folder/file.ext.xhtml?ln=library, abyś mógł go użyć jako np. obraz tła CSS lub favicon. Jedynym wymogiem jest to, że sam plik CSS powinien być również obsługiwany jako zasób JSF, w przeciwnym razie el expressions nie będzie oceniać. Zobacz także jak odwołać się do JSF image resource jako CSS background image url .

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

Oto @import przykład.

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

Oto przykład faviconu. Zobacz także Dodaj favicon do projektu JSF i odwołaj się do niego w .

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

Odwoływanie się do plików CSS innych firm

Pliki CSS stron trzecich ładowane przez <h:outputStylesheet>, które z kolei czcionki referencyjne i/lub obrazy mogą wymagać zmiany w celu użycia wyrażeń #{resource}, jak opisano w poprzedniej sekcji, w przeciwnym razie należy zainstalować UnmappedResourceHandler, Aby móc obsługiwać tych, którzy używają JSF. Zobacz także stronę a. o. bootsfaces pokazuje up w przeglądarce bez żadnych stylizacji i Jak korzystać z Font Awesome 4.X plik CSS z JSF? Przeglądarka nie może znaleźć plików czcionek .

Ukrywanie się w / WEB-INF

Jeśli chcesz ukryć zasoby przed dostępem publicznym, przenosząc cały folder /resources do /WEB-INF, możesz od wersji JSF 2.2 opcjonalnie zmienić ścieżkę webcontent-relative poprzez nowy parametr kontekstowy web.xml w następujący sposób:
<context-param>
    <param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
    <param-value>/WEB-INF/resources</param-value>
</context-param>

W starszych wersjach JSF nie jest to możliwe.

Zobacz także:

 91
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:17

Załóżmy, że uruchamiasz podkatalogi aplikacji webowej. Możesz spróbować w ten sposób:

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

Link '${facesContext.externalContext.requestContextPath}/' pomoże ci natychmiast powrócić do głównego kontekstu.

W względnych adresach URL, główny ukośnik / wskazuje na główny adres domeny. Więc jeśli strona JSF jest na przykład wymagana przez http://example.com/context/page.jsf , CSS URL będzie absolutnie wskazywać na http://example.com/styles/decoration.css . aby poznać poprawnego krewnego URL, musisz znać bezwzględny adres URL zarówno strony JSF, jak i pliku CSS i wyodrębnić jeden z drugiego.

Niech zgadnę, że Twój plik CSS znajduje się w http://example.com/context/styles/decoration.css , Następnie należy usunąć ukośnik wiodący, aby był względem bieżącego kontekstu (tego na stronie."jsp"): {]}

<link rel="stylesheet" type="text/css" href="styles/decoration.css" />
 7
Author: Abimaran Kugathasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-12 08:21:33

Te odpowiedzi pomogły mi rozwiązać ten sam problem. Chociaż mój problem był bardziej złożony, ponieważ używałem SASS i GULP.

Musiałem zmienić (zwróć uwagę na " \ " przed #. Prawdopodobnie efekt uboczny gulp:

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

 background: $blue url("\#{resource['my_theme/images/background-homepage-h1.png']}");
 2
Author: Mircea Stanciu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-25 03:46:19