Sitecore Content and Page Editor: Injecting of resources

Image, that there is a need to add some external script inside Content Editor or/and PageEditor. What do you do? Might be you would start with developing of 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 explain you the exact way of how to do it.

Declarative Configuration

As you probably have guessed we will take advantage of 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.

Configuration patch is the following:

<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:

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

And in the processor itself:

private const string CssLinkPattern = @"<link href=""{0}"" rel=""stylesheet"" />";

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!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s