CARVIEW |
Select Language
HTTP/2 200
date: Wed, 23 Jul 2025 16:15:41 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
x-robots-tag: none
etag: W/"2e7b2526602a70984e8b33a0ea01576a"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=ximMlb0HHJhoZ3lPoRlIpOqC0D4q%2F9LRZhqmhTdM2FcnH34b1GvOYb7n1%2FJ7ZkRjdIn3NKhSFVVwAakcKI4%2B7wnB%2Bug%2BLfvrz07dF0wopgf%2B0tlqkQOmCSPacHFgWrV%2F%2FBMV9rE9ja3ZCVV%2FASwh%2Bp%2Fkew5frdLaLQAFP%2BVpTpPH9kIDDgGp598Ycf%2BTNG5mWHmI9trQedcojA2kE1Uw%2F2tXvOTY%2F7P3KxWAWYmARi9INNy3stCX3fDdKHeug0IohGXOXzWXECBCJZ%2FxZpeDtQ%3D%3D--kPe6uYg2v6ksGZqv--GMLams0mLCBJuh97ePgDcg%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.683623240.1753287341; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 16:15:41 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 16:15:41 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: E06A:351DD4:E6B88C:110D4DD:68810AAD
@Include and @Layout · adoconnection/RazorEngineCore Wiki · GitHub
Skip to content
Navigation Menu
{{ message }}
-
Notifications
You must be signed in to change notification settings - Fork 93
@Include and @Layout
Alexander edited this page Jul 1, 2020
·
6 revisions
Maintainer strongly believes implementing @include
and @Layout
is unnecessary complexity for standalone RazorEngine.
-
Since RazorEngine.Compile accept template as a string, one will need also to accept a
Dictionary (key, template)
to be able to resolve@Include
and@Layout
-
It is easily implementable outside of RazorEngine
We would like to have code like this:
Supply primary template
, parts
, and model
and see the result as a string
namespace ConsoleApp11
{
class Program
{
static void Main(string[] args)
{
string template = @"
@{
Layout = ""MyLayout"";
}
<h1>@Model.Title</h1>
@Include(""outer"", Model)
";
IDictionary<string, string> parts = new Dictionary<string, string>()
{
{"MyLayout", @"
LAYOUT HEADER
@RenderBody()
LAYOUT FOOTER
"},
{"outer", "This is Outer include, <@Model.Title>, @Include(\"inner\")"},
{"inner", "This is Inner include"}
};
IRazorEngine razorEngine = new RazorEngine();
MyCompiledTemplate compiledTemplate = razorEngine.Compile(template, parts);
string result = compiledTemplate.Run(new {Title = "Hello"});
Console.WriteLine(result);
Console.ReadKey();
}
}
}
Output
LAYOUT HEADER
<h1>Hello</h1>
This is Outer include, <Hello>, This is Inner include
LAYOUT FOOTER
Lets make custom template base with Include
function. It will be available as @Include("footer")
in template. We will inialize IncludeCallback
just before running template
public class MyTemplateBase : RazorEngineTemplateBase
{
public Func<string, object, string> IncludeCallback { get; set; }
public Func<string> RenderBodyCallback { get; set; }
public string Layout { get; set; }
public string Include(string key, object model = null)
{
return this.IncludeCallback(key, model);
}
public string RenderBody()
{
return this.RenderBodyCallback();
}
}
public static class RazorEngineCoreExtensions
{
public static MyCompiledTemplate Compile(this RazorEngine razorEngine, string template, IDictionary<string, string> parts)
{
return new MyCompiledTemplate(
razorEngine.Compile<MyTemplateBase>(template),
parts.ToDictionary(
k => k.Key,
v => razorEngine.Compile<MyTemplateBase>(v.Value)));
}
}
public class MyCompiledTemplate
{
private readonly IRazorEngineCompiledTemplate<MyTemplateBase> compiledTemplate;
private readonly Dictionary<string, IRazorEngineCompiledTemplate<MyTemplateBase>> compiledParts;
public MyCompiledTemplate(IRazorEngineCompiledTemplate<MyTemplateBase> compiledTemplate, Dictionary<string, IRazorEngineCompiledTemplate<MyTemplateBase>> compiledParts)
{
this.compiledTemplate = compiledTemplate;
this.compiledParts = compiledParts;
}
public string Run(object model)
{
return this.Run(this.compiledTemplate, model);
}
public string Run(IRazorEngineCompiledTemplate<MyTemplateBase> template, object model)
{
MyTemplateBase templateReference = null;
string result = template.Run(instance =>
{
if (!(model is AnonymousTypeWrapper))
{
model = new AnonymousTypeWrapper(model);
}
instance.Model = model;
instance.IncludeCallback = (key, includeModel) => this.Run(this.compiledParts[key], includeModel);
templateReference = instance;
});
if (templateReference.Layout == null)
{
return result;
}
return this.compiledParts[templateReference.Layout].Run(instance =>
{
if (!(model is AnonymousTypeWrapper))
{
model = new AnonymousTypeWrapper(model);
}
instance.Model = model;
instance.IncludeCallback = (key, includeModel) => this.Run(this.compiledParts[key], includeModel);
instance.RenderBodyCallback = () => result;
});
}
public void Save()
{
/*
TODO
this.compiledTemplate.SaveToFile();
this.compiledTemplate.SaveToStream();
foreach (var compiledPart in this.compiledParts)
{
compiledPart.Value.SaveToFile();
compiledPart.Value.SaveToStream();
}
*/
}
public void Load()
{
// TODO
}
}
You can’t perform that action at this time.