Caching In: Revisiting Data Sharing across Templates

A while back I wrote a post on using Context Variables as a templating cache. When I came across some requirements to cache data between templates on a recent project I revisited this concept, but found some limitations with Context Variables which I had not realized before. As such I ended up implementing a different approach to caching

Continue reading

SDL Web Design Pattern: “Slicing”

As a Tridion an SDL Web developer, you’ve very likely converted a single block of HTML design into appropriate Tridion Building Blocks. The idea of breaking a page into types of content, represented in Tridion as Component Presentations, is not new to you. But have you “sliced” a Component by sets of fields?

A few months back, Damian Jewett, explored the idea of multiple Template Layout Building blocks. I’m following up with a potential use case for this approach along with a parallel idea with Component Templates instead. We can call this slicing, where we have a consistently used subset of fields out of a collection of Component fields.*

*I first heard the term “slice,” in a slightly different context, from a French design agency after they learned how Tridion worked.

First read Damian’s post. Continue reading

TcmTemplateSync: Work with TBBs outside of Tridion:

Working with TBBs outside Tridion? Nothing new there you say – I already edit my DWTs in Dreamweaver and my .NET TBBs in Visual Studio. But what about those other commonly used TBB types; Razor and XSLT, what if you don’t like Dreamweaver (or don’t have a license)? Now there is a tool to help you sync local copies of TBBs with the CMS, and break free from editing them in the CMS GUI: TcmTemplateSync Continue reading

Inside SI4T search integrations : Controlling what gets indexed

si4t-logoThe open source SI4T (Search Integration for Tridion) project allows you to pass through 3 levels of control over what content gets indexed: Firstly, the default, zero-configuration behaviour. Then there is fine-grained configuration via metadata and parameters, and finally total extensibility by coding your own indexing TBBs. This article talks through how you can refine your indexing strategy by passing through these levels. Continue reading

Quick TBB – Serialize Component as JSON

JSON LogoWhile doing some preparation for a hackathon on client-side templating (ie javascript in the browser) on our upcoming SDL Tridion MVP retreat, I created a simple component JSON serializer TBB. This basically takes the TOM.NET Component object and converts it into a JSON format which is friendly for Javascript templating frameworks like Knockout.

Continue reading

Avoid Static Variables in Tridion Templates

I’ve recently helped a client resolve some interesting issues with their Tridion template building blocks. The issue was that when publishing the first time desired results were produced by the template. However, when publishing many pages, or republishing the same page/component presentation, subsequently produced strange output results.

The logic in our TBB parsed the Output item in the package and made various manipulations to it. I won’t get into the details of that. The issue was due to having static private variables declared within the TBB. These variables were various data structures and primitives manipulated by methods within our ITemplate-inherited class. The methods themselves had to also be declared as static.  Refactoring the code away from “static” resolved the issue.

Here is why you cannot use static variables in Tridion templates:  Primarily because they become global shared variables across all publish threads.  Here is what the Tridion TOM.NET Session and Engine class API states regarding this matter:

IMPORTANT NOTE: Session objects are not thread-safe; you must not share Session objects across threads. Furthermore, the thread that creates a Session object should be in a Single Threaded Apartment (STA), since the Session will internally create an Apartment Threaded COM object. See SetApartmentState(ApartmentState). 

The Tridion Session object, which the Engine uses (or, as the docs put it, “aggregates”) subscribes to the Single Threaded Apartment model (STA).

An STA is basically a model where the server controls the threads, and each individual thread must not spin off additional sub-threads that depend on the STA-controlled objects. So in our case: the Tridion CM is the server that spins off and controls threads (e.g. we can publish many items simultaneously), and each template is executed within it’s own thread. So if we develop a template that spins of other threads, the common memory across threads, i.e. static variables, isn’t managed.  So STA threads can overwrite each other.

Here is a snippet from an article explaining STAs in much more detail:

…all access to global variables and functions of the server will need to be serialized properly because more than one object may try to access these from different threads. This rule also applies to class static variables and functions. [http://www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa]

So in a common scenario, when is it appropriate to use “static” within a TBB? Well, how about in procedural methods that take some inputs, create new objects, massage them and return them. In other words, if the method is self-contained. A Utility class is a common such scenario.

In conclusion, don’t use static variables inside your TBBs or Event System code.

DWT strings, integers and repeatable fields

I was reviewing a solution I’ve been working on and noticed that at one point I was pushing out a ‘QuantityOfListItems’ from C# into the package – and couldn’t recall why.

On further investigation I saw that I was using this in the DWT to detect when I was on the last list item so I could compare this with the TemplateRepeatIndex value. Although it all worked fine it felt like overkill to rely on C# for something so trivial and didn’t add any value so I had a scoot around.

I found a CollectionLength built-in function that looked like it might be just what the Dr. ordered…

So… the reason for the post… It took quite some phaffing to tweak the syntax for this – just due to the fact I’ve had my head in C# code more than I have DWT lately so I thought I’d share it!

All I need to do is check

  • if the current index of the item in the repeatable field is the first then print the opening tags
  • write out the repeated syntax/value for each instance of the repeatable field
  • if the current index of the item in the repeatable field is the last then print the closing tags
First attempt:
<!-- TemplateBeginRepeat name="Component.Fields.repeatField" -->
 <!-- TemplateBeginIf cond = "TemplateRepeatIndex == 0 " -->
 <ul>
 <!-- TemplateEndIf -->
 <li>@@Field@@</li>
 <!-- TemplateBeginIf cond = "TemplateRepeatIndex == @@CollectionLength("repeatField")@@" -->
 </ul>
 <!-- TemplateEndIf -->
<!-- TemplateEndRepeat -->

OK, so the obvious error – TemplateRepeatIndex is 0 based whilst the CollectionLength returns a 1 based  result! The other syntax is pretty standard so we’ll concentrate on the test for the last index item.

<!-- TemplateBeginIf cond = "TemplateRepeatIndex == @@CollectionLength("repeatField")-1@@" -->

No Joy. So I have another scoot around and find an interesting StackOverflow post reminding me the value returned is a string. As we need to perform an integer calculation and comparison we need to parse the value to an integer.

<!-- TemplateBeginIf cond = "TemplateRepeatIndex == @@parseInt(${CollectionLength("repeatField")})@@-1" -->

Now I’m using the debug method Frank van Puffelen describes in his StackOverflow posting and all appears well – I can see the CollectionLength and the TemplateRepeatIndex are both 1 and the end tag still isn’t written out.

See the deliberate error (well it wasn’t deliberate and it was one of those annoyingly simple things that I’m sure others will trip up on!).  Although our first comparison with TemplateRepeatIndex and == 0 above is with an integer and it works as we want (even if the comparison is against a non-zero integer) I figured I’d try to parseInt the TemplateRepeatIndex…

<!-- TemplateBeginRepeat name="Component.Fields.repeatField" -->
 <!-- TemplateBeginIf cond = "TemplateRepeatIndex == 0 " -->
 <ul>
 <!-- TemplateEndIf -->
   <li>@@Field@@</li>
 <!-- TemplateBeginIf cond = "@@parseInt(TemplateRepeatIndex)@@ == @@parseInt(${CollectionLength("repeatField")})@@-1" -->
 </ul>
 <!-- TemplateEndIf -->
<!-- TemplateEndRepeat -->

Success!

Hopefully this simple pattern can assist you in not having to resort to C# as I’d figured I had to originally.

Quick Tip: Turn off verbose template logging in Tridion Event Log

As a good developer, you write out useful information and debug messages in your .NET TBBs using the built in templating logger. This is great when running the TBBs in the template builder to give a bit of extra info about the processing. However, by default info messages will be logged in the Tridion Event Log of your Publisher server, causing log bloat, and making it harder to see important Error and Warning messages. Its really easy to turn this off, but I am not sure I have seen it documented anywhere. Heres how…

Continue reading

Making an HTML Design play nice with Tridion

Clean SheetI am sure we have all had it – that feeling of excitement of a crisp blank piece of paper and a set of freshly sharpened coloured pencils. You are about to start implementing Tridion templates for a greenfield website implementation. No legacy VBScript scribbles already on your canvas to worry about, your favourite .NET TBBs and Custom Functions at hand to boost productivity. You will be knocking out Component and Page Templates by the hour and feel the buzz of seeing that sexy new site start to form on staging before the end of the day! Then you check the source of the html files in the zip provided by the design agency and your heart starts to sink…

Continue reading

Using Context Variables as a Templating Cache

Nickoli previously wrote a post introducing Context Variables, with nice Custom Functions to get and set them from your Dreamweaver Templates.  This post discusses the scope of Context Variables, and how that leads to other useful applications like caching.

Continue reading