Showing posts with label XSLT. Show all posts
Showing posts with label XSLT. Show all posts

SDL Tridion XSLT Variables for Linked (Multimedia) Component

While Cleaning My Desktop... Tidbit #1

I share a lot, but surprisingly, I still have too many tidbits and side projects that I'd like to get out to the community. Here's another long-overview due (and marginally relavant) post on XSLT. Dominic Cronin might call these types of blog posts "notes to self" and I've posted about this kind of Secondary Memory.

So here's some starter XSLT variables I've used when transforming source Tridion Component XML and referencing a linked Component. With modular templating you'd normally use something like the Get Extension (DGX) to be able to reference related Components. Otherwise you would add these Components to the package.

But with the older style XSLT templates, or anytime you had access to the content model while using XSLT, we used the document() function against the other component's namespace. This is one of the places where you'd be glad you always gave a Schema a good namespace.

XSLT referencing another Component

<xsl:for-each select="//namespace:link_to_multimediacomponent">
<xsl:variable name="COMP" select="document(@xlink:href)/tcm:Component"/>
<xsl:variable name="DATA" select="$COMP/tcm:Data"/>
<xsl:variable name="CONTENT" select="$DATA/tcm:Content"/>
<xsl:variable name="META" select="$DATA/tcm:Metadata"/>
<xsl:for-each>


You could also use the same approach when referencing the Component that's being rendered by the XSLT template. You can see an example in my "Inspect Component Details" post:

<xsl:variable name="Content" select="/tcm:Component/tcm:Data/tcm:Content" />

You could then reference Xpaths starting from $Content.

<xsl:apply-templates select="$Content/*" />

With a few variables, you've made selecting something as easy as remembering its path based on the source XML. But then this isn't Tridion per se, but just XSLT's variables.

Thanks for letting me reminisce. XSLT + Tridion brings me back to the "old days" on the forum, where I feared the likes of power forum users like +Dominic Cronin or +Jeremy Grand-Scrutton. Maybe Dom will forgive me for referencing W3School. :-P

Inspect Component XML With C#

If you want to see the source XML of a Tridion component, which is more intuitive or appealing to you?
  •  <xsl:copy-of select=".">
  • component.Content.OuterXml
  • Clicking on view source tab

XSLT

I typically use three XSL functions to dig around an XML source when doing XSLT template development. When in doubt, a copy-of is GPS for XSLT.

But Now...

I'm compelled to revisit my set of templating and rending tools which have, up-until-now, focused on XSLT and the Content Delivery API.

Key-Value Lookup Example (Tridion R5.3)

The following is adapted from a post of mine on the Tridion World Forum (an account required which is available to Tridion clients). Key-value "lookup tables" can be stored in xml files to manage Tridion-related information such as identifiers (tcm ids) or  other not-so-friendly key names and their corresponding friendly values. For example, rather than hard-coding unique Tridion identifiers for each environment, we can output a text-based configuration file. This simple example highlights re-use, separation of layers, and ease of content (re)creation.

1) Ordered Pair - embeddable schema Consisting of two items:
  • key (text)
  • value (text)
Description can be first and second item, with mention of "key" and a friendly name. This could even be localized to match the needs of a given publication and/or (end-user) language.

2) List of Ordered Pairs - schema Consists of one item: ordered pair (the embedded schema above, allowing multiple values) (also give this a useful namespace such as: 
http://www.example.com/schemas/listorderedpair)


3) Key Value XML Output - Component Template (XSLT)
(match the namespace above, the names space will differ in different versions of Tridion)

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
 xmlns:xlink="http://www.w3.org/1999/xlink"
 xmlns:tcmse="http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant"
 xmlns:listorderedpair="http://www.example.com/schemas/listorderedpair"
 exclude-result-prefixes="xsl tcm xlink tcmse listorderedpair">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:template match="/">
  <values>
    <xsl:apply-templates select="/tcm:Component/tcm:Data/tcm:Content/*" />
  </values>
</xsl:template>
<xsl:template match="*">
  <xsl:for-each select="//listorderedpair:orderedpair">
    <value>
      <xsl:attribute name="key">
       <xsl:value-of select="listorderedpair:key" />
      </xsl:attribute>
      <xsl:value-of select="listorderedpair:value" />
    </value>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

4) Ouput Generic XML - Page Template (VBScript, but any templating language can work)

[% 'this outputs a physical xml file
'component and corresponding component template that outputs actual xml via XSLT is required
 for each comp in page.componentpresentations
   writeout comp.content
 next

%]

To create the lookup XML file after setting up the embeddable schema, regular schema, and templates, first create a component based on List of Ordered Pairs. Then create the page, add the component (+ template = component presentation), and publish. The resulting file will look like:
<values>
 <value key="1">First Value</value>
 <value key="2">Second Value</value>
</values>
This example can relate  friendly names to their programatic equivalents. This can work in other scenarios and can serve as a general content-to-physical-xml file example.
If you've ever needed to make a quick and robust interface for this type of configuration data (or any content), a WCMS like Tridion can easily handle anything from the node and attributes values in an XML to rich-text, multimedia, and more complicated sets of content. 
Other use cases:
  • states and state abbreviation list
  • departments and abbreviations or codes
  • Tridion items and their tcm-ids (ids would be hardcoded, but example could be adapted to link to items directly)
  • other mappings for external databases or information
A few of these could be handled via web services, custom code, or other Tridion integration points. However, a lot can be done with Tridion's out-of-the-box functionality. Please feel free to leave suggestions, clarification, or questions. I'll likely overhaul this with a Tridion 2011 treatment as well.

Develop XSLT Templates in Three Steps

A variety of Web-related technologies, including SDL Tridion, have the ability to use XSL Transformations (XSLT) to transform XML into almost any other text-based format; which is handy when converting say, component content stored in XML into HTML or XHTML.*

I love sites like W3Schools that provide detailed tutorials and references on how XSLT works. Other "cookbook" references like this one from XMLPlease.com or the actual XSLT Cookbook from O'Reily give practical and useful examples. An online search for "XSLT identity template" will get you started, but where do we go from there?

I want to add some practical advice on how to work with XSLT in different scenarios, starting with this tip:

<xsl:copy-of select="."/> is GPS for XPath.

When developing and moving around nodes, it helps to see the full source of what you're selecting via XPath. The xsl:copy-of function is the printf() of XSL.

When working with XSLT, I typically iterate towards a final template using three XSL functions. The following assumes you're somewhat familiar with XSLT, have read some of the resources above, but might be stuck on where to start or how to troubleshoot a non-matching XPath.

1) I typically start by reviewing the example source XML file or using the copy-of function.

2) For simple text values, I use xsl:value-of, setting the select attribute to the XPath to the right node or attribute I need. This is useful for structured content where you have a title or headline in plain text and you want to place it somewhere in your output.

3) The final (non-trivial) step is to add xsl:apply-templates as needed to do less selecting and more transforming. The resources above can go into further detail in how to replace nodes, remove namespaces, and best use recursion to do some pretty impressive transformations to the source XML.

If you have the ability to innately understand an XML schema and figure out XPath strings on-the-fly, feel free to skip this copy-of, value-of, apply-templates "method." But if you ever find yourself deeply nested in someone else's XSLT template and can't figure out why something doesn't match, these functions can save some time and frustration.

If the Xpath match doesn't do anything, double check the source with <xsl:copy-of select="."/> within context or replace the period with the Xpath you're troubleshooting. If that doesn't give you anything, go one step higher and remove the last node in your Xpath.

*Tridion uses a variety of templating languages from script-based to XSLT to modular templates using HTML-like Dreamweaver syntax and C# building blocks. XSLT may be a strong and elegant tool, but it's only one of several ways to work with content in Tridion or any other Web-related technology stack.