The Picker is the template engine provided by AgileSites to implement the "original html" templating features.
The actual library implementing the Picker is the JSoup Library and inherits its selector syntax. All the available selectors are described in detail here
Here there is a guide to the Picker, including a reference list for the selector syntax, literally copied from here is available next, and a guide to the available methods.
For the examples, please consider the /sample.html
resource is the following:
<div id="title">
<h1>Hello</h1>
</div>
<div id="content">
<p>How are you?</p>
</div>
<div id="menu">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
</div>
and that the selector syntax #content
will select the part of the html with id="content"
Picker mostly load snippets of html, parse them allowing to replace it with the content taken from the CMS and finally returns the HTML as string.
Html resources are bundled in the jar of the application. More specifically all the .html and .htm files placed under the directory app/src/main/static
are packaged in the jar.
You need to use an absolute path inside the jar to locate resources, using direct slashes.
Here some samples of loading:
Load the html from a resource in the jar (packaged from the original placed under app/src/main/static/mysite/template.html
)
Picker.load("/mysite/resource.html")
Load from the same resource as before the html block identified by the selector "#content" (see below for the selectors):
Picker.load("/mysite/resource.html", "#content")
You can create a picker using literal html if you need it (typically if it is a small piece of html):
Picker.create("<h1>Title<h1>")
If you load a snippet of html like this
Picker p = Picker.load("/sample.html", "#title")
To get the whole block selected you use p.outerHtml()
:
<div id="title">
<h1>Hello</h1>
</div>
If you instead use p.html()
you will output only the inner part of the loaded html.
<h1>Hello</h1>
The picker can perform a replacement using the "moustache" syntax.
Anything that in the html has the format `can be replaced by a value coming from a source passed to the method
htmland
outerHtml`.
The source is a object that implements the interface Content
. Note that both Asset
and Env
implements this interface so you can pass them as a source.
You can also create a new Content
on the fly using model(arg("Key", "Value"), arg("Key", "Value"))
(model
and arg
are defined in the import static wcs.Api.*
).
As an example, if you have this snippet of html in a template:
<h1></h1>
<b>by </b>
<p><p>
Now, assume that you have an asset a
with an attribute named "Body" and a variable "author" in the current enviroment (in variable e
). Also you want to set the title from the name of the asset. You can then do this way:
html.outerHtml(e, a, model(arg("Title", a.getName()))
The variable Title
will be then located in the name, the variable author
will be extracted from the enviroment and the attribute Body
from the attribute Body
of the asset.
The picker uses the css selector syntax (very similar to the syntax used by the jQuery library) to locate parts of html you want to change.
You use selectors almost everywhere:
Picker.load(resource, selector)
: load a resource then select to the part of the html identified by the selectorPicker.select(selector)
: restrict to the part of the html identified by the selectorPicker.replace(selector, string)
: replace the part indentifed by the selector with the string[attr^=value], [attr$=value], [attr*=value]: elements with attributes that start with, end with, or contain the value, e.g. [href*=/path/]
[attr=value]: elements with attribute value
[attr~=regex]: elements with attribute values that match the regular expression; e.g. img[src~=(?i).(png|jpe?g)]
*: all elements,
Note that the above indexed pseudo-selectors are 0-based, that is, the first element is at index 0, the second at 1, etc.
Let's see which replacements methods are available with some samples
Replace is the most used method:
Picker.load("/sample.html", "#content")
.replace("p", "welcome")
.outerHtml()
Result:
<div id="content">
<p>welcome.</p>
</div>
You can return a single instance of a sequence of items, append, prepend and remove items.
Check those examples:
Picker p = Picker.load("/sample.html", "#menu li");
p.single("li").html();
Result:
<ul>
<li>First</li>
</ul>
Code:
p.after("li", "<li id=\"second\">Second</li>");
p.before("#second", "<li>One and Half</li>");
p.remove("li:eq(1)")
p.html();
<ul>
<li>One and Half</li>
<li id="second">Second</li>
</ul>
Some samples of replacement and removal of attributes:
Code:
Picker.load("/sample.html", "#title")
.addClass("h1", "demo")
.attr("h1", "test", "demo")
.removeAttrs("div", "id")
.outerHtml();
Results:
<div id="replaced">
<h1 test="demo" class=" demo">Hello</h1>
</div>
Picker lets you to temporarily restrict to a part of the html you are working with, with p.select(selector)
.
All the replacements then will happen only in the selected part. You can restrict further with other select, and you can come up to the stack of the selections with up.
NOTE the selections does not affect the output: p.html()
and p.outerHtml()
will return the whole originally loaded snippet of html.