How to Insert Snippets via Component Link from Rich Text Fields in Tridion Razor Templates

567 Views Asked by At

I have been unsuccessful in my research so far, but I am looking for a way for an content editor of a rich text field in Tridion to be able to call a content component from inside a Rich Text field. I am using Razor templates.

Perhaps an example of some content might illuminate what I mean. If the below was rich text, I would want a way for the text "tcm:mytcm" to be identified and processed as a command during publication to render that component from inside the other component this rich text field is in, instead of treating it as text. I set it apart with { to illustrate that some kind of syntax would be appropriate.

Rich text: This is the rich text, and this is the component I want to link to from inside it {tcm:mytcm}. And this is some more rich text that comes after.

Essentially, the main purpose of this would be to provide a way to insert "snippets" of more complex html code inline into the rich text. An example of something to insert would be a hyperlink with various parameters, or a call to a web service variable, etc. The markup/code for that snippet would be generated by the component template for tcm:mytcm and processed during publication in place of the rich text entry that called to it.

If this general methodology is the wrong direction to take, I'm open to any ideas for how to do this insertion. Any advice or direction would be appreciated. I don't see anything in the documentation or in any other threads online so far that address this issue, but perhaps my search terms are not the best.

4

There are 4 best solutions below

1
On

I have little knowledge of the Razor Mediator, but this is a common challenge with C#, XSLT and Dreamweaver Templates. I think your best bet is to pre-process the Component with either XSLT or C# and replace the liked TCMURI with the XML of the other component or other Data, and them continue with the traditional documented techniques to access data from the package.

2
On

I have done something somewhat similar some time ago with "glossary" links, where an Editor could create a link to a component that contained an expanded definition for a term (the text of the link) and we had to, at publish time, get this expanded definition and include it in Javascript (so that the text would show in a tiny bubble if the visitor moused over it).

It involved the following steps:

  1. Parse the Rich Text Field with XML
  2. Find all anchors within the RTF that point to a tcm URI
  3. Find if the target component was based on the glossary schema
  4. If yes, read the target component's "glossary text" into a separate attribute of the anchor, and modify some other value.

I think doing this in a Razor template will be a lot more complex than doing it as a post-processing step in your Template.

0
On

Just to add a (hopefully useful) Code Sample to support Chris And Nuno's answer about post processing it in C#. It is partially pseudo code. I am very bad at RegEx, so this you need to figure out. Also in the ReplaceUrls() Method you need to add whatever it is you want based on certain code between the {}:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager.Templating.Assembly;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.ContentManagement.Fields;

namespace TBB.Templates
{
    public class ReplaceString : TemplateBase
    {
        private static readonly Regex tcmReference = new Regex(@"{tcm:mytcm})", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
        private string _outputContent;

        public override void Transform(Engine engine, Package package)
        {
            this.Initialize(engine, package);
            Page page = this.GetPage();

            this._outputContent = package.GetByType(new ContentType("text/html")).GetAsString();

            ReplaceUrls();

            package.GetByType(new ContentType("text/html")).SetAsString(this._outputContent);
        }

        private void ReplaceUrls()
        {
            string[] textContainer = new string[] { this._outputContent };
            foreach (Match match in TemplateUtilities.GetRegexMatches(textContainer, tcmReference))
            {
                Group group = match.Groups["url"];
                if (group.Value.Contains("specific"))
                {
                    this._outputContent = this._outputContent.Replace("specificParam", "SnippetCode");
                }
            }
        }
    }
}
0
On

What Chris and Nuno said is the answer:

Nuno describes the logic of actually processing the linked components

Chris makes the crucial point that this is best done as a pre-processing step before you reach the Razor TBB. You can modify the XML in the package.