Take the 2-minute tour ×
Tridion Stack Exchange is a question and answer site for Tridion developers and administrators. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 8 down vote accepted

Some 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>
}
share|improve this answer
    
Thank you, Will. This is our first project using Razor and we are investigating all the possibilities. Could you post a Razor Template with an example of using this helper? –  Guskermitt Feb 20 at 8:13
    
Theres plenty of info on importing TBBs in the Razor Mediator documentation, and also example Template code. The new Field..Marker functions are documented (in Dreamweaver syntax - but you will get the idea) in the online docs: sdllivecontent.sdl.com/LiveContent/web/… –  Will Price Feb 20 at 10:06

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(), "]");
  }

}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.