A teammate pinged me close to midnight after wrestling with a messy JSF view. It was a JSP with scriptlets hiding in the corner and the header copied across six pages. We moved it to Facelets with a simple template, and the whole thing calmed down. No magic. Just XHTML, ui tags, and a layout we could trust. The next morning the team shipped a new section by only touching a content file. Coffee tasted better that day.
\n\n\n\nWhy Facelets cleans up JSF views
\n\n\n\nJSF 2 ships with Facelets as the default view handler. That change matters. JSP tried to be everything and ended up fighting the component tree. Facelets is XHTML first, compiles to the component tree cleanly, and plays nice with templating. You get tag composition, better reuse, and a layout that does not break every time you add a form. It is also easier on the server with fewer surprises at render time. On GlassFish v3 or Tomcat, Facelets pages feel steady and predictable.
\n\n\n\nTemplating basics that pay off
\n\n\n\nStart with a base template and fill slots with content. The Facelets ui:composition, ui:insert, and ui:define trio is all you need. Put your header, menu, and footer in one place. Then each page defines only what changes. Search engines like the cleaner markup and devs like the shorter diffs. Here is a tiny example that will cover most sites I see in the wild.
\n\n\n\n<!-- template.xhtml -->\n<!DOCTYPE html>\n<html xmlns="http://www.w3.org/1999/xhtml"\n xmlns:h="http://java.sun.com/jsf/html"\n xmlns:ui="http://java.sun.com/jsf/facelets">\n <h:head>\n <title><ui:insert name="title">My App</ui:insert></title>\n </h:head>\n <h:body>\n <header> <h:outputText value="Site Header"/> </header>\n <nav><ui:insert name="menu"/></nav>\n <section><ui:insert name="content"/></section>\n <footer> © <h:outputText value="#{now.year}"/> </footer>\n </h:body>\n</html>\n\n\n\n<!-- page.xhtml -->\n<ui:composition template="/WEB-INF/templates/template.xhtml"\n xmlns="http://www.w3.org/1999/xhtml"\n xmlns:h="http://java.sun.com/jsf/html"\n xmlns:ui="http://java.sun.com/jsf/facelets">\n\n <ui:define name="title">Products</ui:define>\n\n <ui:define name="menu">\n <h:link outcome="home" value="Home"/> |\n <h:link outcome="products" value="Products"/>\n </ui:define>\n\n <ui:define name="content">\n <h:form>\n <h:inputText value="#{productBean.query}" />\n <h:commandButton value="Search" action="#{productBean.search}"/>\n </h:form>\n </ui:define>\n\n</ui:composition>\n\n\n\nReusable slices and simple includes
\n\n\n\nBreak repeating pieces into Facelets fragments and pull them in with ui:include. You can pass parameters and keep pages tiny. Keep these fragments under WEB INF so they are not fetched directly. When a table or a sidebar changes, you touch one file and call it a day. The view stays consistent and QA is calmer. You also avoid copy and paste fatigue that ends in tiny bugs across the site. Here is a small include with a parameter for clarity.
\n\n\n\n<!-- include: /WEB-INF/fragments/pager.xhtml -->\n<ui:composition xmlns="http://www.w3.org/1999/xhtml"\n xmlns:h="http://java.sun.com/jsf/html"\n xmlns:ui="http://java.sun.com/jsf/facelets">\n <h:panelGroup rendered="#{bean.totalPages > 1}">\n Page #{bean.page} of #{bean.totalPages}\n </h:panelGroup>\n</ui:composition>\n\n<!-- usage -->\n<ui:include src="/WEB-INF/fragments/pager.xhtml">\n <ui:param name="bean" value="#{productBean}"/>\n</ui:include>\n\n\n\nPractical tips from real projects
\n\n\n\nStick to XHTML and the proper namespaces on every page. Prefer JSF tags for forms and output so the component tree stays honest. Use implicit navigation from JSF 2 to drop bulky configs. Put templates and fragments in WEB INF to keep crawlers out. For complex widgets, look at composite components in resources, which pair nicely with Facelets and keep markup tidy. On GlassFish or JBoss you get fast reloads with Facelets development mode, great for quick loops while you polish a layout.
\n\n\n\nSummary: Facelets gives JSF views a clean spine. Templates, includes, and composition remove duplication and stop layout drift. The code above is enough to ship pages that are easier to read, easier to test, and friendlier for search engines. If your JSF pages still live on JSP, move one screen to Facelets this week. The drop in noise is real, and your future self will send a thank you note.
\n\n\n