Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TemplateEnv Globals are removed after a call to Render #235

Closed
sdegrande opened this issue Feb 15, 2023 · 3 comments
Closed

TemplateEnv Globals are removed after a call to Render #235

sdegrande opened this issue Feb 15, 2023 · 3 comments

Comments

@sdegrande
Copy link

Here is a small example which fails to run as expected:

#include <iostream>
#include <map>
#include <jinja2cpp/template.h>
#include <jinja2cpp/template_env.h>

int main(int argc, char *argv[])
{
	jinja2::TemplateEnv tplEnv;
	tplEnv.AddGlobal("global_var", jinja2::Value("foo"));
	{
		jinja2::Template tpl(&tplEnv);
		tpl.Load("Hello {{ global_var }}!!!");
		std::string result = tpl.RenderAsString(jinja2::ValuesMap{}).value();
		std::cout << result << std::endl;
	}
	{
		jinja2::Template tpl(&tplEnv);
		tpl.Load("Hello {{ global_var }}!!!");
		std::string result = tpl.RenderAsString(jinja2::ValuesMap{}).value();
		std::cout << result << std::endl;
	}
	return 0;
}

The output is:

Hello foo!!!
Hello !!!

I displayed the content of the Globals before and after the first rendering, using that code:

tplEnv.ApplyGlobals([](jinja2::ValuesMap &map) {
	for (const auto& [key, val] : map) {
		std::cout << "-> tplenv " << key << " " << val.asString() << std::endl;
	}
});

Here is the result:

-> tplenv global_var foo
Hello foo!!!
-> tplenv global_var
Hello !!!

So, something is removing the content of the global vars, which is annoying because currently it means that globals have to be "reloaded" before a call to Render...

Note that MakeCallable globals are still present and working after a call to Render:

#include <iostream>
#include <map>
#include <jinja2cpp/template.h>
#include <jinja2cpp/template_env.h>
#include <jinja2cpp/user_callable.h>

int main(int argc, char *argv[])
{
	jinja2::TemplateEnv tplEnv;
	tplEnv.AddGlobal("global_var", jinja2::Value("foo"));
	tplEnv.AddGlobal("global_fn", jinja2::MakeCallable([]() { return "bar";	}));
	{
		jinja2::Template tpl(&tplEnv);
		tpl.Load("Hello {{ global_var }} {{ global_fn() }}!!!");
		std::string result = tpl.RenderAsString(jinja2::ValuesMap{}).value();
		std::cout << result << std::endl;
	}
	{
		jinja2::Template tpl(&tplEnv);
		tpl.Load("Hello {{ global_var }} {{ global_fn() }}!!!");
		std::string result = tpl.RenderAsString(jinja2::ValuesMap{}).value();
		std::cout << result << std::endl;
	}
	return 0;
}

returns:

Hello foo bar!!!
Hello  bar!!!
@rmorozov
Copy link
Member

rmorozov commented Jun 2, 2023

Sorry, for not reacting earlier, I am doing some investigations.

Hope I'll manage to fix it and bump deps.

@sdegrande
Copy link
Author

Thanks. I also hope you'll fix it ! :-)

rmorozov added a commit that referenced this issue Jun 2, 2023
mutable reference to vector of variants triggered a situation when
destructor cleared a global var after template rendering

add a test for regression
@rmorozov
Copy link
Member

rmorozov commented Jun 2, 2023

@sdegrande , please check this fix, feel free to reopen issue if it still exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants