All Projects → jcfromsiberia → Redzone

jcfromsiberia / Redzone

Licence: bsd-2-clause
Lightweight C++ template engine with Jinja2-like syntax

Projects that are alternatives of or similar to Redzone

Jinja2cpp
Jinja2 C++ (and for C++) almost full-conformance template engine implementation
Stars: ✭ 257 (+756.67%)
Mutual labels:  template-engine, jinja2
Jingoo
OCaml template engine almost compatible with jinja2
Stars: ✭ 86 (+186.67%)
Mutual labels:  template-engine, jinja2
Jinja
A very fast and expressive template engine.
Stars: ✭ 8,170 (+27133.33%)
Mutual labels:  template-engine, jinja2
jinja.dart
Jinja2 template engine port for Dart.
Stars: ✭ 38 (+26.67%)
Mutual labels:  template-engine, jinja2
liquidpy
A port of liquid template engine for python
Stars: ✭ 49 (+63.33%)
Mutual labels:  template-engine, jinja2
templatel
Jinja inspired template language for Emacs Lisp
Stars: ✭ 46 (+53.33%)
Mutual labels:  template-engine, jinja2
Tera
A template engine for Rust based on Jinja2/Django
Stars: ✭ 1,873 (+6143.33%)
Mutual labels:  template-engine, jinja2
voldemort
A simple static site generator using Jinja2 and Markdown templates.
Stars: ✭ 48 (+60%)
Mutual labels:  template-engine, jinja2
Cookie
A Template-based File Generator. Like cookiecutter but works with file templates instead of project templates.
Stars: ✭ 261 (+770%)
Mutual labels:  template-engine, jinja2
Xtd forms
Modern c++17 library to create native gui for Microsoft Windows, Apple macOS and Linux.
Stars: ✭ 25 (-16.67%)
Mutual labels:  native
Originr
Species origin data from the web in R
Stars: ✭ 13 (-56.67%)
Mutual labels:  native
React email editor
This project is experimental! It's my attempt to create visual email template editor using React+Redux+etc... tools stack.
Stars: ✭ 19 (-36.67%)
Mutual labels:  template-engine
React Native Geolocation Service
React native geolocation service for iOS and android
Stars: ✭ 934 (+3013.33%)
Mutual labels:  native
Easytemplatejs
小巧,纯粹,高性能的 JavaScript 模板引擎,支持浏览器, Node.js, Express, koa。Small, pure, high-performance JavaScript template engine, support Browser, Node.js, Express, Koa.
Stars: ✭ 14 (-53.33%)
Mutual labels:  template-engine
Spring Velocity Support
An support project of legacy velocity based on Spring Framework
Stars: ✭ 22 (-26.67%)
Mutual labels:  template-engine
Ti.splashview
💦 Support for the splash-screen library CBZSplashView in Appcelerator Titanium.
Stars: ✭ 20 (-33.33%)
Mutual labels:  native
Crisscross
A Markdown-centric template engine for batch offline document generation.
Stars: ✭ 18 (-40%)
Mutual labels:  template-engine
Hamlit
High Performance Haml Implementation
Stars: ✭ 898 (+2893.33%)
Mutual labels:  template-engine
Imgui
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
Stars: ✭ 33,574 (+111813.33%)
Mutual labels:  native
Ninjadog
Pug/Jinja template support for Python.
Stars: ✭ 20 (-33.33%)
Mutual labels:  jinja2

RedZone

RedZone is a lightweight C++ template engine with Jinja2-like syntax support. Inspired by microtemplates. This is the starting point for other languanges extensions (e.g. Python). Data exchange is provided via JSON protocol.

Build

To build RedZone library you should have installed GCC 4.9 as well as CMake tool. Execute this shell script:

$ git clone https://github.com/jcfromsiberia/RedZone && cd RedZone && mkdir build && cd build && cmake .. && make

Building Python extension

You'll need the same tools with Python dev package and Cython. Use -DBUILD_LANG_EXTENSION=python flag for cmake command:

$ cmake -DBUILD_LANG_EXTENSION=python .. && make

You'll find built RedZone.so python module in the build dir.

How to use?

There are equivalent examples for C++ and Python.

Link RedZone library to your application or library and use these following classes inside:

RedZone::Writer

This is an abstract class for output. It has only two pure virtual methods

  • void write( std::string const & data )
  • void flush()

There are obly two classes which implement this abstract class:

RedZone::FileWriter

Writes string data to file on disk. Constructor accepts a path to output file.

RedZone::FileWriter writer( "/tmp/out.html" );
RedZone::StringWriter

Writes string data to in-memory string. Constructor accepts a reference to certain string.

std::string out;
RedZone::FileWriter writer( out );

RedZone::Template and its derived ones

There is only one working class RedZone::FileTemplate to load a template from filesystem by path for the time being.

RedZone::FileTemplate tpl( "/tmp/test.tpl" );

This code creates reads file contents from the given path (e.g. /tmp/test.tpl), parses it and then creates a new RedZone::Template instance.

json11::Json

RedZone uses JSON protocol for storing the rendering context. To implement JSON protocol, I have used json11.

json11::Json json( json11::Json::parse( R"(
      {                                               
         "items": [                                   
           { "text": "Hello World!", "active": true },
           { "text": "Foo", "active": true },         
           { "text": "Bar", "active": false }         
         ],
         "numbers": {
            "first": 5,
            "second": 11,
            "third": true
         }  
      }                                               
       )", err ) );

RedZone::Context

Rendering context accepts json object-type instances only. You can not pass arrays or something else. RedZone::Template classes have render method to render the template with user context into a stream represented as pointer to Writer isntance.

RedZone::Context context( json ); 
tpl.renderToStream( &writer, &context);
context.setJson( anotherJson );

Also they have render method, which returns complete rendered output. It uses StringWriter inside.

std::string rendered = tpl.render( &context );

RedZone supports a primitive code evaluation support. It supports main expression operations like:

  1. math expressions;
  2. function calls;
  3. string operations;
  4. comparison operations.

You can use them in variable blocks; as bool condition in 'if' block; as container expression in for block.

So, having this markup in /tmp/test.tpl:

{% for item in items %}
    {% if item.active && length(item.text) == 3 %}
	<div class="active">{{ item.text }}</div>
    {% else  %}
	<div class="inactive">{{ item.text }}</div>
    {% endif  %}
{% endfor %}

// Testing expression parser
{{ "f" * 8 + "u" * 8 + "~" }} should be ffffffffuuuuuuuu~
{{upper("f"*8+"u"*8+"~")}} should be FFFFFFFFUUUUUUUU~
{{ sin( 0 )}} should be 0
{{ cos( 0 ) }} should be 1
{{ length( [] ) }} should be 0
{{ length( [ 2, 4, { "s": 55 } ] ) }} should be 3
{{ length( { "key1": "value1", "key2": "value2" } ) }} should be 2
{{ 16 / 4 }} should be 4
{{ get( { "key1": "value1", "key2": "value2" }, "key2" ) }} should be value2
{{ get( numbers, "first" ) }} should be 5
{{ get( numbers, "second" ) }} should be 11
{{ get( numbers, "third" ) }} should be true
{{ get( numbers, "foo" ) }} should be null
{{ ( 2 + 2 ) * (2 + 2) }} should be 16

{% cache 5000 "TestCache" items %}{{ random(20, 100500) }}{% endcache %} should be {% cache 5000 "TestCache" items %}{{ random(20, 100500) }}{% endcache %} cached

and the context which is represented above , we will get this output:


    
        <div class="inactive">Hello World!</div>
    

    
        <div class="active">Foo</div>
    

    
        <div class="inactive">Bar</div>
    


// Testing expression parser
ffffffffuuuuuuuu~ should be ffffffffuuuuuuuu~
FFFFFFFFUUUUUUUU~ should be FFFFFFFFUUUUUUUU~
0 should be 0
1 should be 1
0 should be 0
3 should be 3
2 should be 2
4 should be 4
value2 should be value2
5 should be 5
11 should be 11
true should be true
null should be null
16 should be 16

95199 should be 95199 cached

Detailed description

Functions

Function name Arguments Return value
sin val numeric (numeric) sine of val radians
cos val numeric (numeric) cosine of val radians
length val string or array or object (numeric) length value of val Json object
not val bool (bool) not val
get val string or array or object
key string or numeric
(any value or null) child item of val by key
lower val string (string) lowered val
upper val string (string) uppered val
random a numeric
b numeric
(numeric) random number value in range [a, b]

Binary operators

Operator Left value Right value Return value
+ lhs numeric rhs numeric (numeric) addition of lhs and rhs
+ lhs string rhs string (string) concatenated string of lhs and rhs
- lhs numeric rhs numeric (numeric) subtraction of rhs from lhs
* lhs numeric rhs numeric (numeric) multiplication of lhs and rhs
* lhs string rhs numeric (string) lhs string repeated rhs times
/ lhs numeric rhs numeric (numeric) division of lhs by rhs
> lhs any object rhs any object (bool) comparison of lhs > rhs. Calls json11::Json approperiate operator
< lhs any object rhs any object (bool) comparison of lhs < rhs. Calls json11::Json approperiate operator
== lhs any object rhs any object (bool) comparison of lhs == rhs. Calls json11::Json approperiate operator
!= lhs any object rhs any object (bool) comparison of lhs != rhs. Calls json11::Json approperiate operator
>= lhs any object rhs any object (bool) comparison of lhs >= rhs. Calls json11::Json approperiate operator
<= lhs any object rhs any object (bool) comparison of lhs <= rhs. Calls json11::Json approperiate operator
&& lhs any object rhs any object (bool) logical AND of lhs and rhs
|| lhs any object rhs any object (bool) logical OR of lhs and rhs

All operators are being executed in this order:

  1. *, /
  2. +, -
  3. , <, ==, !=, <=, >=

  4. &&, ||

In Python

Having built RedZone python module, you can use the above classes in your own Python scripts, excepting there is no Json class -- Python dict replaces it completely.

from RedZone import *

context = Context({                                               
"items": [                                   
      { "text": "Hello World!", "active": True },
      { "text": "Foo", "active": True },         
      { "text": "Bar", "active": False }         
],
"numbers": {
      "first": 5,
      "second": 11,
      "third": True
}
})
tpl = FileTemplate('test.tpl')

print tpl.render(context)

You get the same output.

In plans

  • extend template syntax with template inheritance done
  • make Cython extension to use RedZone from Python done
  • add install/setup scripts
  • add an ability to add custom functions in Python
  • add an ability to add custom tags in Python
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].