Improving Code Readability in View Section Using Return Templates

Introduction

Code-behind is a programming pattern that separates the presentation logic from the HTML code, allowing for a cleaner separation of concerns. It involves creating a separate class file for the code, which can help with maintainability and readability.

Common people usually know Code-Behind with Microsoft web-form. Please note that the CodeBehind framework is a back-end framework for .NET Core, and its structure has nothing to do with Microsoft's former web form.

The Code-Behind pattern completely separates the design section (such as html) from the server-side coding section, and the server-side and client-side developers do the development without being involved in the work.

The problem of loops and conditionals

Please note that things like variables between the design part code are still considered Code-Behind unless the server part code is added.

The presence of variables between html or xml codes, etc., is completely recognizable.

Example of variables between the design part

Razor syntax

<h1>@model.PageName</h1>

Standard syntax

<h1><%=model.PageName%></h1>

In the two examples above, the @model.PageName and <%=model.PageName%> values are easily recognized in the html tags, so the Code-Behind pattern is still in place, and designers or client-side developers can easily recognize these values.

There will be no problem here, and it is based on the Code-Behind pattern.

But, usually, for repetitive parts such as loops and conditions, you should either add the codes of the design part in the server side codes or add the server side codes in the design part.

So you have no escape!

An example of server-side coding is in the design section.

<table>
    <thead>
        <tr>
            <th>Column1</th>
            <th>Column2</th>
            <th>Column3</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.Column1</td>
                <td>@item.Column2</td>
                <td>@item.Column3</td>
            </tr>
        }
    </tbody>
</table>

Example of integration of the design part in the server-side codes

model.ListValue = "<ul>";

foreach(string s in List)
    model.ListValue += "<li>" + s + "</li>";

model.ListValue += "</ul>";

Using Templates for Code-Behind Compliance

One of the most famous frameworks that guaranteed the separation of server-side codes from the design department was Microsoft's web form, but this guarantee was a heavy price, such as additional codes and lack of full control of the designers over the design department.

Currently, the CodeBehind framework supports a 100% Code-Behind-based design structure; this is thanks to the new recursion template feature added in the latest version of this framework.

Templates are sections of a page view that are attached to template variables before the view section is compiled.

The template is used for razor syntax and standard syntax. The razor syntax template cannot be used for standard syntax; likewise, the standard syntax template cannot be used for razor syntax.

A simple example of the template (standard syntax).

<%@ Page Controller="YourProjectName.DefaultController" Model="YourProjectName.DefaultModel" %>
<!DOCTYPE html>
<html>
<head>
+   <#GlobalTags#>
    <title><%=model.PageTitle%></title>
</head>
<body>
    <%=model.BodyValue%>
</body>
</html>

+<#GlobalTags 
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-16" />
+<meta http-equiv="content-language" content="en">
+<script type="text/javascript" src="/client/script/global.js" ></script>
+<link rel="alternate" type="application/rss+xml" title="rss feed" href="/rss/" />
+<link rel="shortcut icon" href="/favicon.ico" />
+<link rel="stylesheet" type="text/css" href="/client/style/global.css" />
+#>

In this example, a Template section is called in the Template variable, and the output is converted as follows.

<%@ Page Controller="YourProjectName.DefaultController" Model="YourProjectName.DefaultModel" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-16" />
    <meta http-equiv="content-language" content="en">
    <script type="text/javascript" src="/client/script/global.js" ></script>
    <link rel="alternate" type="application/rss+xml" title="rss feed" href="/rss/" />
    <link rel="shortcut icon" href="/favicon.ico" />
    <link rel="stylesheet" type="text/css" href="/client/style/global.css" />
    <title><%=model.PageTitle%></title>
</head>
<body>
    <%=model.BodyValue%>
</body>
</html>

The example above showed the simple ability of templates in the CodeBehind framework and introduced you to the concept of templates, but return templates have a unique feature; returned templates are first inserted into the template, and then the entire template is replaced by the returned template.

There are two types of templates.

  1. Template
  2. Return template

Both types of templates can be called with the template variable.

Example of template definition (Razor syntax).

+@#TemplateName{
@{
string ExampleText = "This is example text";
}
<b>Example value is : @ExampleText</b>
+}

The at sign and sharp (@#) characters are used at the beginning of each template definition, and then the name of the template is written, and at the end, the block character ({) is used. Then, the desired values are added, and finally, the block is closed (}).

To call the template, it is necessary to write the template variable. To write the template variable, sign, and sharp (@#) characters are added at the beginning, and then the name of the template is written.

Example for call template by template variable.

<!DOCTYPE html>
<html>
<body>
+  @#TemplateName
</body>
</html>

Example of after pasting the template.

<!DOCTYPE html>
<html>
<body>
@{
string ExampleText = "This is example text";
}
<b>Example value is : @ExampleText</b>
</body>
</html>

Returned templates are first inserted into a variable with the same name as the template name, and then the entire template is replaced by the returned template (all three are the same name).

The at sign and sharp (@#) characters are used at the beginning of each return template definition, and then the name of the template is written. Then, the equal character (=) is added, and at the end, the block character ({) is used. Then, the desired values are added, and finally, the block is closed (}).

Example (Razor syntax)View the section before pasting the template.

<div class="header">
  <a href="#default">@model.Title</a>
  <div class="header-right">
    @#Tags={<a href="@#Href">@#PageName</a>}
  </div>
</div>

@#Tags{
@foreach (PageItem page in model.PageItemList)
{
    @#Tags
}
}

@#PageName{@page.Title}
@#Href{@(((page.Path == "main")? "/" : page.Path))}

In the codes above, there is a return template called Tags, which is specified with the string @#Tags= and its value is known inside the blockpPasting template auto step 1.

<div class="header">
  <a href="#default">@model.Title</a>
  <div class="header-right">
    @#Tags={<a href="@#Href">@#PageName</a>}
  </div>
</div>

@#Tags{
@foreach (PageItem page in model.PageItemList)
{
    <a href="@#Href">@#PageName</a>
}
}

@#PageName{@page.Title}
@#Href{@(((page.Path == "main")? "/" : page.Path))}

As you can see in the above codes. First, the value inside the returned template block with the name Tags is replaced in the Tags template variable inside the Tags template.

pasting template auto step 2.

<div class="header">
  <a href="#default">@model.Title</a>
  <div class="header-right">
    @foreach (PageItem page in model.PageItemList)
    {
        <a href="@#Href">@#PageName</a>
    }
  </div>
</div>

@#PageName{@page.Title}
@#Href{@(((page.Path == "main")? "/" : page.Path))}

According to the above codes, in the second step, the values of the Tags template are replaced in the place of the returned template.

pasting template auto step 3 (finally).

<div class="header">
  <a href="#default">@model.Title</a>
  <div class="header-right">
    @foreach (PageItem page in model.PageItemList)
    {
        <a href="@(((page.Path == "main")? "/" : page.Path))">@page.Title</a>
    }
  </div>
</div>

In the last step, the values of other templates are replaced in the place of template variables.

In the template placement example, if you add the template externally, you will have the following html in the design section.

View the section before pasting the template.

<div class="header">
  <a href="#default">@model.Title</a>
  <div class="header-right">
+    @#Tags={<a href="@#Href">@#PageName</a>}
  </div>
</div>

Without a return template, at best, you will have the following html in the design section.

View the section without the use of the return template.

<div class="header">
  <a href="#default">@model.Title</a>
  <div class="header-right">
+ @foreach (PageItem page in model.PageItemList)
+ {
+    <a href="@(((page.Path == "main")? "/" : page.Path))">@page.Title</a>
+ }
  </div>
</div>

Please note that this was a simple example, and the situation may be very complex.

You can also use a template for standard syntax. The following code shows the previous template example in standard syntax.

<div class="header">
  <a href="#default"><%=model.Title%></a>
  <div class="header-right">
    <#Tags=<a href="<#Href#>"><#PageName#></a>#>
  </div>
</div>

<#Tags 
<% foreach (PageItem page in model.PageItemList)
{
    <#Tags#>
}
%>
#>

<#PageName <%=page.Title%>#>
<#Href <%=((page.Path == "main")? "/" : page.Path)%>#>

If the return value is placed between the standard syntax tags, the syntax will be automatically closed before the return value, and the syntax will be opened after it.

pasting template auto step finally for standard syntax.

<div class="header">
  <a href="#default"><%=model.Title%></a>
  <div class="header-right">
    <% foreach (PageItem page in model.PageItemList)
    {
        %><a href="<%=((page.Path == "main")? "/" : page.Path)%>"><%=page.Title%></a><%
    }
    %>
  </div>
</div>

Conclusion

No matter how much you try to avoid mixing server-side codes in the view section, in some cases, such as loops and conditions, you will have to use server-side codes in the view section; the presence of mixing server-side codes reduces the readability of the codes and makes the appearance of the view section ugly, and it becomes difficult to maintain the codes and also leads to complex interaction between the server-side and client-side developers in high-scale applications. Applying the return template keeps the code of the server section outside the view section. As a result, the view section will have a great appearance, and the Code-Behind pattern will be fully respected.

Code example

Reference