Mustache text templates for modern C++

Overview

About

  • Mustache implementation for modern C++ (requires C++11)
  • Header only
  • Zero dependencies
  • Templated string type for compatibility with any STL-like string (std::string, std::wstring, etc)
  • Boost license

travis appveyor ghe codecov

Example usage

All examples assume using namespace kainjow::mustache. Additional examples and usage can be found in the tests.cpp file.

Example 1 - Hello World

mustache tmpl{"Hello {{what}}!"};
std::cout << tmpl.render({"what", "World"}) << std::endl;
// Hello World!

Example 2 - Lists

mustache tmpl{"{{#employees}}{{name}}, {{/employees}}"};
data employees{data::type::list};
employees << data{"name", "Steve"} << data{"name", "Bill"};
tmpl.render({"employees", employees}, std::cout);
// Steve, Bill,

Example 3 - Custom Render Handler

mustache tmpl("Hello {{what}}!");
std::stringstream ss;
tmpl.render({"what", "World"}, [&ss](const std::string& str) {
    ss << str;
});
// ss.str() == "Hello World!"

Supported Features

This library supports all current Mustache features:

  • Variables
  • HTML escaping
  • Sections
  • Inverted Sections
  • True/False
  • Lists
  • Lambdas
  • Partials
  • Comments
  • Set Delimiter

Additional features:

  • Custom escape function for use outside of HTML
Issues
  • Standalone lines should be removed from the template

    Standalone lines should be removed from the template

    As far as I can tell, this implementation doesn't follow the Mustache spec when it comes to trimming lines that only contain tags (and whitespace).

    Any reason why you're not testing against the official spec tests?

    bug 
    opened by mihe 22
  • Consider allowing defining a custom Context for providing values on-demand

    Consider allowing defining a custom Context for providing values on-demand

    In my case it would be far more convenient to use an existing function for looking up the values of variables embedded in Mustache templates, but this doesn't currently possible and all variables and partials need to be defined beforehand. This is especially annoying for the latter, as partials are basically just files, so they need to be read from disk and provided as part of the data, even if they end up not being used at all by the current template.

    So I'd basically like to be able to provide my own Context and override its get() method. I realize that it's not completely trivial because it would need to be refactored to separate push/pop() and get() methods, but it would be nice to be able to do this.

    enhancement 
    opened by vadz 15
  • Request method to initialize with alternate delimiters

    Request method to initialize with alternate delimiters

    I think it would be particularly useful if there was a way to set what the tag delimiters were on the mustache object directly.

    Example:

    mustache tmpl{"Hello <%%what%%>!"};
    
    tmpl.set_delimiters("<%% %%>");
    std::cout << tmpl.render({"what", "World"}) << std::endl;
    
    
    opened by derekbsnider 9
  • build(cmake): improve cmake for header only lib

    build(cmake): improve cmake for header only lib

    this MR improves the usage of this library in the context of a cmake based project.

    this MR adds the needed patches to install the header file as well as cmake files which can be used to do find_package by consumer projects

    opened by gocarlos 7
  • Lambda Renderer Incorrectly

    Lambda Renderer Incorrectly "grabs" Text Ahead of the Lambda Tag

    Take the following example:

     kainjow::mustache::mustache tmpl{
     "It is true that {{#wrapped}}{{name}} is awesome.{{/wrapped}}"};
    
     kainjow::mustache::data data;
     data["name"] = "Willy";
     data["wrapped"] = kainjow::mustache::lambda2{
     [](const std::string& text, const kainjow::mustache::renderer& render) {
        const auto renderedText = render(text);
        return "<b>" + renderedText + "</b>";
      }};
    

    Here, we'd expect the output of rendering the template to be: "It is true that <b>Willy is awesome.</b>"

    Instead we get: "<b>It is true that Willy is awesome.</b>"

    What's also interesting is that the pre-lambda text is only rendered for the first time render is called within the lambda:

    kainjow::mustache::data data;
    data["name"] = "Willy";
    data["wrapped"] = kainjow::mustache::lambda2{
      [](const std::string& text, const kainjow::mustache::renderer& render) {
       const auto& pre_lambda_text = render("");
        const auto& renderedText = render(text);
        return pre_lambda_text + "`<b>`" + renderedText + "`</b>`";
      }};
    

    The above actually produces the output we desire, but the issue is that the lambda should not capture text outside of the wrapping tags.

    bug 
    opened by hellochitty 6
  • Compile-time parsing

    Compile-time parsing

    I was wondering if your parsing is really compile-time? If not, then you may want to consider to use constexpr for example or other ways to make sure of it is since the mustache syntax won't change during runtime (obviously).

    You may also consider using the excellent and insanely fast header-only fmt lib (soon in C++20), that would be awesome then I won't have to convert strings all the time with my code. https://github.com/fmtlib/fmt

    Example of a compile-time regex lib: https://github.com/hanickadot/compile-time-regular-expressions

    question 
    opened by patlecat 5
  • Parser chokes on open tags without close

    Parser chokes on open tags without close

    If the template contains dangling open tags, there will be no output (note, this works with https://github.com/no1msd/mstch).

    Example:

    int main()
    {
        mustache tmpl{"Hello {{what}}! {{"};
    
        std::cout << "Rendered: " << tmpl.render({"what", "there"}) << std::endl;
    
        return 0;
    }
    

    Output: Rendered:

    Expected: Rendered: Hello there! {{

    opened by derekbsnider 4
  • Add a version define/const in hpp.

    Add a version define/const in hpp.

    It would be nice to have a mustache version available in the code. (It is currently present in the comments but it is not easy to use/parse).

    Something like #define MUSTACHE_VERSION "4.1"

    It would allow build script to check the mustache version at configure step. For example, using meson syntax (not tested) :

    compiler = meson.get_compiler('cpp')
    if not compiler.check_header('mustache.hpp')
      error("Cannot find mustache")
    endif
    result = compiler.run("#include <iostream>\n#include <mustache.hpp>\nint main() { std::cout << MUSTACHE_VERSION << std::endl; }")
    mustache_version = result.stdout()
    if not mustache_version.version_compare(">=4.1")
      error("Mustache is too old")
    endif
    
    opened by mgautierfr 4
  • More modern CMake and cleanup

    More modern CMake and cleanup

    Hi! I made those changes on my own fork and you might be interested.

    • I'm using more modern CMake when possible. This reduce CMake code to write when using Mustache and CMake, just have to specify Mustache as dependency and the correct directory should be known and C++17 is enabled as well.
    • I renamed the executable generated by the test target to make it obvious this executable is a test.
    opened by IohannRabeson 4
  • Help with reading partials

    Help with reading partials

    I'm trying to use the {{>filename}} mustache syntax but it always results in a blank in the generated output. Reading the test code in this repository I seem to understand that I need to register all the filenames beforehand, for example:

        dat["filename"] = partial([](){
            std::ifstream all_data("filename.mstch");
            all_data >> std::noskipws;
            return std::string(
                std::istream_iterator<uint8_t>(all_data),
                std::istream_iterator<uint8_t>()
            );
        };
    

    While it's fine with me to provide such a function, I don't see how I could foresee all the possible filenames the end user could come up with. How can I deal with the generic case of users wanting to do {{>filename}} one day and {{>donaldduck}} the next?

    question 
    opened by KingDuckZ 4
  • "make install" does not work

    make install does not work.

    https://github.com/kiwix/kiwix-lib/ says

    Just copy the header mustache.hpp somewhere it can be found by the compiler and/or set CPPFLAGS with correct '-I' option

    but I find that much more complicated than just running make install and be done with it.

    enhancement 
    opened by probonopd 4
  • basic_data could be a std::variant

    basic_data could be a std::variant

    Is there a reason (other than the project being designed for older C++ versions) that basic_data isn't std::variant or at least implemented a bit like std::variant? Why so many unique_ptrs laying around?

    private:
        type type_;
        std::unique_ptr<basic_object<string_type>> obj_;
        std::unique_ptr<string_type> str_;
        std::unique_ptr<basic_list<string_type>> list_;
        std::unique_ptr<basic_partial<string_type>> partial_;
        std::unique_ptr<basic_lambda_t<string_type>> lambda_;
    
    
    opened by the-moisrex 1
Releases(v4.1)
Owner
Kevin Wojniak
Kevin Wojniak
Library for writing text-based user interfaces

IMPORTANT This library is no longer maintained. It's pretty small if you have a big project that relies on it, just maintain it yourself. Or look for

null 1.9k Jun 18, 2022
The libxo library allows an application to generate text, XML, JSON, and HTML output using a common set of function calls. The application decides at run time which output style should be produced.

libxo libxo - A Library for Generating Text, XML, JSON, and HTML Output The libxo library allows an application to generate text, XML, JSON, and HTML

Juniper Networks 240 Jun 13, 2022
Rich text library supporting customizable Markdown formatting

Rich text library supporting customizable Markdown formatting

Brace Yourself Games 76 Jun 12, 2022
Read Non-Rectangular Text Data

meltr The goal of ‘meltr’ is to provide a fast and friendly way to read non-rectangular data (like ragged forms of ‘csv’, ‘tsv’, and ‘fwf’). Standard

R infrastructure 25 May 3, 2022
A library to automatically generate a text based interface for programs and libraries.

Introduction Auto Menu is an open-source library to automatically generate a text based interface for your programs and libraries. Installation Clone

Soumya Ranjan Patnaik 7 Oct 31, 2021
A c++ file just to show how can we change color of Background and Text in C++...

A c++ file just to show how can we change color of Background and Text in C++...

null 1 Nov 2, 2021
The lightweight and modern Map SDK for Android and iOS

Open Mobile Maps The lightweight and modern Map SDK for Android (6.0+) and iOS (10+) openmobilemaps.io Getting started Readme Android Readme iOS Featu

Open Mobile Maps 90 Jun 13, 2022
An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples

rootkit-arsenal-guacamole An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples All projects have been por

Matteo Malvica 44 Apr 12, 2022
A Template Engine for Modern C++

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, lo

pantor 1.1k Jun 18, 2022
Pretty Printer for Modern C++

Highlights Single header file Requires C++17 MIT License Quick Start Simply include pprint.hpp and you're good to go. #include <pprint.hpp> To start p

Pranav 863 Jun 25, 2022
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Microsoft 6.9k Jun 22, 2022
LibOS is a modern C++17 library that makes OS-specific features cross-platform.

LibOS is a modern C++17 library that makes OS-specific features cross-platform. Ever tried to get Windows version after Windows 8? Or to send ke

Gavrilikhin Daniil 27 Jun 15, 2022
A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation.

mp-units - A Units Library for C++ The mp-units library is the subject of ISO standardization for C++23/26. More on this can be found in ISO C++ paper

Mateusz Pusz 603 Jun 24, 2022
The most powerful and customizable binary pattern scanner written on modern C++

Sig The most powerful and customizable binary pattern scanner written on modern C++ ✔ Capabilities: Support for all common pattern formats: Pattern +

Александр 132 Jun 11, 2022
A modern compile-time reflection library for C++ with support for overloads, templates, attributes and proxies

refl-cpp v0.12.1 Documentation refl-cpp encodes type metadata in the type system to allow compile-time reflection via constexpr and template metaprogr

Veselin Karaganev 658 Jun 23, 2022
📚 C++ Templates 2ed 笔记:C++11/14/17 模板技术

?? C++ Templates 2ed 笔记:C++11/14/17 模板技术

null 1.1k Jun 28, 2022
Templates, algorithms and data structures implemented and collected for programming contests.

Templates, algorithms and data structures implemented and collected for programming contests.

Shahjalal Shohag 1.8k Jun 27, 2022
Basic jam templates using Handmade libraries to get up and running quickly.

This is a selection of template projects to get up and running with for the Wheel Reinvention Jam. They are built on top of Handmade-inspired librarie

Handmade Network 13 Jun 19, 2022
URI Templates expansion and reverse-matching for C++

URI-template This library implements URI Template with full support up to Level 4 providing expansion and match capabilities. It requires c++17 compil

Tinkoff.ru 7 Jan 21, 2022
Variadic recursive expression templates which look like ordinary (possibly nested) containers.

Variadic resursive expressions with lazy evaluation which look like nested containers LazyExpression is a header-only library written in C++17. It imp

null 9 Jan 6, 2022
Blazing-fast Expression Templates Library (ETL) with GPU support, in C++

Expression Templates Library (ETL) 1.3.0 ETL is a header only library for C++ that provides vector and matrix classes with support for Expression Temp

Baptiste Wicht 201 Jun 4, 2022
C++ intrusive container templates. Abstract node links, no use of new/delete.

C-plus-plus-intrusive-container-templates C++ intrusive container templates. Abstract node links, no use of new/delete (AVL tree, singly-linked list,

Walt Karas 11 Feb 10, 2022
Concise CMake templates for creating C++ libraries or executables.

cmake_templates Concise cmake templates for creating C++ libraries and executables. Creating a normal cmake project Copy the chosen project template s

Ali Can Demiralp 109 Apr 28, 2022
010 Editor binary templates to open some newer Eurocom/EngineX formats.

gforce-tools 010 Editor binary templates to open some newer Eurocom/EngineX formats. https://sphinxandthecursedmummy.fandom.com/wiki/EngineX The Filel

Swyter 2 May 5, 2022
This is my very own text editor inspired by the kilo text editor

Xenon-text-editor This is my very own text editor inspired by the kilo text editor which you can find here: https://github.com/snaptoken/kilo-src/blob

Arin 15 Aug 28, 2021
Typewriter Effect with Rich Text + *Correct* Text Wrapping

Typewriter Effect with Rich Text + Correct Text Wrapping I've spent way too long getting this right. This is meant as a base class for a UMG dialogue

Sam Bloomberg 24 May 27, 2022
Text - A spicy text library for C++ that has the explicit goal of enabling the entire ecosystem to share in proper forward progress towards a bright Unicode future.

ztd.text Because if text works well in two of the most popular systems programming languages, the entire world over can start to benefit properly. Thi

Shepherd's Oasis 195 Jun 8, 2022
Lingo - Text encoding for modern C++

Lingo Lingo is an encoding aware string library for C++11 and up. It aims to be a drop in replacement for the standard library strings by defining new

Rick de Water 28 Nov 21, 2021
A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support.

Turbo Vision A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support. I

null 1.3k Jun 24, 2022