From 333869e83e552c07d99718fa4352925ea9fca172 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 21 Apr 2017 17:43:51 +0100 Subject: [PATCH 1/2] Add a render overload that takes a functor for partials. Client code is free to provide a functor that implements the search and file opening logic to have {{> test}} to open ~/mydata/test.mustache for example. --- include/mstch/mstch.hpp | 5 +++++ src/mstch.cpp | 18 ++++++++++++++---- src/render_context.cpp | 11 +++++++---- src/render_context.hpp | 5 +++-- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/mstch/mstch.hpp b/include/mstch/mstch.hpp index 58d3330..2a36186 100644 --- a/include/mstch/mstch.hpp +++ b/include/mstch/mstch.hpp @@ -6,6 +6,7 @@ #include #include +#include #include namespace mstch { @@ -110,4 +111,8 @@ std::string render( const std::map& partials = std::map()); +std::string render( + const std::string& tmplt, + const node& root, + std::function(const std::string&)> partial_loader); } diff --git a/src/mstch.cpp b/src/mstch.cpp index 4d84e97..fb20a63 100644 --- a/src/mstch.cpp +++ b/src/mstch.cpp @@ -12,9 +12,19 @@ std::string mstch::render( const node& root, const std::map& partials) { - std::map partial_templates; - for (auto& partial: partials) - partial_templates.insert({partial.first, {partial.second}}); + return render(tmplt, root, [&partials](const std::string& partial_name) { + return partials.count(partial_name) ? + boost::make_optional(partials.at(partial_name)) + : + boost::optional() + ; + }); +} - return render_context(root, partial_templates).render(tmplt); +std::string mstch::render( + const std::string& tmplt, + const node& root, + std::function(const std::string&)> partial_loader) +{ + return render_context(root, partial_loader).render(tmplt); } diff --git a/src/render_context.cpp b/src/render_context.cpp index 90b2ffc..b2e2cc8 100644 --- a/src/render_context.cpp +++ b/src/render_context.cpp @@ -26,8 +26,8 @@ std::string render_context::push::render(const template_type& templt) { render_context::render_context( const mstch::node& node, - const std::map& partials): - m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node) + const std::function(const std::string&)> partials): + m_partial_resolv(partials), m_nodes(1, node), m_node_ptrs(1, &node) { m_state.push(std::unique_ptr(new outside_section)); } @@ -67,6 +67,9 @@ std::string render_context::render( std::string render_context::render_partial( const std::string& partial_name, const std::string& prefix) { - return m_partials.count(partial_name) ? - render(m_partials.at(partial_name), prefix) : ""; + auto value = m_partial_resolv(partial_name); + if (value) + return render(template_type{*value}, prefix); + else + return ""; } diff --git a/src/render_context.hpp b/src/render_context.hpp index b97d41b..6994ab4 100644 --- a/src/render_context.hpp +++ b/src/render_context.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "mstch/mstch.hpp" #include "state/render_state.hpp" @@ -25,7 +26,7 @@ class render_context { render_context( const mstch::node& node, - const std::map& partials); + const std::function(const std::string&)> partials); const mstch::node& get_node(const std::string& token); std::string render( const template_type& templt, const std::string& prefix = ""); @@ -42,7 +43,7 @@ class render_context { const mstch::node& find_node( const std::string& token, std::list current_nodes); - std::map m_partials; + std::function(const std::string&)> m_partial_resolv; std::deque m_nodes; std::list m_node_ptrs; std::stack> m_state; From 45122d1d515c90a54d509d4b2d8d9279348518f5 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 7 Jun 2017 00:38:14 +0100 Subject: [PATCH 2/2] Add support for boost::string_view --- include/mstch/mstch.hpp | 3 ++- src/visitor/is_node_empty.hpp | 6 +++++- src/visitor/render_node.hpp | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/mstch/mstch.hpp b/include/mstch/mstch.hpp index 2a36186..fb3ae3f 100644 --- a/include/mstch/mstch.hpp +++ b/include/mstch/mstch.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace mstch { @@ -99,7 +100,7 @@ using node = boost::make_recursive_variant< internal::lambda_t, std::shared_ptr>, std::map, - std::vector>::type; + std::vector, boost::string_view>::type; using object = internal::object_t; using lambda = internal::lambda_t; using map = std::map; diff --git a/src/visitor/is_node_empty.hpp b/src/visitor/is_node_empty.hpp index a0ae432..ba49bb6 100644 --- a/src/visitor/is_node_empty.hpp +++ b/src/visitor/is_node_empty.hpp @@ -30,7 +30,11 @@ class is_node_empty: public boost::static_visitor { } bool operator()(const std::string& value) const { - return value == ""; + return value.empty(); + } + + bool operator()(const boost::string_view& value) const { + return value.empty(); } bool operator()(const array& array) const { diff --git a/src/visitor/render_node.hpp b/src/visitor/render_node.hpp index 633dd4d..8b892d8 100644 --- a/src/visitor/render_node.hpp +++ b/src/visitor/render_node.hpp @@ -36,6 +36,10 @@ class render_node: public boost::static_visitor { return value ? "true" : "false"; } + std::string operator()(const boost::string_view& value) const { + return std::string(value); + } + std::string operator()(const lambda& value) const { template_type interpreted{value([this](const mstch::node& n) { return visit(render_node(m_ctx), n);