As part of the total re-write of the Repository module, I am rewriting the template engine to be more powerful, more flexible and more useful than ever. A lot of the enhancement requests could be addressed through a more flexible and extensible template engine, so I have taken a more traditional approach to the engine as opposed to the current 'token replace' technology.
I have also refactored the template engine into a reusable public class in case you would like to take advantage of templating within your own DotNetNuke modules.
Before I get into the details, here's a quick snippet to whet your appetite and show you how you would use the template engine in your code. Hopefully this little snippet will let you see how much the engine has changed from it's previous usage. This is the simplest example, there are many ways to 'load' a template and many ways to set the values of the tokens. I will cover those other options later in the article.
|Dim template as New Repository.Template()
template.LoadString = "Hello [FIRSTNAME] [LASTNAME]"
Dim results as string = template.ToString()
' results will be "Hello Steve Fabian"
So, let's talk about the 'template' object.
A Repository template has a 'source' property which represents the template 'instructions'. Much like the the current template function being used in the 3.X version and the TokenReplace functionality elsewhere in the core, it includes static text and tokens delimited by square brackets. In the previous example, "Hello [FIRSTNAME] [LASTNAME]" is the template source, and FIRSTNAME and LASTNAME are the tokens.
In order to use a template you need to follow these steps...
1. create a new template object
2. set the template source
3. set the token values
4. tell the template to process the source and render its' output
1. Create a new template object
There are a number of ways to create a new template object, calling the plain initializer then setting the properties individually, or using one of the other initializer functions to create and initialize some properties in one call.
|' basic initializer function
Dim template As New Repository.Template()
' initialize and set the template source
Dim template As New Repository.Template(templateString)
' initialize and set the current module id and local resource file
Dim template As New Repository.Template(moduleid, localresourcefile)
' initialize and set the current portal id, moduleid and resource file
Dim template As New Repository.Template(portalid, moduleid, localresourcefile)
2. Set the template source
Once you have a template object, the next step is to set the source. As with the initialization step, there are a couple of ways to set the source. Setting the source using one of these 2 methods will trigger the template Parse() function to determine what static content and what tokens are included in the template.
|' pass a string as the source
' load the contents of a text file into the template source
3. Set the Token values.
Here's the meat of the template engine. Now that a template has been loaded and parsed, you need to 'marry' up the data values to the tokens. You can set each token individually..
The direct method works fine for simple templates with a small number of tokens, however, in order to make it easy to load up a large number of tokens, you can pass any 'object' and the template SetToken method will iterate through all available tokens looking for a matching object property using reflection to 'bulk load' the tokens
you can call the SetToken method multiple times to make multiple object's data available
This is really powerful, as you no longer need specialized tokens built-in to the template engine but can pass any object with properties to the SetToken method, then use tokens to extract specific data values into your templates.
4. Render the output
The final step is to tell the template engine to 'process' the source, replacing the tokens with the values you've set. You can either call the Render() method with no parameters in which case the template engine will return a string, or you can pass a placeholder and the template engine will 'inject' all output into the placeholder. If your template will be rendering controls, or input controls, you have to use the placeholder method in order to inject actual control objects.
|' render the template output to a string object
Dim results As String = template.ToString()
' render the template object into a placeholder
Dim ph As New PlaceHolder
If you want to build a list or table you can iterate through your data collection.
|Dim results As String = String.Empty
For Each item In myItemCollection
results = results & template.ToString()
The new template engine is extremely flexible and because it is being made visible as a public class, you will be able to easily use the template class in your own module development.
We've talked about how to use the template engine. The next article will talk about 'tokens', what they are, how they're used and how you can extend them to include 'functionality' by writing your own token Render() function.