Symfony 2.5 SEO Friendly URLs - symfony

I'm trying to build my own CMS based on Symfony 2 since I swapped jobs and now require some symfony practice, but got stuck when trying to do something sensible with routes. In Zend it was possible with preDispatch so I hope Symfony 2 will have something similar too.
Consider this URL: http://www.example.com/page_one/sub_page/another_sub_page/yet_another_sub/
What I am trying to achieve is to have http://www.example.com/page_one/ matching to some controller and getting me the content of the page that has the url_string parameter same as that portion of URL. Then http://www.example.com/page_one/sub_page/ should also match to the same controller but render content for the sub_page portion of URL.
The route must match n portions because I cannot know how deep the structure might go.
So I will not accept something like
/{slug1} or
/{slug1}/{slug2} or
/{slug1}/{slug2}/{slug3}
as that is nonsense.
I am planning to make this route as last one in the routing config so should there be some matches on other routes they will be picked up instead, and this one despite it is most important route will be last resort matching kinda thing.

Using the following config will match all urls, and the entire path will be passed into the controller "slug1/slug2/slug3".
SymfonyBundle/DefaultBundle/Resources/config/routing.yml:
symfony_default_page:
path: /{path}
defaults: { _controller: SymfonyBundle:Default:page }
requirements:
path: "^.+"
Or** ou can also use regex in the requirements path. This will exclude "admin", "login", "blog", however it's much easier if you simplify things and just place the routing in the correct order like you said
requirements:
path: "^(?!admin|login|blog).+"
app/config/routing.yml
By importing the default bundle routing last, it means any routing yml files above will take priority and therefore not match the default route which will catch any url.
SymfonyAdminBundle:
resource: "#SymfonyAdminBundle/Resources/config/routing.yml"
prefix: /admin
#import this last
SymfonyDefaultBundle:
resource: "#SymfonyDefaultBundle/Resources/config/routing.yml"
prefix: /
Controller:
class DefaultController extends Controller
{
public function pageAction($path)
{
//You could split the URL and handle accordingly, also filter / escape?
$parts = explode("/", $path);
}
}

Related

Symfony2 - FOSUserBundle - Add _locale in url

I would like to overwrite default routing of FOSUserBundle for Symfony2 to get a result like this:
www.mysite.com/en/login
www.mysite.com/es/login
www.mysite.com/fr/login
www.mysite.com/en/profile
www.mysite.com/es/profile
www.mysite.com/fr/profile
Thanks for your help.
Look at this link. I think it is exactly what you need.
[...] to add a prefix before the _locale string (e.g. /admin/en/dashboard), you can add the “i18n_prefix” option.
# app/config/routing.yml
dashboard:
...
options: { i18n_prefix: admin }

Symfony - Defining a route only in dev. environment

I'm using SF2 and I created some routes helping the debugging of the project:
widget_debug_page:
path: /debug/widget/{widgetName}
defaults: { _controller: WidgetBundle:Debug:default }
The problem is that this route MUST never be reachable when going in production.
I could not find a parameter to specify the environment.
Just for people who want use with annotation system:
/**
* #Route("/my-route", condition="'dev' === '%kernel.environment%'")
*/
public function index() {}
You can add your route in routing_dev.yml (Symfony 2/3) or create a dev-only routing file in config/routes/dev/ (Symfony 4).
As mentioned perviously you can define the conditional route by adding 'condition' directive to the route definition. In case you need to limit the route for the appropriate environment you can check %kernel.environment% parameter value directly. For example:
widget_debug_page:
path: /debug/widget/{widgetName}
defaults: { _controller: WidgetBundle:Debug:default }
condition: "%kernel.environment% === 'dev'"
I just had a similar problem myself since I wanted to create a "System temporarily down due to maintenance"-page that would disable my site entirely in prod-environment only as I use dev-environment to make sure everything is alright after deploying an update to my production server. I guess its debatable whether this is good practice, but anyway...
The comment made by Leto to a previous answer gave me an idea how to solve it and I think I have successfully managed to make my route only work in dev-environment like so:
default_update_view:
path: /{route}
defaults: { _controller: WalanderBundle:Default:maintenanceInfo }
condition: "request.getScriptName() == '/app.php'"
requirements:
route: .+
No the question was to only enable a route in dev-environment which would then be done by changing the condition as follows if I'm not missing anything obvious:
condition: "request.getScriptName() == '/app_dev.php'"
Hope this helps although the question was a bit old!
Perhaps in the case when you want to enable a route in the dev-environment only the already provided answer by JonaPkr is best practice though.
Symfony >= 5.3
when#dev:
widget_debug_page:
path: /debug/widget/{widgetName}
defaults: { _controller: WidgetBundle:Debug:default }
reference: https://symfony.com/blog/new-in-symfony-5-3-configure-multiple-environments-in-a-single-file

Send multiple paths to one route without redirect function

I am updating my website to a Meteor application with iron-router, and need to change my urls. The old scheme had capitalized page names like this:
mysite.com/Contact
but I've changed everything to be lowercase:
mysite.com/contact
That contact route isn't complicated, so it's set up like this:
this.route('contact');
but I want the /Contact url to be redirected. I know I could just do this:
this.route('Contact', {
onBeforeAction: function() {
Router.go('contact');
}
});
but it's so much messier. I'd prefer to do something like this:
this.route('contact', {
path: ['/contact', '/Contact']
});
where the route simply is mapped to multiple paths.
Is there a feature like this? Or is my onBeforeAction the best I'm going to get?
https://github.com/EventedMind/iron-router/blob/devel/DOCS.md#dynamic-path-segments
You can use a Regular Expression for your path segment (see the last example in the Dynamic Path Segments link).
Your path would be:
this.route('contact', {
path: /contact/i
});
Where the 'i' after the forward-slash is the regular expression modifier to be case insensitive allowing you to accept any variation of 'contact' (whether cOntact, Contact, or conTACT).
See http://www.w3schools.com/jsref/jsref_regexp_i.asp for details on the RegEx modifier.

How can I allow root-relative routes in Symfony2 (eg: /{slug}) without overriding other routes

I have an application that manages store location. Our current routes use a /location/{postalCode} route pattern.
The previous version of the site allowed for location shortcuts based on a slug using a /{slug} pattern.
I load my bundle's routing last (after all other routes)…
# (File: app/config/routing.yml)
# Locations
# =========
# Note: this is intentionally last because locations must match root-relative
# wildcard slugs (eg: /atlanta /alberta /boston) for location and city pages.
foo_locations:
resource: "#FOOLocationsBundle/Resources/config/routing.yml"
prefix: /
…and define the shortcut route last…
# (File: src/FOO/LocationsBundle/Resources/config/routing.yml)
# Location Alias/Shortcuts
# ========================
# NOTE: this must be the last route defined so that it does not get clobbered
# by other routes
foo_location_shortcut:
pattern: /{slug}
defaults: { _controller: FOOLocationsBundle:Default:shortcut }
I figured by loading these routes last, it would allow other routes to match first. This doesn't appear to be the case. Most (though, not all) other routes will invoke the FOOLocationsBundle:Default:shortcut action.
This question appears to be the closest to an answer I could find, but it seems it is defining explicit matches in the requirements, which won't work for me as these slugs are managed in the CMS.

Symfony2 routing repeating pattern

I have a URL that can accept any number of parameters but not in exactly the same order. For example
example.com/myapp/service1/username1/service2/username2
or
example.com/myapp/service2/username2/service1/username1
or
example.com/myapp/service7/username7
How can I write a rounting yml entry to catch any of those routes so that I can split them into service/username for example array("service" => "Instagram", "username" => "JoBloggs") or how ever many were passed to the URL.
I have access to a pre-made list of about 30 services, but usernames could pretty much be any value.
I'm not really sure even how to ask this question so I'll give any additional info that would be useful.
Ideally, I'd like to avoid something like example.com/myapp/?service1=username1&...
Seems like I can add mimic catch all at the end of a URL Slash in parameter
route_name:
pattern: /myapp/{services}
defaults: { _controller: bundle.controller.homepage:index }
requirements:
services: ".+"

Resources