Code Monkey home page Code Monkey logo

zmpl's Introduction

Zmpl logo

Zmpl is a templating language for Zig 🦎

  • Use Zig code directly in templates for control flow.
  • Simple and intuitive DSL for building flexible, JSON-compatible data objects.
  • Compiles to Zig code for syntax and type validation.
  • Used by the Jetzig web framework.

Documentation

Visit the Jetzig Documentation page to see detailed Zmpl documentation with usage examples.

Syntax Highlighting

Syntax highlighters are currently community-sourced. Please get in touch if you have created a plugin for your editor of choice and we will gladly list it here.

  • VSCode by Zackary Housend
  • NeoVim syntax highlighting can be achieved by using the above VSCode grammar with the nvim-textmate plugin. You may need to use this fork if you have issues compiling the UTF-8 extension.

Example

See src/templates for more examples.

Template

<!-- Zig mode for template logic -->
@zig {
  if (std.mem.eql(u8, "zmpl is simple", "zmpl" ++ " is " ++ "simple")) {
    <span>Zmpl is simple!</span>
  }
}

<!-- Easy data lookup syntax -->
<div>Email: {{.user.email}}</div>
<div>Token: {{.auth.token}}</div>

<!-- Partials -->
@partial example_partial

<!-- Partials with positional args -->
@partial mailto(.user.email, "Welcome to Jetzig!")

<!-- Partials with keyword args --->
@partial mailto(email: .user.email, subject: "Welcome to Jetzig!")

<!-- Partials with slots --->
@partial mailto(email: .user.email, subject: "Welcome to Jetzig!") {
  <a href="https://example.com/auth/{{.auth.token}}">Sign in</a>
  <a href="https://example.com/unsubscribe/{{.auth.token}}">Unsubscribe</a>
}

@markdown {
  # Built-in markdown support

  * [jetzig.dev](https://www.jetzig.dev/)
}

mailto Partial

@args email: *ZmplValue, subject: []const u8
<a href="mailto:{{email}}?subject={{subject}}">{{email}}</a>

@zig {
    for (slots, 0..) |slot, slot_index| {
        <div class="slot-{{slot_index}}">{{slot}}</div>
    }
}

Output HTML

<!-- Zig mode for template logic -->
    <span>Zmpl is simple!</span>


<!-- Easy data lookup syntax -->
<div>Email: [email protected]</div>
<div>Token: abc123-456-def</div>

<!-- Partials -->
<span>An example partial</span>
<!-- Partials with positional args -->
<a href="mailto:[email protected]?subject=Welcome to Jetzig!">[email protected]</a>
<!-- Partials with keyword args --->
<a href="mailto:[email protected]?subject=Welcome to Jetzig!">[email protected]</a>
<!-- Partials with slots --->
<a href="mailto:[email protected]?subject=Welcome to Jetzig!">[email protected]</a>
        <div class="slot-0"><a href="https://example.com/auth/abc123-456-def">Sign in</a></div>
        <div class="slot-1"><a href="https://example.com/unsubscribe/abc123-456-def">Unsubscribe</a></div>

<div><h1>Built-in markdown support</h1>
<ul><li><a href="https://www.jetzig.dev/">jetzig.dev</a></li></ul></div>

Example Usage

Default template path is src/templates. Use -Dzmpl_templates_path=... to set an alternative (relative or absolute) path.

const std = @import("std");
const zmpl = @import("zmpl");

test "readme example" {
    var data = zmpl.Data.init(std.testing.allocator);
    defer data.deinit();

    var body = try data.object();
    var user = try data.object();
    var auth = try data.object();

    try user.put("email", data.string("[email protected]"));
    try auth.put("token", data.string("abc123-456-def"));

    try body.put("user", user);
    try body.put("auth", auth);

    if (zmpl.find("example")) |template| {
        const output = try template.render(&data);
        defer std.testing.allocator.free(output);

        try std.testing.expectEqualStrings(
            \\<!-- Zig mode for template logic -->
            \\    <span>Zmpl is simple!</span>
            \\
            \\
            \\<!-- Easy data lookup syntax -->
            \\<div>Email: [email protected]</div>
            \\<div>Token: abc123-456-def</div>
            \\
            \\<!-- Partials -->
            \\<span>An example partial</span>
            \\<!-- Partials with positional args -->
            \\<a href="mailto:[email protected]?subject=Welcome to Jetzig!">[email protected]</a>
            \\<!-- Partials with keyword args --->
            \\<a href="mailto:[email protected]?subject=Welcome to Jetzig!">[email protected]</a>
            \\<!-- Partials with slots --->
            \\<a href="mailto:[email protected]?subject=Welcome to Jetzig!">[email protected]</a>
            \\        <div class="slot-0"><a href="https://example.com/auth/abc123-456-def">Sign in</a></div>
            \\        <div class="slot-1"><a href="https://example.com/unsubscribe/abc123-456-def">Unsubscribe</a></div>
            \\
            \\<div><h1>Built-in markdown support</h1>
            \\<ul><li><a href="https://www.jetzig.dev/">jetzig.dev</a></li></ul></div>
        , output);
    } else {
        try std.testing.expect(false);
    }
}

License

MIT

Credits

Templ - inspiration for template layout.

zmpl's People

Contributors

bobf avatar deecellar avatar dannyjjk avatar stephenafamo avatar btipling avatar

Stargazers

Leo Shimonaka avatar Arya Bakhtiari avatar  avatar Michael B. avatar Ross Davidson avatar Noël Mugnier avatar Virak avatar Nelson avatar sbhamad avatar huaxk avatar  avatar Enver Bisevac avatar Brad Pillow avatar  avatar Najib Muhammad avatar  avatar Manu avatar 0x4a61636f62 avatar Edwin avatar thomas avatar Javier Dominguez II avatar Alve Larsson avatar Adhe avatar Piotr Wera avatar Daniil Zuev avatar Hoang Phan avatar  avatar Yuan Huang avatar Gabriel Celis avatar Tim avatar Julien Bisconti avatar  avatar  avatar Randell Callahan avatar sibkit avatar Arne Bahlo avatar Jens van de Wiel avatar Uli Troyo avatar HeDui avatar  avatar 16hournaps avatar Noam avatar  avatar Alvaro avatar  avatar leonidas avatar redaready avatar Ashish Acharya avatar Denis Denisov avatar  avatar Slava avatar hsnmkls avatar  avatar Ethan Holz avatar Patrick Smith avatar  avatar Alejandro avatar Greg Wedow avatar vitalspace avatar Matías Cartes avatar Seth Vincent avatar astrolemonade avatar xiusin avatar Matthew Winter avatar Malcolm Still avatar  avatar  avatar  avatar Govind avatar Zikani Nyirenda Mwase avatar  avatar  avatar elijah avatar  avatar Lee Cannon avatar Guido Schmidt avatar Kamil Shakirov avatar  avatar Andrew Chou avatar Jan Ph. H. avatar Ali Cheraghi avatar

Watchers

 avatar  avatar

zmpl's Issues

Markdown in zmpl

Having markdown directly in zmpl files may lead to greater flexibility in its interaction with zig.

Multiline HTML with brackets raises Zmpl.SynaxError

The following code will give the Zmpl.SyntaxError "Error resolving braces" when placed in a .zmpl file.

<style>
#myHeader {
  background-color: lightblue;
  color: black;
  padding: 40px;
  text-align: center;
}
</style>

I can condense it into one line and it works fine, although requiring everything be condensed into one line seems like it could be a problem (specifically with JavaScript)

HTML in markdown

Sometimes it is not enough makrdown features. E.g. I need to insert <video> in markdown that will be server from public folder.
And inserting html directly is valid for GitHub or VisuaStudio Code (preview)
I want to have /src/views/some/some.md.zmpl:

# Some cool movie title

## Subheader

<video width="320" height="240" controls>
  <source src="./robocop_parking.mp4" type="video/mp4">
</video>

Above works in GitHub or VisuaStudio Code but does not work in zmpl.
Is this implemented/supported?

I got following in browser response:

<p class='p-3'>&lt;video width="320" height="240" controls&gt;</p><p class='p-3'>  &lt;source src="./robocop_parking.mp4" type="video/mp4"&gt;</p><p class='p-3'>&lt;/video&gt;</p>

Multiline tailwind code not supported

  1. icreate the simple project with jetzig
  2. run by using the zig build run, and it compiled as below
    yes
  3. but when break the code in to multiple line it throw error as below
    no

-- i'm using the windwo os 11.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.