encodeBegin vs encodeEnd in JSF and which one should be preferred - jsf

I am using the javax.faces.render.Renderer class to render my custom components. I override either encodeBegin or encodeEnd to achieve my desired output.
I would like to know when should I use either of these methods? Is there any guideline on when should encodeBegin and encodeEnd be used?

That depends on the component tree hierarchy. Key is, do you expect children? How do you want the encoded output to look like when there are children?
Usually, you use encodeBegin() if you want to encode output before children are encoded. E.g. a start tag like HTML <div>. Usually, you use encodeEnd() if you want to encode output after children are encoded. E.g. an end tag like HTML </div>. Or perhaps an additional <script> which should work on the before-generated <div>.

Related

Allow only specific tag in <h:outputText> [duplicate]

Is there any HTML sanitizer or cleanup methods available in any JSF utilities kit or libraries like PrimeFaces/OmniFaces?
I need to sanitize HTML input by user via p:editor and display safe HTML output using escape="true", following the stackexchange style. Before displaying the HTML I'm thinking to store sanitized input data to the database, so that it is ready to safe use with escape="true" and XSS is not a danger.
In order to achieve that, you basically need a standalone HTML parser. HTML parsing is rather complex and the task and responsibility of that is beyond the scope of JSF, PrimeFaces and OmniFaces. You're supposed to just grab one of the many existing HTML parsing libraries.
An example is Jsoup, it has even a separate method for the particular purpose of sanitizing HTML against a Safelist: Jsoup#clean(). For example, if you want to allow some basic HTML without images, use Safelist.basic():
String sanitizedHtml = Jsoup.clean(rawHtml, Safelist.basic());
A completely different alternative is to use a specific text formatting syntax, such as Markdown (which is also used here). Basically all of those parsers also sanitize HTML under the covers. An example is CommonMark. Perhaps this is what you actually meant when you said "stackexchange style".
As to saving in DB, you'd better save both the raw and parsed forms in 2 separate text columns. The raw form should be redisplayed during editing. The parsed form should be updated in background when the raw form has been edited. During display, obviously only show the parsed form with escape="false".
See also:
Markdown or HTML

Embed HTML in JSF [duplicate]

Is there any HTML sanitizer or cleanup methods available in any JSF utilities kit or libraries like PrimeFaces/OmniFaces?
I need to sanitize HTML input by user via p:editor and display safe HTML output using escape="true", following the stackexchange style. Before displaying the HTML I'm thinking to store sanitized input data to the database, so that it is ready to safe use with escape="true" and XSS is not a danger.
In order to achieve that, you basically need a standalone HTML parser. HTML parsing is rather complex and the task and responsibility of that is beyond the scope of JSF, PrimeFaces and OmniFaces. You're supposed to just grab one of the many existing HTML parsing libraries.
An example is Jsoup, it has even a separate method for the particular purpose of sanitizing HTML against a Safelist: Jsoup#clean(). For example, if you want to allow some basic HTML without images, use Safelist.basic():
String sanitizedHtml = Jsoup.clean(rawHtml, Safelist.basic());
A completely different alternative is to use a specific text formatting syntax, such as Markdown (which is also used here). Basically all of those parsers also sanitize HTML under the covers. An example is CommonMark. Perhaps this is what you actually meant when you said "stackexchange style".
As to saving in DB, you'd better save both the raw and parsed forms in 2 separate text columns. The raw form should be redisplayed during editing. The parsed form should be updated in background when the raw form has been edited. During display, obviously only show the parsed form with escape="false".
See also:
Markdown or HTML

How to render a block in JSF, similar to Tapestry <delegate to="xxx"> tag

I am trying to convert a Tapestry application to JSF.
Tapestry has a useful feature, block.
You can have many blocks (typically html snippets) on a page,
and then, using the <delegate to="block"> component, choose one block
and render it dynamically at runtime.
Here is the Tapestry block documentation:
http://tapestry.apache.org/5.3.7/apidocs/org/apache/tapestry5/corelib/components/Delegate.html
The closest thing I could find is <ui:include src="#{sampleBean.block}"/>
where sampleBean.getBlock() returns something like "/templates/block1.xhtml"
at runtime.
This solution forces me to have many small block files, which I don't think is efficient
or the best way to go.
Does nyone have a better solution? Thanks.
I solved this <ui:include>ing template that contains series of blocks, and using a parameter, only one would be rendered at a time

Add target property for dropdownnode in Widget Container

I would like to add a target (e.g. _blank) property for a basicLeafNode on the Widget Container from the extension library.
I do not see the property for this.
Instead I could use the onClick property and return an URL. But then I still would have no target defined.
I could add a postScript method
var target = url;
view.postScript("window.open('"+target+"','_blank')")
but this fires when the container is loaded.
Can I add a target property without using the onClick Property?
In case I use the onClick property what method should I use or how I prevent the postscript is executed when the container is loaded?
The basicLeafNode doesn't currently provide a target property. You have 2 courses of action:
implement your own custom node as Michael suggested (hard)
use a class on the link e.g. "newpageopen" and add an onPageReady script that selects all a elements with the calss newpageopen and add the target property to the resulted HTML.
Something like this:
require(["dojo/ready","dojo/query"], function(ready){
ready(function(){
dojo.query("a.newpageopen").attr("target", "_blank");
});
});
Hope that helps;
To make this list of solutions a bit longer here another on wich does not require dojo or jquery:
Instead of using your code as SSJS like:
var target = url;
view.postScript("window.open('"+target+"','_blank')")
You can use the Client Side Code and add SSJS code in #{javascript:}' wich i think is the shortest solution on this Problem. Here a hardcoded example:
<xe:basicLeafNode>
<xe:this.onClick><![CDATA[window.open('#{javascript: return "http://www.google.com";}','_blank');]]></xe:this.onClick>
</xe:basicLeafNode>
the above example will also work with viewScope variables or SSJS funktions:
<xe:basicLeafNode>
<xe:this.onClick><![CDATA[window.open('#{javascript: return viewScope.url;}','_blank');]]></xe:this.onClick>
</xe:basicLeafNode>
You can add the target attribute using JavaScript. It's kind of inconvenient way but would work.
You can use dojo.query to query the HTML output generated by basicLeafNode on the Widget Container. Once you get the node of <a> then you can add attribute using dojo.attr.
One problem you might face is that the ID generated by XPages contains the character :, which will not work so you would have to escape it.
function escapeColon(controlID) {
return controlID.replace(/:/g, "\\3A");
}
So your code would be something like:
dojo.addOnLoad(function() {
dojo.attr(dojo.query(escapeColon("#{id:ID_of_basicLeafNode}") + " > a")[0], "target", "_blank");
});
The code escapeColon("#{id:ID_of_basicLeafNode}") + " > a" would generate a CSS selector. Here I am assuming that basicLeafNode on the Widget Container would generate something like this <div id="_id1:basicLeafNode"><a href=".... So the CSS selector would search for a tag with that ID and inside it the <a> tag. You would have to modify this based on the output that is generated.
As I said its a bit inconvenient. Also I haven't tested this code.

How to display HTML inside h:inputTextarea

How to display value with HTML tag inside h:inputTextarea?
In DB I have column contain data, it contain plain text and HTML tag, I want display it on h:inputTextarea. How can I do it?
i want display HTML inside h:inputTextArea it mean in DB contain <br/> or <b> and </b> , when it display on h:inputTextArea it must display bold or break line.
That's not possible due to the nature of HTML <textarea> element. Even, if it was possible this puts doors wide open to XSS injection attacks. Also, how would you ever let the enduser edit the markup in the textarea like changing bold to for example italics or to add another markup? That's plain impossible with a <textarea>.
If your sole intent is to have a rich text editor, then you need to homegrow one with help of a <div> and a good shot of JavaScript or, better, use an existing JSF component which achieves this. For example, PrimeFaces' <p:editor>.
Or, if your sole intent is to display it only, then use <h:outputText> with the escape attribute set to false. Once again, keep XSS risks in mind.
Use the f:verbatim tag -> JSF Verbatim Tag

Resources