Giter Site home page Giter Site logo

botika / yarte Goto Github PK

View Code? Open in Web Editor NEW
279.0 10.0 15.0 3.52 MB

Yarte stands for Yet Another Rusty Template Engine

Home Page: https://yarte.netlify.com

License: Apache License 2.0

Rust 86.35% HTML 2.73% Handlebars 10.92%
rust template-engine handlebars

yarte's Introduction


Yet Another Rust Template Engine

Yarte Latest version Netlify Status

Yarte stands for Yet Another Rusty Template Engine. Uses a Handlebars-like syntax, well-known and intuitive for most developers. Yarte is an optimized, and easy-to-use rust crate, with which developers can create logic around their HTML templates using conditionals, loops, rust code and template composition.



Documentation

In order to fully understand Yarte's capabilities take a look at the following documentation:

Or, in nightly, just:

#[yarte] "{{> my_template }}"

bytes-buf feature can produce SIGILL. More details in zzau13/v_escape#54.

Yarte is under development.

Is it really fast?

Run cargo bench with rust nightly.

Results in my AMD Ryzen 9 5900HX

Teams                   time:   [62.335 ns 62.704 ns 63.138 ns]
Big table               time:   [28.546 µs 28.690 µs 28.873 µs]

See it for yourself in the TechEmpower benchmarks with actix and ntex

Acknowledgment

Yarte is based on all previous templates engines, syntax as well as its documentation is highly influenced by Handlebars. Logo adapted from Creative Commons images

Code of conduct

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4

License

This project is distributed under the terms of both the Apache License (Version 2.0) and the MIT license, specified in LICENSE-APACHE and LICENSE-MIT respectively.

yarte's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar focureneb avatar himanshu007-creator avatar renovate[bot] avatar zzau13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yarte's Issues

Yarte hir & HTML5 front end

Refactor html5ever tokenizer and tree builder sink for accept yarte_hir::HIR at input and yarte_dom::DOM at output
Remove ugly HIR -> string -> Sink adapter
Adapter for html5libs-test coverage
Forbidden dynamic class builder <{{ }}> since it does not match the static type and is easily reproducible with a fabric pattern with conditionals.
In the case of attribute names, only conditionals with static ends will be allowed, will collect names and values in boolean.

It shouldn't be too complicated to redo html5ever to make this possible, if anyone gets excited!

#37

Migrate prettyprint to bat

For new projects, you might want to use bat instead, which can be used as a library now. prettyprint is in maintenance mode now, which means it will not see any major updates anymore, but pull requests will still be reviewed and dependencies will be kept up-to-date for the time being. You might want consider migrating away, though.

https://github.com/sharkdp/bat

Why do abstractions have a cost?

I don't know of any 'no cost' framework.
IT energy consumption is skyrocketing and it is the beginning, but the industry adds superfluous costs.

Is it really necessary? My answer is no. By typing and metaprogramming it is possible to build a framework at no cost in runtime.

It's really already being done in low-level implementations.

The web and mobile are working under abstractions with a cost that in most cases is enormous. If we multiply by the number of executions the useless expense created by the profit of a few who control the distribution markets is totally idiotic. In these cases javascript and java seem to be the kings, in the realm of planetary entropy.

With a quick search we see that in Javascript the consumption of finite resources (second principle of thermodynamics) to do absolutely the same. But consumption soars in the case of WASM.

https://timkadlec.com/remembers/2020-04-21-the-cost-of-javascript-frameworks/

Actually, the only idea to try in yarte is how to create abstractions without entailing a much higher cost than the raw implementation.

It's a draft, I will continue it

RFC Async/await functionality over `bytes::BytesMut`

The only idea is to eliminate intermediate allocations in asynchronous streams.
It is indifferent to accumulate in an intermediate buffer than directly on the output buffer. bytes::BytesMut is a lock free shared memory making it perfect for this experiment.

Consume serialize

Like yarte do, but need implement for owned and borrowed values. And redo implementations of Serialize for T and &T (collections use drain, ...)

Runtime-provided templates

I currently have a use-case where users should be able to provide the template and I just fill it in during runtime and generate the resulting text. Is this possible with yarte? All examples show that you have to specify the path to the template, but in my case this is not possible.

Web render interface on top of gfx-hal

There are many implementations of web renders at runtime. Taking with it a large amount of functionality that is not used at all times. It is totally normal when the content is not known before compiling.
Taking advantage of Rust, you can implement a web render with enormous granularity, adding at compile time the strictly necessary modules.
For this, the script system is eliminated, forcing all the logic to be known at compilation time, replacing it by a messaging system ensuring that the number of different behaviors is finite.

For this implementation you do not have to reinvent anything, just put together well-worked concepts over time. So the current implementations should be reused for much of the code or at least take them as a reference

Components and extension

Design of modularity

The developers should have a way to pack their implementations and reuse them.
Partials are very primitive tool, therefore, this feature consist of an extension of the existing one because this isn't complete enough to be able to reuse all their implementations with yarte.

Abstract

  • New children element component under control of an app or another component
  • Nested messages (without nested dispatch)
  • Unique reference to the component cell (?Sync + ?Send)
  • Demultiplexer app state
  • Module bundle integrated in the rust compiler tools (like webpack, if it is with plugins it would be nice)
  • Incremental compilation through IR
  • Component Lifetime integrated in the same message queue

Most difficult it's types solver. Possible solutions without modifying rustc:

  • Schema
  • components in separated crates and build scripts
  • Standard types and rudimentary component types resolution

Draft of generated code

/// Component definition
// struct ComState { props: String }

struct MyAppState {
    component_prop: String,
}

// In derive of App
struct MyAppBB {
    component: MyComDOM,
}

struct MyApp {
    /// Component only exist in template
    state: MyAppState,
    bb: MyAppBB,
}

// In derive of the App
impl App for MyApp {
    fn dispatch(&mut self) {
        let MyApp { state, bb } = self;
        do_something(&mut MyComState { state }, bb);
        do_something2(&mut MyComState { state }, bb);
    }
}

// In derive
trait ComStateI {
    fn get_prop_mut(&mut self) -> &mut String;
    fn get_prop(&self) -> &String;
}

/// Wrapper around App unique reference for demultiplexer state
// In derive of the App
struct MyComState<'a> {
    state: &'a mut MyAppState,
}

/// Virtual DOM references
// In derive
struct MyComDOM {
    some: String,
}

// In derive of the App
impl<'a> ComStateI for MyComState<'a> {
    fn get_prop_mut(&mut self) -> &mut String {
        &mut self.state.component_prop
    }

    fn get_prop(&self) -> &String {
        &self.state.component_prop
    }
}

// In derive
trait ComDOMI {
    fn get_bb(&mut self) -> &mut MyComDOM;
    fn set_change_at_prop(&mut self);
}

// In derive of the App
impl ComDOMI for MyAppBB {
    fn get_bb(&mut self) -> &mut MyComDOM {
        &mut self.component
    }

    fn set_change_at_prop(&mut self) {}
}

trait App: Sized {
    fn dispatch(&mut self);
}

fn do_something<S: ComStateI, V: ComDOMI>(state: &mut S, dom: &mut V) {
    let MyComDOM { some } = dom.get_bb();
    some.push_str(state.get_prop());
}

fn do_something2<S: ComStateI, V: ComDOMI>(state: &mut S, dom: &mut V) {
    state.get_prop_mut().push_str("foo");
    dom.set_change_at_prop();
}

There are several limitations when integrating the yarte language in rust language. First and foremost, we do not have types in the proc_macro environment. Therefore type resolution is somewhat rudimentary.

I clarify that the structures of the components will be formed only by unique references. Later specification with a DSL to the kind of component (for example Forms Components).

It can certainly be understood as a series of embedded DSL over rust

Mininizer html

  • DOM
  • serialize
  • coverage
  • replace assured in favor of mode attribute
  • throw error when html comment

`char` type is not escaped

description

When char type is passed to template, it is not escaped.

Example

Template:

<h1>{{ content }}</h1>

Rust code:

use yarte::Template;

#[derive(Template)]
#[template(path = "example.hbs")]
struct Example {
    content: char
}

fn main() {
    let template = Example { content: '<' };
    println!("{}", template.call().unwrap());
}

Output:

<h1><</h1>

Improve error output

Remove all panics! (it's possible) and collect in ErrorMessage for beautiful output

  • yarte_hir
  • yarte_parser
  • Debug annotate snippets dependency. In certain cases the label does not appear
  • source-map
  • Improve message (parser and lowering)

proc-macro2 doesn't get span at proc-macro crate

It is not possible to have a source map using syn since proc-macro2 uses rustc and it does not know about templates.

The only way to have a source map is to use something else that doesn't use proc-macro2 for the lexer.

Compile time CSSOM implementation

  • parse
  • canonize
  • optimize
  • compile on DOM structure for with render envioroments
  • compile to DOM interface on Hardware Abstraction Layer

Code print can alloc too big

When compile example with code logger activated, returns:

not memory allocation of 8391155392347897856 bytes failed

Some components of logger have a bug. Not use in 0.11.0 and previous and rustc 1.46.0-nightly (6bb3dbfc6 2020-06-22) previous. In nightly works well.

Write to fixed allocation

Everything goes much faster if there is no possibility of realloc. New trait and derive for write &[u8] to &mut [u8] safely.

@fafhrd91 Can you tell me what you think of this solution?

Add to Fixed traits `ccall` method

In order to avoid references, refactor RenderSafe and RenderFixed so that they can make proper use of the auto deref and not reference the types that implement Copy trait. Add ccall method for consume Template and render it for Fixed traits.

Allow code to build when .html template has been changed.

Hi, thank you for the awesome crate!

I am having a little problem, when I change a template (.html) and rebuild the project those changes don't take effect, they only change when I build the .rs file where the template struct has been declared.

Allow html Comments when using html-min

I'm getting a yarte (feature=["html-min"]) error for

<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

obviously this html comment is more than a simple html comment and should therefore work.
error I'm getting:
"No use html comment, use yarte comments instead"

Edit: Mentioning html-min feature

In derive shared cache for serialize nested

I really don't know if it is possible, since the order is not confirmed. But you can try saving an intermediate representation of each structure in a static Rwlock and something for synchronize . If it works it can be implemented to modularize yarte.

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.