diff --git a/README.md b/README.md index 607eb35..47149ce 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,12 @@ env.add_callback("double-greetings", 0, [greet](Arguments args) { return greet + " " + greet + "!"; }); env.render("{{ double-greetings }}", data); // "Hello Hello!" + +// You can also add a callback without return variable, e.g. for debugging: +env.add_void_callback("log", 1, [greet](Arguments args) { + std::cout << "logging: " << args[0] << std::endl; +}); +env.render("{{ log(neighbour) }}", data); // Prints nothing to result, only to cout... ``` ### Comments diff --git a/include/inja/environment.hpp b/include/inja/environment.hpp index 791c3de..ebe7f74 100644 --- a/include/inja/environment.hpp +++ b/include/inja/environment.hpp @@ -173,7 +173,14 @@ public: @brief Adds a variadic callback */ void add_callback(const std::string &name, const CallbackFunction &callback) { - function_storage.add_callback(name, -1, callback); + add_callback(name, -1, callback); + } + + /*! + @brief Adds a variadic void callback + */ + void add_void_callback(const std::string &name, const VoidCallbackFunction &callback) { + add_void_callback(name, -1, callback); } /*! @@ -183,6 +190,13 @@ public: function_storage.add_callback(name, num_args, callback); } + /*! + @brief Adds a void callback with given number or arguments + */ + void add_void_callback(const std::string &name, int num_args, const VoidCallbackFunction &callback) { + function_storage.add_callback(name, num_args, [callback](Arguments& args) { callback(args); return json(); }); + } + /** Includes a template with a given name into the environment. * Then, a template can be rendered in another template using the * include "" syntax. diff --git a/include/inja/function_storage.hpp b/include/inja/function_storage.hpp index a0b62b2..fc2dad2 100644 --- a/include/inja/function_storage.hpp +++ b/include/inja/function_storage.hpp @@ -13,6 +13,7 @@ using json = nlohmann::json; using Arguments = std::vector; using CallbackFunction = std::function; +using VoidCallbackFunction = std::function; /*! * \brief Class for builtin functions and user-defined callbacks. diff --git a/include/inja/renderer.hpp b/include/inja/renderer.hpp index f318198..cb9ac0f 100644 --- a/include/inja/renderer.hpp +++ b/include/inja/renderer.hpp @@ -54,10 +54,9 @@ class Renderer : public NodeVisitor { void print_json(const std::shared_ptr value) { if (value->is_string()) { *output_stream << value->get_ref(); - } else if (value->is_number_float()) { - *output_stream << value->dump(); } else if (value->is_number_integer()) { *output_stream << value->get(); + } else if (value->is_null()) { } else { *output_stream << value->dump(); } diff --git a/single_include/inja/inja.hpp b/single_include/inja/inja.hpp index 8cefd0c..0a35699 100644 --- a/single_include/inja/inja.hpp +++ b/single_include/inja/inja.hpp @@ -1526,6 +1526,7 @@ using json = nlohmann::json; using Arguments = std::vector; using CallbackFunction = std::function; +using VoidCallbackFunction = std::function; /*! * \brief Class for builtin functions and user-defined callbacks. @@ -3348,10 +3349,9 @@ class Renderer : public NodeVisitor { void print_json(const std::shared_ptr value) { if (value->is_string()) { *output_stream << value->get_ref(); - } else if (value->is_number_float()) { - *output_stream << value->dump(); } else if (value->is_number_integer()) { *output_stream << value->get(); + } else if (value->is_null()) { } else { *output_stream << value->dump(); } @@ -4061,7 +4061,14 @@ public: @brief Adds a variadic callback */ void add_callback(const std::string &name, const CallbackFunction &callback) { - function_storage.add_callback(name, -1, callback); + add_callback(name, -1, callback); + } + + /*! + @brief Adds a variadic void callback + */ + void add_void_callback(const std::string &name, const VoidCallbackFunction &callback) { + add_void_callback(name, -1, callback); } /*! @@ -4071,6 +4078,13 @@ public: function_storage.add_callback(name, num_args, callback); } + /*! + @brief Adds a void callback with given number or arguments + */ + void add_void_callback(const std::string &name, int num_args, const VoidCallbackFunction &callback) { + function_storage.add_callback(name, num_args, [callback](Arguments& args) { callback(args); return json(); }); + } + /** Includes a template with a given name into the environment. * Then, a template can be rendered in another template using the * include "" syntax. diff --git a/test/test-functions.cpp b/test/test-functions.cpp index 3d9d9cb..f903102 100644 --- a/test/test-functions.cpp +++ b/test/test-functions.cpp @@ -228,10 +228,15 @@ TEST_CASE("callbacks") { return number1.length(); }); + env.add_void_callback("log", 1, [](inja::Arguments args) { + int a = 2; + }); + env.add_callback("multiply", 0, [](inja::Arguments args) { return 1.0; }); CHECK(env.render("{{ double(age) }}", data) == "56"); CHECK(env.render("{{ half(age) }}", data) == "14"); + CHECK(env.render("{{ log(age) }}", data) == ""); CHECK(env.render("{{ double-greetings }}", data) == "Hello Hello!"); CHECK(env.render("{{ double-greetings() }}", data) == "Hello Hello!"); CHECK(env.render("{{ multiply(4, 5) }}", data) == "20.0");