I have one simple question:
We are using Razor templating in Tridion 2013 SP1. Is it including the Experience manager tags to the generated HTML? Or Do we need to add the EM tags manually?
Tridion Stack Exchange is a question and answer site for Tridion developers and administrators. It only takes a minute to sign up.
Sign up to join this communitySome tags are written out automatically, for example if you use the RenderComponentPresentation()
method it will output the markup for a component presentation, and if you use RenderComponentField()
it will output the markup for a field.
New in 2013 SP1 are the FieldStartMarker()
, FieldValueStartMarker()
, FieldEndMarker()
and FieldValueEndMarker()
functions, which are not in the current version of the Razor Mediator.
As a workaround on the project I am working on I created these as helper functions, in a TBB which is imported in all TBBs, I expect these will be included in the mediator in a future release...
@using Tridion.ContentManager.Templating.Expression
@using Tridion.ContentManager.ContentManagement
@using Tridion.Extensions.Mediators.Razor.Models
@helper FieldStartMarker(string fieldExpression)
{
var fn = new BuiltInFunctions(TridionHelper.Engine, TridionHelper.Package);
@fn.FieldStartMarker(fieldExpression)
}
@helper FieldEndMarker()
{
@:</tcdl:Field>
}
@helper FieldValueStartMarker(int index=0)
{
@:<tcdl:FieldValue index="@index">
}
@helper FieldValueEndMarker()
{
@:</tcdl:FieldValue>
}
Here are the RAZOR functions that we wrote to accomplish this: (hope this helps someone)
@functions{
@*
==========================================================================================
<summary>Get the TCM number based on the WebDAV path sent in.</summary>
<param name="webdav">WebDAV path of the object to find TCM of</param>
<returns>TCM number of the item</returns>
==========================================================================================
*@
public string URIFromWebDAV(string webdav)
{
return TridionHelper.Engine.GetObject(webdav).ToXml().GetAttribute("ID");
}
@*
==========================================================================================
<summary></summary>
<param name="webdav"></param>
<returns></returns>
==========================================================================================
*@
public string MarkPage(string serverUrlBase)
{
IdentifiableObject page = TridionHelper.Engine.PublishingContext.ResolvedItem.Item;
IdentifiableObject template = TridionHelper.Engine.PublishingContext.ResolvedItem.Template;
var pageSettings = string.Format("<!-- Page Settings: {{'PageID':'{0}','PageModified':'{1}','PageTemplateID':'{2}','PageTemplateModified':'{3}'}} -->", page.Id, FormatDate(page.RevisionDate), template.Id, FormatDate(template.RevisionDate));
var scriptTag = string.Format("<script type='text/javascript' language='javascript' defer='defer' src='{0}/WebUI/Editors/SiteEdit/Views/Bootstrap/Bootstrap.aspx?mode=js' id='tridion.siteedit'></script>", serverUrlBase);
return pageSettings + Environment.NewLine + scriptTag;
}
@*
==========================================================================================
<summary></summary>
<param name="webdav"></param>
<returns></returns>
==========================================================================================
*@
public string MarkComponentPresentation()
{
IdentifiableObject component = TridionHelper.Engine.PublishingContext.ResolvedItem.Item;
IdentifiableObject template = TridionHelper.Engine.PublishingContext.ResolvedItem.Template;
return string.Format("<!-- Start Component Presentation: {{ 'ComponentID' : '{0}', 'ComponentModified' : '{1}', 'ComponentTemplateID' : '{2}', 'ComponentTemplateModified' : '{3}' }} -->",
component.Id, FormatDate(component.RevisionDate), template.Id, FormatDate(template.RevisionDate));
}
@*
==========================================================================================
<summary></summary>
<param name="webdav"></param>
<returns></returns>
==========================================================================================
*@
public string MarkComponentPresentation(string componentId, string templateId)
{
return MarkComponentPresentation(componentId, templateId, true);
}
@*
==========================================================================================
<summary></summary>
<param name="webdav"></param>
<returns></returns>
==========================================================================================
*@
public string MarkComponentPresentation(string componentId, string templateId, Boolean isQueryBased)
{
IdentifiableObject component = TridionHelper.Engine.GetObject(componentId);
ComponentTemplate template = (ComponentTemplate)TridionHelper.Engine.GetObject(templateId);
var dynamicProperty = template.IsRepositoryPublishable ? ", 'IsRepositoryPublished': true" : "";
var queryBasedProperty = isQueryBased ? ", 'IsQueryBased': true" : "";
return string.Format("<!-- Start Component Presentation: {{ 'ComponentID' : '{0}', 'ComponentModified' : '{1}', 'ComponentTemplateID' : '{2}', 'ComponentTemplateModified' : '{3}'{4}{5} }} -->",
component.Id, FormatDate(component.RevisionDate), template.Id, FormatDate(template.RevisionDate), dynamicProperty, queryBasedProperty);
}
@*
==========================================================================================
<summary></summary>
<param name="webdav"></param>
<returns></returns>
==========================================================================================
*@
private static string FormatDate(DateTime date)
{
return date.ToString("u").Replace(' ', 'T').Replace("Z", "");
}
@*
==========================================================================================
<summary>If a Component is based on a schema that uses a custom root node name, this method will allow the node name to be passed or be to found out based on the Component. The method also allows for the field path to be used to create the output XPath for ExpMan to make the field editable.</summary>
<param name="rootElement">Custom root element name of the Component</param>
<param name="fieldPath">The DWT function name of the current path to be used for replacement in the XPath</param>
<param name="name">The last field (or field string) to be edited</param>
<returns>Marked XPath field for in-line editing through ExpMan</returns>
==========================================================================================
*@
public string MarkComponentField(string rootElement, string fieldPath, string name)
{
@* If the root element name is not given, find it*@
if (string.IsNullOrEmpty(rootElement))
{
Component component = TridionHelper.Engine.PublishingContext.ResolvedItem.Item as Component;
rootElement = component.Schema.RootElementName;
}
@* If the field path is given, RegEx out the indexes to their correct format *@
if (!string.IsNullOrEmpty(fieldPath))
{
string matchExpression = @"\[(\d+)\]+";
MatchEvaluator addToIndex = AddToIndexForExpMan;
fieldPath = Regex.Replace(fieldPath, matchExpression, addToIndex);
fieldPath = "/custom:" + fieldPath.Replace(".", "/custom:");
}
@* Format the string for the return value *@
return string.Format("<!-- Start Component Field: {{'XPath' : 'tcm:Content/custom:{0}{1}/custom:{2}'}} -->", rootElement, fieldPath, name);
}
@*
==========================================================================================
<summary></summary>
<param name="fieldPath">The DWT function name of the current path to be used for replacement in the XPath</param>
<param name="name">The last field (or field string) to be edited</param>
<returns>Marked XPath field for in-line editing through ExpMan</returns>
==========================================================================================
*@
public string MarkMetadataField(string fieldPath, string name)
{
@* If the field path is given, RegEx out the indexes to their correct format *@
if (!string.IsNullOrEmpty(fieldPath))
{
string matchExpression = @"\[(\d+)\]+";
MatchEvaluator addToIndex = AddToIndexForExpMan;
fieldPath = Regex.Replace(fieldPath, matchExpression, addToIndex);
fieldPath = fieldPath.Replace(".", "/custom:");
}
@* Format the string for the return value *@
return string.Format("<!-- Start Component Field: {{'XPath' : 'tcm:Metadata/custom:Metadata/custom:{0}{1}'}} -->", fieldPath, name);
}
@*
==========================================================================================
<summary> Helper method for the custom MarkComponentField method to RegEx replace add to the indexes of the FieldPath.</summary>
<param name="m">Match of the RegEx to be added to</param>
<returns>String of the correctly incremented path</returns>
==========================================================================================
*@
private string AddToIndexForExpMan(Match m)
{
@*
If the number inside the index is zero make it one
For the issue of "Input string was not in a correct format"
Else, add one to the index
*@
if (m.Groups[1].Value.Equals("0"))
return "[1]";
else
return string.Concat("[", (int.Parse(m.Groups[1].Value) + 1).ToString(), "]");
}
}
TBB used to remove the comments tags for a target that should not be enabled (Live):
<%@ Import Namespace="System.Text.RegularExpressions"%>
<%@ Import Namespace="Tridion.ContentManager.Publishing"%>
// Remove Experience Manager tags for pages that are not being published to ExpMan target
if (engine.PublishingContext.PublicationTarget != null && engine.PublishingContext.PublicationTarget.Id != "tcm:0-X-65537") {
log.Warning(string.Format("Removing ExpMan tags for publishing to {0}", engine.PublishingContext.PublicationTarget.Id));
// 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))
{
string uglyOutput = outputItem.GetAsString();
// Gets the converted output string
string fixedOutput = Regex.Replace(uglyOutput, @"(<!-- Start Component Presentation[\S\s]*?-->)|(<!-- Start Component Field[\S\s]*?-->)", "");
log.Warning("[Remove ExpMan Comments]: Removed 4/12/2017 12:08:48 PM");
// Remove the old output string, and put the new one in place
package.Remove(outputItem);
outputItem.SetAsString(fixedOutput);
package.PushItem(outputName, outputItem);
}
}