Skip to main content

Enabling JSTL Support in JSP Templating

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:
  • 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;
Running the TBB above in Template Builder yields the following:

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

Popular posts from this blog

Running sp_updatestats on AWS RDS database

Part of the maintenance tasks that I perform on a MSSQL Content Manager database is to run stored procedure sp_updatestats . exec sp_updatestats However, that is not supported on an AWS RDS instance. The error message below indicates that only the sa  account can perform this: Msg 15247 , Level 16 , State 1 , Procedure sp_updatestats, Line 15 [Batch Start Line 0 ] User does not have permission to perform this action. Instead there are several posts that suggest using UPDATE STATISTICS instead: https://dba.stackexchange.com/questions/145982/sp-updatestats-vs-update-statistics I stumbled upon the following post from 2008 (!!!), https://social.msdn.microsoft.com/Forums/sqlserver/en-US/186e3db0-fe37-4c31-b017-8e7c24d19697/spupdatestats-fails-to-run-with-permission-error-under-dbopriveleged-user , which describes a way to wrap the call to sp_updatestats and execute it under a different user: create procedure dbo.sp_updstats with execute as 'dbo' as

Content Delivery Monitoring in AWS with CloudWatch

This post describes a way of monitoring a Tridion 9 combined Deployer by sending the health checks into a custom metric in CloudWatch in AWS. The same approach can also be used for other Content Delivery services. Once the metric is available in CloudWatch, we can create alarms in case the service errors out or becomes unresponsive. The overall architecture is as follows: Content Delivery service sends heartbeat (or exposes HTTP endpoint) for monitoring Monitoring Agent checks heartbeat (or HTTP health check) regularly and stores health state AWS lambda function: runs regularly reads the health state from Monitoring Agent pushes custom metrics into CloudWatch I am running the Deployer ( installation docs ) and Monitoring Agent ( installation docs ) on a t2.medium EC2 instance running CentOS on which I also installed the Systems Manager Agent (SSM Agent) ( installation docs ). In my case I have a combined Deployer that I want to monitor. This consists of an Endpoint and a

Debugging a Tridion 2011 Event System

OK, so you wrote your Tridion Event System. Now it's time to debug it. I know this is a hypothetical situtation -- your code never needs any kind of debugging ;) but indulge me... Recently, Alvin Reyes ( @nivlong ) blogged about being difficult to know how exactly to debug a Tridion Event System. More exactly, the question was " What process do I attach to for debugging even system code? ". Unfortunately, there is no simple or generic answer for it. Different events are fired by different Tridion CM modules. These modules run as different programs (or services) or run inside other programs (e.g. IIS). This means that you will need to monitor (or debug) different processes, based on which events your code handles. So the usual suspects are: dllhost.exe (or dllhost3g.exe ) - running as the MTSUser is the SDL Tridion Content Manager COM+ application and it fires events on generic TOM objects (e.g. events based on Tridion.ContentManager.Extensibility.Events.CrudEven