Symfony translation web site and view the list of languages - php

Hello I come to because I need a little help,
I want to translate my website into 3 languages: en, fr, es
I translated everything in the translation file but the problem is not how to display the choice of language on the website and also how to display it in the url
in my balise html :
<html lang="{{ app.request.locale }}">
and my paramters.yaml :
parameters:
locale: fr
in my translation file I have 3 files like this :
messages.fr.yml
messages.en.yml
messages.es.yml
I want to display a URL like this
www.mydomaine.com/fr/accueil
www.mydomaine.com/en/home
www.mydomaine.com/es/acogida
And how show lists of the links? Towards it is languages ?

Well, the following solution is tested on symfony 3.4, might be a bit different for symfony 4.* versions.
In your config.yml set all the languages site will operate on under parameters option, like this:
parameters:
locale: fr
locales: [en, fr, es]
Again in config.yml set the translator fallback locale & paths to your translations:
framework:
translator:
fallback: "%locale%"
paths: ['%kernel.root_dir%/../src/AppBundle/Resources/translations']
Then define your routes this way (yml definition example):
home:
path: /{_locale}/home
defaults: { _controller: AppBundle:Default:home }
Then all may access your home page with every locale you provided (answering question how to display language in the url).
www.mydomaine.com/fr/home
www.mydomaine.com/en/home
www.mydomaine.com/es/home
Now if the question's is also about how to get translated content on your web site page - You can use different file formats for keeping translations, I will go again with .yml as for example. Usually translations are put to files like messages.en.yml (as for other languages, create same files with different locale, e.g. messages.fr.yml).
Then assuming you have a key foo in your translations files, e.g. foo: bar, you may display its value in twig using trans filter: {{ 'foo'|trans({}, 'messages')} }}.
More information you may find in official documentation

Related

Creating URLs containing the locale in Symfony 4

I am creating a Symfony 4 web app that supports multiple languages. The routing is done, so I can have /en/suchpage or /de/suchpage. I am now looking for a way to link to "suchpage" using the right locale.
Routing looks as follows:
suchpage:
path: /{_locale}/suchpage/
controller: App\Controller\SimplePageController::such
requirements:
maw: '%app.locales%'
defaults:
_locale: '%locale%'
I am using Twig, and it is from Twig templates that I need to be able to link to the right version of a page. This "works":
{{ path('suchpage', {'_locale': app.request.locale}) }}
It has two issues though:
I do not want to be repeating this all over the place. Something like {{ page('suchpage') }} would be much better. Does a function like this exist? Can path() be made to behave like this?
This fails if the locale was not specified in the request, as can happen, since it is not required on all pages (since some have a default).
There is a maintened bundle, JMSI18nRoutingBundle, to achieve what you need.
composer require jms/i18n-routing-bundle
Some usefull links about this bundle :
Packagist : https://packagist.org/packages/jms/i18n-routing-bundle
GitHub : https://github.com/schmittjoh/JMSI18nRoutingBundle

Adding multi language option to a symfony 3 project

Reading the documentation of symfony 3, I got very confused, and I'm not sure if I'm doing everything right. This is how one of my normal controller looked at the start:
class IndexController extends Controller
{
/**
* #Route("/", name="index")
*/
public function indexAction(Request $request)
{
$articles = $this->getDoctrine()
->getRepository(Article::class)->findAll();
return $this->render("index.html.twig", array(
'articles' => $articles
));
}
}
I wanted to add option for multy language. Before symfony I saw doing this with simple saving in session the language, and a button for changing it. In symfony I added a translations folder, and a file for each language.
//messages.en.yml
base.menu.1: Home
base.menu.2: Products
base.menu.3: Brands
//messages.bg.yml
base.menu.1: Начало
base.menu.2: Продукти
base.menu.3: Марки
After this I saw in some titorial that I can add my _locale, in my route like this:
#Route("{_locale}/", name="index")
And this actually worked. My I could of change my home page's language by going in bg/, or en/.
But the locale variabe wasn't saved anywhere. If I went to other page, it doesn't know what language was setted up before. So I read more, and was I can fix this, by saving all of my routes in routing.yml like this:
index:
path: /{_locale}/
defaults: { _controller: AppBundle:Index:index }
requirements:
_locale: '%app.locales%'
and then set up my config:
parameters:
locale: bg
app.locales: bg|en
framework:
translator: { fallbacks: ['%locale%'] }
All this is working, except I have to move my routing from their controllers to routing.yml. I want to ask if this is the right method, to do all of this, because I'm not sure, the documentation isn't 100% clear (most likely I just cant understand it), and can't find any good titorials.
use the 'make locale sticky' method, as stated above,
then set the locale using
$request->setLocale($locale);
$request->getSession()->set('_locale', $locale);
//now redirect as the locale change will take affect on the next pageload
(set both, and redirect)
Whether by Annotation or by configuration in YAML, the end result is the same. You'll fall into a debate of for/against annotations if you're not careful though, and I'll just go ahead and say that I do not recommend them personally. Your routing.yml approach is the approach I would recommend, and should work perfectly fine.
I believe that you've read Symfony's post on How to Work with the User's Locale and what you're looking for is Making the Locale "Sticky" during a User's Session.
Symfony stores the locale setting in the Request, which means that this setting is not automtically saved ("sticky") across requests. But, you can store the locale in the session, so that it's used on subsequent requests.

Different host and routes in Symfony witho JMS i18n

I want different host and different routes in my multicountry web with Symfony 3. I used the JMS i18n routing for this.
My config YML file:
jms_i18n_routing:
default_locale: es_ES
locales: [es_ES, fr_FR, en_GB]
strategy: custom
hosts:
es_ES: www.aaa.local
fr_FR: www.aaa-fr.local
en_GB: www.aaa-uk.local
redirect_to_host: true
With this, I can use different host correctly, but I don't know how I can "translate" the routes, f.ex: /contacto /contact and /contact.
I want load differents routing.yml depends on the locale.
When using the JMSI18nRoutingBundle your routes are being Translated automatically based on your route_name using the routes domain (Symfony Translation Component).
So, assumed your route_name is contact, just create a Translations like this:
id/source: contact
domain: routes
locale: en
translation/target: /contact
id/source: contact
domain: routes
locale: es
translation/target: /contacto
Now your routes using the Symfony router (which is wrapped by the one from the bundle) will return automatically the translated route from the current locale.
If you want to translate it to a specific locale, just add the route parameter _locale like this:
{{ path("contact", {"_locale": "es"}) }}
or
$this->get('router')->generate('contact', array('_locale' => 'es'));

Symfony translating routes using BeSimple/BeSimpleI18nRoutingBundle duplicate routes

I'm creating a multi language website and I'm using BeSimple/BeSimpleI18nRoutingBundle for route translations. Route in my config looks like that:
about:
locales: { en: "/{_locale}/about-us", lt: "/{_locale}/apie-mus" }
defaults: { _controller: BaseBundle:Base:about }
However in this case I get duplicate route as if I enter /en/about-us or /lt/about-us it works in both ways. but in the second way it should be 404 error because the route for lt locale should be /lt/apie-mus which also works fine.
Is there any way of fixing that? Or maybe any better ways of translating routes?
However in this case I get duplicate route
There is one route per language:
$ app/console router:debug
about.en ANY ANY ANY /{_locale}/about-us
about.lt ANY ANY ANY /{_locale}/apie-mus
When you are on the URL /lt/about-us the UrlMatcher will match the en version:
$ app/console router:match /lt/about-us
Route "about.en" matches
[router] Route "about.en"
Name about.en
Path /{_locale}/about-us
Path Regex #^/(?P<_locale>[^/]++)/about\-us$#s
Host ANY
Host Regex
Scheme ANY
Method ANY
Class Symfony\Component\Routing\Route
Defaults _controller: AppBundle:Default:index
_locale: en
Requirements NO CUSTOM
Options compiler_class: Symfony\Component\Routing\RouteCompiler
In this case, the local will be en and not lt.
But I don't think that you should worry about it because the only way that a visitor will visite /lt/about-us is by editing the URL himself.
After battle with BeSimple I switched my project to JMSI18nRoutingBundle in 10 minutes. It works well and resolves problem with routes. Firstly: it containes multiple modes of prefixation (with locale) and secondly it allows to translate every route.

Change routing basing on language, translate URL parts

Is it posible in Symfony 1.2 to change routing basing on lang?
In my system there are 2 langs - EN, PL
Sample route look like this:
produkt_show:
url: /products/:pslug/:idslug
param: { module: product, action: show }
What I want to achieve: I want produkt_show route to match [and generate] different url depending on the current language. So in PL my url would look like this:
/produkty/:pslug/:idslug
It is essential those routes to have the same names. I can't change all url_for/link_to etc. calls and pass different routes names to them.
If anything is unclear -please, ask ahead.
UPDATE
according to the advice of j0k I used plugin. I choosed zxI18nRoutingPlugin. It seems to partialy work - it resolves url to right route if I write it literally in browser address input. But it still generates URLs that are not translated.
e.g.
my route:
contact_form:
url: /contact_form
param: { module: contact_request, action: new}
trans unit:
<trans-unit>
<source>contact_form</source>
<target>formularz-kontaktowy</target>
</trans-unit>
generated url:
Kontakt
But if I type BASE_URL/formularz-kontaktowy - right action is executed.
This is my configuration from dev toolbar:
Request:
parameterHolder:
action: new
module: contact_request
sf_culture: pl
attributeHolder:
sf_route: 'sfRoute Object()'
User
options:
auto_shutdown: false
culture: pl
default_culture: pl_PL
use_flash: true
logging: '1'
timeout: 10800
attributeHolder:
symfony/user/sfUser/attributes: { LAST_CATEGORY_ID_PATH_VAR: null, product_elements_on_page: 50 }
culture: pl_PL
I just can't figure it out, I would appreciate any help, suggestions, anything, because I'm stuck with this.
UPDATE 2
factories.yml:
all:
routing:
# class: sfPatternRouting
# param:
# generate_shortest_url: true
# extra_parameters_as_query_string: true
class: zxPatternI18NRouting
param:
generate_shortest_url: true
extra_parameters_as_query_string: true
use_cultures: [pl, de, en, ru] # destination cultures. Plugin looks for translations for these cultures.
culture_into_url: false # defines if culture should be always placed in url
There are some plugins that can handle such case (or at least gave you a way to do this on your own):
zxI18nRoutingPlugin
The zxI18nRoutingPlugin extends sfPatternRouting class giving possibility to translate routes patterns static text to different languages.
gbI18nRoutePlugin
Easy way to have I18N Routing.
An other option can be to add the culture inside the route, like /pl/product, /en/product, etc ..

Categories