access to locale variable from routing in Symfony2 - php

I got the following issue. I am developing a project in which the routes will depend upon the locale variable. Currently is working but it has some issues that I would like to fix.
The structure I got is this one:
AppBundle
->config
->routing.en.yml #routes in English
->routing.es.yml #routes in Spanish
->routing.php #in charge of making the magic
#/app/config/routing.yml
app:
resource: "#AppBundle/config/routing.php"
type: php
fos_user:
resource: "#FOSUserBundle/Resources/config/routing/all.xml"
##AppBundle/config/routing.es.yml
about_us:
path: /nosotros
defaults: { _controller: AppBundle:Default:about }
##AppBundle/config/routing.en.yml
about_us:
path: /about_us
defaults: { _controller: AppBundle:Default:about }
The php file is invoked and this is what it does
//#AppBundle/config/routing.php
<?php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Yaml\Yaml;
$collection = new RouteCollection();
$collection->addCollection(
$loader->import("#AppBundle/Controller/", "annotation")
);
$config = Yaml::parse(__DIR__."/../../../app/config/parameters.yml");
$locale = $config["parameters"]["locale"];
$routes = Yaml::parse(__DIR__."/routing.{$locale}.yml");
foreach($routes as $name => $data)
{
$collection->add($name, new Route($data["path"],$data["defaults"]));
}
return $collection;
It so far works but the problem is that is reading from the file and not from the session. I would like to know how can I inject that value from the session

Once again i am plagued with my lack of reputation and cannot just leave a comment on your post.
From what I understand, you want to make some routes available only for a given locale. For example, a french user will be able to access the route /bonjour but an english gentleman will only have the equivalent route /hello.
It is a bit weird. Why not make all routes available and change the locale to match the route? For example our french fellow will have a page in english if he tries to access the /hello url. Seems a lot more simple and handy.

Related

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.

Generate appropriate urls in multiple sub-domain hostname in Symfony2

I am developing a multi sub-domain web application in Symfony 2.
Subdomains:
admin.example.com is the main hosting site.
member.example.com is another sub-domain pointing to same source code.
As mentioned in the documentation here, I configured routing as below :
Parent Routing for member.example.com:
my_app_member:
resource: "#member.yml"
prefix: /
host: "member.example.com"
Note : The above routing is the parent route config for all routes for member.example.com defined in member.yml.
**Now I have anoter route for admin.example.com : **
admin_user_mod:
path: /admin/new
defaults: { _controller: "somecontroller" }
However if I have to generate a full url for the route admin_user_mod using code :
$modLink = $this->get("router")->generate('admin_user_mod');
The generated route path is correct but the base url still stays as member.example.com which should be admin.example.com
Is there an way, or I am missing anything in above route configuration to get the desired results.
OR
Is there any symfony event listener to overwrite router's "generate()" method call?
All your inputs are highly appreciable.
Thank you
Router has getContext() method you can use:
$context = $this->getContainer()->get('router')->getContext();
$context->setHost('admin.example.com');
As it says in the Routing Documentation, passing true as the third parameter for the generate method will generate an absolute URL.
So in your case it would be...
$modLink = $this->get('router')->generate('admin_user_mod', [], true);
Just make sure you specify the host in the route configuration when doing this. So for example your route should be...
admin_user_mod:
path: /admin/new
host: admin.example.com
defaults: { _controller: "somecontroller" }

Need Assistance with Symfony 2.7 creating first page

I am trying to learn the Symfony framework and struggling with it. The instructions are not very helpful or assume I know a lot more than I know. I am just trying to create a single web page with proper route and controller. I have been googling to find answers and made some progress but no luck yet. Right now I just have the standard install of Symfony with just default bundles etc. I created a project called "gtest3" and chose PHP for it...
I am not sure where I put the new route in (what file) or maybe it needs to be put in more than one file?
I found the "routing.yml" file which seems that is where I need to put it...
here is what is in there right now:
gtest3:
resource: "#gtest3Bundle/Resources/config/routing.php"
prefix: /
app:
resource: "#AppBundle/Controller/"
type: annotation
I am guessing I need to add something to this and put the location/filename of the controller? I have tried doing this a few ways and just get errors.
There is also the "routing.php" file that is referenced in the above code. I am not sure if this is the "controller" or if it is an additional piece of the "route". Here is the code from that file:
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('gtest3_homepage', new Route('/hello/{name}', array(
'_controller' => 'gtest3Bundle:Default:index',
)));
return $collection;
I am not sure what if anything I would add here.
Finally - there is the "DefaultConroller.php" file I found as well which may also be the controller. I dont think I need to include the code of that file here.
So - all I am trying to do is create a route of maybe "/gman" and then have the controller just echo something on the page. Super basic stuff. And I cannot figure out how to get this going.
Can anyone help with this? Thanks so much...
You can define your routes in three ways, either by using yml files, xml files, or by using a php file. This is documented behaviour.
You are from the looks of your routing.yml trying to set up a php version. I would not recommend it, and instead use configuration over coding the routing.
The annotation example would look like:
Adding a controller:
namespace Gtest3Bundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class Gtest3Bundle extends Controller
{
/**
* #Route("/hello/{name}")
* #Template()
*/
public function indexAction($name)
{
return array('name' => $name);
}
}
And add in your app/config/routing.yml:
gtest3:
resource: "#Gtest3Rights/Controller/"
type: annotation
prefix: /what-ever-you-want
You can check what kind of routes you have defined by using:
./app/console router:debug
If it doesn't appear hear, you have something misconfigured.
Please be advised that your bundle names breaks the convention of how bundles should be named in the symfony2 context.
It is advised to use NamespaceProjectBundle. This also documented. If you are stuck, try generating a bundle via the ./app/console generate:bundle. This way you can create a whole symfony2 structure which should show the default page hello/foo page just fine.
If it doesn't seem to run at all, make sure you have registered your bundle at the in the app/AppKernel.php file in the registerBundles() method.
To configure routes you can use yml, php or xml file. You can specify it in app/config/config.yml
framework:
router:
resource: "%kernel.root_dir%/config/routing.yml"
It's where you can check which file is used now.
There are some manners to store the routes.
app:
resource: "#AppBundle/Controller/"
type: annotation
This is how you use routes by writing annotations above your actions (eg indexAction) inside your controller class. Read more.
Another common approach is to build one or more .yml files inside each Bundle.
in app/config/routing.yml you should write this:
app:
resource: "#AppBundle/Resources/config/routing.yml"
prefix: /
Then you need to create the file (and directories if necessary) src/AppBundle/Resources/config/routing.yml and add the following content:
app_homepage:
path: /
defaults: { _controller: AppBundle:Default:index }
It will then try to find the DefaultController and fires the indexAction in the AppBundle (src/AppBundle/Controller/DefaultController.php).
To debug your routes simply type in your console from your projects directory:
app/console router:debug

Symfony 2 dynamic routing (e.g. for stores)

I'm new at Symfony 2, now I'm trying to get a dynamic routing, I mean really dynamic.
For example:
example.com/en/categoryLevel1/categoryLevel2/categoryLevel3/productId-ProductName
OR
example.com/en/categoryLevel1/categoryLevel2/productId-ProductName
OR
example.com/en/categoryLevel1/categoryLevel2/categoryLevel3/
The number of category levels (the category depth) have to be flexible to 100%. It must be possible and able to use one level to twenty levels.
Where is the entry point to setup this (which classes are doing those routing stuff)?
Another example is:
routes on the old page:
example.com/{categoryLvl1}/{categoryLvl2}/.../p-{productId}
at the new page are some changes in the routes:
example.com/{lang}/{catLevel1}/{catLevel2}/.../{productId}-{productName}
how i do the regex, etc.. i know. But i can't find the routing process in symfony (better the pre-routing process). I would like to build an pre-routing class and fallback the "normal" symfony2 routing. i have to match old and new, both are completely dynamic.. the old one is written in ZF1 (pretty easy for me) but symfony2 is a new area for me...
Let's assume you have a bundle that handles this type of URL, you might add the following in the bundle's routing.yml (I prefer yml, YMMV).
YourSomethingBundle_main_any:
pattern: /{request}
defaults: { _controller: YourSomethingBundle:Main:dispatcher }
requirements:
request: ".*"
Important: This is a “catch-all”, letting you process the actual request path in your controller. You should either prefix the pattern path, or load this bundle after all other bundles, or other routes will no longer work.
As per SF2 conventions, you would now have a MainController class with a dispatcherAction method:
<?php
namespace Your\SomethingBundle\Controller;
use \Symfony\Bundle\FrameworkBundle\Controller\Controller;
class MainController extends Controller
{
public function dispatcherAction($request='')
{
$request = preg_split('|/+|', trim($request, '/'));
// ... and so on.
}
}

need some help about codeigniter route

Is there a way to make the route in codeigniter work like that in symfony?
Cause in there you can rename the route path and it still wouldn't affect your output cause what you call is the route name not the route path unlike in codeigniter.
For example, in symfony, routes are set like this:
news_index:
path: /news
defaults: { _controller: CmsBundle:News:index }
news_view:
path: /news/view/{id}
defaults: { _controller: CmsBundle:News:view }
and then I can access that in my template by calling the route name, not the route path
<?php
// outputs: /news
echo $view['router']->generate('news_index');
// outputs: /news/view/1
echo $view['router']->generate('news_view',array('id' => $news_id));
?>
so if I change the route path it wouldn't affect the way i call it in my code because i'm calling the route name, all it will do is change the output:
news_index:
path: /articles
defaults: { _controller: CmsBundle:News:index }
news_view:
path: /articles/item/{id}
defaults: { _controller: CmsBundle:News:view }
still same code but output is changed
<?php
// outputs: /articles
echo $view['router']->generate('news_index');
// outputs: /articles/item/1
echo $view['router']->generate('news_view',array('id' => $news_id));
?>
while in codeigniter, if i set my route like this:
$route['news'] = 'NewsController';
$route['news/view/(:num)'] = 'NewsController/view/$1';
the only way i know to call it is by the route path:
<?php
echo anchor('news');
echo anchor('news/view'.$news_id);
?>
and if I change my path, I would have to change what I wrote in view as well. That would be a hassle. So I'm wondering if there could be a way to make it work like in symfony. I would appreciate it if anyone could help me. And I apologize if my explanation is not clear. English is not my mother tongue :)
There is blog post available from #kennyk that describes his approach to symfony-like named routes using a router extension.
The article is called Easy Reverse Routing with CodeIgniter.
I guess that's what you're looking for.

Categories