WebStencils provides a powerful layout system similar to other template engines like Razor. This system allows you to define a common structure for your pages and inject specific content into that structure.
The @LayoutPage directive is used in a content page to specify which layout template should be used
as the structure for that page. It's typically placed at the top of the content file:
@LayoutPage BaseTemplate
<h1>Welcome to My Page</h1>
<p>This is the content of my page.</p>
The @RenderBody directive is used in the layout template to indicate where the content from the
specific page should be inserted. For example, in your BaseTemplate.html:
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<header>
<!-- Common header content -->
</header>
<main>
@RenderBody
</main>
<footer>
<!-- Common footer content -->
</footer>
</body>
</html>
The @Import directive allows you to merge an external file into a specific location in the current
template. This is useful for creating reusable components.
This directive allows structuring your templates in nested folders. It’s also possible to omit the file extension, as long as the default one has been defined in the Engine or Processor.
@Import Sidebar.html
@* Same behaviour as the previous one *@
@Import Sidebar
@* Use nested templates for better organization *@
@Import folder/Sidebar
WebStencils supports several common template patterns that can help you organize your application's views effectively.
This pattern uses the built-in @LayoutPage and @RenderBody approach we've already
discussed. It's ideal for maintaining a consistent structure across your site while allowing individual pages to
provide their specific content. This demo follows this pattern.
In this pattern, each page is an individual template, but they all share common parts like headers and footers. Instead of using a layout page, you might structure your templates like this:
@Import Header.html
<main>
<!-- Page-specific content here -->
</main>
@Import Footer.html
This approach offers more flexibility than the standard layout pattern but may require more management of common elements.
Using the @Import directive, you can define individual sets of components that can be reused
throughout your application. This directive also allows passing of iterable objects and even defining aliases
for a more agnostic component definition. For example:
<div class="product-list">
@Import ProductList { @list = @ProductList }
</div>
<div class="tasks">
@ForEach (var Task in Tasks.AllTasks) {
@Import partials/tasks/item { @Task }
}
</div>
This pattern allows you to break your UI into smaller, manageable pieces that can be easily maintained and reused across different pages. You can find some examples of this pattern in the code of this demo.