This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Component/Templating/DelegatingEngine.php

104 lines
2.5 KiB
PHP
Raw Normal View History

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Templating;
/**
* DelegatingEngine selects an engine for a given template.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DelegatingEngine implements EngineInterface, StreamingEngineInterface
{
/**
* @var EngineInterface[]
*/
2019-01-16 09:39:14 +00:00
protected $engines = [];
/**
* @param EngineInterface[] $engines An array of EngineInterface instances to add
*/
2019-01-16 09:39:14 +00:00
public function __construct(array $engines = [])
{
foreach ($engines as $engine) {
$this->addEngine($engine);
}
}
/**
* {@inheritdoc}
*/
2019-01-16 09:39:14 +00:00
public function render($name, array $parameters = [])
{
return $this->getEngine($name)->render($name, $parameters);
}
[HttpFoundation] added support for streamed responses To stream a Response, use the StreamedResponse class instead of the standard Response class: $response = new StreamedResponse(function () { echo 'FOO'; }); $response = new StreamedResponse(function () { echo 'FOO'; }, 200, array('Content-Type' => 'text/plain')); As you can see, a StreamedResponse instance takes a PHP callback instead of a string for the Response content. It's up to the developer to stream the response content from the callback with standard PHP functions like echo. You can also use flush() if needed. From a controller, do something like this: $twig = $this->get('templating'); return new StreamedResponse(function () use ($templating) { $templating->stream('BlogBundle:Annot:streamed.html.twig'); }, 200, array('Content-Type' => 'text/html')); If you are using the base controller, you can use the stream() method instead: return $this->stream('BlogBundle:Annot:streamed.html.twig'); You can stream an existing file by using the PHP built-in readfile() function: new StreamedResponse(function () use ($file) { readfile($file); }, 200, array('Content-Type' => 'image/png'); Read http://php.net/flush for more information about output buffering in PHP. Note that you should do your best to move all expensive operations to be "activated/evaluated/called" during template evaluation. Templates --------- If you are using Twig as a template engine, everything should work as usual, even if are using template inheritance! However, note that streaming is not supported for PHP templates. Support is impossible by design (as the layout is rendered after the main content). Exceptions ---------- Exceptions thrown during rendering will be rendered as usual except that some content might have been rendered already. Limitations ----------- As the getContent() method always returns false for streamed Responses, some event listeners won't work at all: * Web debug toolbar is not available for such Responses (but the profiler works fine); * ESI is not supported. Also note that streamed responses cannot benefit from HTTP caching for obvious reasons.
2011-10-17 16:17:34 +01:00
/**
* {@inheritdoc}
[HttpFoundation] added support for streamed responses To stream a Response, use the StreamedResponse class instead of the standard Response class: $response = new StreamedResponse(function () { echo 'FOO'; }); $response = new StreamedResponse(function () { echo 'FOO'; }, 200, array('Content-Type' => 'text/plain')); As you can see, a StreamedResponse instance takes a PHP callback instead of a string for the Response content. It's up to the developer to stream the response content from the callback with standard PHP functions like echo. You can also use flush() if needed. From a controller, do something like this: $twig = $this->get('templating'); return new StreamedResponse(function () use ($templating) { $templating->stream('BlogBundle:Annot:streamed.html.twig'); }, 200, array('Content-Type' => 'text/html')); If you are using the base controller, you can use the stream() method instead: return $this->stream('BlogBundle:Annot:streamed.html.twig'); You can stream an existing file by using the PHP built-in readfile() function: new StreamedResponse(function () use ($file) { readfile($file); }, 200, array('Content-Type' => 'image/png'); Read http://php.net/flush for more information about output buffering in PHP. Note that you should do your best to move all expensive operations to be "activated/evaluated/called" during template evaluation. Templates --------- If you are using Twig as a template engine, everything should work as usual, even if are using template inheritance! However, note that streaming is not supported for PHP templates. Support is impossible by design (as the layout is rendered after the main content). Exceptions ---------- Exceptions thrown during rendering will be rendered as usual except that some content might have been rendered already. Limitations ----------- As the getContent() method always returns false for streamed Responses, some event listeners won't work at all: * Web debug toolbar is not available for such Responses (but the profiler works fine); * ESI is not supported. Also note that streamed responses cannot benefit from HTTP caching for obvious reasons.
2011-10-17 16:17:34 +01:00
*/
2019-01-16 09:39:14 +00:00
public function stream($name, array $parameters = [])
[HttpFoundation] added support for streamed responses To stream a Response, use the StreamedResponse class instead of the standard Response class: $response = new StreamedResponse(function () { echo 'FOO'; }); $response = new StreamedResponse(function () { echo 'FOO'; }, 200, array('Content-Type' => 'text/plain')); As you can see, a StreamedResponse instance takes a PHP callback instead of a string for the Response content. It's up to the developer to stream the response content from the callback with standard PHP functions like echo. You can also use flush() if needed. From a controller, do something like this: $twig = $this->get('templating'); return new StreamedResponse(function () use ($templating) { $templating->stream('BlogBundle:Annot:streamed.html.twig'); }, 200, array('Content-Type' => 'text/html')); If you are using the base controller, you can use the stream() method instead: return $this->stream('BlogBundle:Annot:streamed.html.twig'); You can stream an existing file by using the PHP built-in readfile() function: new StreamedResponse(function () use ($file) { readfile($file); }, 200, array('Content-Type' => 'image/png'); Read http://php.net/flush for more information about output buffering in PHP. Note that you should do your best to move all expensive operations to be "activated/evaluated/called" during template evaluation. Templates --------- If you are using Twig as a template engine, everything should work as usual, even if are using template inheritance! However, note that streaming is not supported for PHP templates. Support is impossible by design (as the layout is rendered after the main content). Exceptions ---------- Exceptions thrown during rendering will be rendered as usual except that some content might have been rendered already. Limitations ----------- As the getContent() method always returns false for streamed Responses, some event listeners won't work at all: * Web debug toolbar is not available for such Responses (but the profiler works fine); * ESI is not supported. Also note that streamed responses cannot benefit from HTTP caching for obvious reasons.
2011-10-17 16:17:34 +01:00
{
$engine = $this->getEngine($name);
if (!$engine instanceof StreamingEngineInterface) {
throw new \LogicException(sprintf('Template "%s" cannot be streamed as the engine supporting it does not implement StreamingEngineInterface.', $name));
}
$engine->stream($name, $parameters);
[HttpFoundation] added support for streamed responses To stream a Response, use the StreamedResponse class instead of the standard Response class: $response = new StreamedResponse(function () { echo 'FOO'; }); $response = new StreamedResponse(function () { echo 'FOO'; }, 200, array('Content-Type' => 'text/plain')); As you can see, a StreamedResponse instance takes a PHP callback instead of a string for the Response content. It's up to the developer to stream the response content from the callback with standard PHP functions like echo. You can also use flush() if needed. From a controller, do something like this: $twig = $this->get('templating'); return new StreamedResponse(function () use ($templating) { $templating->stream('BlogBundle:Annot:streamed.html.twig'); }, 200, array('Content-Type' => 'text/html')); If you are using the base controller, you can use the stream() method instead: return $this->stream('BlogBundle:Annot:streamed.html.twig'); You can stream an existing file by using the PHP built-in readfile() function: new StreamedResponse(function () use ($file) { readfile($file); }, 200, array('Content-Type' => 'image/png'); Read http://php.net/flush for more information about output buffering in PHP. Note that you should do your best to move all expensive operations to be "activated/evaluated/called" during template evaluation. Templates --------- If you are using Twig as a template engine, everything should work as usual, even if are using template inheritance! However, note that streaming is not supported for PHP templates. Support is impossible by design (as the layout is rendered after the main content). Exceptions ---------- Exceptions thrown during rendering will be rendered as usual except that some content might have been rendered already. Limitations ----------- As the getContent() method always returns false for streamed Responses, some event listeners won't work at all: * Web debug toolbar is not available for such Responses (but the profiler works fine); * ESI is not supported. Also note that streamed responses cannot benefit from HTTP caching for obvious reasons.
2011-10-17 16:17:34 +01:00
}
/**
* {@inheritdoc}
*/
public function exists($name)
{
return $this->getEngine($name)->exists($name);
}
public function addEngine(EngineInterface $engine)
{
$this->engines[] = $engine;
}
/**
* {@inheritdoc}
*/
public function supports($name)
{
2011-02-10 17:20:44 +00:00
try {
$this->getEngine($name);
} catch (\RuntimeException $e) {
return false;
}
2011-02-10 17:20:44 +00:00
return true;
}
2011-02-07 13:11:46 +00:00
/**
* Get an engine able to render the given template.
*
* @param string|TemplateReferenceInterface $name A template name or a TemplateReferenceInterface instance
2011-02-07 13:11:46 +00:00
*
* @return EngineInterface The engine
*
* @throws \RuntimeException if no engine able to work with the template is found
*/
public function getEngine($name)
{
foreach ($this->engines as $engine) {
if ($engine->supports($name)) {
return $engine;
}
}
throw new \RuntimeException(sprintf('No engine is able to work with the template "%s".', $name));
}
}