In my recent efforts on writing a Java Mediator for SDLTridion templating, I have now reached the point where I can write Template Building Blocks in JSP. Next is to enable JSTL support in the JSP TBB. That means to be able to use the Java Standard Tag Library (JSTL) and Expression Language (EL) in my JSP TBBs.
This functionality allows the following in a JSP TBB:
Next, for reading items from the package using EL, I had to extend a bit the PageContext.findAttribute() method. In EL, the expression ${variable} will end up in the pageContext.findAttribute(variable). This method is responsible with testing the existence of variable in each scope (e.g. page, request, session, application). In my fake implementation, I don't have session or application scopes; instead, I added a custom scope PACKAGE_SCOPE that is in fact backed up by the _package object I am passing into the PageContext (check out my previous post about a detailed explanation of this).
Therefore, in my FakePageContext.java class, I implemented the findAttribute method like this:
This functionality allows the following in a JSP TBB:
- declare a taglib in my JSP with a given prefix. The interesting part is the uri attribute -- which comes from the TLD (Tag Library Definition) file. For JSTL, the .tld files are contained in the JAR itself, under path META-INF/. Each uri identifies a unique .tld file. This way, the J2EE engine knows which .tld to load, and therefore, which implementation classes, tags and method signatures are available within that TLD;
- use EL to read variables from the package. Yes, it is cool! In the example below, expression ${UserName} reads the item with name UserName from the package and outputs its value;
So How Did I Do It?
First, I had to add the two JARs containing the JSTL implementation (standard.jar and jstl.jar) to the jni4net classpath. This gives instant access to the JSTL tags -- due to the fact that their TLDs are within the JAR itself, I don't have to bother with placing the TLDs in the classpath.Next, for reading items from the package using EL, I had to extend a bit the PageContext.findAttribute() method. In EL, the expression ${variable} will end up in the pageContext.findAttribute(variable). This method is responsible with testing the existence of variable in each scope (e.g. page, request, session, application). In my fake implementation, I don't have session or application scopes; instead, I added a custom scope PACKAGE_SCOPE that is in fact backed up by the _package object I am passing into the PageContext (check out my previous post about a detailed explanation of this).
Therefore, in my FakePageContext.java class, I implemented the findAttribute method like this:
public Object findAttribute(String name) {
Object result =
getAttribute(name);
if (result == null) {
result =
getAttribute(name, REQUEST_SCOPE);
}
if (result == null) {
result =
getAttribute(name, PACKAGE_SCOPE);
}
return result;
}
public Object getAttribute(String name, int scope) {
switch (scope) {
case PAGE_SCOPE:
return attributes.get(name);
case REQUEST_SCOPE:
return request.getAttribute(name);
case PACKAGE_SCOPE:
return _package == null ? null : _package.GetValue(name);
default:
throw new IllegalArgumentException("Invalid scope");
}
}
Next Steps
- EL expression on bean-like syntax (something similar to the Get eXtension) in order to allow some kind of EL like this ${component.fields.paragraph[0].bodytext};
- ability to set/modify items in the package: e.g. <c:set var="MyTitle" value="some value" scope="package"/>;
Comments