faces
faces copied to clipboard
h:html instead of f:view and/or f:metadata
As stated many times during the last 10+ years JSF is a framework generating HTML, and should not be used to generate json/xml reponse....
JSF is a MVC framework generating HTML, not some kind of a REST web service framework. You're essentially abusing JSF as a web service. Your concrete problem is simply caused by placing tags and so on > in the view file yourself.
https://stackoverflow.com/questions/10982762/how-to-generate-json-response-from-jsf
Is this still true?
If it's true why not simply create an h:html tag which should be like f:view and remove the f:metadata tag ?
In this way it would be possible to create a template or a page in a simpler and more linear way, for example:
<h:html xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:j="http://xmlns.jcp.org/jsf"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:o="http://omnifaces.org/ui"
lang="en"
locale="en"
transient="#{stateless}" >
<f:importConstants type="org.omnifaces.util.Faces" />
<c:set var="prod" value="#{conf.production}" scope="application" />
<!-- page meta -->
<ui:insert name="meta" />
<h:head>
<!-- template css ... -->
<!-- template analytics js... -->
<!-- template font preload... -->
<!-- page head -->
<ui:insert name="head" />
</h:head>
<h:body>
<div class="maincontent">
<!-- page body -->
<ui:insert name="body" />
</div>
<!-- template js ... -->
</h:body>
</h:html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:o="http://omnifaces.org/ui"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
template="/layout/template.xhtml">
<!-- Stateless View -->
<ui:param name="stateless" value="#{true}" />
<!-- page meta -->
<ui:define name="meta">
<f:viewParam name="id" value="#{bean.id}" />
<f:viewAction action="#{bean.init}" onPostback="false" />
</ui:define>
<!-- head -->
<ui:define name="head">
<title>Hello templating</title>
</ui:define>
<!-- body -->
<ui:define name="body">
<h1>Hello templating</h1>
</ui:define>
</ui:composition>
and remove the f:metadata tag ?
f:metadata is a kind of special tag that we can read without parsing or processing the entire page. In a way it's like a class annotation for xml.
OK that makes sense so its sort of a performance optimization as well
It could be parsed only the first time, usually the xhtml files never changes in Production...
The specs could say that f:importConstant / f:viewAction / f:viewParam should be on the first level children of h:html to optimize the performance ...
im sure this will not improve performance ;) its just another markup style / cosmetics for the user
it's not pure "cosmetic", the final intent is to improve the api to have a less hackish templating system which will be for sure easier to understand, specially for the beginners, and to avoid that people at Omnifaces have to implement alternative solutions like o:importConstant...
Hmm, it makes indeed sense to let h:html extend from f:view/UIViewRoot. But this will be a breaking change. Wondering why this was not done from the beginning on.