Symfony Locale Modify based on Sub domain - symfony

I have a need to set the locale based on subdomain , using Sylius based on Symfony.
I have done the below to make it work, but we need the Locale Code in subdomain mapped to a localcode ( "jp.portal.com" => Locale "ja")
#Routing YML
portal:
resource : "../../src/proj/Resources/config/routing.yml"
host: "{_locale}.%site_host%"
prefix: /
requirements:
_locale: 'en|jp'
defaults:
_locale: 'en'
Difficulty i have is mapped a non locale code like 'jp' to 'ja'
I have tried with below locale Listiner , but it does not help
I get errors
if (strpos($host, 'jp') !== false) {
$locale = 'ja';
} else {
$locale = 'en';
}
$request->setLocale($locale);
if (null !== $this->router) {
$this->router->getContext()->setParameter('_locale', $request->getLocale());
}
I get errors in generate url path througth the site
An exception has been thrown during the rendering of a template
("Parameter "_locale" for route "sylius_shop_homepage" must match "jp"
("en" given) to generate a corresponding URL.").

Related

Symfony CMF Dynamic Router no contentDocument

Following the Dynamic Router doc, I can:
Create a route linked to my content (Page entity)
Persist it with ORM
Load my controller matching the route
But as my controller should expect the $contentDocument parameter, I have nothing.
Here's how I create my route and my entity:
$page = new Page();
$page->setTitle('My Content')
->setBackground(1)
->setDescription('My description')
->setContent('<h1>Hello</h1>');
$manager->persist($page);
$manager->flush(); // flush to be able to use the generated id
$contentRepository = $this->container->get('cmf_routing.content_repository');
$route = new Route();
$route->setName('my-content');
$route->setStaticPrefix('/my-content');
$route->setDefault(RouteObjectInterface::CONTENT_ID, $contentRepository->getContentId($page));
$route->setContent($page);
$page->addRoute($route); // Create the backlink from content to route
$manager->persist($page);
$manager->flush();
Here's my config section:
cmf_routing:
chain:
routers_by_id:
router.default: 200
cmf_routing.dynamic_router: 100
dynamic:
enabled: true
persistence:
orm:
enabled: true
generic_controller: AppBundle:Default:showPage
templates_by_class:
AppBundle\Entity\Page: AppBundle:Default:index.html.twig
My controller:
public function showPageAction($page)
{
return $this->render('default/index.html.twig');
}
And the error:
Controller "AppBundle\Controller\DefaultController::showPageAction()" requires that you provide a value for the "$page" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
Dynamic routing puts the content document into the request with the name "contentDocument". You need to explicitly use that name:
public function showPageAction($contentDocument)
{
return $this->render('default/index.html.twig');
}
if you do not need to do anything in your controller, you don't need to specify the generic_controller. template_by_class will make the bundle provided controller render that template with the page instance found in $contentDocument.

there is no default value + symfony2 + crud

sf 2.8.4 with sylius 0.17
i had generated a controller and routes with generate:doctrine:crud
i can list all datas, but on show and edit, always got this error:
Controller "St\AppBundle\Controller\TranslationDomainController::showAction()" requires that you provide a value for the "$translationdomain" argument (because there is no default value or because there is a non optional argument after this one).
here the show action
public function showAction(TranslationDomain $translationdomain)
{
$deleteForm = $this->createDeleteForm($translationdomain->getId(), 'administration_translations_domain_delete');
return $this->render('StAppBundle:TranslationDomain:show.html.twig', array(
'translationdomain' => $translationdomain,
'delete_form' => $deleteForm->createView(), ));
}
and the route
administration_translations_domain_show:
pattern: /{id}/show
defaults: { _controller: "StAppBundle:TranslationDomain:show", id : 1 }
requirements:
id : \d+
_method : get
You are using a param converter
http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
You have to disable the auto-conversion of type-hinted method arguments feature by setting the auto_convert flag to false.
Look at:
# app/config/config.yml
sensio_framework_extra:
request:
converters: true
auto_convert: false
Change to:
sensio_framework_extra:
request:
converters: true
auto_convert: true
At the end you should always request for an object identifier. It's safe and semantic correct. You want to 'show/edit/update/delete' concrete entity.
If you really wants to have a default show for your set of entities create route like a '/show/default' and use this route with 'show/choose default' link.

Appending route configuration to all routes

I'd like to have multilingual site done with Symfony. So I need to add something like:
# app/config/routing.yml
contact:
path: /{_locale}
defaults: { _locale: "pl" }
requirements:
_locale: pl|en
However I don't want to repeat this on every route I define, so I came up with solution:
# app/config/config.yml
parameters:
locale.available: pl|en
locale.default: pl
<...>
router:
resource: "%kernel.root_dir%/config/routing.php" # note '.php'
<!-- language: lang-php -->
# app/config/routing.php
<?php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Yaml\Parser;
$configFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'routing.yml';
$yaml = new Parser();
try {
$routes = $yaml->parse(file_get_contents($configFile));
} catch (ParseException $e) {
printf("Unable to parse the YAML string: %s", $e->getMessage());
}
$collection = new RouteCollection();
foreach ($routes as $name => $def) {
$route = new Route($def['path']);
foreach (['defaults', 'requirements', 'options', 'host', 'schemes', 'methods', 'condition'] as $opt) {
$mtd = 'add'. ucfirst($opt);
if(isset($def[$opt])) $route->$mtd($def[$opt]);
}
$collection->add($name, $route);
}
$collection->addRequirements(['_locale' => "%locale.available%"]);
$collection->addDefaults(['_locale'=>"%locale.default%"]);
return $collection;
?>
# app/config/routing_dev.yml
<...>
_main:
resource: routing.php
Still, I'm rather new to Symfony2 (now 3), so I wonder... Is there a better way to accomplish such appending route config to all the routes? Perhaps there are more flexible or more "right" ways of doing such things in Symfony? Or should I hook into some existing mechanism?
You could use a custom route loader that extends the default one. See here for more info:
http://symfony.com/doc/current/cookbook/routing/custom_route_loader.html
For example if you wanna support yml, xml and annotations you'd need to extend the Symfony\Component\Routing\Loader\YamlFileLoader, Symfony\Component\Routing\Loader\XmlFileLoader and Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader incorporate the logic you have to the load method and you'd need to change the
sensio_framework_extra.routing.loader.annot_class.class,routing.loader.yml.class and routing.loader.xml.class
parameters to point to your new classes.
Defining your own route_loader seems like the less hacky solution

Symfony 2 redirect route

I have the following route that works via a get:
CanopyAbcBundle_crud_success:
pattern: /crud/success/
defaults: { _controller: CanopyAbcBundle:Crud:success }
requirements:
_method: GET
Where Canopy is the namespace, the bundle is AbcBundle, controller Crud, action is success.
The following fails:
return $this->redirect($this->generateUrl('crud_success'));
Unable to generate a URL for the named route "crud_success" as such route does not exist.
500 Internal Server Error - RouteNotFoundException
How can I redirect with generateUrl()?
Clear your cache using php app/console cache:clear
return $this->redirect($this->generateUrl('CanopyAbcBundle_crud_success'));
If parameters are required pass like this:
return $this->redirect($this->generateUrl('CanopyAbcBundle_crud_success', array('param1' => $param1)), 301);
The first line of your YAML is the route name that should be used with the router component. You're trying to generate a URL for the wrong route name, yours is CanopyAbcBundle_crud_success, not crud_success.
Also, generateUrl() method does what it says: it generates a URL from route name and parameters (it they are passed). To return a 403 redirect response, you could either use $this->redirect($this->generateUrl('CanopyAbcBundle_crud_success')) which is built into the Controller base class, or you could return an instance of Symfony\Component\HttpFoundation\RedirectResponse like this:
public function yourAction()
{
return new RedirectResponse($this->generateUrl('CanopyAbcBundle_crud_success'));
}

Symfony2 Set _locale in home page base on browser's configuration

My local works everywhere on my website but I cant tell the application the set the proper local on the root of the application.
For exemple :
If my website is http://mycompany.com I want that, when I enter this address the application guess what is my local and set it at the end of the url
http://mycompany.com/en if the local exist on my application. Here en or fr and if not the default en
For now when i go to home page I always get english version but my browser is set in french
routing.yml :
_welcome:
pattern: /{_locale}
defaults: { _controller: MyBundle:Default:landing, _locale: en }
requirements:
_locale: en|fr
See this question asked a few days ago and take a look at the first method in the language listener. It does exactly what you need. And take care of the right settings in config.yml
With the help of many other questions related to locale and symfony2 I finally get want I want ! I guess it is not the perfect answer but at least it works !
My landing action is defined in my routing as _welcome route. It is this action that is loaded when I go to the url's root.
/**
* #Route("/landing")
* #Template()
*/
public function landingAction() {
$localeAvailable = array('en', 'fr');
//user language
$localeUser = substr($this->getRequest()->getPreferredLanguage(), 0, 2);
//application language
$localeApp = $this->getRequest()->attributes->get('_locale');
//Redirect to the good locale page
//only if the locale user is on our manager locale and it is not the current locale of the application
if(in_array($localeUser, $localeAvailable) && $localeApp!=$localeUser){
return $this->redirect($this->generateUrl("_welcome", array('_locale' => $localeUser)));
}
return array();
}

Resources