Skip to content

Commit bcf810c

Browse files
committed
Add global scope bound to TemplateEnv
1 parent 9e22243 commit bcf810c

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

include/jinja2cpp/template_env.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "template.h"
88

99
#include <unordered_map>
10+
#include <shared_mutex>
1011

1112
namespace jinja2
1213
{
@@ -61,6 +62,24 @@ class TemplateEnv
6162
nonstd::expected<Template, ErrorInfo> LoadTemplate(std::string fileName);
6263
nonstd::expected<TemplateW, ErrorInfoW> LoadTemplateW(std::string fileName);
6364

65+
void AddGlobal(std::string name, Value val)
66+
{
67+
std::unique_lock<std::shared_timed_mutex> l(m_guard);
68+
m_globalValues[std::move(name)] = std::move(val);
69+
}
70+
71+
void RemoveGlobal(const std::string& name)
72+
{
73+
std::unique_lock<std::shared_timed_mutex> l(m_guard);
74+
m_globalValues.erase(name);
75+
}
76+
77+
template<typename Fn>
78+
void ApplyGlobals(Fn&& fn)
79+
{
80+
std::shared_lock<std::shared_timed_mutex> l(m_guard);
81+
fn(m_globalValues);
82+
}
6483
private:
6584
IErrorHandler* m_errorHandler;
6685
struct FsHandler
@@ -70,6 +89,8 @@ class TemplateEnv
7089
};
7190
std::vector<FsHandler> m_filesystemHandlers;
7291
Settings m_settings;
92+
ValuesMap m_globalValues;
93+
std::shared_timed_mutex m_guard;
7394
};
7495

7596
} // jinja2

src/render_context.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ struct IRendererCallback
2929
class RenderContext
3030
{
3131
public:
32-
RenderContext(const InternalValueMap& extValues, IRendererCallback* rendererCallback)
32+
RenderContext(const InternalValueMap& extValues, const InternalValueMap& globalValues, IRendererCallback* rendererCallback)
3333
: m_rendererCallback(rendererCallback)
3434
{
3535
m_externalScope = &extValues;
36+
m_globalScope = &globalValues;
3637
EnterScope();
3738
(*m_currentScope)["self"] = MapAdapter::CreateAdapter(InternalValueMap());
3839
}
@@ -77,7 +78,12 @@ class RenderContext
7778
if (found)
7879
return valP;
7980
}
80-
return finder(*m_externalScope);
81+
82+
auto valP = finder(*m_externalScope);
83+
if (found)
84+
return valP;
85+
86+
return finder(*m_globalScope);
8187
}
8288

8389
auto& GetCurrentScope() const
@@ -100,7 +106,7 @@ class RenderContext
100106
RenderContext Clone(bool includeCurrentContext) const
101107
{
102108
if (!includeCurrentContext)
103-
return RenderContext(m_emptyScope, m_rendererCallback);
109+
return RenderContext(m_emptyScope, *m_globalScope, m_rendererCallback);
104110

105111
return RenderContext(*this);
106112
}
@@ -112,6 +118,7 @@ class RenderContext
112118
private:
113119
InternalValueMap* m_currentScope;
114120
const InternalValueMap* m_externalScope;
121+
const InternalValueMap* m_globalScope;
115122
InternalValueMap m_emptyScope;
116123
std::list<InternalValueMap> m_scopes;
117124
IRendererCallback* m_rendererCallback;

src/template_impl.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,31 @@ class TemplateImpl : public ITemplateImpl
138138

139139
try
140140
{
141+
InternalValueMap extParams;
141142
InternalValueMap intParams;
142-
for (auto& ip : params)
143+
144+
auto convertFn = [&intParams](auto& params) {
145+
for (auto& ip : params)
146+
{
147+
auto valRef = &ip.second.data();
148+
auto newParam = visit(visitors::InputValueConvertor(), *valRef);
149+
if (!newParam)
150+
intParams[ip.first] = ValueRef(static_cast<const Value&>(*valRef));
151+
else
152+
intParams[ip.first] = newParam.get();
153+
}
154+
};
155+
156+
if (m_env)
143157
{
144-
auto valRef = &ip.second.data();
145-
auto newParam = visit(visitors::InputValueConvertor(), *valRef);
146-
if (!newParam)
147-
intParams[ip.first] = ValueRef(static_cast<const Value&>(*valRef));
148-
else
149-
intParams[ip.first] = newParam.get();
158+
m_env->ApplyGlobals(convertFn);
159+
std::swap(extParams, intParams);
150160
}
161+
162+
convertFn(params);
163+
151164
RendererCallback callback(this);
152-
RenderContext context(intParams, &callback);
165+
RenderContext context(intParams, extParams, &callback);
153166
InitRenderContext(context);
154167
OutStream outStream([writer = GenericStreamWriter<CharT>(os)]() mutable -> OutStream::StreamWriter* {return &writer;});
155168
m_renderer->Render(outStream, context);

test/includes_test.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ class IncludeTest : public TemplateEnvFixture
1212
{
1313
TemplateEnvFixture::SetUp();
1414

15-
AddFile("header", "[{{ foo }}|{{ 23 }}]");
15+
AddFile("header", "[{{ foo }}|{{ bar }}]");
1616
AddFile("o_printer", "({{ o }})");
17+
18+
m_env.AddGlobal("bar", 23);
1719
}
1820
};
1921

0 commit comments

Comments
 (0)