Proper using of Facelet templates & Composite Components
Asked Answered
T

1

7

I'm still not sure about proper using of JSF Templates & Composite Components. I need create an enterprise web applications, which will have a lot of pages. Every page will have the same header, menu, footer and of course different content (= JSF template). The content on every pages will consist of reusable "boxes" (= JSF composite components). The boxes consist of some fileds, buttons etc. Is my solution proper? Or should I use other technology like , Custom Components, decorate ...?

layout.xhtml

<h:body>
    <ui:insert name="main_menu">
        <ui:include src="/xhtml/template/main_menu.xhtml"/>
    </ui:insert>
    <ui:insert name="header">
        <ui:include src="/xhtml/template/header.xhtml"/>
    </ui:insert>
    <ui:insert name="content"/>
    <ui:insert name="footer">
        <ui:include src="/xhtml/template/footer.xhtml"/>
    </ui:insert>
</h:body>

customer_overview.xhtml:

<html xmlns:cc="http://java.sun.com/jsf/composite/composite_component">
<h:body>
    <!-- Facelet template -->
    <ui:composition template="/xhtml/template/layout.xhtml">
        <ui:define name="content">
            <!-- Composite Components -->
            <cc:component_case_history
                caseList="#{customerOverviewController.cases}"
            />
            <cc:component_customer
                ....
            />
            ...
        </ui:define>
    </ui:composition>
</h:body>

component_case_history.xhtml

<html xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
    <composite:attribute name="cases" type="java.util.List"/>
</composite:interface>

<composite:implementation>
    <!-- using of "cases" -->
    ...
</composite:implementation>

CustomerOverviewController.java

@ManagedBean
@ViewScoped
public class CustomerOverviewController {
    public List<Case> getCases() {
        ...
    }
}

EDIT 2012-04-27

Based on: When to use <ui:include>, tag files, composite components and/or custom components?

I think that I should use rather Facelet templates + Facelet tag files instead of Facelet templates + Composite components.

Thong answered 7/4, 2012 at 16:6 Comment(3)
Can you make your question more specific? The basic idea is that a template will have multiple clients, allowing re-use. All the clients then share the same look and feel, and navigate amongst each other. The xhtml is fairly straightforward, JSF 2.1 navigation not so much, in my (limited) experience. Of course, you can have code snippets, headers and what not, so that your HTML follows DRY. What are you asking? Incidentally, '@ManagedBean' is very different from '@Named', just for reference.Karalee
@Thufir: I'm asking if I should use for my web application JSF templating (base on your comment, the answer is YES) and If I should use for "boxes" which have to be reusable, JSF composite components, or something different (decorate, custom component) .. no sure. I don't know what you mean by " HTML follows DRY" and don't know why you mentioned '@ManagedBean' is very different from '@Named'.Thong
DRY=="Do Not Repeat yourself", see wikipedia. oh, I mentioned '@Named' because I'm fighting -- it has nothing to do with your question, sorry.Karalee
R
6

Layout, templating

layout.xhtml:

Every page will have the same header, menu, footer ...

In this case you can omit the ui:insert tags for header, menu, footer.

<h:body>
    <ui:include src="/xhtml/template/main_menu.xhtml"/>
    <ui:include src="/xhtml/template/header.xhtml"/>
    <ui:insert name="content"/>
    <ui:include src="/xhtml/template/footer.xhtml"/>
</h:body>

You may also have a ui:insert without name, so if you want to further simplify:

<h:body>
    <ui:include src="/xhtml/template/main_menu.xhtml"/>
    <ui:include src="/xhtml/template/header.xhtml"/>
    <ui:insert/>
    <ui:include src="/xhtml/template/footer.xhtml"/>
</h:body>

customer_overview.xhtml:

If you have ui:insert without name in layout.xhtml, you don't need ui:define here:

<ui:composition template="/xhtml/template/layout.xhtml">
        <!-- Composite Components -->
        <cc:component_customer/>
        <cc:component_case_history
            caseList="#{customerOverviewController.cases}"
        />
        ...
</ui:composition>

Also you should place your templates in a folder that users cannot access directly (WEB-INF).

reusable "boxes"

One of your composite component looks like this:

<cc:component_customer/>

A component without any attributes is very suspicious.

  • What does it do?
  • displays a username?
  • how does it get the username if you don't pass any attributes?

A component should be self-contained, for other reusable parts use ui:insert instead.

Recapitulate answered 8/4, 2012 at 10:42 Comment(1)
I've fixed <cc:component_customer/> tag to avoiding misunderstanding.Thong

© 2022 - 2024 — McMap. All rights reserved.