Skip to main content

TBB of the Week - Render Page Text Block

I thought about starting a new section on my blog -- TBB of the Week. The intention is to publish a new TBB every week that is somehow worthy. Maybe it is a very generic one, or a best practice, or even a bad practice. There should be a description of the TBB, what it does, where/how to use it in a Compound Template. Of course, there will be source code too.

So to start with, the first "TBB of the Week" is going to be Render Page Text Block TBB. I first got this TBB from a colleague of mine, Eric Huiza, so I won't take credit for it.

Name
Render Page Text Block TBB
Type
· Template in .NET Assembly
Description
Used to:
· Publish Text Block scripts (JS or CSS) attached to a Page as metadata;
Notes:
This TBB expects the Page to have metadata field ‘script’ that contains a Component Link to the Text Block Component. The TBB creates an Output item (or overwrites the existing one) with the content of the TextBlock field in the linked Text Block Component.
The Page in this case should not contain any Component Presentations.
Parameters
n/a
Applicable to
Page Templates

I like the idea a lot -- you don't have to create Component Presentations on your Page in order to publish 'static' text assets like JavaScript or CSS. Instead you just attach them to your Page Metadata.

One thing I don't like, is the inability to use the "Where Used" publishing. Namely, if you want to publish the JS/CSS Text Block Component, this setup will not allow that. In a normal situation, where the Component appears on the Page as CP, publishing the Component will publish the Page using it. Not in this case...

The Code

[TcmTemplateTitle("Render Page Text Block TBB")]
public class RenderPageTextBlock : ITemplate {

    public void Transform(Engine engine, Package package) {
        Item pageItem = package.GetByName(Package.PageName);
        Page page = engine.GetObject(pageItem) as Page;

        ItemFields metaFields = new ItemFields(page.Metadata, page.MetadataSchema);
        ComponentLinkField textblockField = metaFields.Where(w => w.Name.Equals("script")).Cast<ComponentLinkField>().ElementAtOrDefault(0);

        if (textblockField != null) {
            Component textblock = textblockField.Value;
            ItemFields itemFields = new ItemFields(textblock.Content, textblock.Schema);

            MultiLineTextField textField = itemFields.Where(w => w.Name.Equals("TextBlock")).Cast<MultiLineTextField>().ElementAt(0);

            Item output = package.GetByName(Package.OutputName);
            if (output == null) {
                package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Text, textField.Value));
            } else {
                output.SetAsString(textField.Value);
            }
        }
    }
}


Comments