Inja
是現代C ++
的模板引擎,受到jinja for python
的啓發。它有一個簡單而強大的模板語法,包含全部變量,循環,條件,包含,回調,您須要的註釋,嵌套和組合,如您所願。Inja
使用nlohmann
的精彩json
庫進行數據輸入和處理。最重要的是,inja
只須要兩個頭文件,這幾乎與C ++
中的集成同樣簡單。html
下載地址:https://github.com/pantor/injapython
使用 json
對象渲染 std::string
字符串模板git
json data; data["name"] = "world"; render("Hello {{ name }}!", data); // Returns std::string "Hello world!" render_to(std::cout, "Hello {{ name }}!", data); // Prints "Hello world!"
使用環境對象讀取本地模板進行渲染github
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");
能夠根據您的須要配置環境類express
// 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
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%}
等對象。工具
條件語句支持 if
、else if
、else
語句。oop
// 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。目前,如下編譯器已經通過測試: