Accessing the Tridion Package and Engine Objects

advertisement
Tridion Razor Templating Mediator
Version 1.0.1
Alexander Klock
alex@tahzoo.com
Read Me!
You should fully test the Razor Mediator features that you use extensively before deploying it to a live
production environment. Please send me an e-mail with any issues and bugs found so that I may fix
them as soon as possible.
Table of Contents
Introduction .................................................................................................................................................. 3
Limitations of Dreamweaver Templates ................................................................................................... 3
The Power of the Razor Mediator............................................................................................................. 3
Installation .................................................................................................................................................... 4
Requirements............................................................................................................................................ 4
Install (Running the Installer) .................................................................................................................... 4
Uninstall .................................................................................................................................................... 5
Advanced Configuration ........................................................................................................................... 5
CacheTime Attribute ............................................................................................................................. 5
ExtractBinaries Attribute....................................................................................................................... 5
Namespaces .......................................................................................................................................... 5
Assemblies ............................................................................................................................................ 6
Razor Templating Usage and Samples .......................................................................................................... 6
Usage......................................................................................................................................................... 6
Simple Page Template............................................................................................................................... 7
Simple Component Presentation .............................................................................................................. 7
Dynamic Item Fields .................................................................................................................................. 7
Checking ItemFields For Values ............................................................................................................ 8
Handling Embedded Fields ....................................................................................................................... 9
Handling Component Links ....................................................................................................................... 9
Model Class ItemField Shortcuts............................................................................................................. 10
Important Note on Dynamic Objects .................................................................................................. 10
The DynamicPackage Object ................................................................................................................... 11
Accessing the Tridion Package and Engine Objects ................................................................................ 11
Accessing the Page Object from a Component Template ...................................................................... 11
Razor Syntax / DWT Comparison ................................................................................................................ 11
Razor Mediator Templating and API Reference ......................................................................................... 13
From The Tridion Razor Template Base .................................................................................................. 13
ModelUtilities.......................................................................................................................................... 15
ComponentPresentationModel .............................................................................................................. 16
PublicationModel .................................................................................................................................... 17
AbstractRepositoryLocalObject .............................................................................................................. 18
ComponentModel ................................................................................................................................... 19
FolderModel............................................................................................................................................ 19
PageModel .............................................................................................................................................. 20
StructureGroupModel............................................................................................................................. 21
Future of the Razor Mediator ..................................................................................................................... 22
Planned ................................................................................................................................................... 22
Bugs / Feature Requests ......................................................................................................................... 22
Introduction
The Razor Template Engine has been introduced into the .NET community with much success, and you’ll
especially find it common in almost every ASP.NET MVC project you come across now. If you are not
familiar with .NET and the Razor Templating syntax, then perhaps you have heard of Velocity? Razor has
been compared to Java’s Velocity template engine. But why is it so popular? Razor allows an easy to
use syntax (pretty much C# syntax) for template scripting, but with a clean easy to read look and feel (so
no, we’re not taking a step back into the days of VBScript templates!).
Limitations of Dreamweaver Templates
Although Tridion comes with Dreamweaver Templating out of the box, and this is what’s widely used
amongst the Tridion projects out there, anyone who’s worked with this templating style fully
understands the limitations (and frustrations) that DWT’s has to offer. Below is an incomplete list of
some of the drawbacks and limitations to working with DWT’s.
1.) ComponentLink Fields. You just can’t access the fields of a Component from a ComponentLink
field in DWT. You end up either having a TBB that pushes these values to the package, or by
using a Dreamweaver Custom Function (like Nuno’s Dreamweaver Get Extensions, which is a
must in my opinion when working with DWTs).
2.) TemplateRepeatIndex. You can only get this value of the TemplateRepeat loop that you are
working with (ie, can’t get the outer TemplateRepeatIndex value).
3.) Nested Repeat Regions. Because of the above problem, accessing fields from an outer repeat
region is impossible without the help of custom functions or TBBs.
4.) Else Statement. Yep, there is no else statement. You have to write TemplateIf multiple times
using negation. (Though there is a ternary expression you can use when outputting variables.)
5.) Whitespace. Although not too big of an issue, it does bother some the amount of whitespace
that DWTs output.
6.) Flexibility. With DWT there is none. If you want to have Date formatting for example, you have
to write code (TBB or Custom Function) to handle it for you.
The Power of the Razor Mediator
With Razor Templating, all of the above limitations are covered. You actually have the power of .NET
within your Razor Templates. Using the base Tridion Razor Template and utilities that comes with the
Razor Mediator, you’ll have quick and easy access to most of your Template Package items and fields
right at your fingertips. Because you are now able to do more and write less, the templating process can
be done quicker than ever before.
Razor is a strongly typed, case sensitive, scripting language. For example, for a Tridion DateField, you
can format the date right from the template using
<span>@Fields.NewsDate.ToString(“MM/dd/yyyy”)</span>. For a Tridion KeywordField, you have
access to all of the Tridion keyword fields like <span>@Fields.SomeKeywordField.Title</span>. Want to
capitalize your header field? <span>@Fields.Header.ToUpper()</span>. What about accessing fields
of Component Links? <div>@Fields.SomeComponentLink.FieldName</div>. You can even go as deep
as you want with Component Links.
<div>@Fields.SomeComponentLink.AnotherComponentLink.FieldName</div>. You can also add
your own scriptlet like helper functions right to your templates if you so desired.
Some of the Tridion types have also been wrapped by Model classes that provide easier functionality of
accessing certain data, like Fields and Metadata (dynamic access that always returns the correct type in
your templates). For these Model classes, you can always access the underlying Tridion Object through
the TridionObject property. For example, @Component.TridionObject.HasUsingItems(). The
Component is of type ComponentModel (the special wrapper class), while the TridionObject property
actually returns the Tridion Component instance. Most of the Model class’ ToString() method writes out
the wrapped Tridion item’s Title property, with the exception of the ComponentModel, which will write
out the Component’s Tcm Uri.
Installation
Requirements
Tridion 2011 and .NET 4.0 is required on the Tridion CMS server for usage of the Razor Mediator. .NET
4.0 should have already been installed during the Tridion installation process.
Install (Running the Installer)
The Razor Mediator uses the Tridion Mediator architecture, so it will not break any of your existing
work.
Installation is simple, just run the RazorMediatorInstaller.msi installer file on the Tridion CMS Server.
The installer will add System.Web.Razor.dll and Tridion.Extensions.Mediators.Razor.dll to the GAC. It
will also automatically make a backup of the Tridion.ContentManager.config configuration file (with
timestamp), and then make the necessary automatic changes to the configuration (includes registering
the Razor Template type, adding the Mediator, and adding a custom configuration section for
razor.mediator).
Once the installation has completed, you will need to restart the Tridion Content Manager COM+
package, the Tridion Publisher service, and Template Builder if it’s open. You do not have to restart the
box.
As a recap, the steps are:
1.) Double click the RazorMediatorInstaller.msi.
2.) Follow the steps of the Installer.
3.) Once installed, restart the Tridion Content Manager COM+ Package, the Tridion Publisher
service, and Template Builder (if it’s open).
Uninstall
If for any reason you need to uninstall, just uninstall it like you would a program (selecting Uninstall
from the context menu of RazorMediatorInstaller.msi, or by going to Control Panel and removing the
program named “Razor Templating Mediator”) . It’ll remove the DLL’s from the GAC and remove the
Razor Mediator sections from the Tridion.ContentManager.config file. A time stamped backup of the
Tridion.ContentManager.config will also be automatically created for you, just in case you want to keep
some of the advanced custom configuration for the Razor Mediator handy.
Advanced Configuration
The Tridion.ContentManager.config file, after installation, will contain a configurable section for the
Razor Mediator for further customization of your templates, such as adding references to other libraries
to your templates, and including namespace imports globally to all of your templates.
Below is a sample of what this section can look like.
<razor.mediator cacheTime=”600” extractBinaries=”true”>
<namespaces>
<add namespace=”System.Linq” />
<add namespace=”Tridion.ContentManagement” />
</namespaces>
<assemblies>
<add assembly=”RazorSample.Test, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=60ad7434f03dfcdc” />
<add assembly=”C:\Program Files\Razor\Tests\Test.Sample.dll” />
</assemblies>
</razor.mediator>
CacheTime Attribute
Razor Templates are compiled in memory before they are executed. Due to this, normally the first time
a Razor Template runs will take the longest.
For performance, templates are cached after being compiled. This prevents a template from being
compiled each and every time it is run. The cacheTime attribute represents the time in seconds that a
template will live in the cache before being expired.
ExtractBinaries Attribute
The Razor Mediator, after template execution, can extract binaries from the output and add them to the
package. This is somewhat comparable to the way DWT’s are handled in 2011. If you are handling
binary extraction yourself via a Template Building Block, you can set this value to false.
Namespaces
The <namespaces> element contains a global way to import namespaces into every one of your
templates. Rather than manually adding @using System.Linq into the top of every template, you could
just add <add namespace=”System.Linq” /> instead.
Assemblies
The <assemblies> element is the way for you to reference other libraries to be usable by your templates.
For adding elements contained within the GAC, you can just simple reference the fully qualified GAC
name. For example, if you wanted to use items from SomeLibrary.Blah, you can simply add <add
assembly=”SomeLibrary.Blah, Version=2.1.0.0, Culture=neutral,
However, if you are referencing an item that is not
contained in the GAC, you must add the absolute physical path to the DLL, ie: <add
namespace=”C:\Program Files\Razor\Tests\Test.Sample.dll” />.
PublicKeyToken=ab09ae83cdf90a23” />.
For non-GAC assemblies, because the Razor Templates are compiled in memory, the assemblies get
loaded via an AssemblyResolver event on demand. However, the performance of doing this is more
costly, and will add to your template execution time, so when possible, use items from the GAC.
Razor Templating Usage and Samples
The following sections contain samples and usage. In the samples you might see various ways to access
items from the template.
Usage
Once the Razor Mediator is installed, creating Razor Templates works the same way as creating
Dreamweaver Templates.
1.) Create a New Template Building Block.
2.) Give your TBB a name. I normally add a suffix of “RCT” for Razor Component Templates or
“RPT” for Razor Page Templates, but naming convention is of course completely up to you.
3.) Select the “Source” tab.
4.) For Template Type, select “RazorTemplate”.
5.) In the text area, add your Razor syntax
6.) Select “Save and Close” when finished.
7.) Add your Razor TBB to a Compound Template (just as you would if it were a DWT).
Simple Page Template
<html>
<head>
<title>@Page.Title</title>
<meta name=”keywords” value=”@Page.Metadata.Keywords” />
</head>
<body class=”@Page.Metadata.BodyClass”>
<h1>Page Title: @Page.Title (@Page.ID)</h1>
<h2>Publication Title: @Publication.Title (@Publication.ID)</h2>
<div>
Getting some keywords from a Publication MetaData Field:
<ul>
@foreach (var keyword in Publication.MetaData.SomeKeywordFields) {
<li>@keyword.Title (@keyword.Id)</li>
}
</ul>
</div>
<h3>Test Templates:</h3>
@foreach (var cp in ComponentPresentations) {
if (cp.Template.Title == “Test Template”) {
<div>You have full access to @cp.Component.Title w/ all of its fields like
@cp.Component.Fields.AFieldName</div>
<div>@cp.RenderComponentPresentation()</div>
}
}
<h3>You could have also done it like:</h3>
@foreach (var cp in GetComponentPresentationsByTemplate(“Test Template”)) {
<div>Another component for template @cp.Template.Title:</div>
<div>@cp.RenderComponentPresentation()</div>
}
</body>
</html>
Simple Component Presentation
<div class=”news-article”>
<img src=”@Fields.HeaderImage.ID” alt=”@Fields.HeaderImage.AltText” />
@* Note that Fields is just a shortcut to Component.Fields *@
<h2>@Fields.Header</h2>
<h5>@Fields.NewsDate.ToString(“dd/MM/yy hh:mm”)</h5>
<div class=”body-text”>
@Fields.BodyText
</div>
</div>
Dynamic Item Fields
The Model wrapper classes use a special DynamicItemFields class to represent both Fields and Metadata
for Tridion items. The DynamicItemFields class allows you to call field names (case insensitive!) directly
in dot notation, and get a Type back based on the field type. The template writer will have to know
which Type he/she is getting back to know what further functionality or properties the template
designer can call.
Field Type
Returned Type
Example
TextField
String
DateField
DateTime
KeywordField
Keyword
EmbeddedSchemaField
DynamicItemFields (See Handling
Embedded Fields)
ComponentModel (wrapped Component
object)
ComponentLinkField
ExternalLinkField
String
NumberField
Note: Multivalued Fields
Double
Returns a List<Type>. For example, a
multi-valued ComponentLinkField will
return type of List<ComponentModel>.
@Fields.ATextField
@Fields.ATextField.Length
@Fields.ATextField.ToUpper()
@Fields.ADateField.Year
@Fields.ADateField.ToString(“MMMM”)
@Fields.ADateField.ToUniversalTime()
@Fields.AKeyword
@Fields.AKeyword.Id
@Fields.AKeyword.Key
@Fields.AnEmbeddedField.EmbeddedFieldName
@Fields.AnEmbeddedField.ADateField.Month
@Fields.ACompLinkField.Title
@Fields.ACompLinkField.Fields.Header
@Fields.ACompLinkField.Metadata.Author
@Fields.AnExternalLink
@MetaData.AnotherExternalLink
@MetaData.ANumberField
@foreach (var keyword in Field.SomeKeywords)
{
<li>@keyword.Key ( @keyword.Id )</li>
}
@foreach (var c in Field.SomeCompLinks)
{
<li>@c.Title : @c.Fields.SubHeader</li>
}
Remember, the DynamicItemFields is case insensitive, so the below samples will work:
@Fields.Header
@Fields.header
Checking ItemFields For Values
The DynamicItemFields class will return null if no property name exists in the ItemFields, or if no value
was input for single-valued fields. This will work even if no MetaData Schema has been provided for a
Tridion Item. Below are examples of checking:
@if (Fields.SubHeader != null) {
<h2>@Fields.SubHeader</h2>
}
<title>@(Fields.SubHeader ?? Page.Title)</title>
If you are not familiar with the above syntax, it could also be written like the example below. You have
the complete C# 4.0 syntax at your command.
<title>@(Fields.SubHeader != null ? Fields.SubHeader : Page.Title)</title>
Remember, multi-valued fields will always return a List<T> type (as long as the key exists), so for multivalued fields that have a key specified, you can check against the count.
@if (Fields.SomeMultiValuedField.Count > 0) {
<p>We Have Item! Total: @Fields.SomeMultiValuedField.Count</p>
}
If you just want to check to see if a key even exists in the ItemFields or not, you can call the
HasField(string fieldname) method.
@if (Fields.HasField(“SubHeader”)) {
<div>ItemField ‘SubHeader’ Exists and Has Value of: @Fields.SubHeader</div>
}
The HasField method can be useful when your template is working with different schemas and you want
to make sure a specific field exists.
Handling Embedded Fields
As mentioned in the chart above, field types of EmbeddedSchemaField will return a DynamicItemFields
object. The syntax works pretty much like working with embedded schema fields within a Dreamweaver
Template.
@Component.Fields.TheEmbeddedSchemaField.AFieldName
If the embedded schema field contains another embedded schema field, you can just continue the
nesting.
@Component.Metadata.TheEmbeddedSchemaField.AnotherEmbeddedField.SomeDate
If the embedded field is a multi-valued field, you can just loop over it with a foreach loop. The below
example is if the two levels of embedded schema fields in the above sample were mutli-valued.
@foreach (var field in Metadata.TheEmbeddedSchemaFields) {
<div>@field.AFieldName</div>
@foreach (var innerField in field.AnotherEmbeddedFields) {
<span>@innerField.SomeDate</span>
}
}
You can also use for loops.
@for (int i = 0; i < Metadata.EmbeddedSchemaFields.Count; i++) {
<div>@Metadata.EmbeddedSchemaFields[i].AFieldName</div>
}
Handling Component Links
Component Links work similar to Embedded Fields. The below samples show the full syntax of retrieving
values from a Component Link field. (See the section on shortcuts for a quicker syntax.)
@Component.Fields.CompLink.Fields.FieldName
If the component in the Component Link field contains another component link, you can just continue
the nesting.
@Component.Metadata.CompLink.Fields.AotherCompLink.Fields.AnotherFieldName
If the component link field is a multi-valued field, you can just loop over it with a foreach loop. The
below example is if the two levels of component link fields were multi-valued.
@foreach (var c in Metadata.CompLinks) {
<div>@c.Fields.AFieldName</div>
@foreach (var innerComp in c.Fields.MoreCompLinks) {
<span>@innerComp.Fields.AnotherFieldName</span>
}
}
You can also use for loops.
@for (int i = 0; i < Fields.CompLinks; i++) {
<div>@Fields.CompLinks[i].Fields.AFieldName</div>
<div>@Fields.CompLinks[i].AFieldName</div> @* This shortcut would work too *@
}
Model Class ItemField Shortcuts
The Model class wrappers contains shortcuts for accessing Fields and/or Metadata. You can access an
itemfield directly, as long as a property of that name doesn’t already exist. For example, the following is
equivalent:
@Component.Fields.SomeFieldName
@Component.SomeFieldName
@Component.MetaData.AnotherField
@Component.AnotherField
For ComponentModels, the shortcut access to item fields will check the Fields first, and then the
Metadata.
Note that if the ItemField name has the same name as a property of the class, the property is returned
and not the value of the ItemField. For example:
@Component.Fields.Title
@Component.Title
The above example will not return the same value. The first will access an ItemField with the name of
“Title”, while the second example will return the Component’s Title.
Important Note on Dynamic Objects
It is important to know that the shortcut properties will only work if a keyword is “dynamic”. For
example, to be able to use the ItemField shortcuts for ComponentModel’s while looping a collection of
ComponentLink fields, you must do the following:
@foreach (dynamic c in Fields.SomeComponentLinks) {
<text>The header is @c.Header</text> @* this is a shortcut for @c.Fields.Header *@
}
The following will cause an Exception to be thrown:
@foreach (var c in Fields.SomeComponentLinks) {
<text>The header is @c.Header</text> @* THIS WILL BREAK *@
}
@foreach (ComponentModel c in Fields.SomeComponentLinks) {
<text>The header is @c.Header</text> @* THIS WILL ALSO BREAK *@
}
The shortcut syntax is especially useful when accessing items in for loops.
@Fields.CompLinks[i].Fields.FieldName
@Fields.CompLinks[i].FieldName @* Shortcut syntax *@
@Fields.CompLinks[i].Fields.MoreLinks[x].Fields.FieldName
@Fields.CompLinks[i].MoreLinks[x].FieldName @* Shortcut syntax *@
The DynamicPackage Object
NOTE this functionality has not been tested. Please report issues if found.
From the base template, you can directly access the Package property. Note that this is not the Tridion
package instance, but rather a dynamic wrapper of that instance. Like the DynamicItemFields, the
DynamicPackage allows you to use Dot Notation to access items in the Package.
For example, if you had a C# TBB that pushes out a string item named “foo_bar”, you can access that
string directly by:
@Package.foo_bar
The return type of a property of the DynamicPackage item is dynamic.
ContentType
Return Type
Component
ComponentArray
ComponentPresentationArray
Everything Else
ComponentModel
List<ComponentModel>
List<ComponentPresentationModel>
String
Accessing the Tridion Package and Engine Objects
If you need to access the Tridion Package and Engine objects from your Razor Templates, you can use
the TridionHelper property.
@TridionHelper.Engine
@TridionHelper.Package
Accessing the Page Object from a Component Template
The @Page variable will work not only in a Page template, but a Component Template as well. If the
Page object cannot be found (ie a Dynamic Component Presentation or previewing a CT) @Page will
return null. Because of that, if you are trying to access the Page object from a CT, you should first check
if the value is not null. Otherwise you might run into a null reference exception (“Object reference not
set to an instance of an object.”) when trying to access the Page’s fields.
@if (Page != null) {
<h3>@Page.MetaData.PageSubHeader</h3>
}
Razor Syntax / DWT Comparison
Syntax /
Sample
Razor
DWT
Code Block
@{
N/A, you can’t create or set
variables from a DWT. This can be
a good thing depending on your
approach as to what should be
contained within this type of
template building block.
int x = 123;
string y = “because.”;
var greeting = “Hello”;
}
Expression
Combining Text
and Markup
<div>@greeting</div>
<span>@Component.Title</span>
@foreach (var cp in ComponentPresentations) {
<h1>Page: @Page.Title</h1>
<span>@@Component.Title@@</span>
<!-- TemplateBeginRepeat
name=”Components” -->
<h2>Component: @cp.Component.Title</h2>
<h3>Template: @cp.Template.Title</h3>
<div>
@cp.RenderComponentPresentation()
</div>
}
If / Else
Statements
@if (Component.Schema.Title.Equals(“News Article”)) {
<div>Do some stuff…</div>
} else {
<div>Do some other stuff…</div>
}
Mixing Code
and Plain Text
@if (someVariable) {
<text>Plain Text is @someVariable</text>
}
Escaping the @
sign
Comments
<span>In Razor, you use double @@ to escape the @@
symbol.</span>
Accessing
Component
Link Fields
Nested Nested
Component
Link Fields
Formatting
DateFields
Adding Using
Statements for
Use in your
Template
Adding
Functions
Within Your
Template
Adding Helper
Functions
Within Your
Template
<h1>Page: @@Page.Title@@</h1>
<h2>Component:
@@Component.Title@@</h2>
<h3>Template:
@@ComponentTemplate.Title@@</h3>
<div>
@@RenderComponentPresentation()@@
</div>
<!-- TemplateEndRepeat -->
<!-- TemplateBeginIf
cond=”Component.Schema.Title =
‘News Article’” -->
<div>Do some stuff…</div>
<!-- TemplateEndIf -->
<!-- TemplateBeginIf
cond=”Component.Schema.Title !=
‘News Article’” -->
<div>Do some other
stuff…</div>
<!-- TemplateEndIf -->
<!-- TemplateBeginIf
cond=”someVariable” -->
Plain Text is @@someVariable@@
<!-- TemplateEndIf -->
@* This is a comment *@
@*
So is
this
here.
*@
@foreach (var cLink in Component.Fields.SomeCLinks) {
<div>ID: @cLink.ID</div>
<div>Title: @cLink.Title</div>
<div>Fields:<br />
@cLink.Fields.SomeField
@cLink.Fields.AnotherField
</div>
}
@foreach (var p in Component.Fields.Products) {
<h3>@p.Fields.Header</h3>
<div>@HtmlEncode(p.Fields.Summary)</div>
<ul>
@foreach (var link in p.Fields.Links) {
<li
class=”@link.Fields.LinkClass”>@link.Fields.LinkHeader</li>
}
</ul>
}
<p>The News Date is
@Component.Fields.NewsDateField.ToString(“MMM d”)</p>
<p>This would always show the date this was published:
@DateTime.Now.ToString(“MMM dd, yyyy”)</p>
@using System.Text
@using Tridion.ContentManagement
@functions {
public string Test(string name) {
return “Hello “ + name + “!”;
}
}
<div>@Test(“Administrator”)</div>
@helper Test(string name) {
<div>Hello @name!</div>
}
<div>@Test(“Administrator”)</div>
You can’t access a component link
field directly in a DWT. Not
without the help of a TBB or
custom function (like the Get
Extensions).
You wouldn’t be able to get fields
out like this from your DWT.
You’d have to write some TBB or
Custom Functions to aid you in
this task. Notice how easy it is
to grab items from an outer loop.
Unable to directly. Again, you’d
have to use a TBB to push the
values out, or use custom DW
functions. With Razor, you have
full access to .NET code.
N/A
Dreamweaver Custom Function.
Dreamweaver Custom Function.
Note that a Helper function
returns Razor Syntax, unlike the
above @functions declaration.
Razor Mediator Templating and API Reference
Variable and templating reference with samples.
From The Tridion Razor Template Base
The following is callable directly from your templates, as they are properties and methods of the
TridionRazorTemplate base.
TemplatingLogger Log
Gets the Tridion TemplatingLogger instance.
@Log.Debug(“This is a debug statement”)
ComponentModel Component
Gets the Component in the package. A name “Component” item must exist in the package (Component
Template).
@Component.Title
DynamicItemFields Fields
Shortcut to @Component.Fields
@Fields.FieldName
FolderModel Folder
Shortcut for @Component.Folder. Must have access to the Component.
@if (!Folder.IsRoot) {
<div>Parent Folder Title is: @Folder.Parent.Title</div>
}
DynamicItemFields MetaData / DynamicItemFields Metadata
Shortcut to @Component.MetaData
<span>@Metadata.FieldName is the same as @MetaData.FieldName is the same as
@Component.Metadata.FieldName</span>
ModelUtilities Models
Gets the ModelUtilities helper class, which allows you to get Model wrappers from your template.
@Models.GetComponent(“tcm:23-233”).Fields.SubjectHeader
@Models.GetPage(“tcm:23-555-64”).MetaData.FieldName
DynamicPackage Package
Gets the DynamicPackage item. See “The DynamicPackage Object” section for more reference.
@Package.Output
PageModel Page
Gets the template’s Page. NOTE: This will work in a Page Template OR a Component Template. To work
in a CT, the CT must be a component presentation on a page. Using the Page property from a CT can
cause problems for dynamic component presentations and previewing CTs. As mentioned in an earlier
section, if accessing the Page from a CT, you should check to see if its null first.
<div>@Page.FileName</div>
PublicationModel Publication
Gets the current context Publication of the template.
<span>The root folder’s title is: @Publication.RootFolder.Title</span>
String RenderMode
Gets the RenderMode. “Publish”, “PreviewDynamic”, and “PreviewStatic”.
@if (RenderMode.Equals(“Publish”)) {
<span>This is a way to render this only when publishing and not previewing.</span>
}
StructureGroupModel StructureGroup
Gets the Page’s StructureGroup. Shortcut for @Page.StructureGroup. Note that the template must be
able to access the Page property.
<strong>
This SG contains @StructureGroup.StructureGroups.Count StructureGroups in it.
</strong>
Template Template
Gets the Tridion Compound Template being executed.
@Template.Id : @Template.Title
TridionUtilities TridionHelper
Gets a helper class that contains some utility functions for Tridion.
the Tridion Engine and Package object.
@TridionHelper.Engine.GetObject(“tcm:15-5502”)
@TridionHelper.Package.GetValue(“ValueToGet”)
Also exposes
bool IsComponentTemplate
Gets whether or not the template is a Component Template.
@if (IsComponentTemplate) {
<div>Component Title: @Component.Title</div>
}
bool IsPageTemplate
Gets whether or not the template is a Page Template.
@if (IsPageTemplate) {
<div>Page Title: @Page.Title</div>
}
List<ComponentPresentationModel> ComponentPresentations
Gets a list of the component presentations. There must be a “Components” items in the package (like in
a Page Template).
@foreach (var cp in ComponentPresentations) {
cp.RenderComponentPresentation();
}
List<ComponentPresentationModel> GetComponentPresentationsByTemplate(string templateName)
Gets a list of Component Presentations filtered by the template name.
@foreach (var cp in GetComponentPresentationsByTemplate(“News Content Summary”)) {
cp.RenderComponentPresentation();
}
String RenderComponentPresentation(TcmUri componentID, TcmUri templateID)
String RenderComponentPresentation(string componentID, string templateID)
Renders a component presentation.
@RenderComponentPresentation(“tcm:3-1343”, “tcm:3-2334-32”)
String HtmlDecode(string textToDecode)
Converts a HTML encoded string into a decoded string.
@HtmlDecode(Fields.Header)
String HtmlEncode(string textToEncode)
Converts a string into a HTML encoded string.
@HtmlEncode(Fields.Header)
String UrlDecode(stringToDecode)
Converts an URL encoded string into a decoded string.
@UrlDecode(MetaData.BaseUrl)
String UrlEncode(string textToEncode)
Converst a string into a URL encoded string.
@UrlEncode(MetaData.BaseUrl)
String StripHtml(string text)
Strips a string of html elements.
@StripHtml(Fields.BodyText)
String RenderComponentField(string fieldExpression, int fieldIndex)
String RenderComponentField(string fieldExpression, int fieldIndex, string value)
String RenderComponentField(string fieldExpression, int fieldIndex, bool htmlEncodeResult, bool
resolveHtmlAsRTFContent)
The Tridion Razor Template Base also offers the following Built In Functions, which can be used just like
equivalent in the Dreamweaver Templates (useful for SiteEdit).
ModelUtilities
The ModelUtilities class provides a wrapper of the engine.GetObject() to easily retrieve the specially
wrapped Model classes. You can access the ModelUtilities directly from the @Models property of the
base template.
ComponentModel GetComponent(string itemUriOrWebDavUrl)
ComponentModel GetComponent(TcmUri tcmUri)
Retrieves a Component from the CMS.
@Models.GetComponent(“tcm:15-200”).Fields.FieldName
@foreach (dynamic c in Models.GetComponent(“tcm:17-2345”).Fields.SomeComponentLinks) {
<div>@c.Title</div>
}
FolderModel GetFolder(string itemUriOrWebDavUrl)
FolderModel GetFolder(TcmUri tcmUri)
Retrieves a Folder from the CMS.
@Models.GetFolder(“tcm:15-201-2”).Title
KeywordModel GetKeyword(string itemUriOrWebDavUrl)
KeywordModel GetKeyword(TcmUri tcmUri)
Retrieves a Keyword from the CMS.
@Models.GetKeyword(“tcm:15-3456-1024”).Key
PageModel GetPage(string itemUriOrWebDavUrl)
PageModel GetPage(TcmUri tcmUri)
Retrieves a Page from the CMS.
@Models.GetPage(“tcm:15-202-64”).FileName
StructureGroupModel GetStructureGroup(string itemUriOrWebDavUrl)
StructureGroupModel GetStructureGroup(TcmUri tcmUri)
Retrieves a StructureGroup from the CMS.
@Models.GetStructureGroup(“tcm:15-300-4”).Parent.Title
ComponentPresentationModel
Represents a ComponentPresentation, and has the following properties and methods.
String ComponentID
String ComponentUri
Gets the Component’s Tcm Uri.
@foreach(var cp in ComponentPresentations)
{
<div>@cp.ComponentID</div>
}
String TemplateID
String TemplateUri
Gets the Template’s Tcm Uri.
@foreach(var cp in ComponentPresentations)
{
<div>@cp.TemplateID</div>
}
ComponentModel Component
Gets the Component.
@foreach(var cp in ComponentPresentations)
{
<div>@cp.Component.Fields.FieldName</div>
}
ComponentTemplate Template
Gets the ComponentTemplate
@foreach(var cp in ComponentPresentations)
{
<div>@cp.Template.Title</div>
}
String RenderComponentPresentation()
Renders the Component Presentation.
@foreach(var cp in ComponentPresentations)
{
<text>@cp.RenderComponentPresentation()</text>
}
PublicationModel
A wrapper class for the Tridion Publication object.
DynamicItemFields Fields
DynamicItemFields MetaData
DynamicItemFields Metadata
Gets the Publication’s metadata fields.
@Publication.Fields.FieldName
TcmUri ID
TcmUri Id
Gets the Publication’s Tcm Uri.
@Publication.Id or @Publication.ID
String MultimediaPath
Gets the path to the directory containing published binaries.
@Publication.MultimediaPath
String MultimediaUrl
Gets the URL to the directory containing published binaries.
@Publication.MultimediaUrl
String PublicationPath
Gets the publication publish path.
@Publication.PublicationPath
String PublicationUrl
Gets the publication publish URL.
@Publication.PublicationUrl
FolderModel RootFolder
Gets the Publication’s root Folder.
@Publication.RootFolder.ID
StructureGroupModel RootStructureGroup
Gets the Publication’s root StructureGroup.
@Publication.RootStructureGroup.Title
String Title
Gets the Publication’s title.
@Publication.Title
String WebDavUrl
Gets the Publication’s WebDavUrl
@Publication.WebDavUrl
String ToString()
Returns the Publication’s Title.
@Publication @* Will display the tcm uri of the Publication *@
AbstractRepositoryLocalObject
All of the Model wrapped classes, with the exception of the PublicationModel and
ComponentPresentationModel above, inherit this class and will have access to the following properties.
DynamicItemFields Fields
DynamicItemFields MetaData
DynamicItemFields Metadata
Gets the Item’s Metadata fields.
@StructureGroup.Metadata.SomeField
TcmUri ID
TcmUri Id
Gets the Item’s Tcm Uri.
@Folder.Id or @Folder.ID
Bool IsLocalized
Gets whether or not the Item is localized in the current context Publication.
@if (Component.IsLocalized) {
<span>The component is localized.</span>
}
Bool IsShared
Gets whether or not the Item is shared in the current context Publication.
@if (Page.IsShared) {
<span>The page is shared.</span>
}
Dynamic OrganizationalItem
Gets the organizational item that contains this Tridion object. Will return a Category, FolderModel,
StructureGroupModel or VirtualFolder.
@Publication.Id or @Publication.ID
String Path
Gets the full path to the item.
@Component.Path
PublicationModel Publication
Gets the Item’s Context Repository.
@Component.Publication.Id
String Title
Gets the Item’s title.
@Page.Title
T TridionObject
Gets the underlying Tridion Object.
@Page.TridionObject @* will return the underlying Tridion Page object *@
String WebDavUrl
Gets the WebDAV URL of the Item.
@Component.WebDavUrl
String ToString()
Returns the Item’s title.
@Page
ComponentModel
The ComponentModel has all the properties of the AbstractRepositoryLocalObject, with the following
addition or overwritten ones.
Schema Schema
Gets the Component’s Schema.
@Component.Schema
DynamicItemFields Fields
Gets the Component’s fields.
@Component.Fields.FieldName
FolderModel Folder
Gets the WebDAV URL of the Item.
@Component.WebDavUrl
String ToString()
Returns the Component’s Tcm Uri.
@Component
FolderModel
The FolderModel represents a Tridion Folder, and has all the properties from
AbstractRepositoryLocalObject, with the following additional or overwritten properties.
List<ComponentModel> Components
Gets the child Components of this Folder (non-recursive).
@foreach(var component in Folder.Components)
{
<div>@component.Title</div>
}
List<FolderModel> Folders
Gets the child Folders of this Folder (non-recursive).
@foreach(var folder in Component.Folder.Folders)
{
<div>@folder.Title</div>
}
Bool IsRoot
Whether or not the Folder is the root.
@if (Folder.IsRoot) {
<span>@Folder.Title is the root.</span>
}
FolderModel Parent
Gets the parent folder.
@Folder.Parent.Title
KeywordModel
String Description
Gets the description of the keyword.
@Fields.KeywordField.Description
Bool IsAbstract
Gets whether or not the Keyword is abstract.
@if (Fields.KeywordField.IsAbstract) {
<span>@Fields.KeywordField.Title is Abstract!!!</span>
}
Bool IsRoot
Gets whether or not the Keyword is a root keyword (no parent keywords)
@if (Fields.KeywordField.IsRoot) {
<span>@Fields.KeywordField.Title is a root keyword!!! Yay.</span>
}
String Key
Gets the key of the keyword.
@Fields.KeywordField.Key
PageModel
The PageModel represents a Tridion Page, and has all the properties from
AbstractRepositoryLocalObject, with the following additional or overwritten properties.
List<ComponentPresentationModel> ComponentPresentations
Gets the Page’s Component Presentations.
@foreach (var cp in Page.ComponentPresentations) {
<text>@cp.RenderComponentPresentation()</text>
}
String FileName
Gets the Page’s filename.
@Page.FileName
StructureGroupModel StructureGroup
Gets the Page’s StructureGroup.
@Page.StructureGroup.Title
String PublishLocationPath
Gets the publish path for the Page, including the filename and extension.
@Page.PublishLocationPath
String PublishLocationUrl
Gets the publish URL for the Page.
@Page.PublishLocationUrl
String PublishPath
Gets the publish path of the page, excluding filename and extension.
@Page.PublishPath
StructureGroupModel
The StructureGroupModel represents a Tridion StructureGroup, and has all the properties from
AbstractRepositoryLocalObject, with the following additional or overwritten properties.
Bool IsRoot
Gets whether or not this is the root StructureGroup in a Publication.
@if (StructureGroup.IsRoot) {
<div>It’s the root!</div>
}
List<PageModel> Pages
Gets all the Pages that are contained within this StructureGroup.
@foreach (var page in Page.StructureGroup.Pages) {
<div>@page.Title</div>
}
StructureGroupModel Parent
Gets the parent StructureGroup.
@Page.StructureGroup.Parent.Title
List<StructureGroupModel> StructureGroups
Gets all the children StructureGroups of this StructureGroup (non-recursive).
@foreach (var sg in StructureGroup.StructureGroups) {
<div>@sg.Title</div>
}
Future of the Razor Mediator
Planned
Version 1.1-1.4 : Bug Fixes, Performance Enhancements, Minor Features Requests
Version 1.5 : Helper and Template Includes Support – Ability to include helper and template functions
from either another Razor TBB or even externally from a file on the server.
Version 2.0 : Master Templates – Have your templates share the layout from a Master Template.
Bugs / Feature Requests
For any bugs found or requests for features in future versions of the Tridion Razor Mediator, feel free to
contact me at alex@tahzoo.com. Please add “Razor Mediator” to the subject line.
Download