Parse/render twig template in php

Discussion forum for Extension Writers regarding Extension Development.
Post Reply
Badhon_raj
Registered User
Posts: 204
Joined: Wed Jan 04, 2012 6:33 pm

Parse/render twig template in php

Post 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
Last edited by Badhon_raj on Sun Jan 14, 2018 5:39 pm, edited 1 time in total.
User avatar
kasimi
Former Team Member
Posts: 4900
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Parse/render twig template in php

Post by kasimi »

The code you posted should work fine. Are you getting any errors? For another example, see here: viewtopic.php?p=14875171#p14875171
Badhon_raj
Registered User
Posts: 204
Joined: Wed Jan 04, 2012 6:33 pm

Re: Parse/render twig template in php

Post 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.
User avatar
kasimi
Former Team Member
Posts: 4900
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Parse/render twig template in php

Post 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.
Badhon_raj
Registered User
Posts: 204
Joined: Wed Jan 04, 2012 6:33 pm

Re: Parse/render twig template in php

Post by Badhon_raj »

bump.
nicofuma
3.2 Release Manager
3.2 Release Manager
Posts: 546
Joined: Sun Apr 13, 2014 1:47 am
Location: Grenoble - France

Re: Parse/render twig template in php

Post 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)
Member of phpBB Development-Team
No Support via PM
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Parse/render twig template in php

Post 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.
Last edited by mrgoldy on Fri Mar 16, 2018 4:20 pm, edited 1 time in total.
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
User avatar
kasimi
Former Team Member
Posts: 4900
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Parse/render twig template in php

Post 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.
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Parse/render twig template in php

Post by mrgoldy »

Alright, that sounds do-able.
How about including the built in functions such as {{ lang() }}, etc?
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
User avatar
kasimi
Former Team Member
Posts: 4900
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Parse/render twig template in php

Post by kasimi »

Untested, but try this: inject the template.twig.extensions.collection and do:

Code: Select all

$twig->setExtensions($this->twig_extensions);
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Parse/render twig template in php

Post 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?
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
Post Reply

Return to “Extension Writers Discussion”