4

I am trying to add custom classes & inline styles to a rendered link field in the experience editor without using Glass.

I have a model the looks like this:

public class Header
{
    public HtmlString Link { get; set; }
}

My controller has a model creation method like this:

private static Header CreateModel()
{
    var item = RenderingContext.Current.Rendering.Item;
    var linkStyles = "style=Margin: 0; color: white; color: white !important; font-family: Helvetica, Arial, sans-serif; font-weight: normal; line-height: 1 !important; margin: 0; padding: 0; text-align: left; text-decoration: none;";

    var headerModel = new Header()
    {
        Link = new HtmlString(FieldRenderer.Render(item, "CTA Url",linkStyles))
    };

    return headerModel;
}

And in my view I am outputting this with @Model.Link

The linkStyles string in the controller works, but I cannot figure out how to add classes to this. Also, if the user adds a class in the Style class field in Sitecore, all the styles get removed & reset/replaced with the users input.

Edited to Add

Even using Glass as suggested below. The inline styles are removed anytime the field is edited. For example, on initial load the inline styles are there. If I make any edits such as changing the link description, the link url, or link class, then click OK to close the link dialog window. I see the changes I just made, but all the inline styles are gone. If I save the changes at this point the view will refresh and add the inline styles back.

Is there not a way to persist these styles?

3 Answers 3

4

Why don't you try to have all styles in the cshtml file instead of having them inline?

<style>
my-cta-class { 
    Margin: 0; 
    color: white !important; 
    font-family: Helvetica, Arial, sans-serif; 
    font-weight: normal; 
    line-height: 1 !important;
    margin: 0; padding: 0; 
    text-align: left; 
    text-decoration: none;
}
</style>

That way you can implement Dan's suggestion and yet have it worked for EXM

@RenderLink(Model, x => x.CtaUrl, new { @class = "my-cta-class" })
2

This may be beyond the scope of what you want to do to accomplish this, but I would recommend using an ORM like Glass Mapper to strongly-type your models, and then this kind of thing is handled much more simply:

public class Header
{
    [Glass.Mapper.Sc.Configuration.Attributes.SitecoreField("CTA Url")]
    public virtual Glass.Mapper.Sc.Fields.Link CtaUrl { get; set; }
}

Then, in your Razor view, you can do something simple like this:

@RenderLink(Model, x => x.CtaUrl, new { style = "Margin: 0; color: white; color: white !important; font-family: Helvetica, Arial, sans-serif; font-weight: normal; line-height: 1 !important; margin: 0; padding: 0; text-align: left; text-decoration: none;" })

Even better

I would recommend adding these styles to a CSS class instead, so you can just assign the class like so:

@RenderLink(Model, x => x.CtaUrl, new { @class = "my-cta-class" })
3
  • Thank you for the reply. I would love to keep all the inline styles in a class, but they are needed inline because these are HTML Email templates to be used in EXM.
    – LSpell
    Commented Dec 8, 2018 at 19:36
  • Is there a way to do this without using Glass Mapper?
    – LSpell
    Commented Dec 8, 2018 at 20:56
  • See my other answer below. Not perfect, but doesn’t require Glass. Commented Dec 10, 2018 at 0:16
1

If you don't want to use Glass, judging by this answer on Stack Overflow, it looks like you could do this by incorporating the user-defined styles into the permanent ones you want to add.

However, it may work better (and allow your permanent class to persist better during editing in Experience Editor) to simply pass your item to your view so that you can use the MVC helper methods:

public class Header
{
    public Item HeaderItem { get; set; }
    public string PersistentClasses { get;set; }
}

.

private static Header CreateModel()
{
    return new Header()
           {
               HeaderItem = RenderingContext.Current.Rendering.Item,
               PersistentClasses = "my-cta-class"
           };
}

Then you can combine them in the view, but the Experience Editor will add its extra chrome to allow better inline-editing:

@Html.Sitecore().Field("CTA Url", Model.HeaderItem, new {
     @class = Model.PersistentClasses + " " + ((LinkField)Model.HeaderItem.Fields["CTA Url"]).Class
})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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