Render scripts in block after page scripts loads (EPI 8/ MVC)

1.7k views Asked by At

I am building a dynamic page type, I want to load to it different scripts based on the block that was loaded in a certian ContentArea.

This is the Area:

[AllowedTypes(new[] { typeof(Types.SomeBlockType)})]
public virtual ContentArea SomeArea { get; set; }

On my page view I am rendering the content and the script: (the script render is via the layout)

@Html.PropertyFor(...)
.
.
@section Scripts {

    ...//some scripts loaded
}

The problem I have is that the scripts inside the block in the SomeArea content, are running before the section Script. I want the block scripts to be executed after my layout scripts & page scripts were loaded...

Appreciate any help.

2

There are 2 answers

1
Johan Petersson On BEST ANSWER

The answer is very simple, but first your template(s) must meet these client resource requirements http://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-CMS/75/Client-resources/Client-resources/. The article mention how to register a script on a page level, and in this case it will be injected on ALL templates that meet the requirements, i.e. page type name is XFormPage.

But let’s say you just want to inject a script if a specific block is used on the page. One solution is to use the method in the article and then iterate through all blocks in the page’s content areas and see if the block is used. Probably not the smartest and fastest solution.

A more simple solution is to require the script in the block’s view or in your controller:

var clientResources = ServiceLocator.Current.GetInstance<IRequiredClientResourceList>();

clientResources.RequireScript("/scripts/my-block-script.js", "BlockScript", new[] { "ScriptNameThatShouldExecuteBefore" }).AtFooter();

If the script doesn't have any dependencies, you can pass Enumerable.Empty() instead of new[] { "ScriptNameThatShouldExecuteBefore" }.

0
Ziv Weissman On

Eventually what I did was setting a razor block with switch case,

It will look into current's Model.SomeArea.Items() (or Contents()), I forgot, and will look for the block type, compare it to the blocks I want and will load scripts accordingly.