Reputation: 211
Sometimes javascript code needs some data from server (e.g. constants or configs shared between JS and C#). I don't want to pull this data via Ajax. I want to render this data into html page on server.
Let's say, I have a component which consits of C# server-side code and JS client-side code. Component defines some C# constants to be provided for a specific JS code. This definition can be done somehow in ResourceManifest. Defined C# constants should be rendered into html before JS script links. The first part of JS links is rendered in 'HeadScripts' shape.
The question is how to render something before 'HeadScripts' shape?
I tried to wrap 'HeadScripts' shape. But it didn't help.
Wrapper in IShapeTableProvider
implementation:
builder.Describe("HeadScripts").Configure(desc => desc.Wrappers.Add("HeadScriptsWrapper"));
HeadScriptsWrapper.cshtml:
<script>
var ServerConstants = {
const1: 'value1',
const2: 'value2'
};
</script>
@Display(Model.Child)
The result is:
...
<script src="/.../jquery-1.11.1.js" type="text/javascript"></script>
<script src="/.../some.js" type="text/javascript"></script>
<script src="/.../onemore.js" type="text/javascript"></script>
...
<meta content="Orchard" name="generator" />
<meta content="utf-8" name="charset" />
...
<link href="/.../favicon.png" rel="shortcut icon" type="image/x-icon" />
<script>
var ServerConstants = {
const1: 'value1',
const2: 'value2'
};
</script>
As you can see code from wrapper is rendered after 'HeadScripts'. Please help.
Upvotes: 2
Views: 165
Reputation: 211
I've managed to render custom string before 'HeadScripts' shape.
public class BeforeHeadScriptsShapeProvider : IShapeTableProvider
{
private readonly Work<IOrchardServices> orchardServices;
public BeforeHeadScriptsShapeProvider(Work<IOrchardServices> orchardServices)
{
this.orchardServices = orchardServices;
}
public void Discover(ShapeTableBuilder builder)
{
builder.Describe("HeadScripts")
.OnCreated(created =>
{
orchardServices.Value.WorkContext.Layout.Head.Add(created.New.BeforeHeadScriptsShape());
});
}
[Shape]
public void BeforeHeadScriptsShape(HtmlHelper Html)
{
Html.ViewContext.Writer.WriteLine("<script type=\"text/javascript\"> alert('TEST');</script>");
}
}
I can't explain this code in details, but I've found that some shapes are rendered through TextWriter Output
parameter. But Output
always renders after 'HeadScripts'. 'HeadScripts' (which is a set of 'Script' shapes) uses writer from HtmlHelper Html
parameter. So, using HtmlHelper Html
allows you to render custom content before 'HeadScripts'.
Upvotes: 1