A proposal for psr for rendering templates.
GoalIt is common that a library, application or CMSs need to have a template renderer / engine for rendering data for their websites or emails.
More and more application are going here the data provider way. This application are the one which would benifit from the TemplateRendererInterface as they not only can provide them headless over an API but also make it possible that somebody can render the data via a Template Engine.
As a library author I want to make it free that my service can be used with any template engine the developer want to use. Typical usecases are PHP rendered CMSs like Sulu, Typo3, Drupal, Contao which maybe could benifit from this. But also all other data provider based libraries which ship configureable controller or have template to render like email tools / libraries.
Also for projects when somebody wants maybe switch in future from twig to latte templates as it consider better safety for xss a common interface can benifit here and avoid refractorings.
Defining the scopeThe scope of the TemplateRenderer is only on rendering a given template with a given context. The template render interface will not take care of registering template paths or how to configure the template engine to find the templates. Similar how PSR-18 HttpClient does not care how the client is created or configured.
AnalysisIn this section I did analyse the following existing template engines and added example how the render there templates.
Repository: https://github.com/twigphp/Twig
Current Version: v3.4.1
Supported PHP Version: >=7.2.5
Template Type Hint: string|TemplateWrapper
Context Type Hint: array
Return Type Hint: string or output to buffer
Supports Stream: true
Render a template:
Repository: https://github.com/smarty-php/smarty
Current Version: v3.4.1
Supported PHP Version: ^7.1 || ^8.0
Template Type Hint: string
Context Type Hint: array
Return Type Hint: none
Supports Stream: true (only)
Render a template:
Repository: https://github.com/nette/latte
Current Version: v3.0.0
Supported PHP Version: >=8.0 <8.2
Template Type Hint: string
Context Type Hint: object|mixed[]
Return Type Hint: string or output to buffer
Supports Stream: true
Render a template:
Repository: https://github.com/laminas/laminas-view
Current Version: ^2.20.0
Supported PHP Version: ^7.4 || ~8.0.0 || ~8.1.0
Template Type Hint: string
Context Type Hint: ViewModel<null|array|Traversable|ArrayAccess>
Return Type Hint: null|string
Supports Stream: false
Repository: https://github.com/illuminate/view
Current Version: v9.15.0
Supported PHP Version: ^8.1
Template Type Hint: string
Context Type Hint: array
Return Type Hint: string
Supports Stream: false ?
Render a template:
Repository: https://github.com/illuminate/view
Current Version: 2.7.1
Supported PHP Version: >=5.5.0
Template Type Hint: string
Context Type Hint: array
Return Type Hint: string
Supports Stream: false ?
Render a template:
Repository: https://github.com/TYPO3/Fluid
Current Version: 4.13.4
Supported PHP Version: ^7.4 || ^8.0
Template Type Hint: string
Context Type Hint: object<string, mixed> via dynamic properties
Return Type Hint: string
Supports Stream: false ?
Render a template:
Repository: https://github.com/mezzio/mezzio
Current Version: 3.10.0
Supported PHP Version: ~7.4.0||~8.0.0||~8.1.0
Template Type Hint: string
Context Type Hint: array|object
Return Type Hint: string
Supports Stream: false
Render a template:
Repository: https://github.com/thephpleague/plates
Current Version: v3.4.0
Supported PHP Version: ^7.0|^8.0
Template Type Hint: string
Context Type Hint: array
Return Type Hint: string
Supports Stream: false
Render a template:
Repository: https://github.com/bobthecow/mustache.php
Current Version: v2.14.1
Supported PHP Version: >=5.2.4
Template Type Hint: string
Context Type Hint: array
Return Type Hint: string
Supports Stream: false
Render a template:
The interface for a TemplateRender I would recommend is the following based on my analysis of exist template engines and what is the easiest way to put them together and have maximum interoperability:
For maximum compatibility we even could consider to publish 2 version of the template renderer v1 without typehints so exist template engine still supporting old php version can already implement it and v2 with typehints.
Exist TemplateRenderer DiscussionThere was already an exist disussion about implementing a TemplateRendererInterface here: https://groups.google.com/g/php-fig/c/w1cugJ9DaFg/m/TPTnYY5LBgAJ.
The discussion goes over several topics just to mention the main parts:
To target this specific points. I would focus in this PSR on exist solution as we see most work for template with logical string based names and do not require an object.
I want mention here also developer experience as example in the past why there was created PSR 16 (Simple Cache) where we did still have PSR 6.
So the name of the proposal should maybe be "Simple TemplateRenderer" and not try to reinventing the wheel.
By analysing exist template engine, not everybody support to have an object as a context so I would keep the interface to array for context only. This way it is easy to make exist template engine compatible with PSR interface.
For streaming the output I must say I did not see one
project since 7 years which did use for example the streaming
functionality of twig and for maximum compatibility I would also remove
that requirement from the PSR as the analysis give there are template
engines which do not support that functionality.
The proposal I did write can be found here: https://github.com/php-fig/fig-standards/pull/1280/files.
I know I did skip here some process by already writing something, still
I hope we can put most of the template engine creators / maintainers on
one table to dicuss if they are willing to add such an interface or
for which we maybe can provide a bridge, so system like CMSs, Library,
Newsletter Tools, can make use of it. I will also bring this topic on
the table for our next CMS Garden call which we have every month where several members of different CMS have a call together discussion common topics. So maybe I can reach there a CMS which maybe did not yet part of this mailing list / github discussion.
Best Regards,
Alex
Repository: https://github.com/yiisoft/view
Current Version: 5.0.0
Supported PHP Version: ^7.4|^8.0
Template Type Hint: string
Context Type Hint: array
Return Type Hint: string
Supports Stream: false
--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/3d47a925-9f63-4477-8ca4-654d4cfec180n%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/b60cc456-4d50-446f-bd27-94554f01582bn%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/cabbfab5-11ff-48d8-9fa7-5979ebfbb775%40app.fastmail.com.
Personally, I prefer the full-on view model approach. PHP types can encapsulate quite a bit these days, which would (as in PSR-14) offer decent fallback support via parent types and interfaces, as well as be more self-debugging, etc. It would also be template agnostic. Additional context could be provided by optional named arguments (like $format for "html", "rss", "text", etc.), and those could be engine-specific-extended without breaking anything if we define a few base ones.
There's probably somewhere that would break, but the biggest blocker is, as noted, getting existing engines on board with this. If we can do that, we have options. If not, there's nothing to do.
--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/X4e1z5IaG9E/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/4dcd1e45-239a-45ce-8bb8-8332406bd4d5%40app.fastmail.com.
--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/X4e1z5IaG9E/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/b2667b3a-a819-4877-86ae-c1e93edac2bd%40app.fastmail.com.