TWIG variables between templates? - symfony

Beeing completely new to TWIG (it's also my first templating language) I have a little problem understanding the variables.
Heres what I need:
I have 2 layouts. One inheriting from the other.
On the first one I need to put an if on a div to add a class if on the second layout a variable is declared.
Thanks in advance.

Say in Symfony you write:
return $this->render('::index.html.twig', array('variable' => $somevar));
And 'index.html.twig' looks like this:
{% extends '::foo.html.twig' %}
{# some contents #}
and 'foo.html.twig' looks like this:
{{ variable }}
It should just work. If it doesn't work, post some code and errors here, and I'll see what I can do to help. Obviously this example is unrealistic, but all templates should have access to all variables passed from Symfony, in addition to the global ones and anything you define as Twig extensions.

Related

Is it possible to set a new entity directly from twig?

Sometime i need to check if an user can comment from a voter, obviously at this point of the code the comment does not yet exist, but still i need to check if the user is allowed to comment or not.
From the controller i would usually do $this->isGranted('create', new Comment()) but how i'm supposed to do the same thing in twig? I can't find a clear explaination, and i obviously can't do something like {% if is_granted('create', new comment()) %}.
Is there a way to do this without hacking an object from the controller such as rendering a new Comment() from the controller? Doing so will allow me to avoid a lot of spaghetti code in my voters.
you can extend twig with Symfony Twig Extensions
Look at this documentation link:
Symfony Twig Extensions
Inside your twig you can use is_granted like this:
{{ is_granted(role, object = null, field = null) }}

How to extends dynamic template in Twig?

i need to extends different base template in twig. this is possible? in my code i use dinamically render template with a controller like this
{{ render(controller('AppBundle:Default:menuManager')) }}
in that controller i use one action to choose the right template to render in my page, and this work fine. But in this case is different: i what change my base default (so i presume to extends it, right?) but i don't know how do this. Something like this?
{{ extends(controller('AppBundle:Default:baseManager')) }}
But this code don't work. Is possible? There is a different way? Thanks
This depends on the conditions for choosing the template base but you can use a twig extension. I use that in one project :
{% extends app.request.host | switchBaseTemplate %}
In this example, I use the host for the condition.
You can then write a twig extension easily, as explained here :
http://symfony.com/doc/current/templating/twig_extension.html
Have good dev.

Timber/Twig define Block

I'm new to Timber/Twig, but so far I'm loving it!
I would like to have a folder with partials/components or "blocks" as Timber/Twig calls them, so I could have say a "video.twig" component, that can be reused through out the page.
1) How can I "register" the components/block in a folder?
2) How can I "feed" the component/block with data? I would like to do something like this:
{% block component DATA %}
The syntax in include looks like this:
{% include "comment.twig" with {comment:cmt} %}
It may work for the block too. Give it a shot.

How to render a submenu in symfony-cmf

I am desperately trying to render a submenu in symfony-cmf.
Example
Structure:
page1
├─p1-subpage1
├─p1-subpage2
└─p1-subpage3
page2
├─p2-subpage1
└─p2-subpage2
Whenever the current page is somewhere within the page1 hierarchy it should use p1-subpage* to render the menu, when I am within the page2 hierarchy it should use p2-subpage* to render the menu. Technically that means it should set the current item to the parent of the 1st level (if it's not already on it) and render one level of nodes (e.g. knp_menu_render('main', { depth: 1 })).
The problem can be split in two parts:
Rendering a (sub-)menu from a given node
Retrieving the current node
Thoughts and Trials
TWIG: It has been suggested to support rendering submenus as a functionality of the KnpMenu itself, but it hasn't been done. As a workaround registering a twig extension has been provided by someone in the issue. However this extension is based on the getCurrentItem Method which has been removed with KNP-Menu 2.0. Although the cmf currently uses v1.1 of the knp-menubundle, this is going to change soon
TWIG: The CnertaBreadcrumbBundle would bring back this functionality, but depends on KNP-Menu 2.0 as well.
TWIG: Using a hack similar as suggested here. It checks the current URI, counts the number of slashes and decides based on that what to use. This could probably work. Problem here: I don't have cmfMainContent variable defined, nor can I find anything similar in my {{ dump() }} (nothing containig a menu either).
RouteVoter: The cmf itself has some MenuVoters itself, which are well documented what they are, but not how to use them. I don't think that there is any way to access that functionality whithin twig nor do I know how to intercept the menu building.
Thanks for any help.
have a look here for an example of using voters to make decision about what to highlight:
https://github.com/dbu/conference-tutorial-1.0/pull/20
aside from this we are making good progress on a KnpMenu 2.x compatible version of our MenuBundle but it might be until January until we make a stable release of it (but we might make one earlier .. we will see):
https://github.com/symfony-cmf/MenuBundle/pull/214
I have created a bundle yesterday for my own, similiar, use case.
However as all of my pages share the same route you might need to adapt it quite a bit.
I still think you might find some inspiration, especially for the second part of your problem.
My Bundle:
https://github.com/burki94/RecursiveMenuBundle/blob/master/README.md
AbstractRecursiveBuilder: https://github.com/burki94/RecursiveMenuBundle/blob/master/Menu/AbstractRecursiveBuilder.php:
This is not really a solution because it's not following my requirements of being compatible with KnpMenu 2.*. But this deprecated solution is easy:
{% set currentItem = knp_menu_get('main').currentItem %}
{% if currentItem is not null %}
{% if currentItem.getLevel() == 1 %}
{% set main = currentItem %}
{% else %}
{% set main = currentItem.getParent() %}
{% endif %}
{{ knp_menu_render(main, { 'template': 'ComBundle:Default:left_menu.html.twig', 'currentClass': 'uk-active' }) }}
{% endif %}

How to reference twig for custom field types in dedicated bundle?

I am (still) trying to introduce http://xoxco.com/clickable/jquery-tags-input into a dedicated bundle. As far, I have a type as a child of text and a data transformer that converts comma-separated strings into arrays of Objects and vice versa.
Now I want to decorate the text field with the JQuery code linked above. As far as I understand, I have to define a block like
{% block manytomanycomboselector_widget %}
{% spaceless %}
{{ block('text_widget') }}
<script>
$(function(){
$("#{{ id }}").tagsInput();
});
</script>
{% endspaceless %}
{% endblock manytomanycomboselector_widget %}
in [MyTypeBundle]Resources/views/Form/fields.html.twig
Now, both the documentation and the answers for this question at StackOverflow state that I have to reference fields.html.twig somewhere either in the template that uses the form or in app/, but this doesn't seem to be necessarily for other field-type bundles, though I cannot see in their code why.
What do I have to configure inside the bundle besides this block in this file?
Also I didn't get where I have to put the css and js requirements for the header and how I deal with general requirements like jQuery itself.
I have the same issue & I resolve it by merging my field template in the twig.form.resources parameter.
So, in the DI extension of my bundle (MyBundle/DependencyInjection/MyBundleExtension.php), I add:
$container->setParameter('twig.form.resources', array_merge(
array('MyBundle:Form:field_widget.html.twig'),
$container->getParameter('twig.form.resources')
));
Be aware, your bundle must be registered after the TwigBundle in your AppKernel.
EDIT:
A form field is not linked to any JS or CSS. So, IMO, you have 2 solutions.
Firstly, you directly wrap your JS & CSS in your field template and your bundle stays stand-alone.
Secondly, you instruct final users that they need to include manually some JSS & CSS each time they use your field type.
The IoFormBundle & GenemuFormBundle uses the second solution like explain in their documentation.

Resources