Getting contentTypeId of included item in AutoIndex

Hi,

We have a generic XML template for all our content-types. In the bindings I have defined contentTypeId using rx:sys_contenttypeid. In this way I can modify the XML for any type using an #if statement.

This works fine when you are previewing the output against different content-types.

However, when the template is used as part of an autoindex, the binding variable takes the content type ID of the AutoIndex. What I need is for this to be looking at the IDs of the individual items.

Any ideas how I go about this?

We have done something similar, but we are using the content type name (.getPrimaryNodeType().getType()) to figure out the content type as the id has the potential to change between server instances. We have a custom slot macro for an auto indexer that goes through the slot items to figure out how to display the node (based on the content type).

I’ve done almost exactly the same thing… Although I’ve not tried to use an AutoIndex with it.

My solution was to load velocity code from content-type specific sub-templates and execute that code within the context of the main template. The way I determined what template should be used is by a common prefix followed by the content type name (sans company prefix) of the item being assembled. So, if I had a content type called “myCoolBeans”, and the prefix I use is “myPrefix_”, then the sub-template it would try to load would be “myPrefix_CoolBeans”.

Also of note, the result of executing the template is saved in the $sys.innercontent variable, so you would output the result with #inner(). However, since the inner template executes within the context of the main template, you can manipulate variables in the main template and hide the inner template’s output altogether.

In my case, I define a map in the setup block, and add to it in the inner templates. I then output the elements of the map after the inner template executes without outputting the test of the inner template’s output except in preview mode.

Here’s the code I used.


#set($sysBindingKeys = $sys.ctx.keys)
#set($contentId = $sys.params.sys_contentid[0])
#set($ct = $sys.item.definition)
#set($ctName = $ct.internalName)
#set($tmplName = $ctName.replaceAll('^[^A-Z]*','myTmpl_'))

... do setup stuff for all items using the template ...

#callInnerTemplate($tmplName $sysBindingKeys)
#if($isPreview)
#inner()## Output any debugging information from inner template
#end

... do the main shared output ...

The body of the #callInnerTemplate macro is in my User Velocity Macros system configuration file and looks like this:


## Calls a content-type-specific template if one exists, binds any
## of the called template's bindings to the local context, executes
## the template within the local context, and saves the result in
## $sys.innercontent which can be retrieved with #inner()
#macro(callInnerTemplate $tmplName $sysBindingKeys)
#set($sys.innercontent = '')
#foreach($innerTemplate in $sys.asm.findTemplatesByContentType($sys.item.definition.GUID))
#if($innerTemplate.name == $tmplName)
## Build an evaluator for the type-specific template's bindings.
#set($evaluator = $sys.class.forName('com.percussion.utils.jexl.PSJexlEvaluator').newInstance())
#foreach($key in $sysBindingKeys)
#set($p = $key.indexOf('.'))
#if($p != -1)
#set($key = $key.substring(0,$p))
#end
$evaluator.bind("${tools.esc.getD()}$key",$sys.ctx.get($key))##
#end
$evaluator.bind("${tools.esc.getD()}elements",$elements)##
## Evaluate the type-specific template's bindings and add them to the global variables.
#foreach($binding in $innerTemplate.bindings)
#set($expr = $evaluator.createExpression($binding.expression))
#set($var = $binding.variable)
#set($val = $evaluator.evaluate($expr))
#set($expr = "${tools.esc.getH()}set($var = ${tools.esc.getD()}val)")
#evaluate($expr)
#end
## Evaluate the type-specific template and store the results to the default innercontent var.
#set($sys.innercontent = "#evaluate($innerTemplate.template)")
#end
#end
#end

Please let me know if this is at all helpful.