Symfony2 locale in route - php

I followed Symfony2 doc http://symfony.com/doc/2.0/book/translation.html#the-locale-and-the-url and added locale to my routes. But, I can't find the way to carry locale through routes as I place {{ path('myroute') }} in twig template, but locale always gets fallback value instead taking current locale.
I tried {{ path('myroute', {'_locale': _locale}) }} but I got error "Variable "_locale" does not exist".
Any idea?

Fixed with {{ path('address', {'_locale': app.request.attributes.get('_locale')}) }} thanks to this thread http://www.mail-archive.com/symfony-users#googlegroups.com/msg34838.html.

In Symfony2.1 the locale is stored in the request, so you have to use this:
{{ path('address', {'_locale': app.request.locale}) }}

Two pages:
localhost.lo/xx/about
localhost.lo/xx/hello/{name}
where xx - several locales described in routing.yml
-- routing.yml
home:
resource: "#JetInformBundle/Resources/config/routing.yml"
prefix: /{_locale}
requirements:
_locale: ^en|de|ru|uk|pl$
-- JetInformBundle routing.yml
hello:
pattern: /hello/{name}
defaults: { _controller: JetInformBundle:Default:index, name: 'alexander' }
about:
pattern: /about
defaults: { _controller: JetInformBundle:Default:about }
-- DefaultController.php
<?php
namespace Jet\InformBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function indexAction($name, Request $request)
{
return $this->render('JetInformBundle:Default:index.html.twig',
array('name' => $name, 'matches' => $this->matchAction($request)));
}
public function aboutAction(Request $request)
{
return $this->render('JetInformBundle:Default:about.html.twig',
array('matches' => $this->matchAction($request)));
}
protected function matchAction(Request $request)
{
return $this->get('router')->match($request->getRequestUri());
}
}
-- index.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>{{ 'hello.name'|trans }} {{ name }}!</h1>
<h3>{{ 'your.locale'|trans }} [{{ app.request.get('_locale') }}]</h3>
{% include 'JetInformBundle:Default:locales.html.twig'
with {
'uripath': 'hello',
'params': {
'name': app.request.get('name')
}
}
%}
{% include 'JetInformBundle:Default:matches.html.twig'
with { 'matches': matches } %}
<div>
<p>{{ 'return.to'|trans }} About</p>
</div>
{% endblock %}
-- about.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>{% trans %}about.page{% endtrans %}</h1>
<h3>{% trans %}your.locale{% endtrans %} [{{ app.request.get('_locale') }}]</h3>
{% include 'JetInformBundle:Default:locales.html.twig'
with { 'uripath': 'about', 'params': {}} %}
{% include 'JetInformBundle:Default:matches.html.twig'
with { 'matches': matches } %}
<div>
<p>{% trans%}return.to{% endtrans%} Hello</p>
</div>
{% endblock %}
-- locales.html.twig
{% if not params %}
{% set params = {} %}
{% endif %}
<div class="langs">
<ul>
<li>
{% if app.request.get('_locale') == 'ru' %}
Русский
{% else %}
Русский
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'en' %}
English
{% else %}
English
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'uk' %}
Украiнська
{% else %}
Украiнська
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'de' %}
Deutsch
{% else %}
Deutsch
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'pl' %}
Polish
{% else %}
Polish
{% endif %}
</li>
</ul>
</div>
-- matches.html.twig
<h5>Matches</h5>
<ol>
{% for key, value in matches %}
<li>{{ key }} : {{ value }} </li>
{% endfor %}
</ol>

Shorthand notation:
{{ path('address', {'_locale': app.session.locale}) }}

Related

Twig: Pass Twig Markup to an Include

I want to pass a macro(icon()) to a nested template of mine, through passing the markup as text.
But due to the |raw filter, Twig wont render the markup as Twig. Is there a way to achieve this? Basically I get this rendered {{ icon("phone-call") }}
main.html.twig
{% embed "Block/context_box_column_lane.html.twig" with {
'title': 'Test',
'subtitle': 'Subtitle',
'text': '
<p class="context-box-text">{{ icon("phone-call") }}</p>
'
} %}{% endembed %}
context_box_column_lane.html.twig
{% extends "Block/section_sidebar.html.twig" %}
{% block section_content %}
{% embed 'Block/context-box.html.twig' %}{% endembed %}
{% endblock %}
context-box.html.twig
{% from "#html/macros/icons.twig" import get as icon %}
<div class="b-context-box {% if has_border %}has-border{% endif %}">
{% if subtitle %}
<h3 class="section-subtitle">{{ subtitle|trans }}</h3>
{% endif %}
{% block content %}
{% if text is defined %}
{{ text|trans|raw }}
{% endif %}
{% endblock %}
</div>

Parsing current uri to get the current route params inside a partial. How to avoid?

To render TOC (categories tree) inside the base.twig view I call the render() function passing it the corresponding action url:
{% block sidebar %}
{{ render(url('toc_documents_categories')) }}
{% endblock %}
The matching partial view for the '/toc/documents' action (_toc.documents_categories.twig) is defined as follows:
{% set category_id = (current_uri|split('/'))[4] %}
{% macro recursiveCategory(category, active_category_id) %}
<li>
{% if category.children|length %}
<a><span class="icon icon-plus"></span>{{ category.name_displayed }}</a>
{% else %}
{% set active_class = active_category_id == category.id ? 'active' %}
{% set url = app.url_generator.generate('documents_by_category', {category_id: category.id}) %}
<a href="{{ url }}" class="{{ active_class }}">
{{ category.name_displayed }}
</a>
{% endif %}
{% if category.children|length %}
<ul>
{% for child in category.children %}
{{ _self.recursiveCategory(child, active_category_id) }}
{% endfor %}
</ul>
{% endif %}
</li>
{% endmacro %}
{% if categories %}
<div id="categories">
<ul>
{% for category in categories %}
{{ _self.recursiveCategory(category, category_id) }}
{% endfor %}
</ul>
</div>
{% endif %}
As you can see I'm extracting current category's id by parsing current url. This is preceded by setting the current_uri global:
$app->before(function(Request $request) use ($app) {
$app['twig']->addGlobal('current_uri', $request->getRequestUri());
});
Accessing the route information (global.request.attributes.get('_route')) inside the partial view shows the corresponding subrequest route name and not the actual request route name (master request).
Is there a way to avoid manually parsing the current uri and to get the current request route params inside the partial view?
Here's the solution.
render() issues a subrequest, so you have to use the master request context:
use Symfony\Component\HttpFoundation\Request
$app->get('/documents_categories', function(Request $request) use($app) {
$master_request = $app['request_stack']->getMasterRequest();
$current_route = $master_request->get('_route');
$active_category_id = null;
if($current_route === 'documents_by_category') {
$active_category_id = $master_request->get('_route_params')['category_id'];
}
// ... do things: parse toc tree ...
return $app['twig']->render('_toc.documents.categories.twig', array(
"categories" => $toc_tree,
"active_category_id" => $active_category_id
));
})->bind('toc_documents_categories');
Then inside the partial view you have to only reference the passed active_category_id parameter:
{% if categories %}
<div id="categories">
<ul>
{% for category in categories %}
{{ _self.recursiveCategory(category, active_category_id) }}
{% endfor %}
</ul>
</div>
{% endif %}
Thanks to #keyboardSmasher for 'Why not pass the category_id in the render function' comment. Yet I'm not sure if I did it the way he assumed.

SonataUserBundle override user profile

i want to override my user dashboard [profile show.html.twig], but i don't know how to do it. Someone can explain me or show me his code, so i can have an idea how he did it.
this is my show.html.twig:
{% extends "SonataUserBundle:Profile:action.html.twig" %}
{% block sonata_profile_content %}
{% sonata_template_box 'This is the user profile template. Feel free to override it.' %}
<div class="row row-fluid">
{% set has_center = false %}
{% for block in blocks %}
{% if block.position == 'center' %}
{% set has_center = true %}
{% endif %}
{% endfor %}
<div class="{% if has_center %}span4 col-lg-4{% else %}span6 col-lg-6{% endif %}">
{% for block in blocks %}
{% if block.position == 'left' %}
{{ sonata_block_render({ 'type': block.type, 'settings': block.settings}) }}
{% endif %}
{% endfor %}
</div>
{% if has_center %}
<div class="span4 col-lg-4">
{% for block in blocks %}
{% if block.position == 'center' %}
{{ sonata_block_render({ 'type': block.type, 'settings': block.settings}) }}
{% endif %}
{% endfor %}
</div>
{% endif %}
<div class="{% if has_center %}span4 col-lg-4{% else %}span6 col-lg-6{% endif %}">
{% for block in blocks %}
{% if block.position == 'right' %}
{{ sonata_block_render({ 'type': block.type, 'settings': block.settings}) }}
{% endif %}
{% endfor %}
</div>
</div>
{% endblock %}
Thank you.
You can override the show template in app/Resources/SonataUserBundle/views/Profile/show.html.twig.
You must clear caché at the end

flashMessage on redirect on Symfony2 not working

I have the following code in my controller:
$this->get('session')->getFlashBag()->add(
'storeinfo',
'hayooo'
);
return $this->redirect($this->generateUrl('AppMainBundle_item_detailed_view', array('id' => $picture->getId(), 'caption' => $picture->getURLCaption())), 301);
and my twig looks like this:
{% if app.session.flashbag.get('storeinfo') %}
<div class="comment-confirmation">
{% for flashMessage in app.session.flashbag.get('storeinfo') %}
<p> <b> anjing banget </b></p>
{% endfor %}
</div>
</div>
{% else %}
<p> Oopsie </p>
{% endif %}
so it goes to the first if block however inside the forloop, there is no flashMessage. Why is this?
The FOSUserBundle does something like this, you could also have a look at this great imlementation of a FlashListener
{% for type, messages in app.session.flashbag.all() %}
{% for message in messages %}
{# Will print all your messages #}
{{ message }}
{# Will do something in particular for storeinfo if you want to #}
{% if type is sameas('storeinfo') %}
<p> <b> anjing banget </b></p>
{% endif %}
{% endfor %}
{% endfor %}

Symfony2: Locale Switcher implementation without session/controller [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
So, seems everything ok after 3.5 hours......
Two pages:
localhost.lo/xx/about
localhost.lo/xx/hello/{name}
where xx - several locales described in routing.yml
-- routing.yml
home:
resource: "#JetInformBundle/Resources/config/routing.yml"
prefix: /{_locale}
requirements:
_locale: ^en|de|ru|uk|pl$
-- JetInformBundle routing.yml
hello:
pattern: /hello/{name}
defaults: { _controller: JetInformBundle:Default:index, name: 'alexander' }
about:
pattern: /about
defaults: { _controller: JetInformBundle:Default:about }
-- DefaultController.php
<?php
namespace Jet\InformBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function indexAction($name, Request $request)
{
return $this->render('JetInformBundle:Default:index.html.twig',
array('name' => $name, 'matches' => $this->matchAction($request)));
}
public function aboutAction(Request $request)
{
return $this->render('JetInformBundle:Default:about.html.twig',
array('matches' => $this->matchAction($request)));
}
protected function matchAction(Request $request)
{
return $this->get('router')->match($request->getRequestUri());
}
}
-- index.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>{{ 'hello.name'|trans }} {{ name }}!</h1>
<h3>{{ 'your.locale'|trans }} [{{ app.request.get('_locale') }}]</h3>
{% include 'JetInformBundle:Default:locales.html.twig'
with {
'uripath': 'hello',
'params': {
'name': app.request.get('name')
}
}
%}
{% include 'JetInformBundle:Default:matches.html.twig'
with { 'matches': matches } %}
<div>
<p>{{ 'return.to'|trans }} About</p>
</div>
{% endblock %}
-- about.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>{% trans %}about.page{% endtrans %}</h1>
<h3>{% trans %}your.locale{% endtrans %} [{{ app.request.get('_locale') }}]</h3>
{% include 'JetInformBundle:Default:locales.html.twig'
with { 'uripath': 'about', 'params': {}} %}
{% include 'JetInformBundle:Default:matches.html.twig'
with { 'matches': matches } %}
<div>
<p>{% trans%}return.to{% endtrans%} Hello</p>
</div>
{% endblock %}
-- locales.html.twig
{% if not params %}
{% set params = {} %}
{% endif %}
<div class="langs">
<ul>
<li>
{% if app.request.get('_locale') == 'ru' %}
Русский
{% else %}
Русский
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'en' %}
English
{% else %}
English
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'uk' %}
Украiнська
{% else %}
Украiнська
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'de' %}
Deutsch
{% else %}
Deutsch
{% endif %}
</li>
<li>
{% if app.request.get('_locale') == 'pl' %}
Polish
{% else %}
Polish
{% endif %}
</li>
</ul>
</div>
-- matches.html.twig
<h5>Matches</h5>
<ol>
{% for key, value in matches %}
<li>{{ key }} : {{ value }} </li>
{% endfor %}
</ol>
Solution without session based R/W and without LocalesController with additional request.
Hey, All, what do you think about ?
May be other solutions, another opinions ??
Just interesting...
Thanks.

Categories