Thursday, September 8, 2011

PrettyFaces for SEO-friendly URLs

We all know JSF2 out of the box has still disadvantages with RESTFUL URLs. This problem can easily be solved by PrettyFaces, which allows SEO-friendly URLs with a simple on annotation based configuration.

1) Configuration

Download PrettyFaces binaries and add them to the classpath. If you use Apache Maven, you only need to add PrettyFaces as dependency to your project:
<dependency>
    <groupId>com.ocpsoft</groupId>
    <artifactId>prettyfaces-jsf2</artifactId>
    <version>3.3.0</version>
</dependency>

To ensure maximum flexibility, we configure PrettyFaces on anntotations. The web.xml parameter com.ocpsoft.pretty.BASE_PACKAGE tells PrettyFaces which package have to be scanned recursively for beans with @URLMapping annotation:
<context-param>
    <param-name>com.ocpsoft.pretty.BASE_PACKAGES</param-name>
    <param-value>your.package.structure</param-value>
</context-param>

Congratulations, you have added PrettyFaces to your project successfully.

2) Basic Pages

Now just add @URLMapping's to your action beans like:
@Named
@RequestScoped
@URLMapping(id = "startpage", pattern = "/", viewId = "/pages/startpage.seam")
public class StartpageAction implements Serializable 
{
...
}

The annotation based configuration of PrettyFaces keeps the amount of navigation rules in faces-config.xml small. The new prefix pretty:, could be used as return string on methods of managed beans or as outcome from h:button and h:link components. For a simple reload of the current page just return pretty:. In case of return pretty:startpage PrettyFaces search for the annotation based bean with @URLMapping(id = "startpage", ... and redirect to this page.

On the JSF side you just need to put the id of the @URLMapping as outcome:
<h:link outcome="pretty:startpage" value="Startpage" />

3) Pages With URL Parameters

Pass additional parameters as URL value isn't much harder. Just setup the bean:
@Named
@RequestScoped
@URLMapping(id = "category", pattern = "/cat/#{catId : boardCategoryAction.catId}.html", viewId = "/pages/category.seam")
public class CategoryAction implements Serializable
{
...
    private String catId;
...
    public String getCatId() {
        return catId;
    }

    public void setCatId(String catId) {
        this.catId = catId;
    }
}

And parse the parameter in the "h:link":
<h:link outcome="pretty:category" value="Category">
    <f:param name="catId" value="123" />
</h:link>

Was it ever easier to set up pretty URLs? I don't think so :)
Thanks to Lincoln and the whole OCPSoft Team.

3 comments:

  1. Great work.Nicely presented information in this post, I prefer to read this kind of stuff.I wanted to thank you for this great read!!I have you bookmarked to check out new stuff you post.
    Ecommerce developer

    ReplyDelete
  2. Starting to understand a bit more now... Thanks for keeping it simple!

    SEO Services Singapore

    ReplyDelete
  3. Hi there, awesome site. I thought the topics you posted on were very interesting. I tried to add your RSS to my feed reader and it a few. take a look at it, hopefully I can add you and follow...


    SEO Singapore

    ReplyDelete