Skip to main content

Back-End Development

Injecting Resources into Sitecore Content and Page Editor

Wet Leaf@1x.jpg

What do you do when you need extra resources (JavaScript, CSS) brought into your Content Editor and Page Editor experience? Maybe you have developed a custom field type that requires Google Maps API. Maybe many of your renderings use an external library or a client side helper of your own when in IsPageEditorEditing(). Whatever the case might be you may want to inject resources into your Content and Page Editor environments and do it once globally. And in a declarative way. This blog post will walk you through doing exactly that.

Declarative Configuration

As you probably have guessed we will exploit two different pipelines – one for Content Editor and one for Page Editor. The way I do things in there will be a little different due to the nature of how two editors render themselves but the way I configured the resources to inject is universal:

<processor ...>
    <styles hint="list:addStyleResource">
        <resource>/sitecore modules/...</resource>
    </styles>
    <scripts hint="list:addScriptResource">
        <resource>//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js</resource>
        <resource>/sitecore modules/...</resource>
    </scripts>
</processor>

If you are not familiar with dependency injection features of the Sitecore’s Configuration Factory I recommend this blog post by John West:

To accept the configuration the processors will declare two collection fields and expose two Add*() methods:

private readonly IList<string> _scripts = new List<string>();
private readonly IList<string> _styles = new List<string>();

public void AddStyleResource(string resource)
{
    _styles.Add(resource);
}

public void AddScriptResource(string resource)
{
    _scripts.Add(resource);
}

Content Editor

Content Editor is rendered via renderContentEditor:

<renderContentEditor>
    <processor patch:before="*[1]"
               type="{Namespace}.InjectContentEditorResources, {Assembly}">
        <styles hint="list:addStyleResource">
            ...
        </styles>
        <scripts hint="list:addScriptResource">
            ...
        </scripts>
    </processor>
</renderContentEditor>

And then in the body of the Process(PipelineArgs args) (safety checks removed for brevity):

var page = HttpContext.Current.Handler as Page;

foreach (string script in _scripts)
{
    page.Header.Controls.Add(
        new LiteralControl(
            "<script type='text/javascript' language='javascript' src='{0}'></script>".FormatWith(script)));
}

foreach (string css in _styles)
{
    page.Header.Controls.Add(
        new LiteralControl(
            "<link rel="stylesheet" type="text/css" href="{0}"/>".FormatWith(css)));
}

Page Editor

Page Editor is different. It is designed to render your web site extended with additional elements to support inline and WYSIWYG editing.

[su_note note_color=”#fafafa”]Here at BrainJocks we fully embraced MVC once Sitecore officially supported it in 6.6 and so I won’t cover the pre-MVC pipelines[/su_note]

Take a close look at this configuration patch:

<mvc.requestEnd patch:source="Sitecore.Mvc.config">
    <processor type="Sitecore.Mvc.ExperienceEditor.Pipelines.Request.RequestEnd.AddPageExtenders ..."
               patch:source="Sitecore.MvcExperienceEditor.config"/>
</mvc.requestEnd>

The AddPageExtenders creates a wrapping stream filter that is set on HttpContext.Response.Filter. When it runs it injects page extenders (scripts and styles) right after the <body> tag. The extenders are collected via mvc.renderPageExtenders.

And here we go:

&amp;amp;lt;mvc.renderPageExtenders&amp;amp;gt;
    &amp;amp;lt;processor patch:after="*[last()]"
               type="{Namespace}.InjectPageEditorResources, {Assembly}"&amp;amp;gt;
        &amp;amp;lt;styles hint="list:addStyleResource"&amp;amp;gt;
            ...
        &amp;amp;lt;/styles&amp;amp;gt;
        &amp;amp;lt;scripts hint="list:addScriptResource"&amp;amp;gt;
            ...
        &amp;amp;lt;/scripts&amp;amp;gt;
    &amp;amp;lt;/processor&amp;amp;gt;
&amp;amp;lt;/mvc.renderPageExtenders&amp;amp;gt;

And in the processor itself:

private const string CssLinkPattern = @"&amp;amp;lt;link href=""{0}"" rel=""stylesheet"" /&amp;amp;gt;";

public override void Process(RenderPageExtendersArgs args)
{
    // ...

    Render(args.Writer);
}

protected override bool Render(TextWriter output)
{
    // ...

    foreach (string style in _styles)
    {
        output.Write(CssLinkPattern, style);
    }

    foreach (string script in _scripts)
    {
        output.Write(Sitecore.Web.HtmlUtil.GetClientScriptIncludeHtml(script));
    }

    return true;
}

That’s it. Your extra resources are now present in both Content and Page Editor. Enjoy!

Thoughts on “Injecting Resources into Sitecore Content and Page Editor”

  1. Hey Paul, very useful post, thanks.
    I’ve implemented this on 8.1 and you don’t need to call Render in the Process method. Otherwise, it works perfectly.

    Thanks,

    Nick

  2. Pingback: Sitecore Taglist Field | Georgi Bilyukov Blog

  3. Hello, thanks for the post, it helped a lot… but not completely.

    When I implement the code, it adds the CSS and JS files to the ribbon which of course is in an iframe. I need those files to render outside the ribbon’s iframe.

    Would you happen to have any idea as to why it only affects the ribbon?

    FYI, I am using Sitecore 8.1 update 3

    Thanks

  4. Pingback: A Different Approach: Injecting Resources into the Experience Editor – Eric Stafford

  5. Pingback: Take Two – A Different Approach: Injecting Resources into the Experience Editor – Eric Stafford

  6. Pingback: Injecting Resources into Experience Editor in Powerful Ways | jammykam

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Brian Beckham

As a Sitecore MVP, Brian spends most of his time consulting and architecting software solutions for enterprise-level Sitecore projects.

More from this Author

Follow Us
TwitterLinkedinFacebookYoutubeInstagram