Currently I am doing a small code in symfony that will cause url have resource like this:
http://url/val/abc.abxhd
I was able to get the parameter abc successfully from http://url/val/abc, but when I try to run the URL of http://url/val/abc.abxhd. Symfony simply throw a 404 error.
What could be the problem here. the URl are written using rawurlencode also.
group:
url: /group/:group
param: {module: group, action: show}
requirements:
sf_method: [get]
Actually symfony was finding dot (.) as a segment separator. This is the reason why in my case it cannot find the route. After Add the ff to my route. it works just like expected:
group:
url: /group/:group
param: {module: group, action: show}
requirements:
sf_method: [get]
options:
segment_separators: [/]
Seems like Symfony doesn't like dots . in urls : http://groups.google.com/group/symfony-users/browse_thread/thread/65d928b601bff9f4/096af0fcc478997b?pli=1
Users provide several tips and solutions.
What you can do is to handle this with url rewriting (as suggested in the thread) but take care not to rewrite files (meaningly: http://url/folder/myjquery.js)
Related
I'm working on a symfony3 project, and i'm stuck with a problem,
We are sending emails that are twig based, with a button that has a link to our platform.
Button example
And the open document button link is the following one:
app.example.com/books/bookId/pageId
Which is generated through twig:
url("open_book", { bookId: book_id, pageId: page_id })
And the url is defined on a controller file, with annotations
#Route("/book/{bookId}/{pageId}", name="open_book")
So, the link that user gets on the email, is the original, but with double // before books, like this:
app.example.com//books/bookId/pageId
I'm working on last twig version, and I don't know if it can be symfony issue either, since its only happening on our prod environments (it works on local, yey)
If it helps, our routing.yml
app:
resource: "#BooksBundle/Controller/"
type: annotation
prefix: /
host: app.%host%
This is only happening with urls that are generated by twig. We are using jms translation and jms i18n bundles also, so I thought maybe its trying to set a null locale betwen / / like:
app.example.com/en/books/bookId/pageId
But instead of en, an empty language maybe.
Any idea to start with?
UPDATE 3/01/18
Hey! Thanks for all answers. It seems that was a problem with symfony configuration at the end...
On file parameters.yml:
router.request_context.scheme: '%env(ROUTER_REQUEST_CONTEXT_SCHEME)%'
router.request_context.host: '%env(ROUTER_REQUEST_CONTEXT_HOST)%'
router.request_context.base_url: '%env(ROUTER_REQUEST_CONTEXT_BASE_URL)%'
Then our value for base_url was /. Seems that was the real problem. Removing / on that param does the trick.
Thanks!!
For every route in the controller you are using prefix /:
app:
resource: "#BooksBundle/Controller/"
type: annotation
prefix: /
host: app.%host%
This means that every route like:
#Route("/book/{bookId}/{pageId}", name="open_book")
Will be prefixed with /. In the end this route path will be //book/{bookId}/{pageId}. Some libraries truncate path values, the other ones not.
So just remove prefix parameter completly or declare route's path without leading slash:
#Route("book/{bookId}/{pageId}", name="open_book")
try to replace this line
url("open_book", { bookId: book_id, pageId: page_id })
By
url("open_book", { bookId: book_id, pageId: page_id }) | replace({'//': "/"})
OR
{{ app.request.schemeAndHttpHost }} {{ path("open_book", { bookId: book_id, pageId: page_id }) }}
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
How to setup default routing in Symfony2?
In Symfony1 it looked something like this:
homepage:
url: /
param: { module: default, action: index }
default_symfony:
url: /symfony/:action/...
param: { module: default }
default_index:
url: /:module
param: { action: index }
default:
url: /:module/:action/...
I was looking through the cookbook for an answer to this, and think I've found it here. By default, all route parameters have a hidden requirement that they match any character except the / character ([^/]+), but this behaviour can be overridden with the requirements keyword, by forcing it to match any character.
The following should create a default route that catches all others - and as such, should come last in your routing config, as any following routes will never match. To ensure it matches "/" as well, a default value for the url parameter is included.
default_route:
pattern: /{url}
defaults: { _controller: AcmeBundle:Default:index, url: "index" }
requirements:
url: ".+"
I don't think it's possible with the standard routing component.
Take a look to this bundle, it might help :
https://github.com/hidenorigoto/DefaultRouteBundle
// Symfony2 PR10
in routing.yml:
default:
pattern: /{_controller}
It enables you to use this kind of urls: http://localhost/MySuperBundle:MyController:myview
Symfony2 standard routing component does not support it, but this bundle fills the gap Symfony1 left:
https://github.com/LeaseWeb/LswDefaultRoutingBundle
It does what you expect. You can default route a bundle using this syntax:
FosUserBundle:
resource: "#FosUserBundle"
prefix: /
type: default
It scans your bundle and automatically adds routes to your router table that you can debug by executing:
app/console router:debug
Example of automatically added default routes:
[router] Current routes
Name Method Pattern
fos_user.user.login_check ANY /user/login_check.{_format}
fos_user.user.logout ANY /user/logout.{_format}
fos_user.user.login ANY /user/login.{_format}
...
You see that it also supports the automatic "format" selection by using a file extension (html, json or xml).
Here is an example: http://docs.symfony-reloaded.org/master/quick_tour/the_big_picture.html#routing
A route definition has only one mandatory parameter pattern and three optionals parameters defaults, requirements and options.
Here's a route from my own project:
video:
pattern: /watch/{id}/{slug}
defaults: { _controller: SiteBundle:Video:watch }
requirements: { id: "\d+", slug: "[\w-]+"
Alternatively, you can use #Route annotation directly in a controller file. see https://github.com/sensio/SensioFrameworkExtraBundle/blob/master/Resources/doc/annotations/routing.rst
As for the default routes, I think Symfony2 encourages explicit route mapping.
Create a default route is not a good way of programming. Why? Because for this reason was implemented Exception.
Symfony2 is built just to do right things in the right way.
If you want to redirect all "not found" routes you should use exception, like NotFound404 or something similar. You can even customise this page at your own.
One route is for one purpose. Always. Other think is bad.
You could create your own bundle that handled all requests and used URL parameters to construct a string to pass to the controller's forward method. But that's pretty crappy, I'd go with well defined routes, it keeps your URLs cleaner, and decouples the URL and controller names. If you rename a bundle or something, do you then have to refactor your URLs?
If you want to create a "catch all", your best bet would be to hook on the KernelEvents::EXCEPTION event. This event gets triggered whenever an Exception falls through to the HttpKernel, this includes the NotFoundHttpException thrown when the router cannot resolve a route to a Controller.
The effect would be similar to Symfony's stylized 404 page that gets rendered when you send the request through app_dev.php. Instead of returning a 404, you perform whatever logic you're looking to.
It depends... Some of mine look like this:
api_email:
resource: "#MApiBundle/Resources/config/routing_email.yml"
prefix: /
and some look like
api_images:
path: /images/{listingId}/{width}/{fileName}
defaults: { _controller: ApiBundle:Image:view, listingId: null, width: null, fileName: null }
methods: [GET]
requirements:
fileName: .+
I'm trying to find a way get the symfony 1.4 to render the page:
/detail/id/1
when url called is:
/?url=/detail/id/1
Any ideas? Been googling around but so far haven't found the solution for it. Any ideas? I know it could be done with rewrites but i hoped i can do it through routing.yml somehow.
You can manually add that line into your routing.yml, in your case I would do (i suppouse that the module is detail and the action is id):
detail_id:
url: /?url=/detail/id/:id
param: { module: detail, action: id }
requirements:
id: \d+
Getting the id from the action with $this->getParameter('id')
Say that I have to following 2 routes in this order:
Zip:
url: home/:zip
param: { module: home, action: results }
State:
url: home/:state
param: { module: home, action: results }
and I use a route such as:
'#State?state=CA'
Why does it resolve to the Zip route?
I thought when you specified the route name explicitly: '#State' that it did not parse the entire routing file and just used the specific route you asked for.
I would like to be able to use the same action to display data based on the variable name (zip or state) I don't want to have to create the same action (results) twice just to pass in a different parameter.
You need to add requirements so that it will recognize the different formats
Zip:
url: home/:zip
param: { module: home, action: results }
requirements: { zip: \d{5} } # assuming only 5 digit zips
State:
url: home/:state
param: { module: home, action: results }
requirements: { state: [a-zA-Z]{2} }
That should fix it, although I agree with you that when you use a route name in a helper it should use the named route.
the problem here is that both routing rules resolves to somewhat same url ( /home/) and when generating links it uses correct named route to generate url.
when you click on that generated url( for example /home/CA) withouth requirements addition it will match the first rule in routing.yml file that matches and that is your "Zip" route.
just to explain what is happening.
It does use the named route. The issue is that your URLs are the same (the paramater name is irrelevant) so when you load the URL in your browser, the first route to match will always be Zip as there is no way for Symfony to know which one you want.
Adding requirements: is the way to go.