Jinja2с ++
การใช้งาน C ++ การใช้งานเครื่องยนต์เทมเพลต Jinja2 Python ไลบรารีนี้นำการสนับสนุนของคุณลักษณะเทมเพลต Jinja2 ที่ทรงพลังในโลก C ++ รายงานหน้า HTML แบบไดนามิกและการสร้างซอร์สโค้ด
การแนะนำ
คุณสมบัติหลักของ jinja2c ++:
- อินเทอร์เฟซสาธารณะที่ใช้งานง่าย เพียงแค่โหลดเทมเพลตและแสดงผล
- เป็นไปตามข้อกำหนดของ Jinja2
- สนับสนุนอย่างเต็มรูปแบบของสตริงแคบและกว้างทั้งสำหรับเทมเพลตและพารามิเตอร์
- การสะท้อนในตัวสำหรับประเภท C ++ ทั่วไป, ห้องสมุด Nlohmann และ Rapid JSON
- นิพจน์ jinja2 ที่มีประสิทธิภาพเต็มรูปแบบพร้อมการกรอง (ผ่าน '|' ตัวดำเนินการ) และ 'if'-expressions
- คำสั่งควบคุม (
set for , if , filter , do , with ) - ส่วนขยายเทมเพลตรวมถึงและการนำเข้า
- มาโคร
- การรายงานข้อผิดพลาดมากมาย
- สภาพแวดล้อมเทมเพลตที่ใช้ร่วมกันพร้อมการสนับสนุนแคชเทมเพลต
ตัวอย่างเช่นรหัสง่าย ๆ นี้:
# include < jinja2cpp/template.h >
std::string source = R"(
{{ ("Hello", 'world') | join }}!!!
{{ ("Hello", 'world') | join(', ') }}!!!
{{ ("Hello", 'world') | join(d = '; ') }}!!!
{{ ("Hello", 'world') | join(d = '; ') | lower }}!!!
)" ;
Template tpl;
tpl.Load(source);
std::string result = tpl.RenderAsString({}).value(); สร้างสตริงผลลัพธ์:
Helloworld!!!
Hello, world!!!
Hello; world!!!
hello; world!!!
เริ่มต้น
หากต้องการใช้ Jinja2c ++ ในโครงการของคุณคุณต้อง:
- โคลนที่เก็บ jinja2c ++
- สร้างตามคำแนะนำ
- ลิงก์ไปยังโครงการของคุณ
การใช้ Jinja2c ++ ในรหัสนั้นค่อนข้างง่าย:
- ประกาศวัตถุเทมเพลต jinja2 :::
- เติมด้วยเทมเพลต:
tpl.Load( " {{ 'Hello World' }}!!! " );- แสดงเทมเพลต:
std::cout << tpl.RenderAsString({}).value() << std::endl; และได้รับ:
Hello World!!!
นั่นคือทั้งหมด!
ตัวอย่างรายละเอียดเพิ่มเติมและคุณสมบัติคำอธิบายสามารถพบได้ในเอกสารประกอบ: https://jinja2cpp.github.io/docs/usage
การสนับสนุน Jinja2 ปัจจุบัน
ปัจจุบัน Jinja2c ++ รองรับคุณสมบัติจำนวน จำกัด ของคุณสมบัติ Jinja2 โดยวิธีการที่ Jinja2c ++ มีการวางแผนว่าจะเป็นข้อกำหนด Jinja2 ที่สอดคล้องกันอย่างเต็มที่ การสนับสนุนในปัจจุบันถูก จำกัด ไว้ที่:
- การแสดงออก คุณสามารถใช้เกือบทุกรูปแบบการแสดงออก: ง่ายกรองเงื่อนไขและอื่น ๆ
- ตัวกรองจำนวนมาก ( เรียงลำดับ, ค่าเริ่มต้น, ครั้งแรก, สุดท้าย, ความยาว, สูงสุด, นาที, ย้อนกลับ, ไม่ซ้ำกัน, ผลรวม, attr, แผนที่, ปฏิเสธ, ปฏิเสธ, เลือก, Selectattr, pprint, dictsort, abs, ลอย, int, urlencm
- จำนวนผู้ทดสอบจำนวนมาก ( Eq, กำหนด, GE, GT, ITERABLE, LE, LT, การทำแผนที่, NE, จำนวน, ลำดับ, สตริง, ไม่ได้กำหนด, ใน, แม้กระทั่ง, คี่, ต่ำกว่า, บน )
- จำนวนฟังก์ชั่น ( ช่วง , loop.cycle )
- 'if' คำสั่ง (ด้วย 'Elif' และ 'Else' Branches)
- 'สำหรับ' คำสั่ง (ด้วย 'อื่น' สาขาและ 'if' สนับสนุนส่วน)
- คำสั่ง 'รวม'
- คำสั่ง 'นำเข้า'/'จาก'
- คำสั่ง 'set' (ทั้งบรรทัดและบล็อก)
- คำสั่ง 'ตัวกรอง'
- คำสั่ง 'ขยาย'/'บล็อก'
- คำสั่ง 'มาโคร'/'การโทร'
- 'กับ' คำสั่ง
- คำสั่งส่วนขยาย 'ทำ'
- วนซ้ำ
- การควบคุมอวกาศและบล็อก 'raw'/'endraw'
ข้อมูลทั้งหมดเกี่ยวกับการสนับสนุนข้อกำหนด Jinja2 และตารางความเข้ากันได้สามารถดูได้ที่นี่: https://jinja2cpp.github.io/docs/j2_compatibility.html
คอมไพเลอร์ที่รองรับ
การรวบรวม JINJA2C ++ ทดสอบบนคอมไพเลอร์ต่อไปนี้ (ด้วยคุณสมบัติที่เปิดใช้งาน C ++ 14 และ C ++ 17):
- Linux GCC 5.5 - 9.0
- Linux Clang 5.0 - 9
- MacOS X-Code 9
- macos x-code 10
- MacOS X-Code 11 (C ++ 14 ในการสร้างเริ่มต้น C ++ 17 พร้อม Boost ที่จัดเตรียมไว้ภายนอก)
- Microsoft Visual Studio 2015 - 2019 x86, x64
- Mingw GCC Compiler 7.3
- Mingw GCC Compiler 8.1
หมายเหตุ: การสนับสนุนเวอร์ชัน GCC> = 9.x หรือรุ่น Clang> = 8.0 ขึ้นอยู่กับเวอร์ชันของไลบรารี Boost ที่มีให้
สร้างสถานะ
| ผู้ประกอบการ | สถานะ |
|---|
| MSVC 2015 (x86, x64), Mingw 7 (x64), Mingw 8 (x64) | |
| X-Code 9, 10, 11 | |
| MSVC 2017 (x86, x64), MSVC 2019 (x86, x64), C ++ 14/C ++ 17 | |
| G ++ 5, 6, 7, 8, 9, 10, 11 Clang 5, 6, 7, 8, 9, 10, 11, 12 C ++ 14/C ++ 17/C ++ 20 | |
สร้างและติดตั้ง
Jinja2c ++ มีการพึ่งพาภายนอกหลายประการ:
-
boost Library (อย่างน้อยเวอร์ชัน 1.65) -
nonstd::expected-lite https://github.com/martinmoene/expected-lite -
nonstd::variant-lite https://github.com/martinmoene/variant-lite -
nonstd::optional-lite https://github.com/martinmoene/optional-lite -
nonstd::string-view-lite https://github.com/martinmoene/string-view-lite -
fmtlib::fmt https://github.com/fmtlib/fmt
ตัวอย่างของการสร้างสคริปต์และการกำหนดค่าการสร้างที่แตกต่างกันสามารถพบได้ที่นี่: https://github.com/jinja2cpp/examples-build
ในกรณีที่ง่ายที่สุดในการรวบรวม jinja2c ++ ที่คุณต้องการ:
- ติดตั้งระบบสร้าง CMake (อย่างน้อยเวอร์ชัน 3.0)
- โคลน jinja2cpp repository:
> git clone https://github.com/flexferrum/Jinja2Cpp.git
- สร้าง Build Directory:
> cd Jinja2Cpp
> mkdir build
- เรียกใช้ cmake และสร้างห้องสมุด:
> cd build
> cmake .. -DCMAKE_INSTALL_PREFIX=<path to install folder>
> cmake --build . --target all
"Path to Install Folder" นี่คือเส้นทางไปยังโฟลเดอร์ที่คุณต้องการติดตั้ง jinja2c ++ lib
- ติดตั้งไลบรารี:
> cmake --build . --target install
ในกรณีนี้ Jinja2c ++ จะถูกสร้างขึ้นด้วยการพึ่งพาภายในและติดตั้งตามลำดับ แต่ jinja2c ++ รองรับการสร้างด้วย deps ที่จัดเตรียมไว้ภายนอก
การใช้งานกับผู้จัดการการพึ่งพา conan.io
Jinja2c ++ สามารถใช้เป็นแพ็คเกจ Conan.io ในกรณีนี้คุณควรทำตามขั้นตอนต่อไปนี้:
- ติดตั้ง conan.io ตามเอกสาร (https://docs.conan.io/en/latest/installation.html)
- เพิ่มการอ้างอิงไปยังแพ็คเกจ jinja2c ++ (
jinja2cpp/1.2.1 ) ลงใน conanfile.txt, conanfile.py หรือ cmakelists.txt ตัวอย่างเช่นด้วยการใช้การรวมของ conan-cmake มันสามารถเขียนได้ด้วยวิธีนี้:
cmake_minimum_required ( VERSION 3.24)
project (Jinja2CppSampleConan CXX)
list ( APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} )
list ( APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} )
add_definitions ( "-std=c++14" )
if ( NOT EXISTS " ${CMAKE_BINARY_DIR} /conan.cmake" )
message ( STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan" )
file (DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/0.18.1/conan.cmake"
" ${CMAKE_BINARY_DIR} /conan.cmake"
TLS_VERIFY ON )
endif ()
include ( ${CMAKE_BINARY_DIR} /conan.cmake)
conan_cmake_autodetect(settings)
conan_cmake_run(REQUIRES
jinja2cpp/1.1.0
gtest/1.14.0
BASIC_SETUP
${CONAN_SETTINGS}
OPTIONS
jinja2cpp/*:shared= False
gtest/*:shared= False
BUILD missing)
set (TARGET_NAME jinja2cpp_build_test)
add_executable ( ${TARGET_NAME} main.cpp)
target_link_libraries ( ${TARGET_NAME} ${CONAN_LIBS} )
set_target_properties ( ${TARGET_NAME} PROPERTIES
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON )
CMake Build Flags เพิ่มเติม
คุณสามารถกำหนด (ผ่านตัวเลือก CMAKE บรรทัดคำสั่งผ่านคำสั่ง) ธงบิลด์ต่อไปนี้:
- jinja2cpp_build_tests (ค่าเริ่มต้นจริง) - เพื่อสร้างหรือไม่เพื่อการทดสอบ Jinja2c ++
- jinja2cpp_strict_warnings (ค่าเริ่มต้นจริง) -เปิดใช้งานการรวบรวมโหมดที่เข้มงวด (-wall -werror ฯลฯ )
- jinja2cpp_msvc_runtime_type (ค่าเริ่มต้น /MD) - ประเภทรันไทม์ MSVC เพื่อเชื่อมโยงด้วย (ถ้าคุณใช้คอมไพเลอร์ Microsoft Visual Studio)
- jinja2cpp_deps_mode (ค่าเริ่มต้น "ภายใน") - โหมดสำหรับการจัดการการพึ่งพา ค่าต่อไปนี้เป็นไปได้:
-
internal ในโหมดนี้ jinja2c ++ บิลด์สคริปต์ใช้การพึ่งพาการพึ่งพา (รวม boost ) จัดส่งเป็นโครงการย่อย ไม่จำเป็นต้องจัดเตรียมไว้ภายนอก -
external-boost ในโหมดนี้สคริปต์ Jinja2c ++ Build ใช้ boost เฉพาะการขึ้นอยู่กับการพึ่งพาจากภายนอก การพึ่งพาอื่น ๆ ทั้งหมดมาจากโครงการย่อย -
external ในโหมดนี้ควรมีการพึ่งพาทั้งหมดภายนอก เส้นทางที่จะ boost , nonstd-* libs, ฯลฯ ควรระบุผ่านตัวแปร cmake มาตรฐาน (เช่น CMAKE_PREFIX_PATH หรือ libname_dir) - โหมดพิเศษ
conan-build สำหรับการสร้าง JINJA2C ++ ผ่านสูตร Conan
สร้างด้วยมาตรฐาน C ++ 17 ที่เปิดใช้งาน
JINJA2C ++ พยายามใช้รุ่นมาตรฐานของ std::variant , std::string_view และ std::optional ถ้าเป็นไปได้
กิตติกรรมประกาศ
ขอบคุณ @flexferrum สำหรับการสร้างห้องสมุดนี้สำหรับการเป็นหนึ่งในจิตใจที่สว่างที่สุดในชุมชนวิศวกรรมซอฟต์แวร์ พักผ่อนอย่างสงบเพื่อน
ขอบคุณ @Manu343726 สำหรับการปรับปรุงสคริปต์ CMake การล่าแมลงและการแก้ไขและบรรจุภัณฑ์ Conan.io
ขอบคุณ @martinmoene สำหรับไลบรารี XXX-Lite ที่ใช้งานได้อย่างสมบูรณ์แบบ
ขอบคุณ @vitaut สำหรับไลบรารีการจัดรูปแบบข้อความที่น่าทึ่ง
ขอบคุณ @martinus สำหรับการใช้งานแผนที่แฮชอย่างรวดเร็ว
การเปลี่ยนแปลง
เวอร์ชัน 1.3.2
มีอะไรเปลี่ยนแปลง
- แก้ไขการแยกวิเคราะห์ตัวอักษรที่ว่างเปล่าใน #243
- แก้ไขการป้องกันความโกรธชีวิตที่หายไปสำหรับตัวกรองย้อนกลับ (และอื่น ๆ ) โดย @jferreyra-sc ใน #246
- ความสามารถในการปิดใช้งานกฎการติดตั้ง Jinjacpp โดย @ilya-lavrenov ใน #250
- cmake พบเฉพาะ Rapidjson ที่ดาวน์โหลดโดย @ilya-lavrenov ใน #254
- อัปเดตการเพิ่มการพึ่งพาโดย @CheaterDev ใน #253
ผู้มีส่วนร่วมใหม่
- @jferreyra-sc บริจาคครั้งแรกใน #246
- @Ilya-Lavrenov ได้บริจาคครั้งแรกใน #250
- @CheaterDev บริจาคครั้งแรกใน #253
เวอร์ชัน 1.3.1
การเปลี่ยนแปลงและการปรับปรุง
- Bump deps เวอร์ชัน
- เพิ่ม JSON ใหม่ที่มีผลผูกพัน - Boost :: JSON
- Speedup Regex Parsing โดยการเปลี่ยนเป็น Boost :: regex (std :: regex ช้ามาก)
แก้ไขข้อบกพร่อง
- การแก้ไขขนาดเล็กข้ามฐานรหัส
ทำลายการเปลี่ยนแปลง
- ตอนนี้ deps ภายในใช้ผ่าน cmake fetch_content
- ค่าเริ่มต้น JSON Serializer/Deserializer ถูกเปลี่ยนเป็น Boost :: JSON
เวอร์ชัน 1.2.1
การเปลี่ยนแปลงและการปรับปรุง
- Bump deps เวอร์ชัน
- รองรับคอมไพเลอร์ที่ทันสมัย (สูงถึง 12) และมาตรฐาน (C ++ 20)
- การล้างรูปแบบรหัสเล็ก ๆ
แก้ไขข้อบกพร่อง
- การแก้ไขขนาดเล็กข้ามฐานรหัส
ทำลายการเปลี่ยนแปลง
- deps ภายในชี้เพื่อสร้างการสร้างตามพื้นฐาน
เวอร์ชัน 1.1.0
การเปลี่ยนแปลงและการปรับปรุง
- เพิ่มตัวกรอง
batch - เพิ่มตัวกรอง
slice - เพิ่มตัวกรอง
format - เพิ่มตัวกรอง
tojson - เพิ่มตัวกรอง
striptags - เพิ่มตัวกรอง
center - เพิ่มตัวกรอง
xmlattr - เพิ่มแท็ก
raw / endraw - เพิ่มตัวดำเนินการสตริงซ้ำ (เช่น
'a' * 5 จะผลิต 'aaaaa' ) - เพิ่ม Metadata เทมเพลต (
meta / endmeta Tags) -
-fPIC Flag เพิ่มไปยังการกำหนดค่า Linux Build
แก้ไขข้อบกพร่อง
- แก้ไขพฤติกรรมของการตั้งค่าทั่วโลก LSTRIPBLOCK/TRIMBLOCKS ตอนนี้มันสอดคล้องกับ Origina Jinja2 อย่างเต็มที่
- แก้ไขข้อผิดพลาดด้วยการแสดงเนื้อหา
block หลักหากเด็กไม่ได้แทนที่บล็อกนี้ - แก้ไขปัญหาการรวบรวมด้วย callables ที่ผู้ใช้กำหนดด้วยจำนวนอาร์กิวเมนต์มากกว่า 2
- แก้ไขการเข้าถึงฟังก์ชั่น Jinja2 ทั่วโลกจากเทมเพลตที่รวม/ขยาย
- จุดแก้ไขของการประเมินผลของมาโคร
- แก้ไขการวนรอบสายสตริง
- คำเตือนการทำความสะอาด
ทำลายการเปลี่ยนแปลง
- จากนี้ด้วย C ++ 17 มาตรฐานที่เปิดใช้งาน Jinja2c ++ ใช้ตัวแปรประเภท
variant , string_view และ optional มาตรฐาน
เวอร์ชัน 1.0.0
การเปลี่ยนแปลงและการปรับปรุง
- แอตทริบิวต์
default เพิ่มลงในตัวกรอง map (#48) - การรองรับ Sepace Sequences เพิ่มลงในตัวอักษรสตริง (#49)
- ช่วงตามอำเภอใจลำดับที่สร้างขึ้นอินพุตตัววนซ้ำ ฯลฯ ตอนนี้สามารถใช้กับประเภท
GenericList (#66) - nonstd :: string_view ตอนนี้เป็นหนึ่งในประเภทที่เป็นไปได้สำหรับ
Value - การสนับสนุนแท็ก
filter เพิ่มลงในตัวแยกวิเคราะห์เทมเพลต (#44) - การสนับสนุนตัวกรอง
escape เพิ่มลงในตัวแยกวิเคราะห์เทมเพลต (#140) -
capitalize การสนับสนุนตัวกรองที่เพิ่มลงในตัวแยกวิเคราะห์เทมเพลต (#137) - แท็ก
set หลายรุ่นเพิ่มลงในตัวแยกวิเคราะห์ (#45) - เพิ่มการสะท้อนในตัวสำหรับห้องสมุด Nlohmann Json และ Rapidjson (#78)
- การสนับสนุนตัวแปร
loop.depth และ loop.depth0 เพิ่มการสนับสนุน - {fmt} ใช้เป็นไลบรารีการจัดรูปแบบแทน iostreams
- แผนที่ Robin Hood Hash ใช้สำหรับที่เก็บค่าภายใน
- การปรับปรุงประสิทธิภาพการทำงาน
- แคชเทมเพลตที่ใช้ใน
TemplateEnv - callables ที่ผู้ใช้กำหนดตอนนี้สามารถยอมรับบริบททั่วโลกผ่าน
*context พิเศษพารามิเตอร์ - Mingw, Clang> = 7.0, xcode> = 9, gcc> = 7.0 ได้รับการสนับสนุนอย่างเป็นทางการในฐานะคอมไพเลอร์เป้าหมาย (#79)
แก้ไขข้อบกพร่อง
- คงที่ PIPE (
| ) ความสำคัญของโอเปอเรเตอร์ (#47) - แก้ไขข้อผิดพลาดในตัวแปลงภายใน char <-> wchar_t บน windows
- แก้ไขความผิดพลาดในแท็กการแยกวิเคราะห์
endblock - การควบคุมขอบเขตคงที่สำหรับ
include และ for แท็ก - แก้ไขข้อผิดพลาดด้วยการเรียกแมโครภายในบริบทนิพจน์
ทำลายการเปลี่ยนแปลง
- ตอนนี้ประเภทรันไทม์ MSVC ถูกกำหนดโดยตัวแปร
JINJA2CPP_MSVC_RUNTIME_TYPE cmake cmake
เวอร์ชัน 0.9.2
การเปลี่ยนแปลงที่สำคัญ
- callables ที่ผู้ใช้กำหนดใช้งาน ตอนนี้คุณสามารถกำหนดวัตถุที่เรียกได้ของคุณเองส่งผ่านเป็นพารามิเตอร์อินพุตและใช้ภายในเทมเพลตเป็นฟังก์ชั่นปกติ (ทั่วโลก) ตัวกรองหรือผู้ทดสอบ ดูรายละเอียดที่นี่: https://jinja2cpp.github.io/docs/usage/ud_callables.html
- ตอนนี้คุณสามารถกำหนดพารามิเตอร์ทั่วโลก (สภาพแวดล้อมทั่วทั้งเทมเพลต) ที่สามารถเข้าถึงได้สำหรับเทมเพลตทั้งหมดที่ผูกกับสภาพแวดล้อมนี้
-
include import และ from ข้อความที่นำมาใช้ ตอนนี้เป็นไปได้ที่จะรวมเทมเพลตอื่น ๆ และใช้มาโครจากเทมเพลตอื่น ๆ -
with คำสั่งที่นำไปใช้ -
do งบที่ใช้งาน - ตัวอย่างโครงการสร้างสำหรับตัวแปรการใช้งาน jinja2c ++ ต่างๆที่สร้างขึ้น: https://github.com/jinja2cpp/examples-build เหมือน
- ไซต์เอกสารที่สร้างขึ้นสำหรับ jinja2c ++: https://jinja2cpp.github.io
การเปลี่ยนแปลงเล็กน้อย
- เพิ่มการจัดการข้อผิดพลาดเวลาในการแสดงผล
- โหมดการจัดการการพึ่งพาเพิ่มในสคริปต์บิลด์
- แก้ไขข้อบกพร่องที่มีการรายงานข้อผิดพลาดในช่วงเวลาที่แยกวิเคราะห์
- อัพเกรดเวอร์ชันการพึ่งพาภายนอก
ทำลายการเปลี่ยนแปลง
- วิธี
RenderAsString จะส่งคืน nonstd::expected จะแทนที่จะเป็น std::string ปกติ - เทมเพลตที่มี
import extends และ include การสร้างข้อผิดพลาดหากแยกวิเคราะห์โดยไม่ต้องตั้งค่า TemplateEnv - การเปิดตัวชุดข้อมูล (คลังเก็บ) ได้รับการกำหนดค่าด้วยโหมดการจัดการการพึ่งพา
external โดยค่าเริ่มต้น
เวอร์ชัน 0.9.1
- เพิ่มตัวกรอง
applymacro ซึ่งอนุญาตให้ใช้แมโครโดยพลการเป็นตัวกรอง - การพึ่งพาเพื่อเพิ่มการลบออกจากส่วนต่อประสานสาธารณะ
- สคริปต์ CMake ดีขึ้น
- ข้อบกพร่องต่าง ๆ คงที่
- ปรับปรุงการไตร่ตรอง
- คำเตือนการล้างข้อมูล
เวอร์ชัน 0.9
- สนับสนุนคำสั่ง 'extents'/'block'
- สนับสนุนคำสั่ง 'Macro'/'Call'
- การรายงานข้อผิดพลาดมากมาย
- สนับสนุนลูปแบบเรียกซ้ำ
- รองรับการควบคุมอวกาศก่อนและหลังบล็อกควบคุม
- ปรับปรุงการไตร่ตรอง
เวอร์ชัน 0.6
- มีการใช้ตัวกรองจำนวนมาก ชุดตัวกรองที่รองรับเต็มรูปแบบที่ระบุไว้ที่นี่: #7
- มีการทดสอบจำนวนมาก ชุดทดสอบที่รองรับเต็มรูปแบบที่ระบุไว้ที่นี่: #8
- 'concatenate เป็นสตริง' ตัวดำเนินการ ('~') ได้ถูกนำไปใช้
- สำหรับลูปด้วยเงื่อนไข 'if' ได้ถูกนำไปใช้
- แก้ไขข้อบกพร่องบางอย่างในตัวแยกวิเคราะห์