I am experiencing a weird behaviour with Symfony 2.6
I have a page that lists my users and its routing is in routing.yml as follows:
nononsense_users_homepage:
path: /{page}/{query}
defaults: { _controller: NononsenseUserBundle:Users:index, page: 1, query: 'q'}
Even if I remove the cache the "hard way" by deleting the app/cache folder it does not matter what I do with the controller I always get the same web page!!
Of course I also used:
php app/console cache:clear
with equivalent results setting the env flag also.
If I replace my routing with, for example:
nononsense_users_homepage:
path: /{page}/{query}
defaults: { _controller: kkkkkkkkk, page: 1, query: 'q'}
The page keeps showing. But if I remove the page or query parts the corresponding twig complains.
I changed other actions and routes in the same bundle and I get the expected results when, for example, I replace a whole action by an exit() call...so it is not I am changing the wrong file :-)
I stopped and run several times the server from the console and I even change browsers and users (you have to be logged to access that page) and nothing changes, there is nothing I can do to get an error page!!!
Nevertheless the action has some DB calls to the UsersRepository and if I include an exit() there I get an empty page as expected.
Does anyone know what I am doing wrong.
If you changed the controller in your routing.yml file and the controller does not change, you are probably using a different route. In dev mode, can you check which route is matched and you will most likely see that a different route is matching causing the error.
Related
Im trying to create a cms with Symfony. I want users to be able to create their own pages. I got this all set up but what did not work for me was loading pages with an url that contains a /.
This is my route that does not allow a /:
#[Route('/{slug}', name: 'dynamic_page', defaults: ["slug" => null], methods: ['GET'])]
public function showStoredPage(Page $page)
{
return $this->render('blocks/base.html.twig');
}
If I add requirements: ["slug" => ".+"] to my route, I am able to go to any/route/that/exists with as many slashes as I wish. Which is what I want.
But after adding this I figured that my debug toolbar does not load anymore. The debug bar shows loading... in all pages I have. Also, when looking at the text the symfony built-in server shows in cmd, it keeps looping a request. If I wait long enough the server even crashes because it can never load the toolbar...
How can I make my toolbar load but also keep my route dynamic the way I want it? I'm using Symfony 5.4 with PHP 8+.
It appears this can be solved very easily. I just had to add priority: -1 to my route attribute. Now it looks like this:
#[Route('/{slug}', name: 'dynamic_page', defaults: ["slug" => null], requirements: ["slug" => ".+"], methods: ['GET'], priority: -1)]
Also with the command php bin/console debug:router you can now see the route is on the bottom of the table and the toolbar will load first.
For more control over what the route does, and does not match, without having to rely on the priority setting, you can use a more precise regex. You can use a negative lookahead to define what not to match. All the paths you want to avoid start with '_' so, you could use '(?!_).+' but that will prevent you from matching anything starting with '_'. To only exclude the defined routes use '(?!_(error|wdt|profiler)).+'
#[Route('/{slug}', name: 'dynamic_page', defaults: ["slug" => null], requirements: ["slug" => "(?!_(error|wdt|profiler)).+"], methods: ['GET']]
Y have this /src/AppBundle/Resources/views/tests/index.html.twig which just contains:
{{text}}
And is controlled from /src/AppBundle/Controller/TestsController.php which was working fine with a Route over the function that renders "text". Now i want to have a routes file which I've located at /src/AppBundle/Resources/config/routing.yml. Apparently in older versions this could be done with:
tests_index:
path: /tests/index
defaults: [_controller: AppBundle:Tests:index]
But maybe I'm missing something or the newer Symfony isn't buying it when I try to reach it at http://localhost/project/web/tests/index. The error is:
Unable to find the controller for path "/pruebas/index". The route is
wrongly configured.
The title of your question is rather strange, because you do want to use a controller. Anyway, your config is not right. It should look like this:
tests_index:
path: /tests/index
controller: App\Controller\TestsController::show
In this case show is the name of the function in your controller.
Also I would advise to use routing annotations. It makes life much easier. Read more about it 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
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.
I heve an embedded controller in my base template. It's a search bar.
For the search bar controller, I have a route "myProject/search".
What I would like is that this route will be taken only when the template where I am embedding the controller (base.html.twig) will call it, and not when i manually put in the browser: "myproject/search".
Any idea on how to do that.
I think, since some time you can't do it:
http://symfony.com/doc/current/book/templating.html#embedding-controllers
quote from the docs:
Even though this controller will only be used internally, you'll need
to create a route that points to the controller
(...)
Since Symfony 2.0.20/2.1.5, the Twig render tag now takes an absolute
url instead of a controller logical path. This fixes an important
security issue (CVE-2012-6431) reported on the official blog. If your
application uses an older version of Symfony or still uses the
previous render tag syntax, you should upgrade as soon as possible.
Anyway, I guess, you can try do it yourself by passing some "secret" argument to search action when you call it from your template. Next in the action you check if the argument was passed to it, and if not you throw 404.
Another way to achieve your goal is use .htaccess file.
You can restrict your route to a certain method by _method option in your routing configuration:
your_rote:
pattern: /myProject/search
defaults: { _controller: YourBundle:YourController:YourAction }
requirements:
_method: POST