Use the default route with Zend Router by default - php

How can I configure Zend_Controller_Router to use the default route by default? For whatever reason unknown, it uses the current route.
This is causing some annoying routing issues, and I don't feel like editing hundreds of links to explicitly use the default route is a reasonable solution to add one custom route.

Your question isn't obvious and is confusing, I will try though.
I am going to assume you do not mean Zend_Controller_Route but in fact are talking about links generated in your views.
You can use baseUrl() like this
About Us
You can set the baseUrl in your Bootstrap like this
Zend_Controller_Front::getInstance()->setBaseUrl("/");
If you are working locally you may want to set it to something like this
Zend_Controller_Front::getInstance()->setBaseUrl("/my-app/public");
Using baseUrl() in your views will now use that path to base all your URLs on. Remember you must wrap your links in baseUrl() for this to work.
The url() helper is not useful for this, this is used for doing things like pagination where you want the current parameters of the request object to be maintained.
Hope that helps.

From Matthew Weier O'Phinney:
The logic you quote above is within
the assemble() method. assemble() may
be called with or without routing
having occurred. By default, the
assumption is that if no route name is
provided, the currently matched route
is utilized -- and if matching was
never performed (or no route matched),
the 'default' route will be used.
The rationale for using the currently
matched route is that typically you
will be routing within the same schema
-- as an example, if you are within a RESTful paradigm, the majority of your
links will be within the current
resource. If we were to follow your
suggestion to utilize the "default"
route when no route is specified (at
least, that's how I interpret what you
said), because the Rest_Route is not
the default route, every single call
to assemble() would require using the
route name -- which others would
deride as causing "headaches."
Personally, I prefer to be explicit
and always specify the route name;
this way I know exactly what route I'm
targetting during assemble(), which
makes debugging easier.
Sounds like the only solution is to set the route for each link to use 'default' instead of leaving it NULL.

Related

Symfony2 - What is the point of specifying your own route names?

Currently learning Symfony. Just wondering about route names, which the book doesn't really seem to say in advance what they are for.
As I understand it, #Route annotations are given a default name based on the bundle, controller and action name. So what's the point in specifying your own route names?
Is it good practice to either leave all routes to have a default name?
Is it better practice to specify your own name for every route?
What if two routes have the same name?
How am I expected to know if I'm using a route name which is already taken, perhaps in another bundle?
Route names are important because your code will often need to build url's. The route name is how you specify which url to construct. Names are also handy for listeners (such as authentication) which process specific url's.
Annotation generated default names are fine but tend to be long and could change on you.
Yes, I would give every route a custom name for convenience and readability. Plus, I don't use annotations. To me at least, storing routes in a central file make the code easier to maintain. It avoids the need to search through multiple controller files trying to determine which code handles which request.
Routes with the same name will replace any previously loaded route. It's useful if you wish to override a route from a third party bundle.
Namespace your route by using some form of your bundle name as a prefix.

Use cases for generated URLs in Symfony2?

Coming from a straight PHP and Drupal background, I am recently learning the Symfony2 framework. Currently I am in the routing chapter of the book. This is probably a simple question.
What are some real world use cases for why one would want to generate URLs in a Symfony app? I understand the code but I'm having a bit of trouble determining its practical applications.
I'm referring to this section should you need a refresher.
As always, thank you!
P.S. Symfony is amazing. :)
Basically, you need to generate a URL whenever you need to link to anywhere in your application.
Let's say that you have an application that needs to manage some users. This means that you will probably have URLs like /user/create, /user/edit/(user id) and /user/remove/(user id).
Whenever you display a link to edit a user you need to know on what URL you can find the page that allows you to edit a user. So you need to link to /user/edit/(user id). One solution would be to have this as a fixed link so that in your code you could just write
edit this user
But what if you want to change this URL scheme? Let's say someone is unhappy with the term "user", after all the humans managed by this system are not only users, they are actually "person"s! So now you need to change all the URLs containing "user". Probably there are quite a few places in your app where you have had to hardcode these URLs and now you will need to find and change all of them. Eugh.
But fear not, for Symfony routing comes to the rescue!
Instead of hardcoding these URLs, we can simply let the Symfony router generate them for us. This means that we first need to tell Symfony which routes we have, e.g. by adding the following YAML code to our routes config file:
user_edit:
path: /user/edit/{userId}
defaults: { _controller: AppBundle:User:edit }
requirements:
userId: \d+
This tells our application "Okay, whenever somebody requests a page that looks like /user/edit/{userId}, then you need to call the editAction method in our UserController class in the AppBundle namespace and you need to pass the userId as a parameter. Oh, and also you should only call the controller if userId is a valid integer with at least one number."
So this is how Symfony knows how to map URLs to controllers. But the goodness that comes along with it is that we can use this information for the reverse way as well.
Usually, in our application we do not really care about what the URL looks like for a certain action we want to perform. All we know is that when clicking a certain link, then the browser should jump to a page that allows me to edit a user. And since we just defined a route that takes us right there, we can have Symfony generate the correct URL to achieve just that.
So in your view you can now discard the hardcoded URL from earlier and instead replace it with a route generated by the Symfony router:
edit this user
Now whenever you need to change what the URL actually looks like all you need to do is edit your routing config and not a lot of separate views.
Because, imagine you want to change a given page URL and you've hardcoded it in 10 Twig templates. You will have to modify all these files. On the opposite, when using the routing component:
You would only have to change the URL where the route is defined.
The routing component "takes" care of the current environment you are using (dev, prod...)
Also note that is a bad practice to "switch environment", a typical issue is to hardcode an URL in a Javascript. In this case you can expose your Symfony2 routes in the Javascript by using a bundle like FOSJsRoutingBundle.
I almost immediately realized their use and now I feel silly. :) For those who stop by this question in the future:
Notes about Generating URLs:
Similar to the Drupal l() function, sometimes you need to generate links inside your application based on a variety of parameters.
You don't always want to hardcode your links in case you decide to change paths sometime down the line.
In summary: Think of this as an alternative to using straight anchor tags with href elements all over the app and, instead, keeping things dynamic.
Use case
In the project I'm working I use generateUrl to redirect the user
after creating, editing an entity.
For example after creating a Service entity, I redirect the user to the view
of the just created Service.
Controller
return $this->redirect($this->generateUrl('myentity_view', array('id'=> $id)));
Additional note
In twig files, you can use the path function which call the routing component and generate url with given route name and parameters.

Laravel pattern routing to controller methods

How can I make a router like this
Route::any("/{controller}/{method}/{param}", "$controller#$method");
So that instead of specifing every single method in the routes file, I would be able to define a route for most cases for the convention http://example.com/controller/method/param
I don't really know why you would want to do this, I think you lose flexibility in the routes file with such approach. I'd rather have things explicitly defined, like so:
Route::get('/users/{id}', 'UserController#show');
Route::post('/users', 'UserController#store');
And, as you can see, different routes, despite being handled by methods belonging to the same controller, might have different amounts and kind of parameters (e.g.: getting a specific user requires sending an ID parameter, but storing a new user doesn't require sending parameters, at least not via the URL).
Besides,
Route::any("/{controller}/{method}{param}" ...
means everything inside {} is a parameter, including {param}.
Seems you want a generic one-liner route. Is it really worth it?
You could use Route::controller, but you'd have to do it for every controller:
Route::controller('my-controller', 'MyController');
This will redirect my-controller/test to MyController#test or my-controller/double-test to MyController#doubleTest.
#Emmanuel Figuerola Yes, it is worth to have the routing convention that most frameworks use out there, because if you need to define any special route, you can just define it without breaking anything and it is something very convenient for the developer, as he does not have to deal with hundreds of route definitions in the route files, which may be confusing, error prone and difficult to maintain.
Laravel becomes really cumbersome by defining a route for every view, for every method in a controller and for every AJAX callback when most of those routes can perfectly fit in the common and know pattern "controller/action/id", keeping simplicity, performance, maintainability and smaller code. I am still struggling to find a way to implement something similar in Laravel but it seems my efforts are in vain.
The Route::controller(); was deprecated as of Laravel 4, if I remember well, in favor of the RESTful controllers.

Web browser behavior for relative path using CodeIgniter or any php framework

I've been using CodeIgniter for some time, but mostly for the convenience features such as internationalization, and cookie and session control. I also like that it separates my views from my logic. I have learned about the core things such as database access, which is the one of the core reasons why people use a php framework, but I just haven't been building sites that requires it for now.
One of the things that I couldn't find an answer on is about relative path. In my a tags, I've always put the complete path. For example
Home
However, I've discovered that if I just put
Home
it would actually work as long as I'm using the same controller, method and language. I even tried in the French section of my and it works too. Obviously, to switch language, I'd have to give the full path. I don't think this has anything to do with CI, but a browser behavior.
What is this behavior exactly? When a browser sees a relative path, does it look at the current path, goes to the nearest / character, erase everything after it and add the relative path? Can I count on this every time?
Yes, you can count on this behaviour. The approach of having slash-separated names to identify a page comes from the original approach of linking those strings to a folder location. So, /users/halfer.html would have been, prior to the popularity of dynamic routing, a file halfer.html inside a folder called users, which was itself inside the web/vhost root.
That means that, if you are in that page, any link that does not start with a protocol reference (e.g. http://) or a forward slash (i.e. the vhost root) is relative to the current address, so BringMeAnother.html would in fact reference /users/BringMeAnother.html.
Now, with modern routing, the .html suffix is redundant, so this can be dropped. However, the "folder-based" approach to relative links is still honoured by the browser. Thus, a link on this page to BringMeAnother would link to the route /users/BringMeAnother.
In relation to your comment, the implementation of some routing systems is rather partial, in my opinion. They will always convert a URI path to a controller, method and parameters, but they don't all offer named routes so that route hard-wiring can be avoided. However, this is probably very simple to add to CodeIgniter (of course, check that it is not offered already - it may be!).
Here's an example. Let's say your route /users/:user_name points to controller UserController and method run, and you wire each use case of this link in manually. You then decide that you wish to rename the route to /browse/users/:user_name, which is a problem since you've hardwired it in twenty places.
The solution is to add routes via a method that allows you to name them. Symfony 1 does this via this syntax:
#users?user_name=halfer
That means that a route named "users" would be expanded out to whatever the route definition was (e.g. /browse/users/halfer). However, I'm not suggesting you switch frameworks. Just add a custom method that stores names against route definitions (and adds them to your routing system automatically) so that you avoid hardwiring what a route looks like in each use case.

CakePHP 2.0 Disable Routing Issue

I have my own routing rules in routes.php, defined for all the pages that should be accessible via URL, such as mywebsite/blog/ and mywebsite/blog/category/category-name, i.e. the structure of my whole website is covered by my custom routes.
Now, I have a lot of elements that make use of requestAction, such as
$websiteabstract = $this -> requestAction(array(
'controller' => 'assets',
'action' => 'displayHomeAbstract'
));
This gives me an error Error: Controller could not be found, probably because I have not defined a route for /assets/displayHomeAbstract. But why do I have to define a custom route for that, when I explicitly state the name of the controller and the action? Shouldn't that bypass the routing altogether?
Either I have not understand Routing at all. Or do I really have to define ALL the possible routes (even those that are only used by requestAction) in my routes.php? I mean, I don't want to allow users to directly access mywebsite/assets/displayHomeAbstract anyway, only via an Element.
Thank you
EDIT: Here is my routes.php http://pastebin.com/aAKBwNZJ
Please have a look at line 128, this is exactly what I do not want since /assets/displayHomeAbstract is ONLY accessed via requestAction.
EDIT: And this is the element, that makes the request: http://pastebin.com/0tK5dYJk
Okay, after extensive discussion with the devs in IRC, I think I understand this well enough to explain to you:
You do have to define your custom routes for your requestAction in this case. requestAction is emulating a full request. It dispatches a request as if accessed using the string url every time, even when the url provided is an array. The book is referring to how when you have a custom route defined in addition to using the default routes (the last line of routes.php), you can use array urls to be agnostic of those routes. However, these array urls rely on the default routes.php in the /lib/ folder and are used to construct a url string. If you're going to have a custom routing pattern, you have to construct the url strings on your own.
Note: the comments below were from earlier versions of this answer.
The key to your problem is understanding the scope of Cake's routing and how it work.
When you define a route in CakePHP, it isn't just used for mapping URLs to controllers. It's also used by the Router for things like generating link addresses and, in your case, mapping the path supplied to requestAction() to a controller. Behind the scenes, Cake is creating a URL string based on your parameters, and then passes it off to the Router to find the correct controller. Since no such route exists, it fails.
As a solution, I would actually recommend not using a controller for that logic. Depending on what it does, a component or a helper may be a better place.
Look at line 156. You commented out the line that loads CakePHP's default routes.

Categories