<% if (predicate) { %>
<p>my predicate was true</p>
<% } %>
2016-08-09
Avoid JSP scriptlets (except for prototyping)
Prefer JSP Expression Language
JSP EL Functions
Implicit Objects (JSP + EL)
Taglibs
There are a quite a few other template engines (for many languages including several for Java). Because CQ/AEM® is built in Java, I am focusing on the leading solution, JSPs (Java Server Pages), which is supported out of the box. It is certainly not the only template solution, but is the most mature and documented (just not necessarily by Adobe).
Initially, JSPs were created as an alternative to pure-Java Servlets. The problem with pure-Java (or any programming language) is the output looks nothing like the source code. Instead, templating should strive to make the source code look like the output as much as possible. Obviously, a certain amount of control (such as conditionals, looping, and imports) will look different than the output, but should strive to not look "out of place" in the source. Therefore, anything that looks foreign to HTML (and Java qualifies) should be minimized or eliminated.
Another problem with code in a JSP is testability. Template content is static, thus doesn’t have to be tested for different states. Java logic does need testing. Even if it worked in one state, Java code can throw runtime exceptions in another. Therefore, the best practice is to move as much logic as possible into bundles or custom taglibs. Either of these can be unit tested at build time (faster and earlier feedback compared to installing then functional testing).
In order to actually do anything interesting, Tag Libraries were created (especially the Core and Function taglibs). In the following 2 examples, compare the jaring shift in syntax and parsing of scriptlets with the relatively consistent syntax using a JSTL taglib. Java developers may consider the scriptlet syntax a small penalty, but it is actually brittle and uncomfortable for others. The effect compounds with more business logic and nesting.
<% if (predicate) { %>
<p>my predicate was true</p>
<% } %>
<c:if test="<%= predicate %>"> <%- Java expression sticks out slightly -%>
<p>my predicate was true</p>
</c:if>
OR
<c:if test="${predicate}"> <%- JSP EL even cleaner -%>
<p>my predicate was true</p>
</c:if>
JSP Expression Language was initially created to greatly simplify using Maps and Java Beans.
(Java Beans are just a standard with all properties are private, public getters/setters named after the properties, public no-arg constructors, and implements Serializable).
EL has operators (math, comparison, logical), some limited functions, and can call taglib functions ( such as ${fn:containsIgnoreCase(theString, 'TEST')}
).
In other words, EL simplifies JSP Expressions.
Example |
Java Expression |
JSP EL |
zip parameter |
|
|
query string |
|
|
access map |
|
|
map with illegal key |
|
|
bean getter |
|
|
get cookie |
N/A (have to walk |
|
The biggest disappointment with JSP-EL on AEM is the supported version. JSP-EL has supported calling methods (with arguments) since v2.2 (Servlet v3.0), but AEM 6.1 shows JSP 2.1/JEXL 2.0 (Apache Commons JEXL is the EL implementation loaded in AEM. Release Notes)
param
, paramValues
cookie
header
, headerValues
initParam
pageContext
pageScope
, requestScope
, sessionScope
, applicationScope
Type |
Example |
Purpose |
HTML |
|
Literal output - hopefully the bulk of the template |
Scriptlet |
|
External logic or organization. Useful for prototyping but confusing for production code. |
Expression |
|
Inject the value of the java expression (especially result of a function or method) into the template. NOTE: no semicolons. |
Directive |
|
Declare page attributes or include taglibs & classes. |
Tag Libraries |
|
(Standard Tag Library) or custom TagLibs. Encapsulate logic in a format that approaches XML with optional attributes depending on the tag. |
Group |
Usage |
Purpose |
CQ Tag Library |
|
AEM taglibs for safe text rendering, including components/ClientLibs |
Core Tags |
|
Logic for conditionals & looping. A few control features such as redirects or importing. |
String Functions |
|
Common string manipulation functions. |
Formatting |
|
Parsing & Output of set formats such as numbers & dates. Also internationalization. |
SQL |
|
Interacting with relational databases. |
XML |
|
Create and manipulate XML documents. |