Symfony2, how to pass a parameter off route - symfony

Id like to know how to pass a parameter off route
route:
frontend_agences_list:
path: /agences/{page}
defaults: { _controller: ProjectFrontendBundle:Frontend:listAgences, page: 1 }
Is it like this ?
twig:
<a href="{{ path('frontend_agences_list') }}?mode=list">
<a href="{{ path('frontend_agences_list') }}?mode=grid">
<a href="{{ path('frontend_agences_list') }}?mode=block">
in fact, I'd like to display results in 3 modes, list , grid and block. In the controller I do a test ,If mode=list so render "list-view.html.twig", elseif mode=grid so render "grid-view.html.twig" ....
Is it the good way to do this or there is another way to do it ?

Twig:
list mode
grid mode
block mode
Your controller:
public function listAgencesAction()
{
$mode = $this->get('request')->get('mode');
if($mode == 'list') {
...
}
}

Related

Symfony Twig - get default _locale in twig

I'm adding a language switcher on my website.
my parameters are like this :
avc_coming_soon:
resource: "#AVCComingSoonBundle/Controller/"
type: annotation
prefix: /{_locale}
defaults:
_locale: en
requirements:
_locale: |fr
en is set by default
In my twig, I did that:
<div class="languages">
<ul class="lang-menu">
<li class="en"><img src="{{ asset('images/flag_en.gif') }}" alt="EN"></li>
<li class="fr"><img src="{{ asset('images/flag_fr.gif') }}" alt="FR"></li>
</ul>
</div>
But when I click on 'English', my path become www.mysite.com/en or the good route is www.mysite.com/ (without the /en) because in parameters, I have this :
defaults:
_locale: en
How to get the default _locale in twig ?
{{ path(app.request.get('_route'), {'_locale': <<<default>>> }) }}
thank you :)
You need to use app.request.attributes:
{{ path(app.request.get('_route'), {'_locale': app.request.attributes.get('_locale') }) }}
If you have configuration in controller you need to set default value in function parameter:
/**
* #Route("/", name="coming_soon", options={"expose"=true}, requirements={"_locale" = "fr|en"})
*/
public function indexAction($_locale = 'en')
{
...
}
I use this bundle: https://github.com/schmittjoh/JMSI18nRoutingBundle
Thanks to the bundle I never have to mess with locales..
You can configure the bundle to prefix everything except the default locale (which is what you wan't, reading the comments to the other answer).
And for the language switcher you simply set the _locale on any given route.
when using '%locale%' parameter from service.yaml the value in twig file does not change using subscriber. Using this code works for me:
app.request.session.get('_locale')

redirect to page#about using symfony&twig

I'm using Symfony , I wanna redirect the user to a specific frame in a page
So How can i translate this <a href="index.html#about"/> to twig ? I tried <a href="{{path('pl_index')}}#about"/> but it doesnt work
in twig you can use {{path('_welcome') }} and it will send you to your home index, check your route.yml and you can see what are the paths generated by symfony.
for example this is my config.yml:
//savabundle config.yml
sava_inventario_construccion:
path: /productos/construccion
defaults: { _controller: savaInventarioBundle:Inventario:construccion }
sava_inventario_index:
path: /productos/
defaults: { _controller: savaInventarioBundle:Inventario:index }
if i want to generate www.mypage.com/productos/construccion#about link, this is what my html should look like
<a href="{{path('sava_inventario_construccion') }}#about"/>
you can read more in here
http://symfony.com/doc/current/book/templating.html

Checking class scope ACLs in Twig templates

I'm building a small-scale symfony project, as much for my own edification as anything else.
I have a Network class which extends Entity in a Doctrine ORM setup, and a bunch of users (also entities in a Doctrine setup). I've given some users the CREATE permission on the Network class, and that seems to be working. At least the exception is thrown when I expect it:
$securityContext = $this->get('security.context');
$objectId = new ObjectIdentity('class', 'Acme\\AcmeBundle\\Entity\\Network');
if(false === $securityContext->isGranted('CREATE', $objectId)) {
throw new AccessDeniedException("You do not have permission.");
}
But I'd like to check the permission in a twig template, something like this:
{% if is_granted('CREATE', 'Acme\\AcmeBundle\\Entity\\Network') %}
<li>
<a href="{{ path('network_new') }}">
Create a new entry
</a>
</li>
{% endif %}
My goal here is to only show the link if the user has permission to create a new network. But the is_granted() call seems to be returning true for all the users, not just the ones that I've explicitly granted CREATE to, or at least link is always appearing, even for users that have no ACL/ACE entries for the Network class.
It turns out that is_granted() expects an object as the second parameter. This is a Twig Extension that provides a classId() function to return an ObjectIdentifier object.
class ClassIdExtension extends \Twig_Extension
{
public function getFunctions()
{
return array(
'classId' => new \Twig_SimpleFunction('classId', array($this, 'classId'))
);
}
public function classId($class)
{
return new ObjectIdentity('class', $class);
}
public function getName()
{
return 'acme_classidextension';
}
}
Once it's registered as a service in Symfony, you can use it in Twig templates like so:
{% if is_granted('CREATE', classId('Acme\\AcmeBundle\\Entity\\Network')) %}
<li>
<a href="{{ path('network_new') }}">
Create a new entry
</a>
</li>
{% endif %}
And it works as expected.

Make controller only give a value to template, not render it - Symfony2

I have a twig template with the navbar and all other templates (the pages) include this template. I have a value in it which should be equal to all pages. How to set this value?
I tries something like this in a controller:
public function setNotificationsAction() {
$this->setNotifications();
return $this->render('AcmeMyBundle::navbar.html.twig', array(
'debts' => $this->notifications,
));
}
and then this in the template:
<span class="badge badge-important">
{% render(controller('AcmeMyBundle:DebtsLoansController:setNotifications')) %}
{{ debts }}
</span>
The result I want it like this:
<span class="badge badge-important">
3
</span>
but the number should be different and the controller should tell it.
I also tried to create a function which returns the value and to call it in the way like above.
I also tried this syntax
{{ render(controller('AcmeMyBundle:DebtsLoansController:setNotifications')) }}
but it isn't working, too.
I get the following mistake:
The function "controller" does not exist in AcmeMyBundle::navbar.html.twig at line 6
Do you have any idea how to achive this and not to have to edit each controller and each template :S Thanks very much in advance!
Well, I would suggest creating your own Twig extension. Something around the lines of:
<span class="badge">
{{ acme_notifications() }}
</span>
namespace Acme\DemoBundle\Twig\AcmeDemoExtension
class AcmeDemoExtension extends \Twig_Extension
{
public function getFunctions()
{
return array(
'acme_notifications' => new \Twig_Function_Method($this, 'getNotifications');
);
}
public function getNotifications()
{
$notifications = ...;
return $notifications;
}
}
Read more about creating your own Twig extension in the Symfony2 documentation.
You don't need the controller part :
{% render "AcmeBundle:MyController:MyAction" %}
Be aware however, that a render is a completely new request going through the whole Symfony lifecycle and thus can impact performance if you abuse it.
Edit : And as #Wouter J has pointed out : prior to Symfony 2.2 use above notation. After Symfony 2.2 the following has to be used :
{{ render(controller('AcmeArticleBundle:Article:recentArticles', { 'max': 3 })) }}

symfony2 form is not displaying

I am learning symfony2 and i have created one form in controller which is as bellow.
the controller file as DefaultController.php
namespace Banner\TestBundle\Controller;
use Banner\TestBundle\Entity\Contact;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Banner\TestBundle\Entity\Task;
use Symfony\Components\HttpFoundation\Request;
class DefaultController extends Controller
{
public function newAction(Request $request)
{
echo "The controller is called ";
$task = new Task();
$task->setTask("Write a blog Post ");
$task->setDueDate(new DateTime('tomorrow'));
$form = $this->createFormBuilder($task)
->add('task','text ')
->add('duedate','date')
->getForm();
return $this->render('BannerTestBundle:default:zoo.html.twig',array('form'=>$form->createView()));
}
}
my routing file is as below.
routing.yml
task_new:
pattern: /task/{request}
defaults: { _controller: BannerTestBundle:Default:new}
and the zoo.html.twig file is as bellow.
{% extends '::page.html.twig' %}
{% block title %}The Zoo{% endblock %}
{% block content %}
<form action="{{ path('task_new') }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit">
</form>
{% endblock %}
as i am passing the "task/GET" in my url it will shows the 'Request does not exist. error 500'.
what i basically want to do is when i pass the url the zoo.html.twig will be called. i want to display the form in zoo.html.twig.
You don't need to pass $request to your action and you don't need to put it in your route. The request object is available in global context. So
task_new:
pattern: /task-new
defaults: { _controller: BannerTestBundle:Default:new}
You can either leave it this way
public function newAction(Request $request)
or have
public function newAction()
and access request object like this
$request = $this->getRequest();
Your routing file is not properly indented so the yaml will not parse properly. Try:
task_new:
pattern: /task/{request}
defaults: { _controller: BannerTestBundle:Default:new}
Also:
It is probably a bad idea to override request that way
You don't appear to be doing anything with request in your controller

Resources