How do I access the Twig path() function from a Controller? - symfony

Okay, I know I can't literally call a twig template function from a controller, but to make links, I usually do the {{ path('_routeName') }} and that's great.
However, now I want to formulate some links in the controller that will then be passed to the template via parameters like this:
$params = array(
'breadcrumbs' = array(
'Donuts' => '/donuts',
'Bearclaws' => '/donuts/bearclaws',
'Strawberry bearclaw' => null,
),
);
return $this->render('Bundle:Donut:info.html.twig', $params);
Except I don't want to hard-code those links. What I'd like is to be able to do
'Donuts' => path('_donutRoute'),
but how to reach the path method or equivalent?

If your controller is extending the Symfony2 Controller (Symfony\Bundle\FrameworkBundle\Controller\Controller) you can use the following to generate urls like this :
$this->generateUrl('_donutRoute')

If you want it with parameters use the following:
$this->generateUrl('_donutRoute', array('param1'=>'val1', 'param2'=>'val2'))

I found an alternative way to do this that I feel is equal to the one proposed by #d.syph.3r
The plan is to do:
'breadcrumbs' = array(
'Donuts' => 'donutsRoute',
'Bearclaws' => 'bearclawRoute',
'Strawberry bearclaw' => null,
)
Then in the twig template, do:
{% for name, route in breadcrumbs %}
{{ path(route) }}
The advantage here is that the Controller is not generating any HTML in this case.

Related

Use the category node name as a label in Zikula

I do use Zikula 1.5.2dev
My module is generated with modulestudio
I have made two entries in the Category registry. One is showing at the node "Global" and one at the node "Type"
In Global are several entries I can select. Some other entries are inside Type.
The selection is working in my template like expected. But how can I use the node names as a label?
I can not figure out in which template I have to place to label (have to do more searching). But more important, I do not know the right twig syntax to catch the categories label.
if you assign a category to the template, the properties are accessible like normal class properties.
{{ category.name }}
if you need the display name, this is stored as an array with lang codes as keys
{{ category.display_name['de'] }}
Hope that helps.
That sounds good. But now I have recognized this label seem not to be placed in a pure template. There is a form type defined:
class ShowRoomItemType extends AbstractShowRoomItemType
{
/**
* #inheritDoc
*/
public function addCategoriesField(FormBuilderInterface $builder, array $options)
{
$builder->add('categories', CategoriesType::class, [
'label' => $this->__('Category') . ':',
'empty_data' => null,
'attr' => [
'class' => 'category-selector'
],
'required' => false,
'multiple' => false,
'module' => 'RKShowRoomModule',
'entity' => 'ShowRoomItemEntity',
'entityCategoryClass' => 'RK\ShowRoomModule\Entity\ShowRoomItemCategoryEntity',
// added:
'includeGrandChildren' => true
]);
}
}
In my template it is called like this:
{{ form_row(quickNavForm.categories) }}
For this my skills are very limmited. I will write a feature request at modulestudio. (https://github.com/Guite/MostGenerator/issues/1147)
But big thanks for your reply!
This has been fixed for core 1.5.4 / 2.0.4 in https://github.com/zikula/core/pull/3846

Symfony2 KnpMenuBundle - Following tutorial and came across this error

I followed this tutorial:
https://github.com/KnpLabs/KnpMenuBundle/blob/master/Resources/doc/index.md#installation
And have come across the following error:
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "page_show" as such route does not exist.") in /var/www/bundles/src/Acme/DemoBundle/Resources/views/Default/index.html.twig at line 4.
Is there a step I am missing here to pass something to a controller?
From link:
use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
class Builder extends ContainerAware
{
public function mainMenu(FactoryInterface $factory, array $options)
{
$menu = $factory->createItem('root');
$menu->addChild('Home', array('route' => 'homepage'));
$menu->addChild('About Me', array(
'route' => 'page_show',
'routeParameters' => array('id' => 42)
));
// ... add more children
return $menu;
}
}
To actually render the menu, just do the following from anywhere in any Twig template:
{{ knp_menu_render('AcmeDemoBundle:Builder:mainMenu') }}
Do a ./app/console router:debug - it will show you all the routes registered in your application. I am guessing page_show is not one of them.
The documentation you are using probably expects you to add your own routes/pages to the menu like this:
$menu->addChild('Home', array('route' => 'homepage'));
Where 'homepage' has to already exist. So does 'show_page'. So you need a controller somewhere that handles a request to the show_page route, or exchange show_page for a route that you have already defined in your app. Hope I made sense.
Following the tutorial exactly, this error is caused by line 25 in the file
2 // src/Acme/MainBundle/Menu/MenuBuilder.php
...
25 $menu->addChild('Home', array('route' => 'homepage'));
The tutorial code assumes that you have a route called 'homepage'. Assuming you set this up inside a custom Bundle, then a quick way to solve this problem so you can get the tutorial up and running is to go to...
// src/Acme/MainBundle/Resources/config/routing.yml
...and copy the homepage route from there (will look something like acme_main_bundle_homepage)

How to add classes to Laravel 4 Forms

Probably, it is a simple answer but I cannot find any documentation regarding this. I have laid out a form using Laravel 4 and it seems to be working fine but now I need to style it. How can I add classes to the form when its using blade?
{{ Form::open(array('url' => 'foo/bar')) }}
I have a class set up for the form and the buttons but I am not sure how to add it to the blade template.
You may try this
{{ Form::open(array('url' => url('foo/bar'), 'class'=>'form', 'id'=>'frmFoo', 'style'=>'border:solid gray 1px')) }}
You can add inline style, class, id etc.
As far as I know, you can easily pass additional attributes to the open() methods argument:
echo Form::open(array('url' => 'foo/bar', 'method' => 'put', 'class' => 'form-bootstrap'))
Check out the L4 docs for more information http://laravel.com/docs/html

twig render controller() passes an array instead of an object

I'm trying to render a controller amd send the $from->createView() object. Now, this works in <=2.1, but I can't seem to get it to work in 2.2.
Here is the code:
EventsContoller::newAction
return $this->render('SplurginEventsBundle:SplurginEventEvents:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
'existingFiles'=>$existingFiles,
'editId'=>$editId,
'isNew'=>true,
));
Right now the form variable is holding an object of the form view, I verified with var_dump.
In twig:
{% render controller('JulLocationBundle:Googlemaps:placesAutocomplete' , {locationForm: form}) %}
When I go to the controller placesAutocomplete and again use var_dump, I can see that it is an array and not an object.
How can I send an object and not an array to the controller being rendered?
EDIT :
this issue was resolved , with lot's of edits .. if any one is interested in the JulLocationBundle i will provide a pull request in a few days .
try this :
{{ render(controller('JulLocationBundle:Googlemaps:placesAutocomplete' , {locationForm: form})) }}
http://symfony.com/doc/current/book/templating.html#embedding-controllers

How can I add css classes to specific symfony2 form choices?

I could do this with Javascript, but I was wondering if I could add a css class to specific symfony2 form choices (not the choice field itself, but the individual choices).
For example I want to apply different css styles to individual 'option' tags inside a 'select'. I could only find a way to add a class to the tag.
Thanks in advance.
I think you can simply do:
{{ form_widget(form.name, { 'attr' : { 'class' : 'myClass' } }) }}
... as explained here, without creating your own form style.
You can override the layout of specific widgets in your form, which means you can override the way the select renders and put in custom code to check what the value of the option is and output your custom class there.
You need to apply a custom layout to your form, like so
{% form_theme form 'form_theme.html.twig' %}
Then inside the layout file you need to override the specific field for that specific form (unless of course you want to edit the choice_widget directly in which case all fields that use choice will have the functionality).
To do that you have to copy the widget, so choice_widget, then name it [_formName_fieldName_widget]
So if your form name was events and your field name was requireTickets, it'd be _events_requireTickets_widget
The answers that were already provided are very good, and I think #CriticalImpact's is the most flexible. But I just wanted to mention that if you're using a form class, you can also add extra attributes to the field via the form builder definition itself:
class SomeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('someField', "text", array("attr" => array("class" => "someCssClass")))
->add("save", "submit");
}
}
I've found this helpful for basic forms, because it still allows you to make a simple {{ form(someForm) }} call in your Twig file.
(Note that this solution still has the drawback that #CriticalImpact mentioned above)
Add attributes like CSS styles to individual choices can nowadays be achieved with choice_attr, e.g.:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('attending', ChoiceType::class, array(
'choices' => array(
'Yes' => true,
'No' => false,
'Maybe' => null,
),
'choice_attr' => function($val, $key, $index) {
// adds a class like attending_yes, attending_no, etc
return ['class' => 'attending_'.strtolower($key)];
},
));

Resources