0

Sometimes pages don’t do what we want or expect. It’s easy when building out pages and content to bring together several pieces of content and/or widgets, and if you aren’t careful you could be getting variable collisions. Not resetting a query, reusing counters, etc can lead to headaches as you track everything down. This is one area that the page’s $context can come in handy.

What is $context?

$context is a Velocity object that is available on any page. It’s job is to encompass every variable that has been set anywhere on the page’s stack up until the point where you call it (Velocity processes linearly, so things happening after something else can’t be used to affect the earlier stuff). This is useful because it will allow you to see every single Velocity variable you have set on the page, which means you can debug where things are getting set, in case a variable is getting rewritten or reset improperly. You can also use it as a way of doing some more advanced logic on a page, outside of containers.

Getting stuff out of it

You can’t just echo out $context on the page, because it will return an object reference. But, it’s very easy to build a debug panel with it. Try dropping this code somewhere on one of your pages:

<fieldset>
    <legend>Page Context Debug ($!{context})</legend>
    <ul>
#foreach($key in $context.getKeys())
        <li><strong>$!{key} :</strong> $!{context.get($key)}</li>
#end
    </ul>
</fieldset>

This will print out a nice list of all the variables that are set and available to you in Velocity, everything from page variables, to content variables. You should recognize many of these, like $HTMLPAGE_META, $VTLSERVLET_URI, and $friendlyName. But there are probably others you didn’t know were there, like $SERVER_NAME$languages, and $HTML_PAGE_LAST_MOD_DATE.

So what can I do with it?

The obvious one is what I already mentioned: it’s a great way to see what variables are set on a page, and what they are set to at a given point in the page. So it’s a nice debugging tool. But it could also be a way to set things like dynamic page titles based on content in a container. This isn’t too hard on dynamic pages, but with normally static pages, it’s less obvious. You might want to do something like this in cases where you have a lot of pages that themselves have the same name, or maybe users aren’t savvy enough to always update the friendly name of a page (which is set automatically when the page title is set, but won’t change if you update the title later.). All you need are two variables from the $context: $totalSize12345, and $contentList12345 (where ‘12345’ is the inode for your primary container). Consider this:

## SEE IF THE CONTAINER HAS CONTENT IN IT
#if($totalSize12345 > 0)
    ## GRAB THE CONTENT MAP FOR THE FIRST CONTENTLET
    #getContent("$contentList12345.get(0)")
    #set($titleContent = $content)
    #set($dynamicTitle = {$!{titleContent.ContentletTitle} - ")
    ## STRIP HTML TAGS FROM THE WYSIWYG BODY AND TRIM IT TO A SHORT LENGTH
    #set($cleanBody = $titleContent.body.replaceAll('<(.|\n)+?>',''))
    #set($pageDescription = $UtilMethods.prettyShortenString($cleanBody,160))
#end
<html>
<head>
    <title>$!{dynamicTitle}$!{friendlyName} - YourSite.com</title>
#if($pageDescription.length() > 0)
    <meta name="description" content="$!{pageDescription}" /> 
#end
</head>
<body>
...

From there, you can start experimenting. For example, you can change the behavior of one container based on the content or number of contentlets in another container. If content appears in one template, you can apply different classes to it from another template. Having the information gives you the ability to introduce new ways of being flexible in templates, containers, and content.

No comments yet.

Leave a Reply