<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://communitytest.tessitura.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates</link><description>Wiki for creating community documentation.</description><dc:language>en-US</dc:language><generator>Telligent Community 12 Non-Production</generator><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates</link><pubDate>Thu, 11 Apr 2024 18:45:32 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Current Revision posted to Community Docs Wiki by Nick Reilingh on 4/11/2024 6:45:32 PM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tessitura&lt;/td&gt;
&lt;td&gt;v15.1&lt;/td&gt;
&lt;td&gt;v16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Razor&lt;/td&gt;
&lt;td&gt;ASP.NET MVC 3?&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C#&lt;/td&gt;
&lt;td&gt;5.0&lt;/td&gt;
&lt;td&gt;6.0?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RazorEngine&lt;/td&gt;
&lt;td&gt;3.10&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# &lt;code&gt;Execute()&lt;/code&gt; method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16, Razor templates will support C# 9.0, giving them support for &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated" rel="noopener noreferrer" target="_blank"&gt;interpolated strings&lt;/a&gt; (C# 6.0), &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions" rel="noopener noreferrer" target="_blank"&gt;local functions&lt;/a&gt; (C# 7.0), and other features.&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class. Curiously, the HTML Templates editor does not syntax-color code inside of a &lt;code&gt;@functions&lt;/code&gt; directive.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private string SOME_URL_CONSTANT = &amp;quot;https://example.com&amp;quot;;&lt;br /&gt;    private string LinkTag(string link) {&lt;br /&gt;        return &amp;quot;&amp;lt;a href=\&amp;quot;&amp;quot; + SOME_URL_CONSTANT + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + link + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@Raw(LinkTag(&amp;quot;some text&amp;quot;))&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;some text&amp;lt;/a&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Methods are private because&amp;nbsp;the template&amp;#39;s execution is just another method in the same class.&lt;/p&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;pre&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@BoldMe(&amp;quot;look at me, I&amp;#39;m bold!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;b&amp;gt;look at me, I&amp;amp;#39;m bold!&amp;lt;/b&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;The output of the helper correctly writes literal or encoded HTML like the rest of the template does.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative &lt;code&gt;WriteLiteral()&lt;/code&gt; and &lt;code&gt;Write()&lt;/code&gt; functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private void DIYRenderFunction(string content) {&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;p&amp;gt;&amp;quot;);&lt;br /&gt;        Write(content);&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@{ DIYRenderFunction(&amp;quot;here are my paragraph tags &amp;amp; encoded content&amp;quot;); }&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;p&amp;gt;here are my paragraph tags &amp;amp;amp; encoded content&amp;lt;/p&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Helpers can be passed into one another as arguments if your types are correct. The defined helper token refers to a method which returns a&amp;nbsp;&lt;a title="RazorEngine TemplateWriter type" href="https://antaris.github.io/RazorEngine/references/razorengine-templating-templatewriter.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;RazorEngine.Templating.TemplateWriter&lt;/code&gt; type&lt;/a&gt;, which is what writes template content as Literal or HTML-encoded inline. This type has a&amp;nbsp;&lt;code&gt;.ToString()&lt;/code&gt;&amp;nbsp;method which can be used to cast to a string type at the point of use, but this is often non-optimal because if the helper template outputs HTML (which it often will), you will need to&amp;nbsp;&lt;code&gt;@Raw()&lt;/code&gt;&amp;nbsp;the result when using it in another helper template.&amp;nbsp;Luckily, C# supports the &lt;code&gt;dynamic&lt;/code&gt; keyword in a type signature, which means you can pass in either a &lt;code&gt;TemplateWriter&lt;/code&gt; or a raw &lt;code&gt;string&lt;/code&gt; and RazorEngine will do the right thing at runtime:&lt;/p&gt;
&lt;pre&gt;@helper ItalicizeMe(dynamic content) {&lt;br /&gt;    &amp;lt;i&amp;gt;@content&amp;lt;/i&amp;gt;&lt;br /&gt;}&lt;br /&gt;@helper BoldMe(dynamic content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@ItalicizeMe(BoldMe(&amp;quot;I&amp;#39;m bold, AND italic!&amp;quot;))&lt;br /&gt;@ItalicizeMe(&amp;quot;I&amp;#39;m only italic!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;    &amp;lt;i&amp;gt;    &amp;lt;b&amp;gt;I&amp;amp;#39;m bold, AND italic!&amp;lt;/b&amp;gt;&lt;br /&gt;&amp;lt;/i&amp;gt;&lt;br /&gt;    &amp;lt;i&amp;gt;I&amp;amp;#39;m only italic!&amp;lt;/i&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;You can also compose helpers by nesting them inside each other&amp;#39;s templates, since helpers and &lt;code&gt;@functions&lt;/code&gt;&amp;nbsp;directives share the same scope (the generated class). In contrast, variables declared in a code block are local to the render method, so while they can be referenced in the template itself, they cannot be referenced in other class methods like helpers and functions.&lt;/p&gt;
&lt;p&gt;A special syntax exists in Razor 3 for raw text. This is necessary when using helpers without surrounding tags. Information here: &lt;a href="https://weblogs.asp.net/scottgu/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax" rel="noopener noreferrer" target="_blank"&gt;ASP.NET MVC 3: Razor&amp;rsquo;s @: and &amp;lt;text&amp;gt; syntax&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, with all of these tools in our toolbox, only one question remains... Can we avoid writing inline styles?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates/revision/6</link><pubDate>Fri, 28 May 2021 16:03:36 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Revision 6 posted to Community Docs Wiki by Nick Reilingh on 5/28/2021 4:03:36 PM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# &lt;code&gt;Execute()&lt;/code&gt; method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16, Razor templates will support C# 9.0, giving them support for &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated" rel="noopener noreferrer" target="_blank"&gt;interpolated strings&lt;/a&gt; (C# 6.0), &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions" rel="noopener noreferrer" target="_blank"&gt;local functions&lt;/a&gt; (C# 7.0), and other features.&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class. Curiously, the HTML Templates editor does not syntax-color code inside of a &lt;code&gt;@functions&lt;/code&gt; directive.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private string SOME_URL_CONSTANT = &amp;quot;https://example.com&amp;quot;;&lt;br /&gt;    private string LinkTag(string link) {&lt;br /&gt;        return &amp;quot;&amp;lt;a href=\&amp;quot;&amp;quot; + SOME_URL_CONSTANT + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + link + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@Raw(LinkTag(&amp;quot;some text&amp;quot;))&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;some text&amp;lt;/a&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Methods are private because&amp;nbsp;the template&amp;#39;s execution is just another method in the same class.&lt;/p&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;pre&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@BoldMe(&amp;quot;look at me, I&amp;#39;m bold!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;b&amp;gt;look at me, I&amp;amp;#39;m bold!&amp;lt;/b&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;The output of the helper correctly writes literal or encoded HTML like the rest of the template does.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative &lt;code&gt;WriteLiteral()&lt;/code&gt; and &lt;code&gt;Write()&lt;/code&gt; functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private void DIYRenderFunction(string content) {&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;p&amp;gt;&amp;quot;);&lt;br /&gt;        Write(content);&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@{ DIYRenderFunction(&amp;quot;here are my paragraph tags &amp;amp; encoded content&amp;quot;); }&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;p&amp;gt;here are my paragraph tags &amp;amp;amp; encoded content&amp;lt;/p&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Helpers can be passed into one another as arguments if your types are correct. The defined helper token refers to a method which returns a&amp;nbsp;&lt;a title="RazorEngine TemplateWriter type" href="https://antaris.github.io/RazorEngine/references/razorengine-templating-templatewriter.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;RazorEngine.Templating.TemplateWriter&lt;/code&gt; type&lt;/a&gt;, which is what writes template content as Literal or HTML-encoded inline. This type has a&amp;nbsp;&lt;code&gt;.ToString()&lt;/code&gt;&amp;nbsp;method which can be used to cast to a string type at the point of use, but this is often non-optimal because if the helper template outputs HTML (which it often will), you will need to&amp;nbsp;&lt;code&gt;@Raw()&lt;/code&gt;&amp;nbsp;the result when using it in another helper template.&amp;nbsp;Luckily, C# supports the &lt;code&gt;dynamic&lt;/code&gt; keyword in a type signature, which means you can pass in either a &lt;code&gt;TemplateWriter&lt;/code&gt; or a raw &lt;code&gt;string&lt;/code&gt; and RazorEngine will do the right thing at runtime:&lt;/p&gt;
&lt;pre&gt;@helper ItalicizeMe(dynamic content) {&lt;br /&gt;    &amp;lt;i&amp;gt;@content&amp;lt;/i&amp;gt;&lt;br /&gt;}&lt;br /&gt;@helper BoldMe(dynamic content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@ItalicizeMe(BoldMe(&amp;quot;I&amp;#39;m bold, AND italic!&amp;quot;))&lt;br /&gt;@ItalicizeMe(&amp;quot;I&amp;#39;m only italic!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;    &amp;lt;i&amp;gt;    &amp;lt;b&amp;gt;I&amp;amp;#39;m bold, AND italic!&amp;lt;/b&amp;gt;&lt;br /&gt;&amp;lt;/i&amp;gt;&lt;br /&gt;    &amp;lt;i&amp;gt;I&amp;amp;#39;m only italic!&amp;lt;/i&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;You can also compose helpers by nesting them inside each other&amp;#39;s templates, since helpers and &lt;code&gt;@functions&lt;/code&gt;&amp;nbsp;directives share the same scope (the generated class). In contrast, variables declared in a code block are local to the render method, so while they can be referenced in the template itself, they cannot be referenced in other class methods like helpers and functions.&lt;/p&gt;
&lt;p&gt;A special syntax exists in Razor 3 for raw text. This is necessary when using helpers without surrounding tags. Information here: &lt;a href="https://weblogs.asp.net/scottgu/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax" rel="noopener noreferrer" target="_blank"&gt;ASP.NET MVC 3: Razor&amp;rsquo;s @: and &amp;lt;text&amp;gt; syntax&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, with all of these tools in our toolbox, only one question remains... Can we avoid writing inline styles?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates/revision/5</link><pubDate>Fri, 28 May 2021 15:04:13 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Revision 5 posted to Community Docs Wiki by Nick Reilingh on 5/28/2021 3:04:13 PM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# &lt;code&gt;Execute()&lt;/code&gt; method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16, Razor templates will support C# 9.0, giving them support for interpolated strings (among other features).&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class. Curiously, the HTML Templates editor does not syntax-color code inside of a &lt;code&gt;@functions&lt;/code&gt; directive.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private string SOME_URL_CONSTANT = &amp;quot;https://example.com&amp;quot;;&lt;br /&gt;    private string LinkTag(string link) {&lt;br /&gt;        return &amp;quot;&amp;lt;a href=\&amp;quot;&amp;quot; + SOME_URL_CONSTANT + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + link + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@Raw(LinkTag(&amp;quot;some text&amp;quot;))&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;some text&amp;lt;/a&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Methods are private because&amp;nbsp;the template&amp;#39;s execution is just another method in the same class.&lt;/p&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;pre&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@BoldMe(&amp;quot;look at me, I&amp;#39;m bold!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;b&amp;gt;look at me, I&amp;amp;#39;m bold!&amp;lt;/b&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;The output of the helper correctly writes literal or encoded HTML like the rest of the template does.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative &lt;code&gt;WriteLiteral()&lt;/code&gt; and &lt;code&gt;Write()&lt;/code&gt; functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private void DIYRenderFunction(string content) {&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;p&amp;gt;&amp;quot;);&lt;br /&gt;        Write(content);&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@{ DIYRenderFunction(&amp;quot;here are my paragraph tags &amp;amp; encoded content&amp;quot;); }&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;p&amp;gt;here are my paragraph tags &amp;amp;amp; encoded content&amp;lt;/p&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Helpers can be passed into one another as arguments if your types are correct. The defined helper token refers to a method which returns a&amp;nbsp;&lt;a title="RazorEngine TemplateWriter type" href="https://antaris.github.io/RazorEngine/references/razorengine-templating-templatewriter.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;RazorEngine.Templating.TemplateWriter&lt;/code&gt; type&lt;/a&gt;, which is what writes template content as Literal or HTML-encoded inline. This type has a&amp;nbsp;&lt;code&gt;.ToString()&lt;/code&gt;&amp;nbsp;method which can be used to cast to a string type at the point of use, but this is often non-optimal because if the helper template outputs HTML (which it often will), you will need to&amp;nbsp;&lt;code&gt;@Raw()&lt;/code&gt;&amp;nbsp;the result when using it in another helper template.&amp;nbsp;Luckily, C# supports the &lt;code&gt;dynamic&lt;/code&gt; keyword in a type signature, which means you can pass in either a &lt;code&gt;TemplateWriter&lt;/code&gt; or a raw &lt;code&gt;string&lt;/code&gt; and RazorEngine will do the right thing at runtime:&lt;/p&gt;
&lt;pre&gt;@helper ItalicizeMe(dynamic content) {&lt;br /&gt;    &amp;lt;i&amp;gt;@content&amp;lt;/i&amp;gt;&lt;br /&gt;}&lt;br /&gt;@helper BoldMe(dynamic content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@ItalicizeMe(BoldMe(&amp;quot;I&amp;#39;m bold, AND italic!&amp;quot;))&lt;br /&gt;@ItalicizeMe(&amp;quot;I&amp;#39;m only italic!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;    &amp;lt;i&amp;gt;    &amp;lt;b&amp;gt;I&amp;amp;#39;m bold, AND italic!&amp;lt;/b&amp;gt;&lt;br /&gt;&amp;lt;/i&amp;gt;&lt;br /&gt;    &amp;lt;i&amp;gt;I&amp;amp;#39;m only italic!&amp;lt;/i&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;You can also compose helpers by nesting them inside each other&amp;#39;s templates, since helpers and &lt;code&gt;@functions&lt;/code&gt;&amp;nbsp;directives share the same scope (the generated class). In contrast, variables declared in a code block are local to the render method, so while they can be referenced in the template itself, they cannot be referenced in other class methods like helpers and functions.&lt;/p&gt;
&lt;p&gt;A special syntax exists in Razor 3 for raw text. This is necessary when using helpers without surrounding tags. Information here: &lt;a href="https://weblogs.asp.net/scottgu/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax" rel="noopener noreferrer" target="_blank"&gt;ASP.NET MVC 3: Razor&amp;rsquo;s @: and &amp;lt;text&amp;gt; syntax&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, with all of these tools in our toolbox, only one question remains... Can we avoid writing inline styles?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates/revision/4</link><pubDate>Fri, 28 May 2021 04:31:56 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Revision 4 posted to Community Docs Wiki by Nick Reilingh on 5/28/2021 4:31:56 AM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# &lt;code&gt;Execute()&lt;/code&gt; method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16 there&amp;nbsp;is&amp;nbsp;support for interpolated strings, which indicates that the language has been updated to at least&amp;nbsp;C# 6.0.&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class. Curiously, the HTML Templates editor does not syntax-color code inside of a &lt;code&gt;@functions&lt;/code&gt; directive.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private string SOME_URL_CONSTANT = &amp;quot;https://example.com&amp;quot;;&lt;br /&gt;    private string LinkTag(string link) {&lt;br /&gt;        return &amp;quot;&amp;lt;a href=\&amp;quot;&amp;quot; + SOME_URL_CONSTANT + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + link + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@Raw(LinkTag(&amp;quot;some text&amp;quot;))&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;some text&amp;lt;/a&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Methods are private because&amp;nbsp;the template&amp;#39;s execution is just another method in the same class.&lt;/p&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;pre&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@BoldMe(&amp;quot;look at me, I&amp;#39;m bold!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;b&amp;gt;look at me, I&amp;amp;#39;m bold!&amp;lt;/b&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;The output of the helper correctly writes literal or encoded HTML like the rest of the template does.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative &lt;code&gt;WriteLiteral()&lt;/code&gt; and &lt;code&gt;Write()&lt;/code&gt; functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private void DIYRenderFunction(string content) {&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;p&amp;gt;&amp;quot;);&lt;br /&gt;        Write(content);&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@{ DIYRenderFunction(&amp;quot;here are my paragraph tags &amp;amp; encoded content&amp;quot;); }&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;p&amp;gt;here are my paragraph tags &amp;amp;amp; encoded content&amp;lt;/p&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Helpers can be nested by calling &lt;code&gt;.ToString()&lt;/code&gt; on the result of the inner helper before passing to the outer. Note that if the inner helper outputs HTML, then you will need to &lt;code&gt;@Raw()&lt;/code&gt; it in the outer helper.&lt;/p&gt;
&lt;pre&gt;@helper ListMe(string content) {&lt;br /&gt;    &amp;lt;ul&amp;gt;&lt;br /&gt;        &amp;lt;li&amp;gt;@Raw(content)&amp;lt;/li&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;}&lt;br /&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@ListMe(BoldMe(&amp;quot;I am bold, AND in a list!&amp;quot;).ToString())&lt;br /&gt;@* Outputs:&lt;br /&gt;    &amp;lt;ul&amp;gt;&lt;br /&gt;        &amp;lt;li&amp;gt;    &amp;lt;b&amp;gt;I am bold, AND in a list!&amp;lt;/b&amp;gt;&lt;br /&gt;&amp;lt;/li&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;A special syntax exists in Razor 3 for raw text. This is necessary when using helpers without surrounding tags. Information here: &lt;a href="https://weblogs.asp.net/scottgu/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax" rel="noopener noreferrer" target="_blank"&gt;ASP.NET MVC 3: Razor&amp;rsquo;s @: and &amp;lt;text&amp;gt; syntax&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, with all of these tools in our toolbox, only one question remains... Can we avoid writing inline styles?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates/revision/3</link><pubDate>Fri, 28 May 2021 03:36:04 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Revision 3 posted to Community Docs Wiki by Nick Reilingh on 5/28/2021 3:36:04 AM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# &lt;code&gt;Execute()&lt;/code&gt; method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16 there&amp;nbsp;is&amp;nbsp;support for interpolated strings, which indicates that the language has been updated to at least&amp;nbsp;C# 6.0.&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class. Curiously, the HTML Templates editor does not syntax-color code inside of a &lt;code&gt;@functions&lt;/code&gt; directive.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private string SOME_URL_CONSTANT = &amp;quot;https://example.com&amp;quot;;&lt;br /&gt;    private string LinkTag(string link) {&lt;br /&gt;        return &amp;quot;&amp;lt;a href=\&amp;quot;&amp;quot; + SOME_URL_CONSTANT + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + link + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@Raw(LinkTag(&amp;quot;some text&amp;quot;))&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;some text&amp;lt;/a&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Methods are private because&amp;nbsp;the template&amp;#39;s execution is just another method in the same class.&lt;/p&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;pre&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@BoldMe(&amp;quot;look at me, I&amp;#39;m bold!&amp;quot;)&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;b&amp;gt;look at me, I&amp;amp;#39;m bold!&amp;lt;/b&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;The output of the helper correctly writes literal or encoded HTML like the rest of the template does.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative &lt;code&gt;WriteLiteral()&lt;/code&gt; and &lt;code&gt;Write()&lt;/code&gt; functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private void DIYRenderFunction(string content) {&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;p&amp;gt;&amp;quot;);&lt;br /&gt;        Write(content);&lt;br /&gt;        WriteLiteral(&amp;quot;&amp;lt;/p&amp;gt;&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@{ DIYRenderFunction(&amp;quot;here are my paragraph tags &amp;amp; encoded content&amp;quot;); }&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;p&amp;gt;here are my paragraph tags &amp;amp;amp; encoded content&amp;lt;/p&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Helpers can be nested by calling &lt;code&gt;.ToString()&lt;/code&gt; on the result of the inner helper before passing to the outer. Note that if the inner helper outputs HTML, then you will need to &lt;code&gt;@Raw()&lt;/code&gt; it in the outer helper.&lt;/p&gt;
&lt;pre&gt;@helper ListMe(string content) {&lt;br /&gt;    &amp;lt;ul&amp;gt;&lt;br /&gt;        &amp;lt;li&amp;gt;@Raw(content)&amp;lt;/li&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;}&lt;br /&gt;@helper BoldMe(string content) {&lt;br /&gt;    &amp;lt;b&amp;gt;@content&amp;lt;/b&amp;gt;&lt;br /&gt;}&lt;br /&gt;@ListMe(BoldMe(&amp;quot;I am bold, AND in a list!&amp;quot;).ToString())&lt;br /&gt;@* Outputs:&lt;br /&gt;    &amp;lt;ul&amp;gt;&lt;br /&gt;        &amp;lt;li&amp;gt;    &amp;lt;b&amp;gt;I am bold, AND in a list!&amp;lt;/b&amp;gt;&lt;br /&gt;&amp;lt;/li&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;Now, with all of these tools in our toolbox, only one question remains... Can we avoid writing inline styles?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates/revision/2</link><pubDate>Fri, 28 May 2021 03:19:38 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Revision 2 posted to Community Docs Wiki by Nick Reilingh on 5/28/2021 3:19:38 AM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# &lt;code&gt;Execute()&lt;/code&gt; method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16 there&amp;nbsp;is&amp;nbsp;support for interpolated strings, which indicates that the language has been updated to at least&amp;nbsp;C# 6.0.&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class. Curiously, the HTML Templates editor does not syntax-color code inside of a &lt;code&gt;@functions&lt;/code&gt; directive.&lt;/p&gt;
&lt;pre&gt;@functions {&lt;br /&gt;    private string SOME_URL_CONSTANT = &amp;quot;https://example.com&amp;quot;;&lt;br /&gt;    private string linkTag(string link) {&lt;br /&gt;        return &amp;quot;&amp;lt;a href=\&amp;quot;&amp;quot; + SOME_URL_CONSTANT + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + link + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;@Raw(linkTag(&amp;quot;some text&amp;quot;))&lt;br /&gt;@* Outputs:&lt;br /&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;some text&amp;lt;/a&amp;gt;&lt;br /&gt;*@&lt;/pre&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative WriteLiteral() and Write() functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;p&gt;Helpers can be nested by calling &lt;code&gt;.ToString()&lt;/code&gt; on the result of the inner helper before passing to the outer. Note that if the inner helper outputs HTML, then you will need to &lt;code&gt;@Raw()&lt;/code&gt; it in the outer helper.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item><item><title>The Secret Life of HTML Templates</title><link>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates/revision/1</link><pubDate>Fri, 28 May 2021 03:12:29 GMT</pubDate><guid isPermaLink="false">fd08b0f2-65fa-4b2b-916a-cce3e88b61d0:6aa35c30-07ae-4c3a-b10f-0acfb6040cab</guid><dc:creator>Nick Reilingh</dc:creator><comments>https://communitytest.tessitura.com/topical_groups/developers/w/community-developer-documentation/790/the-secret-life-of-html-templates#comments</comments><description>Revision 1 posted to Community Docs Wiki by Nick Reilingh on 5/28/2021 3:12:29 AM&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;or: How I Learned to Stop Worrying and Just Write HTML Templates&lt;/p&gt;
&lt;p&gt;or: HTML Templates: The Missing Manual&lt;/p&gt;
&lt;p&gt;or: The HTML Templates documentation they&amp;nbsp;&lt;em&gt;don&amp;#39;t&lt;/em&gt; want you to know about!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article aims to explain the differences between the Razor template syntax used in Tessitura HTML Templates and the syntax that you might see used in training courses&amp;nbsp;for Razor Pages in ASP.NET Core/MVC web applications. At present, the Tessitura documentation only scratches the surface of what is available syntactically, and doesn&amp;#39;t really attempt to explain how&amp;nbsp;HTML Templates are implemented.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6o9tpq90"&gt;The Big Secret&lt;/h2&gt;
&lt;p&gt;HTML Templates are rendered using an Apache-licensed, open-source project called &lt;a title="Documentation site for RazorEngine" href="http://antaris.github.io/RazorEngine/" rel="noopener noreferrer" target="_blank"&gt;RazorEngine&lt;/a&gt;, which is available &lt;a title="GitHub repo for Antaris/RazorEngine" href="https://github.com/Antaris/RazorEngine" rel="noopener noreferrer" target="_blank"&gt;on GitHub&lt;/a&gt;. To&amp;nbsp;summarize the &lt;a title="About Razor and its syntax" href="https://antaris.github.io/RazorEngine/AboutRazor.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt;, RazorEngine is a framework&amp;nbsp;which consumes the Razor parser -- as is ASP.NET MVC. There is a difference between Razor&amp;#39;s syntax and special features provided by these frameworks. RazorEngine only shares its syntax with other implementations like ASP.NET MVC. This is why convenience methods like &lt;code&gt;@Html.Raw()&lt;/code&gt; (often seen in web results about Razor Pages) do not work in HTML templates -- the &lt;code&gt;@Html&lt;/code&gt; helper is a &lt;a title="HtmlHelper Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2" rel="noopener noreferrer" target="_blank"&gt;class&lt;/a&gt; specifically implemented by the ASP.NET MVC framework. (RazorEngine instead has &lt;code&gt;@Raw()&lt;/code&gt; built-in to provide the &lt;a title="Encoding Values in RazorEngine" href="https://antaris.github.io/RazorEngine/Encoding.html" rel="noopener noreferrer" target="_blank"&gt;same functionality&lt;/a&gt;.) Reading the &lt;a href="https://antaris.github.io/RazorEngine/index.html" rel="noopener noreferrer" target="_blank"&gt;RazorEngine documentation&lt;/a&gt; can be informative. Tessitura appears to implement version 3.10 of RazorEngine.&lt;/p&gt;
&lt;p&gt;The fundamentals of how Razor operates still apply. The Razor syntax parser converts a .cshtml template into a C# Execute() method on a generated class, which, when invoked, has access to the provided model and returns a string.&lt;/p&gt;
&lt;h2 id="mcetoc_1f6oeo60f1"&gt;Assorted Syntactic Tips and Tricks&lt;/h2&gt;
&lt;p&gt;The version of C# available in Tessitura HTML Templates in Tessitura V15.1 is C# 5.0. In Tessitura V16 there&amp;nbsp;is&amp;nbsp;support for interpolated strings, which indicates that the language has been updated to at least&amp;nbsp;C# 6.0.&lt;/p&gt;
&lt;p&gt;The version of Razor available in Tessitura HTML Templates in V15.1 is &amp;quot;Razor 3&amp;quot;, which is versioned as such because it shipped with ASP.NET MVC 3. This means technically, the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor" rel="noopener noreferrer" target="_blank"&gt;syntax documentation linked in the Tessitura docs&lt;/a&gt; is&amp;nbsp;WAY too new for what is actually in use. This explains why &amp;quot;templating methods&amp;quot; described in these docs are not functional in Tessitura HTML Templates.&lt;/p&gt;
&lt;p&gt;Razor supports the use of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#functions" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;@functions&lt;/code&gt; directive&lt;/a&gt;, which gives you a&amp;nbsp;space to define additional members (methods and properties) to be added to the&amp;nbsp;generated class.&lt;/p&gt;
&lt;p&gt;The version of Razor used in RazorEngine 3.10 (Razor 3, shipped in ASP.NET MVC 3) also supports the &lt;code&gt;@helper&lt;/code&gt; directive, which allows you to define a kind of function that contains markup, just like the rest of the template. This allows for easy reuse of template code. Helpers were &lt;a href="https://github.com/aspnet/Razor/issues/281" rel="noopener noreferrer" target="_blank"&gt;removed in&amp;nbsp;Razor 4&lt;/a&gt;, &lt;a href="https://www.c-sharpcorner.com/article/html-helpers-in-asp-net-mvc-5/" rel="noopener noreferrer" target="_blank"&gt;reappear in ASP.NET MVC 5&lt;/a&gt;,&amp;nbsp;were removed again in &lt;a href="https://github.com/dotnet/aspnetcore/issues/5110" rel="noopener noreferrer" target="_blank"&gt;ASP.NET Core&lt;/a&gt;,&amp;nbsp;and finally &lt;a href="https://github.com/dotnet/aspnetcore-tooling/pull/334" rel="noopener noreferrer" target="_blank"&gt;code blocks were enhanced to allow for inline markup in functions&lt;/a&gt;, without the need for the &lt;code&gt;@helper&lt;/code&gt; directive. Helpers can be used as &amp;quot;templating methods&amp;quot; which are otherwise unavailable as described above.&lt;/p&gt;
&lt;p&gt;A regular function can be made to behave like a templating method by defining it with a void type and then calling the imperative WriteLiteral() and Write() functions, which is basically what a Razor template compiles to in the first place. Then this function can be called inside a code block (&lt;code&gt;@{}&lt;/code&gt;) to inject its output at that location.&lt;/p&gt;
&lt;p&gt;Helpers can be nested by calling &lt;code&gt;.ToString()&lt;/code&gt; on the result of the inner helper before passing to the outer. Note that if the inner helper outputs HTML, then you will need to &lt;code&gt;@Raw()&lt;/code&gt; it in the outer helper.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: c#, HTML Templates, razor&lt;/div&gt;
</description></item></channel></rss>