Razorlight: Templates in folders

Created on 6 Nov 2017  路  7Comments  路  Source: toddams/RazorLight

I'm just starting to implement RL alpha3 in my 2.0 project. I've created a folder in Views/ called Mailers to store all my templates. The plan was to organise these so I have
/Shared <- for _Layout /Folder1/Template1.cshtml /Folder2/Template1.cshtml
But I'm not sure how to do this with the engine/key structure.
If /Views/Mailers is my root engine, I can't pass a subfolder in a key to get my core template.
If I create the engine in the subfolder, it can't find the template.

Thanks

question

All 7 comments

Templates are resolved taking as a start point - a root folder that you specify when you create an engine.

So root is your upper folder. Then when you resolve a template you specify the path for it: /Folder/Template1 and in @{ Layout = "/Shared/myLayout" }

Is that what you've been asking?

Thanks. I had that working OK but I wanted to have folders on the same level as Shared with my mail templates in. Like how the normal Views folder is.
So if root is /, templates are in /Users/ResetPassword.cshtml, using the layout in /Shared/_Layout.cshtml

Can you please provide a sample? Cause I still can't get it)

Sorry for being confusing. Hope this helps.
var webRoot = _env.ContentRootPath; var engine = new EngineFactory().ForFileSystem(Path.Combine(webRoot, "Views", "Mailers", "Systems" )); var message = engine.CompileRenderAsync("AdminWelcome", model, viewBag).Result;
So AdminWelcome is my template name, and its in the ContentRoot/Views/Mailers/Systems
My Layout is ContentRoot/Views/Mailers/Shared/_Layout.cshtml though, because I use one template for all my emails.
screenshot 2017-11-10 22 49 09

If I'm setting the Systems folder as the engine path, I can't access the Shared folder (because its a level above the root of the engine). If I set the Mailers folder as the root engine (the contents of which is in the screenshot), I'm not sure how to pass the folder and the template key (cshtml filename) to the engine to render. It doesn't seem to like taking a path like "Systems/AdminWelcome" as the template key.
What I want to be able to do is something like...
var engine = new EngineFactory().ForFileSystem(Path.Combine(webRoot, "Views", "Mailers")); var message = engine.CompileRenderAsync("Systems/AdminWelcome", model, viewBag).Result;
and in my template be putting
@{ Layout = "/Shared/_Layout.cshtml"}

I reproduced the same folder structure as you have and it works for me.

What is the exception message?

I think i've got it working. One next issue - I'm trying to access ViewBag data in my main template. Is it accessible there?
Error Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 'System.Dynamic.ExpandoObject' does not contain a definition for 'AppSite'
yet my ExpandoObject has ((dynamic)viewBag).AppSite = _options.AppSite; which is just a string
`

Scratch that
Error Unable to open 'NewUserWelcome.cshtml': no provider for Users/NewUserWelcome.cshtml.
Code:

var webRoot = _env.ContentRootPath;
// RazorLight 2.0
var viewBag = _baseEmailData.LayoutViewBag(model.Subject);
var emailRoot = MailHelpers.LoadTemplatePath(webRoot,""); // $workspace/Views/Mailers
var engine = new EngineFactory().ForFileSystem(emailRoot);
var message = engine.CompileRenderAsync(Path.Combine("Users", "NewUserWelcome").ToString(), model, viewBag).Result;
Was this page helpful?
0 / 5 - 0 ratings