C++ html template

Inja是现代C ++的模板引擎,受到jinja for python的启发。它有一个简单而强大的模板语法,包含所有变量,循环,条件,包含,回调,您需要的注释,嵌套和组合,如您所愿。Inja使用nlohmann 的精彩json库进行数据输入和处理。最重要的是,inja只需要两个头文件,这几乎与C ++中的集成一样简单。

下载地址:https://github.com/pantor/inja

教程

模板渲染

使用 json 对象渲染 std::string 字符串模板

json data;
data["name"] = "world"; render("Hello {{ name }}!", data); // Returns std::string "Hello world!"
render_to(std::cout, "Hello {{ name }}!", data); // Prints "Hello world!"

使用环境对象读取本地模板进行渲染

Environment env;

// Render a string with json data
std::string result = env.render("Hello {{ name }}!", data); // "Hello world!" // Or directly read a template file
Template temp = env.parse_template("./templates/greeting.txt");
std::string result = env.render(temp, data); // "Hello world!" data["name"] = "Inja";
std::string result = env.render(temp, data); // "Hello Inja!" // Or read the template file (and/or the json file) directly from the environment
result = env.render_file("./templates/greeting.txt", data);
result = env.render_file_with_json_file("./templates/greeting.txt", "./data.json"); // Or write a rendered template file
env.write(temp, data, "./result.txt");
env.write_with_json_file("./templates/greeting.txt", "./data.json", "./result.txt");

可以根据您的需要配置环境类

// With default settings
Environment env_default; // With global path to template files and where files will be saved
Environment env_1 {"../path/templates/"}; // With separate input and output path
Environment env_2 {"../path/templates/", "../path/results/"}; // Choose between dot notation (like Jinja2) and JSON pointer to access elements
env.set_element_notation(ElementNotation::Dot); // (default) e.g. time.start
env.set_element_notation(ElementNotation::Pointer); // e.g. time/start // With other opening and closing strings (here the defaults)
env.set_expression("{{", "}}"); // Expressions
env.set_comment("{#", "#}"); // Comments
env.set_statement("{%", "%}"); // Statements {% %} for many things, see below
env.set_line_statement("##"); // Line statements ## (just an opener)

变量

变量在 {{...}} 表达式中呈现。

json data;
data["neighbour"] = "Peter";
data["guests"] = {"Jeff", "Tom", "Patrick"};
data["time"]["start"] = 16;
data["time"]["end"] = 22; // Indexing in array
render("{{ guests.1 }}", data); // "Tom" // Objects
render("{{ time.start }} to {{ time.end }}pm", data); // "16 to 22pm"

声明

可以使用 {%...%} 语法或整个行的##语法编写语句。

最重要的语句是循环,条件和文件包含。

所有语句都可以嵌套。

循环

// Combining loops and line statements
render(R"(Guest List:
## for guest in guests
{{ loop.index1 }}: {{ guest }}
## endfor )", data) /* Guest List:
1: Jeff
2: Tom
3: Patrick */

在循环中,定义了特殊变量loop / index(number)loop / index1(number)loop / is_first(boolean)loop / is_last(boolean)

在嵌套循环中,父循环变量是可用的,例如,通过 loop/parent/index 。您还可以迭代{%for key,value in time%}等对象。

条件

条件语句支持 ifelse ifelse 语句。

// Standard comparisons with variable
render("{% if time.hour >= 18 %}…{% endif %}", data); // True // Variable in list
render("{% if neighbour in guests %}…{% endif %}", data); // True // Logical operations
render("{% if guest_count < 5 and all_tired %}…{% endif %}", data); // True // Negations
render("{% if not guest_count %}…{% endif %}", data); // True

嵌套

你可以包含其他模板文件或已解析的模板。

// Other template files are included relative from the current file location
render({% include "footer.html" %}, data); // To include in-memory templates, add them to the environment first
env.include_template("footer", temp);
render({% include "footer" %}, data);

函数

在实现 inja 模板语法的过程中,我们实现了一些内置常用函数。

// Upper and lower function, for string cases
render("Hello {{ upper(neighbour) }}!", data); // "Hello PETER!"
render("Hello {{ lower(neighbour) }}!", data); // "Hello peter!" // Range function, useful for loops
render("{% for i in range(4) %}{{ loop.index1 }}{% endfor %}", data); // "1234"
render("{% for i in range(3) %}{{ at(guests, i) }} {% endfor %}", data); // "Jeff Tom Patrick " // Length function (please don't combine with range, use list directly...)
render("I count {{ length(guests) }} guests.", data); // "I count 3 guests." // Get first and last element in a list
render("{{ first(guests) }} was first.", data); // "Jeff was first."
render("{{ last(guests) }} was last.", data); // "Patir was last." // Sort a list
render("{{ sort([3,2,1]) }}", data); // "[1,2,3]"
render("{{ sort(guests) }}", data); // "[\"Jeff\", \"Patrick\", \"Tom\"]" // Round numbers to a given precision
render("{{ round(3.1415, 0) }}", data); // 3
render("{{ round(3.1415, 3) }}", data); // 3.142 // Check if a value is odd, even or divisible by a number
render("{{ odd(42) }}", data); // false
render("{{ even(42) }}", data); // true
render("{{ divisibleBy(42, 7) }}", data); // true // Maximum and minimum values from a list
render("{{ max([1, 2, 3]) }}", data); // 3
render("{{ min([-2.4, -1.2, 4.5]) }}", data); // -2.4 // Convert strings to numbers
render("{{ int(\"2\") == 2 }}", data); // true
render("{{ float(\"1.8\") > 2 }}", data); // false // Set default values if variables are not defined
render("Hello {{ default(neighbour, \"my friend\") }}!", data); // "Hello Peter!"
render("Hello {{ default(colleague, \"my friend\") }}!", data); // "Hello my friend!" // Check if a key exists in an object
render("{{ exists(\"guests\") }}", data); // "true"
render("{{ exists(\"city\") }}", data); // "false"
render("{{ existsIn(time, \"start\") }}", data); // "true"
render("{{ existsIn(time, neighbour) }}", data); // "false" // Check if a key is a specific type
render("{{ isString(neighbour) }}", data); // "true"
render("{{ isArray(guests) }}", data); // "true"
// Implemented type checks: isArray, isBoolean, isFloat, isInteger, isNumber, isObject, isString,

回调函数

您可以使用回调创建自己的更复杂的函数。

函数定义如下:

  • 函数名称
  • 参数数量
  • 函数实现
Environment env;

/*
* Callbacks are defined by its:
* - name
* - number of arguments
* - callback function. Implemented with std::function, you can for example use lambdas.
*/
env.add_callback("double", 1, [](Arguments& args) {
int number = args.at(0)->get<int>(); // Adapt the index and type of the argument
return 2 * number;
}); // You can then use a callback like a regular function
env.render("{{ double(16) }}", data); // "32" // A callback without argument can be used like a dynamic variable:
std::string greet = "Hello";
env.add_callback("double-greetings", 0, [greet](Arguments args) {
return greet + " " + greet + "!";
});
env.render("{{ double-greetings }}", data); // "Hello Hello!"

注释

可以使用 {#...#} 语法编写注释

render("Hello{# Todo #}!", data); // "Hello!"

支持的编译器

Inja使用string_view从C ++ 17,但包括填充工具从martinmoene。这样,最低版本是C ++ 11。目前,以下编译器已经经过测试:

  • GCC 5.0 - 8.0
  • Clang 5.0 - 6.0
  • Microsoft Visual C++ 2015 - 2017

如何使用 C++ Inja html template 模板的更多相关文章

  1. angularjs指令系统系列课程(2):优先级priority,模板template,模板页templateUrl

    今天我们先对 priority,template,templateUrl进行学习 1.priority 可取值:int 作用:优先级 一般priority默认为0,数值越大,优先级越高.当一个dom元 ...

  2. ArcGIS API for Silverlight代码中使用Template模板

    原文:ArcGIS API for Silverlight代码中使用Template模板 在项目开发中,会遇到点选中聚焦闪烁效果,但是因为在使用Symbol的时候,会设置一定的OffSetX和OffS ...

  3. Git commit template 模板设定

    多人协作开发一个项目时,版本控制工具是少不了的,git是linux 内核开发时引入的一个优秀代码管理工具,利用它能很好使团队协作完成一个项目.为了规范团队的代码提交,也方便出版本时的release n ...

  4. 一个简单地template模板

    之前的项目中用到了artTemplate模板,感觉挺有意思,于是查看相关资料,自己动手写了个简单地template模板插件.虽然会有一些不足,但也是自己的一番心血.主体代码如下 /* * 一个简单地t ...

  5. 小程序开发--template模板

    小程序的template模板可以说是我遇到的最简单的了,看看实例: <template name="article"> <view class='containe ...

  6. Vue 组件&组件之间的通信 之 template模板引用与动态组件的使用

    template模板引用 在component的template中书写大量的HTML元素很麻烦. Vue提供了<template>标签,可以在里边书写HTML,然后通过ID指定到组建内的t ...

  7. 微信小程序template模板与component组件的区别和使用

    前言: 除了component,微信小程序中还有另一种组件化你的方式template模板,这两者之间的区别是,template主要是展示,方法则需要在调用的页面中定义.而component组件则有自己 ...

  8. 微信小程序新闻列表功能(读取文件、template模板使用)

    微信小程序新闻列表功能(读取文件.template) 不忘初心,方得始终.初心易得,始终难守. 在之前的项目基础上进行修改,实现读取文件内容作为新闻内容进行展示. 首先,修改 post.wxml 文件 ...

  9. spring框架学习(六)AOP事务及spring管理事务方式之Template模板

    概念 1.事务 1)事务特性:ACID 原子性 :强调事务的不可分割. 一致性 :事务的执行的前后数据的完整性保持一致. 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰. 持久性 :事务一旦 ...

随机推荐

  1. 通用的规则匹配算法(原创)(java+.net)

    1.java里可以使用Spring的 Spel或者Google的Aviator 如果使用 Aviator 则添加以下依赖 <dependency> <groupId>com.g ...

  2. No enclosing instance of type TestGson is accessible. Must qualify the allocation with an enclosing instance of type TestGson (e.g. x.new A() where x is an instance of TestGson).

    main方法中实例化内部类报错: public class TestGson { public static void main(String[] args) { Gson gson=new Gson ...

  3. Kettle解析JSON错误,We MUST have the same number of values for all paths,We can not find and data with path [$.

    最近公司要从聚石塔上抽取数据,其中有JSON格式数据,所以学习一下Kettle解析JSON,碰到小小问题,记录一下: (1) 2015/07/15 15:22:48 - trade_detail.0 ...

  4. 报错——selinux配置文件修改错误导致无法启动虚拟机

    selinux配置文件修改错误导致无法启动虚拟机 问题 错误修改配置文件 [root@centos73 ~]# cat /etc/selinux/config # This file controls ...

  5. 接口参数校验之@Valid与BindingResult

    接口方法往往需要对入参做一些校验,从而判断入参是否合格,而javax.validation包为我们提供了一些常用的参数校验注解,使用起来很方便. 下面这个示例是检验入参对象中的password是否为空 ...

  6. Angular JS - 7 - Angular JS 常用指令2

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. FS,FT,DFS,DTFT,DFT,FFT的联系和区别 数字信号处理

    DCT变换的原理及算法 文库介绍 对于初学数字信号处理(DSP)的人来说,这几种变换是最为头疼的,它们是数字信号处理的理论基础,贯穿整个信号的处理. 学习过<高等数学>和<信号与系统 ...

  8. BZOJ 1818: [Cqoi2010]内部白点(树状数组)

    传送门 解题思路 首先一定不可能有\(-1\)的情况,因为新产生的黑点不会造成任何贡献,它的各个方面都是不优的.那么只需要统计一遍答案,首先要将横坐标相同的两个点看成一条竖线,纵坐标相同的点看成一条横 ...

  9. 自动收集有效IP代理

    自动收集有效IP代理 #需要的外部依赖包requests和lxml#自动获取的代理ip数据保存为”IP代理池.txt“#read_ip函数用于提取”IP代理池.txt“的数据返回类型为列表from l ...

  10. No orientation specified, and the default is horizontal.异常处理(转)

    参考:http://blog.csdn.net/sky_monkey/article/details/21466975 整的错误提示信息为: No orientation specified, and ...