Yes that's by design: There are really two points here: First is template instance creation, we don't allow it as we might need to save some internal state and therefore don't want to provide an API for it (note you still can define your own type if you need to!)
The other thing is re-using ITemplate instances: We don't allow that anymore for multiple reasons. First its not thread safe and second re-using is really error prone.
There is in fact a bug in your code: nested templates (layouts or includes) are not cached properly but recompiled more than actually required...
Therefore I recommend to not use RazorEngine with the legacy API and instead use the new API (sometimes you need to do/think a bit more, but its for the greater good :)
@model M <h2>@Model.Name</h2> @foreach(var x in Model.Parts) { <div>@x</div> }
. Besides that I need to produce a common HTML (e. g., <h2>A</h2> <div>a</div><div>b</div>
for model { Name = "A", Parts = new[] { "a", "b", }, }
), I would like also get some template proper for JavaScript compilation. For this example it may be a JavaScript function m(Model) { var result = "<h2>" + Model.Name + "</h2>"; for(var i = 0; i < Model.Parts.length; i++) { result += "<div>" + Model.Parts[i] + "</div>"; } return result; }
. Or it may be an HTML filled with tokens of one of the JavaScript templating frameworks: <h2><% Model.Name %></h2> <% for(var i = 0; i < Model.Parts.length; i++) { %> <div> <% Model.Parts[i] %> </div> <% } %>
.That said I probably would suggest a webservice instead, keeping the templates on the server (Razor) and calling that service via javascript instead of a client side templating solution.
I have never heard of somebody doing anything similar so you are probably completely on your own (no need to say that it sounds like a really difficult/impossible thing to do)
@matthid
any C# code
Since one follows the ViewModel template, usually anything except direct properties access and basic code control constructions (if-else, for, foreach, switch) are not expected. Thus the task is becoming easier.
calling that service via javascript instead of a client side templating solution
You are right, but I would like to minimize the load on the server and transfer some work to the client side. And simultaneously I would like to consider a situation when JS is blocked by the client.
never heard of somebody doing anything similar
I have found the project https://github.com/jchadwick/RazorClientTemplates, but it is abandoned by the main contributor and thus it is obsolete.
So, I intend to inherit from RazorEngine.Compilation.CompilerServiceBase and implement... yet do not know what. Would you be so kind to point me to the reference or say what should I do after implementation? I have expected some parser class where an instance of type ICompilerService must be supplied. Am I correct?
Ideally you want to intercept somewhere near: https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Compilation/CompilerServiceBase.cs#L356
And the cleanest thing to do would be to create your own "RazorCodeLanguage" class, which outputs JS instead of C# (but that's probably more work than to simply walk over the C# tree) and change the property here: https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Compilation/CompilerServiceBase.cs#L107.
You should start by compiling from source and marking the methods you want to overwrite as virtual (if needed) and implement what you are trying to achieve. I would certainly accept a pull request later on. You should figure out exactly what you want to do and what you expect after compiling a template. The C# code? the JS Code? both? And how to integrate that with the remaining architecture of RazorEngine (for the start it is probably enough to have a CompilerService that outputs JS and run it standalone whenever you need it)