I want to set a prefix for all controllers in the AdminBundle - "/admin". So I did it in routing.yml file:
my_admin:
prefix: /admin
Then I changed all admin bundle's route names from:
/**
* #Route("admin/home", name="admin/home")
*/
to
/**
* #Route("home", name="home")
*/
And the problem is that when I use:
return $this->redirect($this->generateUrl('admin/installation'));
It throws an exception that the route doesn't exist...before setting the prefix it worked. What's wrong?
Router::generateUrl expects a route name, no route path. So if you want to link to the home route you showed us, you use:
return $this->redirect($this->generateUrl('home'));
The prefix option is about route paths, not about the name of a route.
it is because you have no route called admin/installation. Even if you have prefix for whole controller, you have to give unique names to each route.
/**
* #Route("home", name="admin/home")
*/
Related
I have a problem working with URI routing in Codeigniter 4.2.6. I have Controller name Home and a method name getIndex. When accessing http://localhost:8080 all working fine. When I try http://localhost:8080/home/index, a message 'Cannot access the default controller "Home" with the controller name URI path' comes up. I set $routes->setAutoRoute(true); and public bool $autoRoutesImproved = true;. The same problem when I create another method getAbout. Accessing http://localhost:8080/home/about resulting a message Cannot accessing... as well.
The same problem when using Sub directory to separate logic. This is my code of subdirectory name Admin :
<?php
namespace App\Controllers\Admin;
use App\Controllers\BaseController;
class Home extends BaseController
{
public function getIndex()
{
# code...
}
public function getAbout()
{
echo 'This is '.__METHOD__;
}
}
and trying to access it get the same result Cannot access the default controller "Home" with the controller name URI path.
So how to work with URI Routing in codeigniter 4 especially 4.2.6 using Auto Routing enable and Manual Routing ?
Thank you in advance.
UPDATE
This is my Routes.php
<?php
namespace Config;
// Create a new instance of our RouteCollection class.
$routes = Services::routes();
// Load the system's routing file first, so that the app and ENVIRONMENT
// can override as needed.
if (is_file(SYSTEMPATH . 'Config/Routes.php')) {
require SYSTEMPATH . 'Config/Routes.php';
}
/*
* --------------------------------------------------------------------
* Router Setup
* --------------------------------------------------------------------
*/
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Home');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
// ...
// If you don't want to define all routes, please use the Auto Routing (Improved).
// Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
$routes->setAutoRoute(true);
/*
* --------------------------------------------------------------------
* Route Definitions
* --------------------------------------------------------------------
*/
// We get a performance increase by specifying the default
// route since we don't have to scan directories.
$routes->get('/', 'Home::index');
File: app/Config/Feature.php
public bool $autoRoutesImproved = true;
File: app/Config/Routes.php
$routes->setDefaultNamespace('\App\Controllers\Admin');
$routes->setDefaultController('\App\Controllers\Admin\Home');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
// where controller filters or CSRF protection are bypassed.
// If you don't want to define all routes, please use the Auto Routing (Improved).
// Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
$routes->setAutoRoute(true);
// We get a performance increase by specifying the default
// route since we don't have to scan directories.
$routes->addRedirect('/', '/home');
Changes made: https://github.com/steven7mwesigwa/ci4.2.7/commit/2ec6853716029d5704933ed95622875fb3fa6728
Sample repo: https://github.com/steven7mwesigwa/ci4.2.7
Addendum
A. In your web browser instead of: http://localhost:8080/home/index, use http://localhost:8080/home
B. http://localhost:8080/home/about. This URI should work just fine without any "user-defined route".
Step 1
Edit in file app/Config/Feature.php
public bool $autoRoutesImproved = true;
to
public bool $autoRoutesImproved = false;
Step 2
Edit in file app/Config/Routes.php
$routes->setAutoRoute(false);
to
$routes->setAutoRoute(true);
I have an entity that is reachable both using http://example.com/company/d9c363ae-a1b7-11e6-a66d-9e9923e30d94/ and http://example.com/company/custom-domain.com.
Now, the Company can have a slug, but can also not have one.
So, I'd like to check if it has a domain set and if it has and if the URL is based on UUID, I want to redirect it to the version with the slug. If it hasn't a domain set, I simply show the page using the UUID.
I've done this following this Symfony's tutorial:
# routing.yml
redirect_company_to_domain:
path: /company/{domain_host_or_id}
defaults: { _controller: AppBundle:Company:redirectToDomain }
requirements:
url: .*/$
methods: [GET]
And in my controller I have write this method:
/**
* Redirect the URLs with a trailing slash to the version without it.
*
* #param Request $request
*
* #return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function redirectToDomainAction(Company $company, Request $request)
{
die(dump($company));
}
The problem is that the controller is never called.
What am I missing or doing wrong? Why the path is never intercepted by the route?
Maybe because I've mixed annotations and configuration in routing.yml? Because the routes of the CompanyController is all set using annotations.
But using app/console debug:router I can see correctly the route set:
redirect_company_to_domain GET ANY ANY /company/{domain_host_or_id}
Also, I'm sure the method described in the tutorial works as I've implemented it to remove trailing slashes.
I don't understand why it isn't working to make this redirect.
I think because you've specified the parameter (in brackets) incorrectly.
Can you try this instead:
redirect_company_to_domain:
path: /company/{domain_host_or_id}
defaults: { _controller: AppBundle:Company:redirectToDomain }
requirements:
domain_host_or_id: .*/$
methods: [GET]
I think that's the problem, but I'm not 100% certain. Can you try it out and let us know?
Clean setup of Symfony 3 framework, added locale listener from here:
http://symfony.com/doc/current/cookbook/session/locale_sticky_session.html
Example action code:
/**
* #Route("/foo/")
* #Route("/{_locale}/foo/", name="foo", requirements={"_locale"="en|ru|tk"})
*/
public function fooAction(Request $request)
{
return new Response('true');
}
This syntax has to be repeated for every action. Is there a way to make it less verbose without using a Bundle? I'd like the requirements portion to reside in a config somewhere, if possible.
Ideally, I would like to move the defaults={"_locale"="en"}, requirements={"_locale"="%allowed_locales%"} part inside the Locale Listener, but from what I've tried, it seems the listener is called after the route has been matched, and so that is not possible, which is really a shame.
Yes, check out How to Use Service Container Parameters in your Routes which is linked from The Locale and the URL in the Symfony Translations documentation, and states:
Read How to Use Service Container Parameters in your Routes to learn how to avoid hardcoding the _locale requirement in all your routes.
You can essentially set those routes in a global parameter like so:
# app/config/config.yml
parameters:
app.locales: en|ru|tk
Then in your route annotations do the following:
/**
* #Route("/foo/")
* #Route("/{_locale}/foo/", name="foo", requirements={"_locale"="%app.locales%"})
*/
public function fooAction(Request $request)
{
return new Response('true');
}
I'm not sure why the documentation only shows that for defining routes in YAML / XML / PHP but it should work just the same using annotations.
Hey all I have a bit of a problem with root annotations in Symfony2.
I have two different controllers that call methods from the same URL positions /test.
Controller 1:
**
* #Route("/test", service="myProject.test.controller.art")
* #Cache(expires="+5 minutes", public=true)
*/
class BlogController
{
/**
* #Route("/{text}", defaults={"text" = null})
* #Route("/topic/{tag}", defaults={"tag" = null})
* #Method({"GET"})
*/
public function listAction(ArtQuery $query)
{
//.................
}
}
Controller 2:
**
* #Route("/test" , service="myProject.test.controller.sitemap"))
* #Cache(expires="+5 minutes", public=true)
*/
class SitemapController
{
/**
* #Route("/sitemap.xml/")
* #Method({"GET"})
*/
public function sitemapAction()
{
//..................
}
}
The problem is that the second Controller is never matched only if is add in my #route("/sitemap.xml/") but I realy want the route to be only #route("/sitemap.xml").
I think the problem is when i input the url /test/sitemap.xml Symfony treats sitemap.xml as /{text} variable route in first controller.
Can I make a exception so that first controller ends as soon as it hits sitemap.xml....?
I read something about requirements but dont quiet understand this concept
The router will use the first route that matches the path.
The only way to prioritize a route over another which could match is to ensure that the stricter requirements are check before the weaker ones.
Normally this would be accomplished by placing the sitemapAction method above listAction.
However since you have a controller for each of these, you will have to put the controllers in the correct order.
To do this you will need to add the controllers to the config individually like this:
app_sitemap:
resource: "#AppBundle/Controller/SitemapController.php"
type: annotation
prefix: /
app_blog:
resource: "#AppBundle/Controller/BlogController.php"
type: annotation
prefix: /
This way the controllers will be iterated in this order.
However it is better if you can give each route a unique path, perhaps:
#Route("/query/{text}", defaults={"text" = null})
according to documentation
Earlier Routes always Win
What this all means is that the order of the routes is very important.
If the blog_show route were placed above the blog route, the URL
/blog/2 would match blog_show instead of blog since the {slug}
parameter of blog_show has no requirements. By using proper ordering
and clever requirements, you can accomplish just about anything.
http://symfony.com/doc/current/book/routing.html
i suggest to use yml or xml file for routing
or you can make a requirement in your first route
/**
* #Route("/{text}", defaults={"text" = null}, requirements={"text" = "^(?!sitemap\.xml)$"})
* #Route("/topic/{tag}", defaults={"tag" = null})
* #Method({"GET"})
*/
public function listAction(ArtQuery $query)
{
//.................
}
I'm working with Symfony2 and:
I have this in the routing.yml
_welcome:
resource: "#AcmeBundle/Controller/"
type: annotation
I this method within a controller:
/**
* #Route("/{page}")
*/
public function staticAction($page)
{
return $this->render('AcmeBundle:Static:'.$page.'.html.twig');
}
To generate common pages:
/home
/contact
/privacy
But when I make the url on the menu:
Home
Contact
Privacy
And I Symfony generates these urls:
…./?page=home
…./?page=contact
…./?page=privacy
And the right would be:
/home
/contact
/privacy
What must I do?
You've to add a route name in your controller route annotations as follow,
/**
* #Route("/{page}", name="static")
*/
public function staticAction($page)
{
// ...
}
You could then call the twig path helper using that name,
Home