Page 1 of 1

Parse/render twig template in php

Posted: Sun Jan 14, 2018 1:07 pm
by Badhon_raj
Hi,
I was wondering if it is possible to parse/render twig in php.
see the example:

Code: Select all

            $string="{% if true %}Some {{ CONTENT }} in twig template{% endif %}"
            $loader = new Twig_Loader_Array(array(
                'mytemplate' => "$string",
            ));
            $twig = new Twig_Environment($loader);

            $output = $twig->render('mytemplate', $anArray);
I want all the variables available to phpBB, to be available to the render method.
What should I use as the second argument of $twig_>render?

Is it possible to do something like this?
or is there any other way of achieving this?

The purpose is to render some html content for menu for this extension.
viewtopic.php?f=456&t=2438676

Re: Parse/render twig template in php

Posted: Sun Jan 14, 2018 1:10 pm
by kasimi
The code you posted should work fine. Are you getting any errors? For another example, see here: viewtopic.php?p=14875171#p14875171

Re: Parse/render twig template in php

Posted: Sun Jan 14, 2018 5:36 pm
by Badhon_raj
kasimi wrote:
Sun Jan 14, 2018 1:10 pm
The code you posted should work fine. Are you getting any errors? For another example, see here: viewtopic.php?p=14875171#p14875171
Sorry I was not clear in the op.
I was wondering what I can use instead of $anArray.
I don't want to specify a set of predefined variable fur the template.
Instead all the variables available to phpBB should be available during that render.
I am still not sure if I described it correctly.
Please let me know.

And. Thanks for your reply.

Re: Parse/render twig template in php

Posted: Sun Jan 14, 2018 8:10 pm
by kasimi
Here's a solution that does service replacement. The code is for phpBB 3.2. The template service in phpBB 3.1 has different arguments.

Re-define the template service:

Code: Select all

template:
	class: 'foo\bar\my_template'
	arguments:
		- '@path_helper'
		- '@config'
		- '@template_context'
		- '@template.twig.environment'
		- '%core.template.cache_path%'
		- '@user'
		- '@template.twig.extensions.collection'
		- '@ext.manager'
The new my_template class looks as follows. It needs to extend the core's template service class:

Code: Select all

namespace foo\bar;

class my_template extends \phpbb\template\twig\twig
{
	public function render_string($template)
	{
		$old_loader = $this->twig->getLoader();
		$this->twig->setLoader(new \Twig_Loader_Array(['template' => $template]));
		$content = $this->twig->render('template', $this->get_template_vars());
		$this->twig->setLoader($old_loader);
		return $content;
	}
}
Now you can inject the template service the usual way and call the render_string() method:

Code: Select all

echo $this->template->render_string('{{ S_USERNAME }} is on page {{ PAGE_TITLE }}');
I couldn't get this working with service decoration which is the recommended way in phpBB 3.2. If anyone knows how to do it, please share.

Re: Parse/render twig template in php

Posted: Wed Jan 17, 2018 6:05 pm
by Badhon_raj
bump.

Re: Parse/render twig template in php

Posted: Sun Jan 21, 2018 10:29 am
by nicofuma
Actually phpBB template engine IS Twig with an overlay for BC and historic reasons. So you can just use the regular template service and you can assign arrays and objects like with Twig (unlike the 3.0 template engine)

Re: Parse/render twig template in php

Posted: Fri Mar 16, 2018 2:35 pm
by mrgoldy
Alright, I'm resurrecting this cause I am running into a similar problem.

I want to be able to render a 'string' - retrieved from the database - with custom AND common variables.
I tried the above posted method by Kasimi, but that doesn't seem to parse a common variable like U_INDEX, it does however parse the custom variables. Moreover, when I have a {{ lang('TOPIC') }} in the string, it throws the following error:
Unknown "lang" function in "template" at line 35.

controller:

Code: Select all

		$this->template->assign_vars(array(
			'S_PAGE_HEADER'	=> $this->parse_template_from_db($page['page_header'], $template_variables),
		));

Code: Select all

	/**
	 * Private function to parse a 'template string' retreived from the databse
	 *
	 * @param  string		$template_string		The template string from the database
	 * @param  array 		$template_variables 	The template variables that need to be parsed
	 * @return string								A rendered template output
	 * @access private
	 */
	private function parse_template_from_db($template_string, $template_variables)
	{
		/* Decode HTML Special characters: &lt; into < et cetera. */
		$template_string = htmlspecialchars_decode($template_string);
		$twig = new \Twig_Environment(new \Twig_Loader_Array(array('template' => $template_string)));
		/* Parse the template variables we gave them */
		$content = $twig->render('template', $template_variables);

		/* Need to decode HTML Special characters again, for assigned variables */
		return htmlspecialchars_decode($content);
	}
It feels like I am setting up a complete new twig environment, without the standard functions and variables.
And then nicofuma's comment made me thinking - partially cause I don't understand it fully - but that it should be possible to do it easier.
The only thing I found was $template->assign_display, but this doesn't seem to do the trick.

Basically what I am looking for is to render a string (within PHP) retrieved from the db with common and custom variables and functions and then assign it to a template variable.

Re: Parse/render twig template in php

Posted: Fri Mar 16, 2018 3:42 pm
by kasimi
U_INDEX is assigned to the template in the page_header() function. This function is called by the controller.helper's render() method, which you probably call only after calling your parse_template_from_db() method. Either you set all the template variables you want to be available in your template string yourself, or you delay your call to parse_template_from_db() until phpBB has assigned the common template variables, for example in the event core.page_header_after.

Re: Parse/render twig template in php

Posted: Fri Mar 16, 2018 4:19 pm
by mrgoldy
Alright, that sounds do-able.
How about including the built in functions such as {{ lang() }}, etc?

Re: Parse/render twig template in php

Posted: Fri Mar 16, 2018 4:44 pm
by kasimi
Untested, but try this: inject the template.twig.extensions.collection and do:

Code: Select all

$twig->setExtensions($this->twig_extensions);

Re: Parse/render twig template in php

Posted: Fri Mar 16, 2018 5:32 pm
by mrgoldy
Not too sure what you mean / how you mean it. Tried couple of ways but all keep throwing an error, expecting the 1st parameter to setExtensions to be an array, and NULL is given.

Is it not somehow possible to render a template twice?
Like a template file with:

Code: Select all

{{ PAGE_HEADER }}

{{ PAGE_CONTENT }}

{{ PAGE_FOOTER }}
Assign the 'template strings' from the database to this template file.
So it will look something like this:

Code: Select all

{% INCLUDECSS '@vendor_ext/style.css' %}
<div class="panel">Hello {{ S_USERNAME }}</div>

<div class="panel bg2">This is our content, 8 {{ lang('NEW_POSTS') }}</div>

<div class="rules">
	<h3>{{ lang('FORUM_RULES') }}</h3>
	<p><a href="">{{ lang('FORUM_RULES_LINK') }}</a></p>
</div>
Then re-render that same file or inject it into a regular template file and let it be rendered again, so the custom template variables get rendered?