render raw HTML in a Symfony controller - symfony

I'd like to render a template to a string in a symfony controller and avoid escaping it.
I don't want to disble twig escaping globally.
Kind of applying the |raw filter in the template itself, but from the controller.
I imagine something like
$rendered_unescaped = $this->container->get('templating')
->render($templatehere, $paramshere,
array('autoescape'=>false));
By the way, I have wishfully tried the previous with no luck indeed.
This need apears when I want to add an html chunk to an ajax json response and realize that I am getting htmlentities all around.
Thanks,
javier

You could use the autoescape tag
{
"foo": {
"html": "{% autoescape false %}<p>Yo, <span>{{ name }}</span>, I'm real happy for you, and Imma let you finish...</p>{% endautoescape %}"
}
}
Also, I haven't tested this, but you could change the default strategy of the Twig templating.
$this->container->get('templating')->getExtension('escaper')->setDefaultStrategy(false);

Related

Twig how to get html between two tags to a service

I want some simple twig tags that allow me to do the following:
{% customtag 'name' %}
<div> some html </div>
{% endcustomtag %}
And then get that html inside of a service.
I have tried doing this myself but when I finally have al the data that I want inside of my NodeVisitor I can't seem to get it to my service. If I inject it and call a method on it it never gets executed. It only gets called if I try to clear my cache from my command line.
Can somebody please give some insight?
Apparently, you can access your extensions from Twig_Template.
So you can do:
$compiler->write('$this->extensions[')
->string('your_extension')
->write(']->getService()->someFunction();')
->raw(PHP_EOL);
in your twig node. And then in your extension you should just inject the service and return it in the getService method.

rendering controller action in symfony twig

Updating deprecated code and i have following problem with render tag
> {% render url('_internal_main_navigation', {}) %}
transaltes to
{{ render(controller('MyBundle::menu', {})) }}
Twig does this thing where it appends "Controller" and "Action" to the specified route so That should call MyBundle/Controller/Controller->menuAction() but apparently the Controller class is supposed to have some sort of prefix like "MyController" so the twig route can be specified like 'Bundle:My:menu'
otherwise i get
Class "MyBundle" noes not exist
Can i make it work without prefixing the controller?
I'd recommend to use render_esi() which supports routes via url() by name aswell and you're set for ESI in the future.
When using the default render() function (or setting the renderer to
inline), Symfony merges the included page content into the main one
before sending the response to the client. But if you use the esi
renderer (i.e. call render_esi()) and if Symfony detects that it's
talking to a gateway cache that supports ESI, it generates an ESI
include tag. But if there is no gateway cache or if it does not
support ESI, Symfony will just merge the included page content within
the main one as it would have done if you had used render().
See Using ESI in Symfony
The following syntax will work in your case:
{{ render_esi(url('_internal_main_navigation', {})) }}
If you'd like to render by controller-name, you could turn your controller into a service and refer to it by the name of the service (i.e. mybundle_controller):
{{ render_esi(controller('mybundle_controller:menuAction', {})) }}

Variables are being ignored using the Twig Include template tag

I have setup the following:
{% include '_elements/page-heading.html' with {'shortTitle': 'entry.shortTitle','title':'entry.title'} %}
However, when the page renders this template it is actually outputting "entry.shortTitle" in the page when it should surely actually know what the entry.title is for this page.
e.g. it should say "Latest News" not "entry.title".
Just wondering why this would be?
Thanks!
Enclosing entry.shortTitle with (single) quotes tells Twig that this simply is a string. When you want to pass the value of a variable, you have to leave away the quotes:
{% include '_elements/page-heading.html' with { 'shortTitle': entry.shortTitle, 'title': entry.title } %}

How to render only one field of a form with symfony

I want to render only one field of a form. When i put {{form_end(form)}} every other field are coming (symfony doc show it clearly) but how to render only one field ? If i dont put {{form_end(form)}}, there is only one field, but no save button
thanks
Yes, CSS can do the trick. But do you want the working of your application to depend on client side styling rules? In most cases it might beter not to render the field HTML at all.
There are two ways in which you can fix this in your template.
Put {% do form.field_you_want_to_hide.setRendered %} before your {{form_end(form)}}.
This will mark the field as rendered and thus it will not show up when form_rest is called.
Instead of {{form_end(form)}}, use {{ form_end(form, {'render_rest': false}) }}, as explained in the Symfony Twig documentation.
It would be even better to change your form class such that the fields are removed from your form. Is it your own form you would like to render, or a form from a third party bundle?

Creating menu on symfony2.3 using render

on my Admin template I've used render function to add the menu.
The controller sidebar add all links from db.
The problem is made when i want to add "current" class because i can't access of current url/controller from a render request.
{{ render(controller('AdminDashboardBundle:Template:sidebar')) }}
How I can access to all informations from the render controller (without pass a var )?
Thanks
The RequestStack service has been built with Symfony 2.4. If you declare your Template controller as a service and inject RequestStack, you'll be able to use your current render call without passing arguments.
But you are speaking about Symfony 2.3, and unfortunately I don't think it is possible to do what you want without arguments. Here are some example on how to pass the current route / the URL as an argument of your controller.
1) Passing the URL :
{{
render(controller('AdminDashboardBundle:Template:sidebar', {
'url': app.request.requesturi
}))
}}
2) Passing the route :
{{
render(controller('AdminDashboardBundle:Template:sidebar', {
'route': app.request.attributes.get('_route'),
'route_params': app.request.attributes.get('_route_params')
}))
}}
I know you want to use Symfony2.3 and this call without passing vars, I think that's simply not possible because of how work scopes.

Resources