ZML.1.0 1.1.2

Install-Package ZML.1.0 -Version 1.1.2
dotnet add package ZML.1.0 --version 1.1.2
<PackageReference Include="ZML.1.0" Version="1.1.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ZML.1.0 --version 1.1.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: ZML.1.0, 1.1.2"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install ZML.1.0 as a Cake Addin
#addin nuget:?package=ZML.1.0&version=1.1.2

// Install ZML.1.0 as a Cake Tool
#tool nuget:?package=ZML.1.0&version=1.1.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

ZML: The XML Razor

ZML is a tagged programming language designed to create Razor Views/Pages that do not have to contain any C#, VB.NET or F# code, so the Razor entirely looks like a normal XML file, that is valid to use in any ASP.NET app regardless of the programming language it uses.

How does ZML work: you can use ZML in two ways:

  1. add .zml files to your project (and choose to open them with the HTML editor), then call the zml.ZmlPages.Compile() method in the Startup.Configure() method. This will search for all .zml files in your project, and generate the cshtml files from them. This process will only include .zml files that have been modified since last compilation. Using auto generated cshtml files grantees that your app works as a standard Razor app, giving you all control over razor options, including using pre compiled cshtml files.
  2. Use zml with a virtual file provider, to deliver the cshtml content to the Razor Engine in runtime (no cshtml files in the project). To get the compiled C# string, Use the ParseZML method, which is an extension method to both String and XElement classes.

ZML Tags:

ZML contains the most needed tags to represent basic C# statements, Razor statements and some commonly uses tag helpers. All ZML tags belongs to the z: namespace (such as <z:text>) to avoid any confliction with HTML tags (such as <text>). You don't have to define the z: namespace in .zml files, because ZML does that internally, but you have to define it in vbxml code like this:

<zml xmlns:z="zml">

I will list ZML tags in brief. Look at eShopOnWeb.zml and ZML.Test projects, to see how to uses them.

<z:using x /> / <z:imports x /> Generates the @using x statement.

<z:namespace x /> Generates the @namespace x statement.

<z:helpers x="*" /> Generates the @addTagHelper *, x statement.

<z:page [route="x"] /> Generates the @page ["x"] statement.

<z:model type="Integer" /> Generates the @model int statement.

<z:layout page="x" /> Generates the @{Layout = "x";} statement.

<z:inject x.type="int" /> Generates the @inject int x statement.

<z:title>test</z:title> Generates the @{ ViewData["Title"] = "test"; } statement.

<z:title /> Generates the @ViewData["Title"] expression to read Title key.

<z:viewdata x="y"/> Generates the @{ ViewData["x"] = "y"; } expression to read Title key.

<z:section name="x">block</z:section> Generates the @section x { block } razor block.

<z:displayfor var="x" return="x.Name" /> Generates the @Html.DisplayFor(x => x.Name) helper method.

<z:displaynamefor var="x" return="x.Name" /> Generates the @Html.DisplayNameFor(x => x.Name) helper method.

<z:declare x="3"/> Generates the @{ var x=3; } expression.

<z:set x="3"/> Generates the @{ x=3; } expression.

<z:check condition="x" ifnull="y" /> Generates the x ?? y expression.

<z:if></z:if > Generates if statements.. In the simplest form:

<z:if condition="cond">
</z:if >

And you can also have else if and else statements, in the form:

<z:if condition="cond1">

   <z:elseif condition="cond2">

   <z:elseif condition="cond3">


</z:if >

<z:foreach></z: foreach> Generates foreach loop statement.. It has the following form:

<z:foreach type="int" var="x" in="obj">

You can omit the type attribute so var will be used to infer the variable type.

<z:for></z: for> Generates for loop statement.. It has two different forms:

  1. VB.NET alike form:
<z:for type="Integer" i="0" to="10" step="2">

If you omit the type attribute, var will be used. If you omit the step attribute, step="1" is assumed.

  1. C# alike form:
<z:for type="int" i="0" while="i < 9" let="i++">

You can omit the type attribute so var will be used to infer the variable type. You can also omit the let attribute so let="i++" is assumed in the last example.

<z:while></z:while>: It has the form:

<z:while [condition="cond"]>

<z:exit />, <z:break /> and <z:continue />: Use thes tags inside loops. Both <z:exit />, <z:break /> generate the break statement. <z:continue /> generates the continue statement. Note that you can control which loop to exit or continue. To do that, add the label attribute in the loop tag with a unique name, and use this name in the label attribute in the exit, break or continue tags. Ex:

<z:for c="0" to="10" label="for1">
    <z:declare i="0"/>
    <z:while condition="i<=10">
        <z:set i="@i+1"/>
        <z:if condition="i = c">
            <z:continue label="for1"/>

The trick here is that the label="for1" attribute will generate two labels in C# code:

  1. continue_for1: label, added as the last line in the loop body, so jumping to this label will escape the current iteration and continues the next one.
  2. break_for1: label, added at the first line after loop closing bracket, so jumping to this label will break the loop.

Now, when you use the this label in break or exit tags, this generates a goto break_for1 statement, and if you use it in continue tag, it generates a goto continue_for1 statement. This is the generated code from last sample:

"@for (var c = 0; c < 10 + 1; c++) {
  var i = 0;
  while (i<=10) {
    i = i+1;
    if (i == c) {
      goto continue_for1;

<z:invoke> </z:invoke> generates expressions for getting properties, indexers and method return values. In simple cases like @x.Trim(), you don't need to use this tag it can be useful when the method has complex params. For example:

<z:invoke method="Foo">
      <z:lambda x.type="Integer" y.type="Integer" return="x + y"/>

which will generate: @Foo(3, "Adam", (int x, int y) => x + y) To use another method return value as a param, you can use nested invokes directly, or inside arg tags. You can also have named args, by using the name attribute of the arg tag, such as: <z:arg name="required">false</z:arg> which will generate the argument: required: false

<z:lambda m>m.Name</z: lambda> Generates the lambda expression m => m.Name that can be used inside invoke, declare or set tags. You can use the return attribute to set the labda return value, or you can set it as the content of the lambda tag so that you can use another invokes or lambdas. For simplicity use: 'Fn(x as Integer) ⇒ x+1 or 'Fn(int x) => x+1. Ex: '@Html.DisplayNameFor(Fn(m) ⇒ m.RememberMachine)And here is a zml example of declaring a lambda delegate:<z:declare f="Fn(x) ⇒ x + 1"/>This will generate@{ f = x ⇒ x + 1; }in C#. Note that if you want to use theFn(x) ⇒ x + 1as a string, you should enclose it with double single qutes (' then ' on both ends), like this:<z:declare f="''Use this lambda: Fn(x) ⇒ x + 1''"/>This will generate the textUse this lambda: Fn(x) ⇒ x + 1` in the cshtml file.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.2 493 4/28/2019