Currently I'm working on an Umbraco V4 site and had an issue when rendering the meta tags.
The problem:
In my template I've added the keywords and description tag in the head to render the meta information for keywords and description.
<head runat="server">
<meta name="keywords" content="<umbraco:Item field='metaKeywords' recursive='true' runat='server'></umbraco:Item>" />
<meta name="description" content="<umbraco:Item field='metaDescription' recursive='true' runat='server'></umbraco:Item>" />
</head>
I've seen several examples that used the <Umbraco:Item> control with single quotes to set the properties so I thought this should work. However when the output was different then I would expect:
<head>
<meta name="keywords" content="&lt;umbraco:Item field='metaKeywords' recursive='true' runat='server'></umbraco:Item>" />
<meta name="description" content="&lt;umbraco:Item field='metaDescription' recursive='true' runat='server'></umbraco:Item>" />
</head>
The Cause:
When I took a detailed look on this issue I saw that the head tag in my template had a Runat="Server" attribute. When I removed this attribute the output was rendered fine. I'm using a few Ajax Controls on forms that throws an error when it can't find a Head tag with the Runat="Server" attribute, so simply removing it isn't the solution.
The solution, Macro's to the rescue:
With a Macro and an XSLT file this issue can easily be solved and after thinking of it it's also a better solution because it's a better separation between HTML and ASP.Net code. To solve it you just create a Macro that excepts two parameters (keywords and description). Then create an XSLT file that outputs the values like this example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
exclude-result-prefixes="msxml umbraco.library">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:variable name="keywords" select="/macro/keywords"/>
<xsl:variable name="description" select="/macro/description"/>
<xsl:template match="/">
<meta name="keywords" content="{$keywords}" />
<meta name="description" content="{$description}" />
</xsl:template>
</xsl:stylesheet>
Then use the Macro in your template:
<umbraco:Macro keywords="[$metaKeywords]" description="[$metaDescription]" Alias="MetaTags" runat="server"></umbraco:Macro>
Now you have exact the same functionality and it will work in any situation. Because I'm using the $ sign before the fieldnames that are passed to the Umbraco. Umbraco will do a recursive search for the values of those properties, just like the recursive attribute does on the Umbraco:item tag.