diff --git a/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php b/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php
index 82c6a0b2b7..698d979082 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Fragment/ContainerAwareHIncludeFragmentRenderer.php
@@ -32,7 +32,7 @@ class ContainerAwareHIncludeFragmentRenderer extends HIncludeFragmentRenderer
{
$this->container = $container;
- parent::__construct(null, $signer, $globalDefaultTemplate);
+ parent::__construct(null, $signer, $globalDefaultTemplate, $container->getParameter('kernel.charset'));
}
/**
diff --git a/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php
index fafa76368c..1f059da94a 100644
--- a/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php
+++ b/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php
@@ -11,6 +11,10 @@
namespace Symfony\Component\HttpKernel\Fragment;
+if (!defined('ENT_SUBSTITUTE')) {
+ define('ENT_SUBSTITUTE', 8);
+}
+
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Templating\EngineInterface;
@@ -27,6 +31,7 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
private $globalDefaultTemplate;
private $signer;
private $templating;
+ private $charset;
/**
* Constructor.
@@ -34,18 +39,22 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
* @param EngineInterface|\Twig_Environment $templating An EngineInterface or a \Twig_Environment instance
* @param UriSigner $signer A UriSigner instance
* @param string $globalDefaultTemplate The global default content (it can be a template name or the content)
+ * @param string $charset
*/
- public function __construct($templating = null, UriSigner $signer = null, $globalDefaultTemplate = null)
+ public function __construct($templating = null, UriSigner $signer = null, $globalDefaultTemplate = null, $charset = 'utf-8')
{
$this->setTemplating($templating);
$this->globalDefaultTemplate = $globalDefaultTemplate;
$this->signer = $signer;
+ $this->charset = $charset;
}
/**
* Sets the templating engine to use to render the default content.
*
* @param EngineInterface|\Twig_Environment|null $templating An EngineInterface or a \Twig_Environment instance
+ *
+ * @throws \InvalidArgumentException
*/
public function setTemplating($templating)
{
@@ -71,7 +80,9 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
*
* Additional available options:
*
- * * default: The default content (it can be a template name or the content)
+ * * default: The default content (it can be a template name or the content)
+ * * id: An optional hx:include tag id attribute
+ * * attributes: An optional array of hx:include tag attributes
*/
public function render($uri, Request $request, array $options = array())
{
@@ -93,9 +104,29 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
$content = $template;
}
- return new Response(sprintf('%s', $uri, $content));
+ $attributes = isset($options['attributes']) && is_array($options['attributes']) ? $options['attributes'] : array();
+ if (isset($options['id']) && $options['id']) {
+ $attributes['id'] = $options['id'];
+ }
+ $renderedAttributes = '';
+ if (count($attributes) > 0) {
+ foreach($attributes as $attribute => $value) {
+ $renderedAttributes .= sprintf(
+ ' %s="%s"',
+ htmlspecialchars($attribute, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset, false),
+ htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset, false)
+ );
+ }
+ }
+
+ return new Response(sprintf('%s', $uri, $renderedAttributes, $content));
}
+ /**
+ * @param string $template
+ *
+ * @return boolean
+ */
private function templateExists($template)
{
if ($this->templating instanceof EngineInterface) {
diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php
index 1e77374901..53baf5ab51 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php
@@ -64,4 +64,19 @@ class HIncludeFragmentRendererTest extends \PHPUnit_Framework_TestCase
$strategy = new HIncludeFragmentRenderer(null, null, 'global_default');
$this->assertEquals('default', $strategy->render('/foo', Request::create('/'), array('default' => 'default'))->getContent());
}
+
+ public function testRenderWithAttributesOptions()
+ {
+ // with id
+ $strategy = new HIncludeFragmentRenderer();
+ $this->assertEquals('default', $strategy->render('/foo', Request::create('/'), array('default' => 'default', 'id' => 'bar'))->getContent());
+
+ // with attributes
+ $strategy = new HIncludeFragmentRenderer();
+ $this->assertEquals('default', $strategy->render('/foo', Request::create('/'), array('default' => 'default', 'attributes' => array('p1' => 'v1', 'p2' => 'v2')))->getContent());
+
+ // with id & attributes
+ $strategy = new HIncludeFragmentRenderer();
+ $this->assertEquals('default', $strategy->render('/foo', Request::create('/'), array('default' => 'default', 'id' => 'bar', 'attributes' => array('p1' => 'v1', 'p2' => 'v2')))->getContent());
+ }
}