<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tridion Developer</title>
	<atom:link href="http://www.tridiondeveloper.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.tridiondeveloper.com</link>
	<description>Tridion Development portfolio and blog</description>
	<lastBuildDate>Thu, 26 Jan 2012 05:44:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Using XPath to find XML Elements with Inline/Default Namespace and Null Prefix</title>
		<link>http://www.tridiondeveloper.com/xpath-query-for-tags-with-null-prefix</link>
		<comments>http://www.tridiondeveloper.com/xpath-query-for-tags-with-null-prefix#comments</comments>
		<pubDate>Thu, 26 Jan 2012 05:36:29 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Helpful Tridion tips]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=401</guid>
		<description><![CDATA[On the last SDL Tridion Community Webinar, Dominic Cronin suggested a great alternative to Regex for finding, adding, removing, or replacing certain elements or attributes, such as Component Links within Components (or Pages).  The more data-safe approach is to manipulate the Component source as an XML document [via XPath] rather than regex.  I gave it [...]]]></description>
			<content:encoded><![CDATA[<p>On the last SDL Tridion Community Webinar, Dominic Cronin suggested a great alternative to Regex for finding, adding, removing, or replacing certain elements or attributes, such as Component Links within Components (or Pages).  The more data-safe approach is to manipulate the Component source as an XML document [via XPath] rather than regex.  I gave it a shot, except that getting (what seems like) a simple XPath query to work took way more effort than I anticipated.  All of this due to a little unknown detail about XPath queries for items in the default namespace without a prefix.</p>
<p><span id="more-401"></span></p>
<p>In this scenario, the Tridion XML source for a component has elements with inline (or default) xhtml namespaces declared right on the element that we&#8217;re searching for, and no prefix. For example, in the XML below such elements are the anchor and paragraph tags:</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-16&#8243;?&gt;<br />&lt;Content xmlns=&#8221;uuid:7F1745CA-CCFE-4032-BAD7-5699F4149D3B&#8221;&gt;<br /> &lt;Title&gt;Hello Internets!&lt;/Title&gt;<br /> &lt;Introduction&gt;<br /> &lt;div style=&#8221;TEXT-ALIGN: left&#8221; xmlns=&#8221;http://www.w3.org/1999/xhtml&#8221;&gt;Welcome to our website.    This is some random content that isn&#8217;t doing very much, except <strong>&lt;a href=&#8221;http://google.com&#8221;&gt;this link&lt;/a&gt;</strong><br /> &lt;/div&gt;<br /> &lt;/Introduction&gt;<br /> &lt;Body&gt;<br /> <strong>&lt;p xmlns=&#8221;http://www.w3.org/1999/xhtml&#8221;&gt;This is some more body content that has been put into the page.&lt;/p&gt;</strong><br /> &lt;/Body&gt;<br />&lt;/Content&gt;</p>
<p>A basic XPath query such as myXmlDocument.SelectNode(&#8220;//p&#8221;) should return all the &lt;p&gt; elements in the document, however, since they&#8217;re part of the default &#8220;http://www.w3.org/1999/xhtml&#8221; namespace, you get nothing back from your search &#8211; very annoying: thanks XPath engine for making it so hard! If only there had been a prefix, e.g. &lt;p xmlns:xhtml=&#8221;http://www.w3.org/1999/xhtml&#8221;&gt; then the XPath query would be a no brainer: myXmlDocument.SelectNode(&#8220;//xhtml:p&#8221;), and we&#8217;d select all the &lt;p&gt; nodes in the document within that namespace.</p>
<p>Actually, even though you don&#8217;t see a prefix in the above example, there actually is one. It&#8217;s called the NULL prefix. And the way you select nodes with a NULL prefix in C# is as follows:</p>
<p>XmlDocument componentXml = componentItem.GetAsXmlDocument();<br />XmlNamespaceManager nsMgr = new XmlNamespaceManager(componentXml.NameTable);<br /><strong>nsMgr.AddNamespace(&#8220;null&#8221;, &#8220;http://www.w3.org/1999/xhtml&#8221;);</strong><br />foreach (XmlElement pNode in componentXml.SelectNodes(&#8220;<strong>//null:p</strong>&#8220;, nsMgr))<br />{<br />    //do stuff with the pNode,<br />    //such as (random example) remove it completely from the document.</p>
<p>    pNode.ParentNode.RemoveChild(pNode);<br />}</p>
<p>Notice above, the xhtml namespace is added to the NamespaceManager with the &#8220;null&#8221; prefix, and then the XPath query selects the &lt;p&gt; tag with that prefix? That&#8217;s it!</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/xpath-query-for-tags-with-null-prefix/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Generating Web.Sitemap from Tridion (SiteMapDataSource)</title>
		<link>http://www.tridiondeveloper.com/web-sitemap</link>
		<comments>http://www.tridiondeveloper.com/web-sitemap#comments</comments>
		<pubDate>Sat, 21 Jan 2012 03:14:39 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development and templating]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=386</guid>
		<description><![CDATA[In spirit of Nuno&#8217;s post last week (http://nunolinhares.blogspot.com/2012/01/its-little-things-creating-page.html) regarding website navigation and more specifically, how to generate a Breadcrumb from Structure Groups in Tridion, I thought it was time to publish a related post (and a TBB) I&#8217;ve been baking for a while now.  Behold: hooking up Tridion to .NET&#8217;s standard Navigation Controls.  I&#8217;m talking [...]]]></description>
			<content:encoded><![CDATA[<p>In spirit of Nuno&#8217;s post last week (<a title="http://nunolinhares.blogspot.com/2012/01/its-little-things-creating-page.html" href="http://nunolinhares.blogspot.com/2012/01/its-little-things-creating-page.html" target="_blank">http://nunolinhares.blogspot.com/2012/01/its-little-things-creating-page.html</a>) regarding website navigation and more specifically, how to generate a Breadcrumb from Structure Groups in Tridion, I thought it was time to publish a related post (and a TBB) I&#8217;ve been baking for a while now.  <strong>Behold</strong>: hooking up Tridion to .NET&#8217;s standard Navigation Controls.  I&#8217;m talking about Menu, SiteMapPath, and TreeView.  Turns out they all feed off the same, rather basic, XML file called web.sitemap.  Here is the C# code for a generic TBB that creates such a file from your SDL Tridion Web Structure Group and Pages hierarchy.</p>
<p><span id="more-386"></span></p>
<p>Here is the basic structure of a .sitemap file:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;siteMap xmlns=&quot;http://schemas.microsoft.com/AspNet/SiteMap-File-1.0&quot;&gt;
  &lt;siteMapNode title=&quot;Movies Homepage&quot; url=&quot;/&quot; &gt;
    &lt;siteMapNode title=&quot;Action&quot; url=&quot;/action&quot; ...other attributes... &gt;
      &lt;siteMapNode title=&quot;MI4&quot; url=&quot;mi4.aspx&quot; ...other attributes... /&gt;
      ...
    &lt;/siteMapNode&gt;
    &lt;siteMapNode title=&quot;Thrillers&quot; url=&quot;/thrillers&quot; ...other attributes.../&gt;
    ...
    &lt;siteMapNode ... /&gt;
  &lt;/siteMapNode&gt;
&lt;/siteMap&gt;
</div>
</pre>
<p>Naturally, in Tridion (and almost any website) the Structure Groups are organized in much the same way.  So it shouldn&#8217;t be too hard to generate one of these files by recursively traversing through the SGs and pages.  &#8230; and writing a recursive algorithm is always fun.</p>
<p>So here is a TBB that you can plug into a new Page Component Template that will generate and publish a web.sitemap file based on your Structure Groups. </p>
<p>I do want to mention that if you have some funky business rules and handle them through Page or SG Metadata fields (most implementations do), then add a method to this code that gets the relevant Page or SG (e.g. engine.GetObject(tcmId); ), extracts the field value(s) and appends them as attributes to the siteMapNodes.</p>
<p>Just copy/paste the following code into a new class in your TBB project assembly.  Happy Tridionizing y&#8217;all!</p>
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
using System.Xml;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager;
using Tridion.ContentManager.CommunicationManagement;
using Tridion.ContentManager.Templating.Assembly;
using System;

namespace ContentBloom.Templates
{
    ///
    ///
&lt;summary&gt;
    /// This SDL Tridion building block recursively iterates over the
    /// Structure Groups of a publication and generates an ASPX.NET Web.sitemap
    /// file which can be pluged in as a DataSource into a TreeView, Breadcrumb
    /// and other .NET navigation User Controls.
    /// &lt;/summary&gt;

    [TcmTemplateTitle(&quot;Generate Web.sitemap&quot;)]
    public class GenerateWebSitemap : ITemplate
    {
        private Engine engine;
        private Package package;
        private static readonly TemplatingLogger log = TemplatingLogger.GetLogger(typeof(GetWebSitemap));

        private static string xmlns = &quot;http://schemas.microsoft.com/AspNet/SiteMap-File-1.0&quot;;

        public void Transform(Engine engine, Package package)
        {
            //Initialize
            this.engine = engine;
            this.package = package;

            Page page = null;
            Item pageItem = package.GetByType(ContentType.Page);
            if (pageItem != null)
            {
                page = engine.GetObject(pageItem.GetAsSource().GetValue(&quot;ID&quot;)) as Page;
            }
            else
            {
                throw new InvalidOperationException(&quot;No Page found.  Verify that this template is used with a Page.&quot;);
            }
            Publication mainPub = page.ContextRepository as Publication;
            StructureGroup rootSg = mainPub.RootStructureGroup;
            XmlDocument sitemapDoc = GenerateSitemap(rootSg);

            package.PushItem(Package.OutputName, package.CreateXmlDocumentItem(ContentType.Xml, sitemapDoc));
        }

        private XmlDocument GenerateSitemap(StructureGroup sg, XmlElement parent=null, XmlDocument doc=null)
        {
            if (doc == null)
            {
                //create base doc
                doc = new XmlDocument();
                XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration(&quot;1.0&quot;, &quot;utf-8&quot;, null);
                doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
            }
            if (parent == null)
            {
                //create root sitemap element and append to the doc.
                XmlElement root = doc.CreateElement(&quot;siteMap&quot;, xmlns);
                doc.AppendChild(root);

                parent = doc.CreateElement(&quot;siteMapNode&quot;, xmlns);
                root.AppendChild(parent);
                parent.SetAttribute(&quot;url&quot;, sg.PublishLocationUrl);
                parent.SetAttribute(&quot;title&quot;, RemoveNumberPrefix(sg.Title));
            }

            // Get the list of child structure groups and pages in this SG
            Filter filter = new Filter();
            filter.Conditions[&quot;ItemType&quot;] = 68;//pages, structure groups
            filter.BaseColumns = ListBaseColumns.Extended;

            XmlElement childItems = sg.GetListItems(filter);
            foreach (XmlElement item in childItems.SelectNodes(&quot;*&quot;))
            {
                string isPublished = item.GetAttribute(&quot;IsPublished&quot;);
                string itemType = item.GetAttribute(&quot;Type&quot;);
                string itemId = item.GetAttribute(&quot;ID&quot;);
                if (int.Parse(itemType) == (int)ItemType.Page)
                {
                    //only include published pages.  we also exclude index pages
                    //because the parent structure group's URL will default to them.
                    if (bool.Parse(isPublished))
                    {
                        Page childPage = engine.GetObject(itemId) as Page;
                        if (!ShouldBeExcluded(childPage))
                        {
                            XmlElement pageElem = doc.CreateElement(&quot;siteMapNode&quot;, xmlns);
                            parent.AppendChild(pageElem);
                            pageElem.SetAttribute(&quot;url&quot;, childPage.PublishLocationUrl);
                            pageElem.SetAttribute(&quot;title&quot;, RemoveNumberPrefix(childPage.Title));
                        }
                    }
                }
                else
                {
                    log.Debug(&quot;sgId=&quot; + itemId);
                    //if it's a structure group, then
                    //get the object, create a child sitemap node
                    StructureGroup childSg = engine.GetObject(itemId) as StructureGroup;
                    if (!ShouldBeExcluded(childSg))
                    {
                        XmlElement sgElem = doc.CreateElement(&quot;siteMapNode&quot;, xmlns);
                        parent.AppendChild(sgElem);
                        sgElem.SetAttribute(&quot;url&quot;, childSg.PublishLocationUrl);
                        sgElem.SetAttribute(&quot;title&quot;, RemoveNumberPrefix(childSg.Title));

                        GenerateSitemap(childSg, sgElem, doc);
                    }
                }
            }
            return doc;
        }

        ///
        ///
&lt;summary&gt;
        /// Pages and Structure Groups are often named with a numeric prefix to help sort
        /// them in a particular order.  This prefix does not need to be included in the
        /// web.sitemap file, so we strip it out.
        /// &lt;/summary&gt;

        ///
        ///
&lt;param name=&quot;p&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        private string RemoveNumberPrefix(string p)
        {
            string NUMBER_PREFIX_SEPARATOR = &quot;_&quot;;
            return p.Substring(p.IndexOf(NUMBER_PREFIX_SEPARATOR) + 1);
        }

        ///
        ///
&lt;summary&gt;
        /// This function checks if the page should be
        /// excluded from the sitemap. For example, it makes sense to filter
        /// out the index pages, since their parent structure group's url
        /// will point to them, and we don't want to include the index page
        /// twice.
        ///
        /// We also don't want to include user controls, i.e. ascx pages,
        /// so we'll filter those out too.
        /// &lt;/summary&gt;

        ///
        ///
&lt;param name=&quot;page&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        private bool ShouldBeExcluded(Page page)
        {
            string url = page.PublishLocationUrl;
            string title = page.Title;

            //filter out user controls
            if (url.EndsWith(&quot;ascx&quot;) || url.EndsWith(&quot;sitemap&quot;))
            {
                return true;
            }

            //filter out if index page
            string[] indexPageNames = new string[] {&quot;index.html&quot;, &quot;index.htm&quot;, &quot;index.aspx&quot;, &quot;default.aspx&quot;};
            foreach (string indexName in indexPageNames)
                if (url.ToLower().EndsWith(indexName))
                {
                    return true;
                }

            return false;
        }

        ///
        ///
&lt;summary&gt;
        /// It may make sense to exclude any structure groups that don't have any childen pages or other structure
        /// groups.
        /// &lt;/summary&gt;

        ///
        ///
&lt;param name=&quot;sg&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        private bool ShouldBeExcluded(StructureGroup sg)
        {
            Filter filter = new Filter();
            filter.Conditions[&quot;ItemType&quot;] = ItemType.StructureGroup;
            filter.Conditions[&quot;Recursive&quot;] = true;
            filter.BaseColumns = ListBaseColumns.Id;
            int pages = sg.GetListItems(filter).SelectNodes(&quot;*&quot;).Count;
            return pages == 0 ? true : false;
        }
    }
}
</pre>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/web-sitemap/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SDL Tridion webinar: Presentations and resources</title>
		<link>http://www.tridiondeveloper.com/sdl-tridion-webinar-presentations</link>
		<comments>http://www.tridiondeveloper.com/sdl-tridion-webinar-presentations#comments</comments>
		<pubDate>Wed, 11 Jan 2012 20:14:29 +0000</pubDate>
		<dc:creator>John Winter</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Tridion 2011]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=373</guid>
		<description><![CDATA[For anyone that would like the slides from today&#8217;s SDL Tridion community webinar here are the downloads: SDL Tridion powertool (page publisher) (pptx) SDL Tridion embedding for media and vido Thanks Jules/SDL for having us and we&#8217;re looking forward to the next one.]]></description>
			<content:encoded><![CDATA[<p>For anyone that would like the slides from today&#8217;s <a href="http://www.julianwraith.com/sdl-tridion-community-webinars/community-webinar-11th-january-2012/">SDL Tridion community webinar</a> here are the downloads:</p>
<ul>
<li><a href="http://www.tridiondeveloper.com/wp-content/uploads/2012/01/community-webinar-powertools.pptx">SDL Tridion powertool (page publisher)</a> (pptx)</li>
<li><a href="http://www.tridiondeveloper.com/integration-sdl-tridion-jw-media-player">SDL Tridion embedding for media and vido</a></li>
</ul>
<p>Thanks Jules/SDL for having us and we&#8217;re looking forward to the next one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/sdl-tridion-webinar-presentations/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SDL Tridion Application Integration</title>
		<link>http://www.tridiondeveloper.com/sdl-tridion-application-integration</link>
		<comments>http://www.tridiondeveloper.com/sdl-tridion-application-integration#comments</comments>
		<pubDate>Fri, 30 Dec 2011 07:13:06 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Application Integration]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=355</guid>
		<description><![CDATA[When I first got the opportunity to work with Tridion, the biggest question I needed an answer to was how to integrate various applications with SDL Tridion.  At the time, I was running a project that required migrating about 20 J2EE applications tightly integrated with a legacy Plumtree Portal to a .NET platform driven by [...]]]></description>
			<content:encoded><![CDATA[<p>When I first got the opportunity to work with Tridion, the biggest question I needed an answer to was how to integrate various applications with SDL Tridion.  At the time, I was running a project that required migrating about 20 J2EE applications tightly integrated with a legacy Plumtree Portal to a .NET platform driven by  SDL Tridion.  The organization was moving away from J2EE to become a .NET shop, so the apps needed to be rewritten in .NET &#8211; our #1 task.  All we had was a barebone Tridion installation and a bunch of manuals that did not mention anything about how to integrate apps into it.  SDL Tridion training also did not cover this topic &#8211; although we got some useful hints, we needed to see a proven design.  My intent with this article is to help any new Tridion teams to keep their project moving forward if faced with a similar situation.</p>
<p>The approaches discussed here are not limited to .NET.  They can be leveraged to integrate Tridion content into J2EE apps, mobile apps, or anything that you want, such as PHP, Perl, C++.  In other words, the sky is the limit.</p>
<p><span id="more-355"></span></p>
<p>First off, it is important to understand that Tridion offers two publishing models:</p>
<ol>
<li><strong>Static publishing:</strong> the Tridion Content Manager publishes content in the form of files to any location you wish via HTTP, FTP, NFS and others.  For e.g. put a jsp file to an app server, or an aspx file to an IIS server in the DMZ.</li>
<li><strong>Dynamic publishing:</strong> the Tridion Content Manager publishes content in the form of data to the Broker, which is an application configured on your presentation server.  The published content in the Broker is accessed via an API.  This is close to how integration works with other CMS or portal products, except that applications&#8217; requests are not going across the entire firewall back to the Content Manager &#8211; which is sweet!</li>
</ol>
<h2><a name="dynamic publishing"></a>Application Integration with Dynamic Publishing Tutorial</h2>
<p>If you&#8217;ve chosen to leverage the benefits that the Broker has to offer, i.e. option 2 above, then your app can simply use the functions from the Broker API to retrieve content from the Broker.  If your app is Java-based, then simply include the Broker JAR files and set up some parameters in the web.xml.  The same thing applies to a .NET app, except you&#8217;ll be including a DLL instead of the JAR and using the .NET version of the Broker API.  Have a read through the Tridion Content Delivery Implementation Manual for the fine details.  It&#8217;s easy after you have everything configured.  The differences between the Java and the .Net versions of the API are just syntax.  All the methods and classes are pretty much the same.</p>
<p>For those that are new to the Tridion architecture, remember, your app does not query the Content Manager directly like it does in most other products out there such as the Oracle UCM, Sharepoint or the legacy Plumtree Portal.  With SDL Tridion, content management is separate from the published content.  So our apps query the published content in the Broker via the Broker API, which is a separate data store from the Content Manager.  You can, of course, make your app talk directly to the CM via the Business Connector or Custom Pages if you have a proper reason to do that, but if you just need to pull some content in an externally-facing app, then Broker is the tool to use.</p>
<h2><a name="static publishing"></a>Application Integration with Static Publishing Tutorial</h2>
<p>This is my favourite because of its simplicity &#8211; less infrastructure and easy to transition, maintain and in general understand.</p>
<p>On that project which I mentioned in the intro, the mandate from Enterprise Architecture was that, if possible, systems should be loosely integrated without building too much dependency on one particular product.  This means favouring web services over proprietary product API calls inside other systems, as one example.  Loose integration makes it easier to swap systems if introducing another product in the middle or upgrading to a different product.  At an Enterprise Architecture level, it&#8217;s a great strategy to manage technical risk from the point of view that Enterprise IT system&#8217;s average life span is 5-10 years.  So if a system isn&#8217;t meeting your expectations or growing requirements, it&#8217;s cheaper and easier to upgrade or replace it when loosely integrated.  I had the pleasure of experiencing the opposite by having to re-factor many applications when a client of mine switched from the old Plumtree portal to Sharepoint (for internal apps) or Tridion (for external).  Of course there are cons to the Static over the Dynamic publishing approach, but I&#8217;m not going to get into further debate on this here.</p>
<p>As mentioned, with the Static Publishing model, files get published out to a server location.  These files can be of any kind &#8211; jsp, include, aspx, ascx, xml, php, and so on.  You create a Page Template where you can specify any file extension that you choose.  What does this mean?</p>
<p>It means that you can publish out chunks of content as separate &#8220;include&#8221; pages with all the HTML markup or logic, and your apps simply consume them.  You can also create a Page Template that will render and publish out XML (in the format you chose &#8211; refer to Dreamweaver Templating), and your app can consume it by parsing and rendering it.  You can also make the Page Template render the content with HTML markup inside an XML CDATA field.  Once again, the sky is the limit.</p>
<h3><a name=".net integration example"></a>Example: Integration with a Custom .NET App</h3>
<p>Here is an example where promotional content is managed in Tridion, such as widgets and call-to-actions, and an ASP.NET-based user registration system needs to display this content as right rail widgets.</p>
<p>Seems like a User Control would be perfect for the job.  (BTW, if you&#8217;re integrating with Sharepoint, then a Web Part could be used just the same.)  Our user registration system can wonderfully render this User Control in the right rail of its ASPX page.</p>
<h4>Step 1: Create a User Control Component Template</h4>
<p>Suppose you have a Promo schema with fields such as: &#8216;title&#8217;, &#8216;promo page url&#8217;, &#8216;promo image&#8217;, and &#8220;promo text&#8221;. Through the magic of Tridion&#8217;s Compound Templating we create a Tridion Component Template, &#8220;Right Rail CT&#8221;, which contains a Dreamweaver template TBB that looks something like this (let&#8217;s assume all the fields are mandatory for simplicity&#8217;s sake and avoid TemplateBeginIf&#8217;s):</p>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;div class=&quot;rightrailwidget&quot;&gt;

     &lt;a href=&quot;@@Component.promoUrl@@&quot;&gt;&lt;img src=&quot;@@Component.promoImage@@&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
     @@Component.promoText@@
&lt;/div&gt;
</div>
</pre>
<h4>Step 2: Create a User Control Page Template</h4>
<p>Let&#8217;s call this &#8220;Right Rail Promo User Control PT&#8221;.  The file extension for pages generated by this template is &#8220;.ascx&#8221;.  It is a very simple template that renders our Promo items using the &#8220;Right Rail CT&#8221; as User Controls:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;%@ Control Language=&quot;C#&quot; ClassName=&quot;contentbloom&quot; %&gt;

&lt;!-- TemplateBeginRepeat name=&quot;Components&quot; --&gt;
@@RenderComponentPresentations()@@
&lt;!-- TemplateEndRepeat --&gt;
&lt;script runat=&quot;server&quot;&gt;
    //optionally, whatever you normally put in your code-behind, can go here
&lt;/script&gt;
</div>
</pre>
<h4>Step 3: Create and Publish the User Controls</h4>
<p>Now you can create various Promo Right Rail Widget User Controls as Tridion pages and publish them.  Simply create a new Tridion page in a Structure Group such as &#8220;/usercontrols/promos/&#8221;, and in it create pages using the &#8220;Right Rail Promo User Control PT&#8221; template.  Now simply publish it to the same IIS server(s) on which our application is hosted.</p>
<h4>Step 4: Consume the User Controls by the Application</h4>
<p>Our .NET-based New User Registration application can now include the published user controls on the right rail of its ASPX or Master pages.  It&#8217;s pure .NET at this point.  The application&#8217;s ASPX page would have a statement like this in its right rail div:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;%@ Page Language=&quot;C#&quot; %&gt;

User Registration Step 1
&lt;form id=&quot;form1&quot;&gt;
&lt;div class=&quot;main&quot;&gt;
      &lt;!-- Application form fields and other stuff here --&gt;
    &lt;/div&gt;
&lt;div class=&quot;rightrail&quot;&gt;
        &lt;%@ Register TagPrefix=&quot;contentbloom&quot; TagName=&quot;RightRailPromoWidget1&quot; Src=&quot;/usercontrols/promos/promo1.ascx&quot;&gt;&lt;/div&gt;
&lt;/form&gt;
</div>
</pre>
<h4>Bullet-proofing (optional)</h4>
<p>I like to put in a little bit of bullet-proofing into the application&#8217;s logic, so that if a user control is unpublished, the application doesn&#8217;t throw a 500 error since it can&#8217;t find it.  We do this by loading the user controls into the right-rail div programatically from the code-behind (or inline):
</p>
<p>Check this out:</p>
<p>user-registration-step1.aspx:</p>
<pre>
<div class="syntaxhighlighter htmlscript">

&lt;%@ Page Language=&quot;C#&quot; %&gt;

&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;

&lt;script runat=&quot;server&quot;&gt;
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            UserControl promo1 = this.LoadControl(&quot;/usercontrols/promo1.ascx&quot;);
            RightRail.Controls.Add(promo1);
        }
        catch
        {
            //log as a warning and continue with loading the page without the right rail widget.
        }
    }
&lt;/script&gt;

&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head runat=&quot;server&quot;&gt;&lt;title&gt;User Registration Step 1&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;
&lt;div class=&quot;main&quot;&gt;
      &lt;!-- Application form fields and other stuff here --&gt;
    &lt;/div&gt;
&lt;div class=&quot;rightrail&quot;&gt;
        &lt;asp:PlaceHolder id=&quot;RightRail&quot; runat=&quot;server&quot;&gt;&lt;/asp:PlaceHolder&gt;
    &lt;/div&gt;
&lt;/form&gt;

&lt;/body&gt;
&lt;/html&gt;
</div>
</pre>
<p>Now the page will attempt to load the right rail promo user controls, but if they&#8217;re not available or not needed, then the page continues to load normally without them.  This could greatly reduce the likelihood of a severity 1 production issue because a content editor decided to unpublish a certain promo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/sdl-tridion-application-integration/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JavaScript Compression in SDL Tridion (minification and obfuscation. CSS too)</title>
		<link>http://www.tridiondeveloper.com/javascript-compression-in-sdl-tridion</link>
		<comments>http://www.tridiondeveloper.com/javascript-compression-in-sdl-tridion#comments</comments>
		<pubDate>Tue, 20 Dec 2011 01:44:47 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Helpful Tridion tips]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=341</guid>
		<description><![CDATA[I&#8217;ve been building up my jot notes throughout the year and finally got the chance to make them into publishable form, which lead me to this sudden series of articles. Thanks, John, for letting me post on your site. To achieve maximum compression on a JavaScript file, minification is not enough.  Obfuscation is where it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been building up my jot notes throughout the year and finally got the chance to make them into publishable form, which lead me to this sudden series of articles.  Thanks, John, for letting me post on your site.</p>
<p>To achieve maximum compression on a JavaScript file, minification is not enough.  Obfuscation is where it&#8217;s at.  This means replacing variable names to the shortest amount of characters (or bytes) that the language syntax allows.  For example: var myReallyLongVariableName=&#8221;foobar&#8221; would become var a=&#8221;foobar&#8221;; but only within its scope, and so on.  You basically have to implement a decent chunk of code that usually comes as part of any language interpreter or compiler.  It&#8217;s quite a bit more involved than minification alone.  My point is, use a proven package that does this and just hook it up to the best CMS known to man.</p>
<p>My preferred way is actually to not store JavaScript or CSS in Tridion.  Put it with the rest of your website&#8217;s code into the repository like TFS or Subversion.  Basically, bundle it into your build process which should go through Change Management with the likes of JAR/DLL files and DB packages.  JS is code after all.  This way you can just add a step to your build process.  Ask the build master to crunch the JS/CSS through a compressor (possibly as a manual step) before or automate within an ANT, NANT or MSBuild script.  If, however, you are a content author or Support person that hates dealing with your org&#8217;s Change Management process or have some other reason to store js and/or CSS code as easily publishable as content, then this is for you.</p>
<p><span id="more-341"></span></p>
<p>A requirement I often get requests for is to minify and obfuscate JS files which are stored in Tridion, either in Multimedia Components or pasted into a text field of a normal component.    Minification is trivial.  Simply remove the extra whitespace and comments.  Obfuscation, however, is a bit more involved as I mentioned above.  So let&#8217;s find a good JS compressor package that&#8217;s available today.</p>
<p>YUI Compressor is the best minification and obfuscation library that is out there.  It was created by engineers at Yahoo!.  Since the original package is in Java, but Tridion templating is done in C#, we&#8217;ll turn to the YUI Compressor .NET port (link is below).</p>
<p>There are two classes with methods that do what we need to do:</p>
<ol>
<li>CSSCompressor.Compress(<em>string</em>)</li>
<li>JavaScriptCompressor.Compress(<em>string</em>)</li>
</ol>
<p>Both of the above return string.  So all we need to do is extract the CSS or JavaScript content from our component as a string, call the YUI Compressor methods and publish the CSS or JS file.</p>
<p>There are a few ways that a CSS/JS file can be published:</p>
<p>1) Static publishing model &#8211; the component holding the JS is added to a Page and published (using a simple page template).  Our fellow Tridion community member, Jonathan Whiteside, has an excellent article series that dives into these details in his discussion on Tridion CSS Minification (<a href="http://blog.building-blocks.com/2011/01/tridion-tbb-automatically-minify-css-javascript-on-publish" target="_blank">http://blog.building-blocks.com/2011/01/tridion-tbb-automatically-minify-css-javascript-on-publish</a>).</p>
<p>2) Dynamic publishing model &#8211; the component is published via a dynamic component template that relies on a TBB which extracts the JS content from the component and calls the AddBinary method with a Structure Group URI as a parameter.  No Page is necessary here, but you do need at least the file system Broker running.</p>
<p>My aim in this post is not to get into the details of #1 or #2 above.  I will show an example that extracts the JS or CSS as a string from the MM Component (using Jonathan&#8217;s method), call on the YUI Compressor to obfuscate and minify, and place the compress string as a variable onto the Package.  You can do whatever you wish with it at that point &#8211; put the TBB into a static or dynamic CT.</p>
<p>Here we go:</p>
<ol>
<li>Download the .NET port of the YUI Compressor from here: <a href="http://yuicompressor.codeplex.com/" target="_blank">http://yuicompressor.codeplex.com/</a></li>
<li>Take these DLLs and put them in the GAC or the Tridion Bin folder on your Content Manager server(s).  Make sure these DLLs are on all the CM servers that the TBB will need to execute on (all load balanced CM nodes, Dev, QA, Prod, etc).  Make sure to submit a Change Request to have these DLLs installed on anything past the Development environment, but if you have a good, no BS rep with your server admins (like I always do <img src='http://www.tridiondeveloper.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , this shouldn&#8217;t be a problem.</li>
<li>Make sure the Template Base class (which is part of Will&#8217;s Get Linked Components extension) is added into your Visual Studion project. </li>
<li>Create a new Template Building Block class in Visual Studio with this code:
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
using System;
using System.Text;
using System.Text.RegularExpressions;
using Tridion.ContentManager;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager.Templating.Assembly;
using ContentBloom.Tridion.B2C.Templates.Base;
using System.IO;
using Yahoo.Yui.Compressor;
using System.Globalization;

namespace ContentBloom.Tridion.B2C.Templates
{
    [TcmTemplateTitle(&quot;Compress JS and CSS using YUI Compressor&quot;)]
    public class CompressYUI : TemplateBase
    {
        enum BinaryType
        {
            JS, CSS, Other
        }

        public override void Transform(Engine engine, Package package)
        {
            // Initialize
            Initialize(engine, package);
            string codeContent;

            // Get CSS Content
            Logger.Debug(&quot;Retrieving code from Component.&quot;);
            Component comp = this.GetComponent();
            string filename = Utilities.GetFilename(comp.BinaryContent.Filename);
            BinaryType bt = GetFileType(filename);
            if(bt == BinaryType.JS || bt == BinaryType.CSS)
            {
                string needsCompression = package.EvaluateExpression(&quot;Component.Metadata.compress&quot;);
                // if the &quot;Compress&quot; field is not specified, then default it to True.
                if (string.IsNullOrEmpty(needsCompression) || needsCompression == &quot;True&quot;)
                {
                    codeContent = GetCodeContent(comp);

                    try
                    {
                        Logger.Debug(&quot;Before minification:\n&quot; + codeContent);
                        switch (bt)
                        {
                            case BinaryType.CSS:
                                codeContent = CssCompressor.Compress(codeContent);
                                break;
                            case BinaryType.JS:
                                codeContent = JavaScriptCompressor.Compress(codeContent, true, true, false, false, -1, Encoding.UTF8, new CultureInfo(&quot;en-US&quot;, false));
                                break;
                        }
                        Logger.Debug(&quot;After minification:\n&quot; + codeContent);
                    }
                    catch (Exception e)
                    {
                        string message = e.Message;
                        if (e.Message.Contains(&quot;syntax error&quot;))
                        {
                            message = &quot;There is a problem with the encoding of the file. Please change the encoding of the file to UTF-8 WITH NO BYTE ORDER MARK/UTF-8 without signature.&quot;;
                        }
                        throw new InvalidDataException(message, e);
                    }

                    //push to Output.
                    package.PushItem(&quot;Output&quot;, package.CreateStringItem(ContentType.Text, componentCount.ToString(codeContent)));
                }
                else
                {
                    Logger.Info(&quot;Component metadata \&quot;Compress\&quot; field specifies to avoid compression. Therefore, exiting.&quot;);
                }
            }
            else
            {
                Logger.Info(&quot;No CSS or JS file found, so nothing to do.&quot;);
            }
        }

        private BinaryType GetFileType(string filename)
        {
            Logger.Debug(&quot;Entering method GetFileType&quot;);
            BinaryType bt = BinaryType.Other;
            filename = filename.ToLower();
            Logger.Debug(&quot;filename=&quot; + filename);
            if (filename.EndsWith(&quot;.css&quot;))
            {
                bt = BinaryType.CSS;
            }
            else if (filename.EndsWith(&quot;.js&quot;))
            {
                bt = BinaryType.JS;
            }
            Logger.Debug(&quot;Exiting method GetFileType&quot;);
            return bt;
        }

        ///
        /// Get the CSS content in plain text from the current component
        ///
        /// CSS content in plain text
        private string GetCodeContent(Component c)
        {
            // code path
            string codeContent = string.Empty;

            // read the css into a string
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] binary = c.BinaryContent.GetByteArray();
            if (binary != null) codeContent = encoding.GetString(binary, 0, binary.Length);

            return codeContent;
        }
    }
}
</pre>
</div>
</pre>
</li>
<li>Finally, add the TBB to your Component Template and enjoy the sexiest minified and obfuscated JavaScript.</li>
</ol>
<h2>Minify/Obfuscate Only on Demand</h2>
<p>You can go one step further and add a bit of logic to minify and obfuscate only for certain scripts, e.g. obfuscate one, but not the other.  Here&#8217;s what you can do&#8230;</p>
<p>In your JavaScript Multimedia Component schema add a couple of Text metadata fields:</p>
<ol>
<li>Field name: &#8220;Minify&#8221;.  Value: Select from Dropdown &#8220;Yes/No&#8221;.</li>
<li>Field name: &#8220;Obfuscate&#8221;.  Value: Select from Dropdown &#8220;Yes/No&#8221;.</li>
</ol>
<p>Modify the TBB above to read these fields from the Component and minify/obfuscate accordingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/javascript-compression-in-sdl-tridion/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More fun with Dreamweaver Templates &#8211; TemplateRepeatCount</title>
		<link>http://www.tridiondeveloper.com/more-fun-with-dreamweaver-templates-templaterepeatcount</link>
		<comments>http://www.tridiondeveloper.com/more-fun-with-dreamweaver-templates-templaterepeatcount#comments</comments>
		<pubDate>Sun, 18 Dec 2011 05:08:43 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Helpful Tridion tips]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=318</guid>
		<description><![CDATA[Quite a while back (in &#8217;09&#8242; I think) I replied to a thread on the sdltridionworld forum regaring how to get the total count of your elements when doing a TemplateBeginRepeat inside a DWT. For example when you have a special css class that needs to be applied to the last item in the list. [...]]]></description>
			<content:encoded><![CDATA[<p>Quite a while back (in &#8217;09&#8242; I think) I replied to a thread on the sdltridionworld forum regaring how to get the total count of your elements when doing a TemplateBeginRepeat inside a DWT.</p>
<p>For example when you have a special css class that needs to be applied to the last item in the list.</p>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/contact/&quot;&gt;Contact Us&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/sitemap/&quot;&gt;Site Map&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;last&quot;&gt;&lt;a href=&quot;/terms-of-use/&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</div>
</pre>
<p>An intuitive approach is to have a function or a variable that provides the count so that you can use syntax like this:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;ul&gt;
 &lt;!-- TemplateBeginRepeat name=&quot;Component.LinkList&quot; --&gt;
&lt;li&gt;&lt;a href=&quot;@@MyUrlField@@&quot;&gt;@@MyUrlText@@&lt;/a&gt;&lt;/li&gt;

  &lt;!-- TemplateBeginIf cond=&quot;TemplateRepeatIndex == TemplateRepeatCount()-1 --&gt;
&lt;li class=&quot;last&quot;&gt;&lt;a href=&quot;@@MyUrlField@@&quot;&gt;@@MyUrlText@@&lt;/a&gt;&lt;/li&gt;

  &lt;!-- TemplateEndIf --&gt;
&lt;!-- TemplateEndRepeat --&gt;
&lt;/ul&gt;
</div>
</pre>
<p>I&#8217;ll post that function later once I dig up the code again.  Though, here is another approach which I used one late night in the office wanting to finish a template.  It was past my sys admin&#8217;s office time, so I couldn&#8217;t ask him to deploy a new Custom Functions DLL to the CM server&#8217;s GAC/bin, but I just had to get the template done by end of day &#8211; I was in the zone.  Besides, I couldn&#8217;t let it linger the next day.  </p>
<p>
So here is a quick C# fragment that should be used in sequence after Will Price&#8217;s &#8220;Get Linked Components&#8221; extension (just Google it if you don&#8217;t know.  It&#8217;s the best thing since the combustion engine/sliced bread/eh&#8230;SDL Tridion CMS).</p>
<p>Anyway, just drop this C# Fragment in after &#8220;Get Linked Components&#8221;:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
&lt;%@ Import Namespace=&quot;Tridion.ContentManager.ContentManagement.Fields&quot;%&gt;
&lt;%@ Import Namespace=&quot;System.Collections.Generic&quot;%&gt;

/// This TBB loops through all the items in the package and for any items which are Component Arrays
/// adds a new package item with the array entry count.  This is useful when a Dreamweaver TBB needs to know
/// the total count of components or when needing to know if you're on the last component.

List&lt;KeyValuePair&lt;string, Item&gt;&gt; extractedComponentLists = new List&lt;KeyValuePair&lt;string, Item&gt;&gt;();
foreach (KeyValuePair&lt;string, Item&gt; kvp in package.GetEntries())
{
    if (kvp.Value.ContentType == ContentType.ComponentArray)
    {
        //get count
        extractedComponentLists.Add(kvp);
    }
}

// This code has to be kept in a separate loop since you can't modify the package.GetEntries collection while looping through it.
foreach (KeyValuePair&lt;string, Item&gt; kvp in extractedComponentLists)
{
    IComponentPresentationList linkCollectionCPList = ComponentPresentationList.FromXml(kvp.Value.GetAsString());
    int componentCount = linkCollectionCPList.Count;
    package.PushItem(kvp.Key + &quot;Count&quot;, package.CreateStringItem(ContentType.Number, componentCount.ToString()));
}
</pre>
</div>
</pre>
<p>&nbsp;</p>
<p>After this TBB runs, you&#8217;ll get a new entry on the package with the count for each &#8220;Tridion/Component[]&#8221; item type that &#8220;Get Linked Components&#8221; fetches.  So if we had a multi-value component link field in the component called &#8220;LinkList&#8221;, then &#8220;Get Linked Components&#8221; should fetch a component array and call it after your field name &#8211; something like &#8220;LinkList&#8221;.  Then after this DWT a new entry will appear called &#8220;LinkListCount&#8221;.</p>
<p>Use it like this in your DWT:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
&lt;ul&gt;
&lt;!-- TemplateBeginRepeat name=&quot;Component.LinkList&quot; --&gt;
&lt;li&gt;&lt;a href=&quot;@@MyUrlField@@&quot;&gt;@@MyUrlText@@&lt;/a&gt;
&lt;li&gt;&lt;!-- TemplateBeginIf cond=&quot;TemplateRepeatIndex == LinkListCount-1 --&gt; 
&lt;li&gt;&lt;a href=&quot;@@MyUrlField@@&quot;&gt;@@MyUrlText@@&lt;/a&gt;
&lt;li&gt;&lt;!-- TemplateEndIf --&gt;
&lt;!-- TemplateEndRepeat --&gt;
&lt;/ul&gt;
</pre>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/more-fun-with-dreamweaver-templates-templaterepeatcount/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get and Set Variables in DWTs</title>
		<link>http://www.tridiondeveloper.com/get-and-set-variables-in-dwts</link>
		<comments>http://www.tridiondeveloper.com/get-and-set-variables-in-dwts#comments</comments>
		<pubDate>Sat, 17 Dec 2011 00:22:38 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Helpful Tridion tips]]></category>
		<category><![CDATA[Tridion building block]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=295</guid>
		<description><![CDATA[Here is a creative and useful set of Dreamweaver Custom Functions that allow instantiating your own variables in a Dreamweaver Tridion template.  Credit goes out to my fellow team members Trevor Bartlett and Riyaz Hameed. You can do stuff like this: Here is the code:]]></description>
			<content:encoded><![CDATA[<p>Here is a creative and useful set of Dreamweaver Custom Functions that allow instantiating your own variables in a Dreamweaver Tridion template.  Credit goes out to my fellow team members Trevor Bartlett and Riyaz Hameed.</p>
<h2>You can do stuff like this:</h2>
<pre>
<div class="syntaxhighlighter htmlscript">
&lt;!-- TemplateBeginRepeat name=&quot;Field.columnSection&quot; --&gt;
  &lt;div class=&quot;wpsPortlet&quot;&gt;
    &lt;div class=&quot;wpsPortletTitle&quot;&gt;
      &lt;br /&gt;@@Field.title@@&lt;/div&gt;
    @@SetVariable(“columnSectionIndex”, &quot;${TemplateRepeatIndex}&quot;)@@
    &lt;!-- TemplateBeginRepeat name=&quot;Field.subColumnSection&quot; --&gt;
    @@GetVariable(&quot;columnSectionIndex&quot;)@@
    &lt;!-- TemplateBeginRepeat name=&quot;Field.subTitle&quot; --&gt;
       …
    &lt;!-- TemplateEndRepeat --&gt;
  &lt;/div&gt;
&lt;!-- TemplateEndRepeat --&gt;
<h2></h2>
<h2>Here is the code:</h2>
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
/// &lt;summary&gt;
/// Sets a varialbe in the package to the name and value specifed. Also removes any other variable that was set with the same name before.
/// &lt;/summary&gt;
/// &lt;param name=&quot;variableName&quot;&gt;Name of the varialbet&lt;/param&gt;
/// &lt;param name=&quot;value&quot;&gt;Value of the variable&lt;/param&gt;
[TemplateCallable()]
public string SetVariable(string variableName, object value)
{
    //Remove the old variable and set the new variable
    _engine.PublishingContext.RenderContext.ContextVariables.Remove(variableName);
    _engine.PublishingContext.RenderContext.ContextVariables.Add(variableName, value);

    return &quot;&quot;;
}

/// &lt;summary&gt;
/// Gets a varialbe from the publishing context.
/// &lt;/summary&gt;
/// &lt;param name=&quot;variableName&quot;&gt;Name of the variable&lt;/param&gt;
[TemplateCallable()]
public object GetVariable(string variableName)
{
    //Get the varialbe
    return _engine.PublishingContext.RenderContext.ContextVariables[variableName];
}
</pre>
</div>
</pre>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/get-and-set-variables-in-dwts/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting used items using the core service</title>
		<link>http://www.tridiondeveloper.com/getting-used-items-using-the-core-service</link>
		<comments>http://www.tridiondeveloper.com/getting-used-items-using-the-core-service#comments</comments>
		<pubDate>Sun, 27 Nov 2011 18:52:11 +0000</pubDate>
		<dc:creator>John Winter</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Helpful Tridion tips]]></category>
		<category><![CDATA[Tridion 2011]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=285</guid>
		<description><![CDATA[Just wanted to post up a quick code snippet showing how to get a list of used items XML using the SDL Tridion 2011 core service.  Why?  Well previously the API typically used to work like itemType.GetListUsedItems() (where itemType is a Component or Page object etc), where as now the &#8216;Using&#8217; and &#8216;Used&#8217; items are [...]]]></description>
			<content:encoded><![CDATA[<p>Just wanted to post up a quick code snippet showing how to get a list of used items XML using the SDL Tridion 2011 core service.  Why?  Well previously the API typically used to work like <em>itemType.GetListUsedItems()</em> (where itemType is a Component or Page object etc), where as now the &#8216;Using&#8217; and &#8216;Used&#8217; items are read using a filter via the core service client method <em>.GetListXML()</em>.</p>
<p><span id="more-285"></span></p>
<p>The example:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
            // Create a filter
            UsedItemsFilterData usingItemsFilterData = new UsedItemsFilterData
            {
                BaseColumns = ListBaseColumns.Id, // to specify the detail in the XML
                ItemTypes = new[] { ItemType.Folder, ItemType.Schema, ItemType }  // to specify certain items
            };
            // Get the XML by calling .GetListXml on the client (assumes you have a 'client' object already)
            XElement usingXML = client.GetListXml(&quot;tcm:4-283&quot;, usingItemsFilterData);
</pre>
</div>
</pre>
<p>If you&#8217;re looking to get the Using Items, for an item, you can simply use a UsingItemsFilterData filter in exactly the same way &#8211; enjoy <img src='http://www.tridiondeveloper.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/getting-used-items-using-the-core-service/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integration: SDL Tridion &amp; JW Media Player</title>
		<link>http://www.tridiondeveloper.com/integration-sdl-tridion-jw-media-player</link>
		<comments>http://www.tridiondeveloper.com/integration-sdl-tridion-jw-media-player#comments</comments>
		<pubDate>Wed, 09 Nov 2011 13:22:11 +0000</pubDate>
		<dc:creator>Nickoli Roussakov</dc:creator>
				<category><![CDATA[Development and templating]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=274</guid>
		<description><![CDATA[Often clients have a need to embed videos within their rich text content fields of various formats (FLV, mp4 or streaming via RTMP).  Pasting video embed code is one way to deal with this, the video and it&#8217;s dependant files need would to be published separately in Tridion with the video URL hardcoded as part [...]]]></description>
			<content:encoded><![CDATA[<p>Often clients have a need to embed videos within their rich text content fields of various formats (FLV, mp4 or streaming via RTMP).  Pasting video embed code is one way to deal with this, the video and it&#8217;s dependant files need would to be published separately in Tridion with the video URL hardcoded as part of the content.  This is not an elegant, nor a user-friendly solution.</p>
<p>The JW Player Video Renderer module allows the non-technical user to include a video Multimedia Component as a Component Link within their rich text field.  All that is required is a little bit of configuration and a TBB.</p>
<p>Here is the code: <a href="http://www.tridiondeveloper.com/wp-content/uploads/2011/11/ContentBloom.Common.WCMS-2011-11-09.zip">Tridion JW Vide0 Renderer.zip</a></p>
<p>And the document that explains it all: <a title="Media player integration in Tridion" href="http://www.tridiondeveloper.com/wp-content/uploads/2011/11/JW-Video-Player-Tridion-Integration_2011-11-09.pdf" target="_blank">JW Video Player Tridion Integration.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/integration-sdl-tridion-jw-media-player/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remove HTML whitespace from the template output</title>
		<link>http://www.tridiondeveloper.com/remove-whitespace-dwt-tridion-output</link>
		<comments>http://www.tridiondeveloper.com/remove-whitespace-dwt-tridion-output#comments</comments>
		<pubDate>Mon, 10 Oct 2011 23:54:03 +0000</pubDate>
		<dc:creator>John Winter</dc:creator>
				<category><![CDATA[Development and templating]]></category>
		<category><![CDATA[Helpful Tridion tips]]></category>

		<guid isPermaLink="false">http://www.tridiondeveloper.com/?p=248</guid>
		<description><![CDATA[HTML published from Tridion is typically created using Tridion Dreamweaver Templates (DWTs).  These templates can involve a lot of ‘If’ statements to check that values exist or what their value is etc.  I like to put line breaks between each DWT statement so that its easier to read and work with, which usually looks something [...]]]></description>
			<content:encoded><![CDATA[<p>HTML published from Tridion is typically created using Tridion Dreamweaver Templates (DWTs).  These templates can involve a lot of ‘If’ statements to check that values exist or what their value is etc.  I like to put line breaks between each DWT statement so that its easier to read and work with, which usually looks something like this (actually it can get a lot crazier than this!):</p>
<pre><a href="http://www.tridiondeveloper.com/wp-content/uploads/2011/10/sdl-tridion-dwt-snippet.png"><img class="alignnone size-full wp-image-263" title="sdl-tridion-dwt-snippet" src="http://www.tridiondeveloper.com/wp-content/uploads/2011/10/sdl-tridion-dwt-snippet.png" alt="" width="320" height="131" /></a>
</pre>
<p><span id="more-248"></span></p>
<p>The only issue with doing this is that HTML white-space is preserved, resulting in tonnes of extra line breaks in the published HTML.  I&#8217;m anal about HTML, (there will be NO extra line breaks, NOT ON MY WATCH!) so I wrote a little TBB to clean up any lines that are blank, here&#8217;s the code:</p>
<pre>
<div class="syntaxhighlighter htmlscript">
<pre class="brush: jscript; title: ; notranslate">
        public override void Transform(Engine engine, Package package)
        {
            this.Initialize(engine, package);

            //get output item from the package
            string outputName = Package.OutputName;
            Item outputItem = package.GetByName(outputName);

            // if the output is text based, lets clean it up
           if ((outputItem.Type == PackageItemType.String))
            {
                Logger.Debug(&quot;Output exists, cleaning empty lines&quot;);
                string uglyOutput = outputItem.GetAsString();

                //Gets the converted output string
                string fixedOutput = Regex.Replace(uglyOutput, @&quot;^\s*$\n&quot;, string.Empty, RegexOptions.Multiline);
                //Remove the old output string, and put the new one in place
                Logger.Debug(&quot;Output cleaned, updating item in package&quot;);
                package.Remove(outputItem);
                outputItem.SetAsString(fixedOutput);
                package.PushItem(outputName, outputItem);
            }
        }
</pre>
</div>
</pre>
<p>The usual caveat about the code published here is that it is using the <a href="http://www.sdltridionworld.com/community/extension_overview/templatingbase.aspx">SDL Tridion base classes</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tridiondeveloper.com/remove-whitespace-dwt-tridion-output/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

