In my symfony2 application I want specific routes for my pages, to work well with my seo, but I receive some serious problems and I dont understand them..
EXAMPLE:
Two routes:
blog_article:
path: /blog/{slug}
defaults: {_controller: ApplicationEDBlogBundle:Blog:singleArticle}
product:
path: /{category}/{name}
defaults: { _controller: MpShopBundle:Product:view}
The product route works fine, but the blog_article route always redirects to product route..
In my understanding if i open blog: /blog/firstBlog/ by default it thinks that the blog is a category and firstBlog is the product name, because my product route is the last route.
But if in my twig i specificaly tell which route to go to, shouldnt it work?
For example: {{ path('blog_article', {slug: blog.slug}) }}. Shouldnt this look at the blog_article route and open the needed controller? Or it does not work like that?
If so, how to keep my pretty urls the way I want to?
change routing to
blog_article:
path: /blog/{slug}
defaults: {_controller: ApplicationEDBlogBundle:Blog:singleArticle}
product:
path: /cat/{category}/{name}
defaults: { _controller: MpShopBundle:Product:view}
and will be fine .
In your example {category} could be "blog" , so 1st route was matched .
It can also work if you change order ( product w'll be first). But it's not good solution (what if someone add category blog ?)
Nope, it doesn't work like that, i.e. your example path code doesn't mean that the routing should look for the blog_article route:
The twig path function just expands the route into the actual url (/blog/yourslug) and when actually accessing that url, the system makes the matching the other way around from the url to the route (matching to whichever happens to be the first of the above listed two route definitions).
If you have this kind of routes, the solution is to have them neatly in the correct order (most generic ones - the product in this case - being always the last), or if the ordering is not possible, you can try to solve this by placing some specific route requirements if applicable.
Related
Hi I have a fully functioning Symfony2 application. Now as part of the SEO work I need to change the urls. I am able to change the last part of the url by changing in the routes file. But the string after domain name which is controller name, i can't change.
My current URL: http://example.com/logics/show
Updated URL should be http://example.com/logic/show
I have tried to rename the controller filename and class name. But its not worked.
Please guide me how to change the controller name throughout the application or in URL ?
The easiest way to do a redirect is changing your routing.yml file.
For SEO reasons, you must redirect your old public URLs with a 301, if change is temporal you can do 302, Symfony allow do this easiest, like this example:
redirect_logic_show:
path: /logics/show
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: logic_show
permanent: true
For more info click here
I would like to reduce the number of repetitive code and give a canonical URL in my Drupal 8 application. Since the routing system is built on Symfony, I included it in the title.
I am constructing paths under routes in my mymodule.routing.yml file. I want to match a specified number of different strings in the first argument, and a slug which can be any string in the second argument. It looks like this:
entity.my_entity.canonical:
path: '/{type}/{slug}'
defaults:
_controller: '\namespace\PostController::show'
requirements:
_permission: 'perm'
type: different|strings|that|can|match|
Now, when I try to access using for example /match/some-slug then it just says "Page not found".
If I something static to the path, for example path: '/j/{type}/{slug}', then it works as expected when I open /j/match/some-slug in the browser.
My boss doesn't like any unnecessary characters in the URL though, so I would like to achieve this by using two parameters, like shown in the first example.
As Yonel mentioned in the comments you can use debug:router to check all your routes. I don't see anything wrong with your code.
Try running bin/console router:match "/match/blaaa" and if you see some controller that isn't the one you want then you'll need to change the route. It shouldn't be the case though because you're getting a 404.
Here's my exact setup that works
routing.yml:
entity.my_entity.canonical:
path: '/{type}/{slug}'
defaults:
_controller: 'MyBundle:Something:foo'
requirements:
type: different|strings|that|can|match|
Inside MyBundle\SomethingController:
public function fooAction($id)
{
return new Response("bar");
}
Then going to http://localhost/match/fom shows the "bar" response.
I have read the documentation again (RTM), and found out that it is not possible in Drupal 8, while it is possible in Symfony.
Note that the first item of the path must not be dynamic.
Source: Structure of routes in Drupal 8
currently, I'm trying to implement a few routes to symfony 2.5 that lead me to a little problem. I need to have an url scheme that has the same route depending on a custom service.
route_category:
pattern: /{location}/{category}
defaults: { _controller: LocationBundle:Category:index }
condition: "service('location_category_service').isCategory(request.get('category')) == true"
route_merchant:
pattern: /{location}/{merchant}
defaults: { _controller: LocationBundle:Merchant:index }
condition: "service('location_merchant_service').isMerchant(request.get('merchant')) == true"
What I want symfony to do is:
Given URL path: /germany/restaurants
try matching route 1
"isCategory" returns true, so this route matches
Given URL path: /germany/aldi
try matching route 1
"isCategory" returns false, so we skip this route
try matching route 2
"isMerchant" returns true, so this route matches and we execute the MerchantController
Given URL path: /germany/this-does-not-match-anything
try matching route 1
"isCategory" returns false, so we skip this route
try matching route 2
"isMerchant" returns false, so we skip this route
... now we can execute the default behaviour when no route matches
I thought, that the condition would exactly does what I want, but I only have the requestContext and the request in the expression language, not the service container.
Does anybody know, how I can inject the service container to the expression language for routing purposes or maybe something else that would help to solve this problem?
Thanks in advance :-)
Having two variables like this is troublesome. From experience the best practice is to separate these two with a static value like so:
route_category:
pattern: /{location}/category/{category}
route_merchant:
pattern: /{location}/merchant/{merchant}
Otherwise as David Kmenta said you will be writing extra code trying to figure out what is what.
Ask yourself if that type of coding is worth having one less extra word in your urls?
To add to this, think of your users: if you have a merchant that sounds like a category will they know the difference or will the scheme you're after just confuse them.
My Silex routes are defined in a routing.yml config file.
In my php code I would like to add some new routes dynamically and I want these routes to have a higher priority than the routes defined in routing.yml.
Currently I'm adding my routes as in the following example, but they are added to the bottom, i.e. with the lowest priority.
$this->app->match('/page/{slug}', array($this, 'record'))
->bind('extrapages')
->method('GET|POST');
This route for example never gets matched because there is a route in routing.yml that matches the following path:
path: /{contenttypeslug}/{slug}
How do add my new routes above the existing routes?
As an aside I'm using the Bolt CMS, which is built on Silex, and trying to add these new routes in a bolt extension. As this question is about Silex routing the fact that I'm using Bolt shouldn't make a great deal of difference.
It's not a very clean solution but whenever I've overruled an extension's route in my routing.yml, I just add the extension's route to routing.yml again, pointing it to my extension code. If you put it near the top, it will get used, because in Silex routes are parsed 'top down'. First match gets used.
sitemap:
path: /sitemap
defaults:
_controller: 'Bolt\Extension\Bolt\Sitemap\Extension::sitemap'
I apologize for the hackyness of this solution.
I am wondering, what is the use of the "name" of the route in Symfony2 routes.yml file
_welcome:
pattern: /
defaults: { _controller: AcmeDemoBundle:Welcome:index }
For example here, pattern and defaults are obviously keywords, however, what the _welcome stands for? Is it arbitrary or a is it kind of predefined keyword for every bundle? Thank you in advance.
The route name is useful for route debugging and generating urls. You will find the route name is used extensively in Twig templates when generating links with the path() function. You can also generate urls from the route name in a controller. More information here
It is good to follow a logical convention when naming routes. Something like:
bundle_name.controller.action is a good place to start.
In this case _welcome is an arbitrary, unique id for each route you have in your project. You need it if you want to generate a url out of a template or if you want to overwrite a vendor-route...