Lil Josh

A tech blog about web development with PHP, MySQL, jQuery, CSS3 and various other programming languages.

Velocity Cheat Sheet

September 24, 2014

Setting a Variable

#set($varName = "example value")

Using a Variable

<h1>$varName</h1>

Comments

##Comments have two pound signs in front

XPath Tool (Single Node)

#set($firstName = $_XPathTool.selectSingleNode($contentRoot, "firstName").value)
##$contentRoot is a special variable to select the root of the structured data for the page/block
##.value gets the value of that node

XPath Tool (Multiple Nodes)

#set($people = $_XPathTool.selectNodes($contentRoot, "people"))
<p>There are $people.size() people</p>

For Each Loop

#foreach($person in $people)
#set($firstName = $_XPathTool.selectSingleNode($person, "firstName").value)
##notice we used $person instead of $contentRoot this time
#end

**NEW – Query API**

#set($pages = $_.query().byContentType('News Article').maxResults(3).hasMetadata('category', 'sports').sortBy('created').sortDirection('desc').execute())
#set($query = $query.includePages(true))
#set($query = $query.includeFiles(false))
#set($query = $query.includeFolders(false))
#set($query = $query.includeBlocks(false))
#set($query = $query.includeSymlinks(false))
#set($query = $query.siteName("Global"))
#set($query = $query.publishableOnly(true))
#set($query = $query.indexableOnly(true))

Serialize Tool (Getting WYSIWYG HTML)

#set($wysiwyg = $_XPathTool.selectSingleNode($contentRoot, "wysiwygName"))
$_SerializerTool.serialize($wysiwyg, true)
##true means that it'll skip the root element of the wysiwyg which is not part of the HTML content

Locator Tool

#set($page = $_.locatePage("/WRAP_SDDU/IU-CONTAINER-NAME/site-name/path/to/page"))
<h1>$page.metadata.title</h1>

Date Tool

#set($currentPage = $_.locatePage($currentPagePath, $currentPageSiteName)) 
#set($date = $currentPage.createdOn)
$_DateTool.format('dd MMM Y', $date)

Property Tool

$_PropertyTool.outputProperties($currentPage) 
## Check if object exists
#if(!$_PropertyTool.isNull($currentPage.structuredData)))
EXISTS
#end
## use this macro to make it easier to remember
#macro(properties $object)
$_PropertyTool.outputProperties($object)
#end
#properties($object)

Importing Scripts

#import('/WRAP_SDDU/IU-CONTAINER-NAME/site-name/_internal/stylesheets/functions')

Sorting

#set($people = $_XPathTool.selectNodes($contentRoot, "people"))
##parameters are selection string, language, type of element, sort order, and case order
$_SortTool.addSortCriterion("lastName", "en", "text", "ascending", "upper-first") 
$_SortTool.sort($people) 

Defining Macros (Functions)

#macro(macroName $param)
<h1>$param</h1>
#end
#macro(type $object)
$object.identifier.type
#end

Using Macros/Functions

#macroName($param)

More examples at https://github.com/hannonhill/Velocity-Cookbook

More documentation at http://www.hannonhill.com/kb/Script-Formats/ and http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html

Query API:

https://hannonhill.jira.com/browse/CSI-812

Community Macros/Functions

## type - takes an object and shows what type of asset it is
#macro(type $object)
$object.identifier.type
#end
## properties - takes an object and shows what properties are available
#macro(properties $object)
$_PropertyTool.outputProperties($object)
#end
## getChildren - takes a folder object and creates a children variable
#macro(getChildren $object)
#if($object.identifier.type != "folder")
#set($children = $object.parentFolder.children)
#else
#set($children = $object.children)
#end
#end
## getMetadata - takes an object and looks for the metadata
#macro(getMetadata $object $metadata)
#if($metadata == "title")
$!object.metadata.title
#elseif($metadata == "teaser")
$!object.metadata.teaser
#elseif($metadata == "reviewDate")
$!object.metadata.reviewDate
#elseif($metadata == "startDate")
$!object.metadata.startDate
#elseif($metadata == "keywords")
$!object.metadata.keywords
#elseif($metadata == "displayName")
$!object.metadata.displayName
#elseif($metadata == "endDate")
$!object.metadata.endDate
#elseif($metadata == "author")
$!object.metadata.author
#elseif($metadata == "summary")
$!object.metadata.summary
#elseif($metadata == "description")
$!object.metadata.description
#elseif(!$_PropertyTool.isNull($object.metadata.getDynamicField($metadata).value))
$!object.metadata.getDynamicField($metadata).value
#else
$!object.path
#end
#end
apache cascade server cheat sheet hannon hill Locator Tool macros Query API velocity

Cascade Server’s Index Blocks vs Locator Tool vs Query API

September 22, 2014

I’ve compared performance using Cascade Server’s Index Blocks, Velocity Locator Tool and the new (as of version 7.12.2) Query API.

The method:

I setup 3 configurations in a configuration set to get a little over 800 assets.

  1. use an index block that includes metadata and XML inline (i.e. structured data)
  2. use velocity’s locator tool to loop through folders and get children down 3 levels.
  3. use velocity’s Query API to get pages of a specific content type (no limit)

The implementation:

Index block without XML inline:

Screen Shot 2014-09-23 at 10.00.11 AM

with XML inline:

Screen Shot 2014-09-23 at 10.00.32 AM

Velocity Locator Tool:

#set($articlesFolder = $_.locatePage($currentPagePath, $currentPageSiteName).parentFolder)
#set($years = $articlesFolder.children)
#foreach($year in $years) 
#if($year.identifier.type == "folder")
#foreach($month in $year.children)
#foreach ( $article in $month.children )
#if($article.metadata.startDate)
#set ( $title = $article.metadata.title.replaceAll("&amp;","&").replaceAll("&","&amp;") )
#set ( $link = $article.path )
#set ( $startDate = $article.metadata.startDate)
#set ( $category = $article.metadata.getDynamicField("category").value )
#set ( $categoryStripped = $category.replaceAll("-", " ") )
<li class="article $category">
<span class="date $category">$_DateTool.format('MMMM d, yyyy', $startDate)</span> <a href="$link" class="title">$title</a>
<div class="category $category">$categoryStripped</div>
</li>
#end ## start date
#end ## articles
#end ## month
#end ## type
#end ## year

Velocity Query API:

#set($articles = $_.query().byContentType('article').maxResults(9999).sortBy('startDate').sortDirection('desc').indexableOnly(true).publishableOnly(true).execute())
#foreach ( $article in $articles )
#if($article.metadata.startDate)
#set ( $title = $article.metadata.title.replaceAll("&amp;","&").replaceAll("&","&amp;") )
#set ( $link = $article.path )
#set ( $startDate = $article.metadata.startDate)
#set ( $category = $article.metadata.getDynamicField("category").value )
#set ( $categoryStripped = $category.replaceAll("-", " ") )
<li class="article $category">
<span class="date $category">$_DateTool.format('MMMM d, yyyy', $startDate)</span> <a href="$link" class="title">$title</a>
<div class="category $category">$categoryStripped</div>
</li>
#end ## start date
#end ## article

The results:

Index blocks were fast if only indexing metadata and not including XML inline (i.e. the structured data)Screen Shot 2014-09-22 at 4.20.54 PM:

but as soon as you need any of the data from the structured data it slows down significantly:

Screen Shot 2014-09-22 at 4.16.52 PM

 

 

The Locator Tool was just slow, which makes sense, because it’s a nested loop getting objects for each iteration. That’s a lot of interactions with the system.

Screen Shot 2014-09-22 at 4.17.42 PM

 

 

The Query API is also fairly slow when dealing with large sets of data… keep in mind the objects returned with the Locator Tool and the Query API include metadata AND structured data.

Screen Shot 2014-09-22 at 4.18.10 PM

What we can learn from the tests

If you’re only using the metadata from assets then definitely go with Index Blocks

If you’re also using structured data from assets then you’ll likely need to use the Locator Tool and/or the Query API. Index blocks take much longer to render and usually have a limit to number of pages to index. The Query API does allow for sorting and filtering by metadata and content type which could be considerably faster than using the Locator Tool to filter through objects.

Note: here is Hannon Hill’s official statement on Velocity Locator Tool and Performance

Locator Tool can be considered an alternative to Index Blocks altogether. Most formats that use Index Blocks could be rewritten to use Locator Tool instead. Using the Locator Tool in general is much slower than retrieving assets with an Index Block, in that for example, an Index Block with 1,000 assets rendered will generally complete rendering much faster than if a Locator Tool was to perform locate() calls 1,000 times, especially if Index Block rendering cache is used. However, in most cases, the reason for rendering so many assets in an Index Block is only so that it encompasses just a few assets that are really needed for the rendering of a specific Page, such assets being usually spread out across the system. In these scenarios, using the Locator Tool just a few times versus rendering an Index Block with 1,000 assets in it is going to be much faster and a better solution.

To prevent the possibility of a Velocity Format from rendering too slowly or taking too many system resources, and therefore to prevent the Velocity Formats from potentially making the system unstable, the maximum Format transformation time has been set to 5 minutes. After that time, the rendering process will stop, also preventing the Page from getting published. To prevent this from happening, developers should be careful of the number of times the Locator Tool is being used as well as number of times referencing properties are being accessed (examples: asset’s parent Folder, Folder’s children, an asset selected through structured data asset chooser).

cascade server Locator Tool Query API velocity

Time to update your WordPress to 4.0!

September 8, 2014

4.0 upgrade Wordpress

Searching entire Dreamweaver site for files by content

I often want to search my entire site for files that contain a specific word, phrase or string. The best way to do this, that I found, was to GET the entire Dreamweaver site to your computer so now you have all the files locally. Then you can use Dreamweaver search (CTRL + F) to search the entire local site for content. Hope this helps and if not here are some additional sources:

http://webdesign.about.com/od/dreamweaverhowtos/ht/dw_find_replace.htm

http://www.wrensoft.com/zoom/support/dreamweaver.html

http://helpx.adobe.com/dreamweaver/using/live-search-mac.html

content dreamweaver entire site search