1
votes

Throughout my project I often use the Sitecore General Link field for links (external or internal or media). One standard I have is that for all of my pages there is a field on every page called "NavigationTitle". It allows the CMS author to control the display of the text for the item whenever that item is linked to. Ideally I would like to be able to find some way of having the system use that field from the target item whenever that item is linked to. Here is an example.

Let's say that all of the pages in my site have the following basic fields

  • NavigationTitle (text)
  • Content (rich text)

And let's say I have a data template called Promo. And Promo has the following fields:

  • Title (text)
  • Content (text)
  • Image (image)
  • Link (general link)

The Link field on a Promo could link to an internal page or even an external page. Right now when I build the sublayout to display a Promo, if I use a <sc:Link> tag to output the Link field I believe that Sitecore will first use the Text of the Link field for the text. Otherwise I think it will use the Item Name for the text.

I would like to build it so that instead of using the Item Name of the target item, I would like to use a particular field value from the target item. And I would like to have this code run at a low enough level so that this would work in conjunction with something like Glass Mapper. So that when I use Glass Mapper to output the Link field (using something like the Editable method) that it would display the correct link text.

Does anyone know how I would do this? I'm guessing that I might have to create a custom General Link Field that inherits from the normal General Link Field and overrides something. Just a guess. Any help is appreciated.

2

2 Answers

3
votes

Definitely doable, you're best bet will be to add your own pipeline step before the GetLinkFieldValue renderField step. The GetLinkFieldValue uses the LinkRenderer class which does the following cascade to determine what to put in as the link text.

  1. Value set on RawParameters property of the arguments object (only if there's one value)
  2. Text Parameter in the Parameters property of the arguments object
  3. Description on the link field
  4. Item Name

We can set the value of the text parameter.

Configuration

<renderField>
        <processor type="MyLibrary.Pipelines.AddNavigationTitle, MyLibrary" patch:before="*[@type='Sitecore.Pipelines.RenderField.GetLinkFieldValue, Sitecore.Kernel']" />
</renderField>

Code

public class AddNavigationTitle
{
    public void Process(Sitecore.Pipelines.RenderField.RenderFieldArgs args)
    {
        if (args.FieldTypeKey == "general link")
        {
            Sitecore.Data.Fields.LinkField linkField = args.Item.Fields[args.FieldName];

            if (linkField != null && linkField.TargetItem != null)
            {
                var title = linkField.TargetItem["NavigationTitle"];

                if (!string.IsNullOrWhiteSpace(title))
                {
                    args.Parameters["text"] = title;
                }
            }
        }
    }
}

Any time you render a general link field this will run and add in the text from the NavigationTitle field. You also get the added benefit in that if the field isn't filled in it will still cascade down the priority list from above.

0
votes

Your best option with Glass is to implement a custom data handler, you could do this by copying the Link Mapper:

https://github.com/mikeedwards83/Glass.Mapper/blob/master/Source/Glass.Mapper.Sc/DataMappers/SitecoreFieldLinkMapper.cs

Then update line 130:

https://github.com/mikeedwards83/Glass.Mapper/blob/master/Source/Glass.Mapper.Sc/DataMappers/SitecoreFieldLinkMapper.cs#L130

You will then need to register you new handler in the GlassMapperScCustom class that is part of your solution. You do this in the CastleConfig method, you can see how registrations are done here:

https://github.com/mikeedwards83/Glass.Mapper/blob/master/Source/Glass.Mapper.Sc.CastleWindsor/SitecoreInstaller.cs#L189