PrettyFaces using mapped urls and actions, i lose all my stylings - jsf

I have been using pretty faces for urls without issue until i started using mapped URLs feature (Section 3.6). http://ocpsoft.org/docs/prettyfaces/3.3.3/en-US/html/Configuration.html#config.actions
I'm getting the output and the actions i want to happen working fine. The problem though is i can't get to to any of my assets under assets folder. i'm getting a 404. The weird thing is that for every other config there hasn't been a problem. And isn't a problem when I run them together. The app is using a template so the links to css's, js's, etc.. are exactly the same. When I go to a plain ol' (e.g. /home) mapping they work fine, go to the other page with the action, they don't work. The template rendering does though. In fact the parameter injection and the action work as well.
PRETTY CONFIG:
<url-mapping id="home"> <!-- assets work -->
<pattern value="/home" />
<view-id value="/home.jsf" />
</url-mapping>
<url-mapping id="validate-token"> <!-- assets don't work -->
<pattern value="/validate-token/type/#{id:validateByTokenController.tokenType}/token/#{validateByTokenController.token}" />
<view-id value="/validate-token.jsf" />
<action>#{validateByTokenController.init}</action>
</url-mapping>
BEAN:
#RequestScoped
#Named
public class ValidateByTokenController {
private String tokenType;
private String token;
public void init() {
token = "J" + token;
tokenType = "J" + tokenType;
}
XHTML SAMPLE CSS LINKS: (same links for "home" config, but not for "validate-token")
<link rel="stylesheet"
href="assets/plugins/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="assets/css/style.css" />
Thanks in advance.

The problem is that you are using relative URLs for your CSS files.
With an URL like /validate-token/type/foo/token/bar the browser thinks that /validate-token/type/foo/token/ is the current directory. So he tries to load the CSS file from /validate-token/type/foo/token/assets/css/style.css.
Try using absolute URLs for your CSS instead:
<link rel="stylesheet" href="#{request.contextPath}/assets/css/style.css" />

Related

Resource not found with jsf 2.2.12 [duplicate]

The JSF <h:outputStylesheet>, <h:outputScript> and <h:graphicImage> components have a library attribute. What is this and how should this be used? There are a lot of examples on the web which use it as follows with the common content/file type css, js and img (or image) as library name depending on the tag used:
<h:outputStylesheet library="css" name="style.css" />
<h:outputScript library="js" name="script.js" />
<h:graphicImage library="img" name="logo.png" />
How is it useful? The library value in those examples seems to be just repeating whatever is already been represented by the tag name. For a <h:outputStylesheet> it's based on the tag name already obvious that it represents a "CSS library". What's the difference with the following which also just works the same way?
<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
Also, the generated HTML output is a bit different. Given a context path of /contextname and FacesServlet mapping on an URL pattern of *.xhtml, the former generates the following HTML with the library name as request parameter:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/style.css.xhtml?ln=css" />
<script type="text/javascript" src="/contextname/javax.faces.resource/script.js.xhtml?ln=js"></script>
<img src="/contextname/javax.faces.resource/logo.png.xhtml?ln=img" alt="" />
While the latter generates the following HTML with the library name just in the path of the URI:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml" alt="" />
The latter approach makes in hindsight also more sense than the former approach. How exactly is the library attribute then useful?
Actually, all of those examples on the web wherein the common content/file type like "js", "css", "img", etc is been used as library name are misleading.
Real world examples
To start, let's look at how existing JSF implementations like Mojarra and MyFaces and JSF component libraries like PrimeFaces and OmniFaces use it. No one of them use resource libraries this way. They use it (under the covers, by #ResourceDependency or UIViewRoot#addComponentResource()) the following way:
<h:outputScript library="javax.faces" name="jsf.js" />
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:outputScript library="omnifaces" name="omnifaces.js" />
<h:outputScript library="omnifaces" name="fixviewstate.js" />
<h:outputScript library="omnifaces.combined" name="[dynamicname].js" />
<h:outputStylesheet library="primefaces" name="primefaces.css" />
<h:outputStylesheet library="primefaces-aristo" name="theme.css" />
<h:outputStylesheet library="primefaces-vader" name="theme.css" />
It should become clear that it basically represents the common library/module/theme name where all of those resources commonly belong to.
Easier identifying
This way it's so much easier to specify and distinguish where those resources belong to and/or are coming from. Imagine that you happen to have a primefaces.css resource in your own webapp wherein you're overriding/finetuning some default CSS of PrimeFaces; if PrimeFaces didn't use a library name for its own primefaces.css, then the PrimeFaces own one wouldn't be loaded, but instead the webapp-supplied one, which would break the look'n'feel.
Also, when you're using a custom ResourceHandler, you can also apply more finer grained control over resources coming from a specific library when library is used the right way. If all component libraries would have used "js" for all their JS files, how would the ResourceHandler ever distinguish if it's coming from a specific component library? Examples are OmniFaces CombinedResourceHandler and GraphicResourceHandler; check the createResource() method wherein the library is checked before delegating to next resource handler in chain. This way they know when to create CombinedResource or GraphicResource for the purpose.
Noted should be that RichFaces did it wrong. It didn't use any library at all and homebrewed another resource handling layer over it and it's therefore impossible to programmatically identify RichFaces resources. That's exactly the reason why OmniFaces CombinedResourceHander had to introduce a reflection-based hack in order to get it to work anyway with RichFaces resources.
Your own webapp
Your own webapp does not necessarily need a resource library. You'd best just omit it.
<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
Or, if you really need to have one, you can just give it a more sensible common name, like "default" or some company name.
<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
Or, when the resources are specific to some master Facelets template, you could also give it the name of the template, so that it's easier to relate each other. In other words, it's more for self-documentary purposes. E.g. in a /WEB-INF/templates/layout.xhtml template file:
<h:outputStylesheet library="layout" name="css/style.css" />
<h:outputScript library="layout" name="js/script.js" />
And a /WEB-INF/templates/admin.xhtml template file:
<h:outputStylesheet library="admin" name="css/style.css" />
<h:outputScript library="admin" name="js/script.js" />
For a real world example, check the OmniFaces showcase source code.
Or, when you'd like to share the same resources over multiple webapps and have created a "common" project for that based on the same example as in this answer which is in turn embedded as JAR in webapp's /WEB-INF/lib, then also reference it as library (name is free to your choice; component libraries like OmniFaces and PrimeFaces also work that way):
<h:outputStylesheet library="common" name="css/style.css" />
<h:outputScript library="common" name="js/script.js" />
<h:graphicImage library="common" name="img/logo.png" />
Library versioning
Another main advantage is that you can apply resource library versioning the right way on resources provided by your own webapp (this doesn't work for resources embedded in a JAR). You can create a direct child subfolder in the library folder with a name in the \d+(_\d+)* pattern to denote the resource library version.
WebContent
|-- resources
| `-- default
| `-- 1_0
| |-- css
| | `-- style.css
| |-- img
| | `-- logo.png
| `-- js
| `-- script.js
:
When using this markup:
<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
This will generate the following HTML with the library version as v parameter:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&v=1_0" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&v=1_0"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&v=1_0" alt="" />
So, if you have edited/updated some resource, then all you need to do is to copy or rename the version folder into a new value. If you have multiple version folders, then the JSF ResourceHandler will automatically serve the resource from the highest version number, according to numerical ordering rules.
So, when copying/renaming resources/default/1_0/* folder into resources/default/1_1/* like follows:
WebContent
|-- resources
| `-- default
| |-- 1_0
| | :
| |
| `-- 1_1
| |-- css
| | `-- style.css
| |-- img
| | `-- logo.png
| `-- js
| `-- script.js
:
Then the last markup example would generate the following HTML:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&v=1_1" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&v=1_1"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&v=1_1" alt="" />
This will force the webbrowser to request the resource straight from the server instead of showing the one with the same name from the cache, when the URL with the changed parameter is been requested for the first time. This way the endusers aren't required to do a hard refresh (Ctrl+F5 and so on) when they need to retrieve the updated CSS/JS resource.
Please note that library versioning is not possible for resources enclosed in a JAR file. You'd need a custom ResourceHandler. See also How to use JSF versioning for resources in jar.
See also:
JSF resource versioning
JSF2 Static resource caching
Structure for multiple JSF projects with shared code
JSF 2.0 specification - Chapter 2.6 Resource Handling

Pretty faces: one mapping configuration for multi .xhtml page

I have one question. How could pretty faces do this:
<code>
<url-mapping id="home">
<pattern value="/viewer" />
<view-id value="/pages/*" />
</url-mapping>
</code>
Well, I wonder if pretty faces could hide paths of all .xhtml in folder using just one configuration as shown as above, instead of to config for each and every file.
This mapping doesn't make any sense. To which view should PrettyFaces forward if the client requests /viewer?
However, you can do something similar with Rewrite, which is the successor of PrettyFaces. With Rewrite you can do something like:
.addRule( Join.path("/viewer/{page}").to("/pages/{page}.xhtml") )
This will basically map your URLs like this:
/viewer/foo -> /pages/foo.xhtml
/viewer/bar -> /pages/bar.xhtml
/viewer/whatever -> /pages/whatever.xhtml
If you want to migrate your app to Rewrite, which is really simple, have a look at the PrettyFaces Migration Guide.

URL rewrite for JSF

I'm using JSF, Jboss. I used urlrewrite filter and i don't know why:
when i type localhost:8080/myweb/user/myname will be forwarded to localhost:8080/myweb/user.xhtml?u=myname. it makes me don't like urlrewritefilter.
After that, i try using prettyfaces. Maybe, it is good for others, not me. i can't find out good tutorials except the documentation. ajax error after adding prettyfaces into my project. And some codes in pretty-config.xml
<url-mapping id="ideas">
<pattern value="/article/#{g}" />
<view-id value="/ideas/article.xhtml" />
</url-mapping> -->
And a form in jsf page will redirect this page with param
public String addUserToGroup() {
...
return "/ideas/article.xhtml?g=" + g + "&faces-redirect=true";
}
can't run.
Can you give me some advices about what library i should use to rewrite URL now. Or how to fix errors of prettyfaces. thanks
Is your configuration commented out? I noticed the '-->' in your code snippit.
<url-mapping id="ideas">
<pattern value="/article/#{g}" />
<view-id value="/ideas/article.xhtml" />
</url-mapping> -->

Rewriting URLs using pretty-config

I am facing problem with rewriting urls using pretty-config.xml and I want help. This is what I want.
I want to render the URL as:
http://www.example.com/{productId}
and the page actual URL is:
http://www.example.com/page/product.jsf
In short, I have one page but I want to render it each time as different url based on product id from the backing bean.
Sounds fairly simple. I would use this:
<url-mapping>
<pattern value="/#{productId}" />
<view-id value="/pages/product.jsf" />
</url-mapping>
Just make sure that you generate the correct links in your pages upon rendering.

UnmappedResourceHandler cannot convert URL in CSS to JSF 's valid URL

Here is my setup:
Web app 's folder structure and file names are exactly the same as the UnmappedResourceHandler 's javadoc
UnmappedResourceHandler is already registered in faces-config.xml
/javax.faces.resource/* is already mapped to facesServlet in web.xml
The style.css is :
body {
background: url("image/background.png");
}
body .test{
background-image: url("#{resource['css:image/background.png']}");
}
Then I request http://localhost:8080/app/javax.faces.resource/style.css?ln=css and the respond is :
body {
background: url("image/background.png");
}
body .test{
background-image: url("/app/javax.faces.resource/image/background.png?ln=css");
}
I expect that all the relative URLs in CSS will be converted to the JSF 's valid URL like what #{resource} does such that I do not have to use #{resource} to refer to the relative URLs in CSS anymore , but the background 's relative URL of the body selector still remains unchanged .
Update to BalusC 's reply:
If resource library is used , adding ?ln=libraryname to all CSS images will work!
But if resource library is not used , <h:outputStylesheet name="css/style.css" /> generates <link rel="stylesheet" media="screen" type="text/css" href="/app/javax.faces.resource/css/style.css.xhtml">
If I understand correctly from this , using UnmappedResourceHandler and mapping
/javax.faces.resource/* to the facesServlet in web.xml should cause JSF generates the link of the style.css without xhtml extension.
You're using css as a resource library as in:
<h:outputStylesheet library="css" name="style.css" />
This is not right. It's just a folder:
<h:outputStylesheet name="css/style.css" />
This will produce /javax.faces.resource/css/style.css URL instead of /javax.faces.resource/style.css?ln=css. You've otherwise to specify it in the image URL as well:
background: url("image/background.png?ln=css");
I will update the javadoc to clarify that more.
See also:
What is the JSF resource library for and how should it be used?

Resources