Rewrite Route to map to default route - zend-framework

Because of the problems I experienced here: Zend_ Controller_ Router_Exception: “xyz” is not specified
I want to have this route:
":module/:controller/:id"
and map it onto this:
":module/:controller/:action/id/$id"
Is there any possibility to do this with Zend Framework? I do not want to forward the browser to that URL. I just want to tell Zend Framework how to handle this route.
As for reasons why I would like to do this, you can find them in that linked SO question.

Yes it is possible. In my application.ini I specify my routes using regex this way:
resources.router.routes.something.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.something.route = "mymodule/mycontroller/([0-9]+)"
resources.router.routes.something.defaults.module = "mymodule"
resources.router.routes.something.defaults.controller = "mycontroller"
resources.router.routes.something.defaults.action = "myaction"
resources.router.routes.something.map.1 = "id"
I am not familiar with the ":variable" way of defining routes, but you can take from my example the ability to set default controllers, modules, and actions, without the need to explicitly define them in the url.

Related

unique string route base for zend framework

i want to have some route for shortest url method for zend framework.
i have a router like this
http://mysite.org/en/articles/view/id/34/title/MyUniqueArticleTitleInEnglish
i can easily change to
http://mysite.org/en/viewarticle/MyUniqueArticleTitleInEnglish
i want to have something like this
http://mysite.org/MyUniqueArticleTitleInEnglish
that check if unique title not available check for 'MyUniqueArticleTitleInEnglish' controller like default route.
what must i do?
What you could do is create a routing stack that goes to the desired controller for scenario 3 if there is only one parameter in the url and goes to a 'normal' module/controller/action route if more params are supplied. Should look like:
routes.shortest.route = "/:slug"
routes.shortest.defaults.module = public
routes.shortest.defaults.controller = article
routes.shortest.defaults.action = show
routes.default.route = ":module/:controller/:action"
routes.default.defaults.controller = index
routes.default.defaults.action = index
(untested but should work)

Zend Router Question

I use modules layout to structure my controllers:
:module/:controller/:action
I would like to add a new custom route so that the following url will work.
domain.com/username
where username is a username of any registered user on the website.
Can anyone point me in the right direction?
Thank you
See this blog post for a detailed explanation of how to do this in ZF:
http://tfountain.co.uk/blog/2010/9/9/vanity-urls-zend-framework
Not sure if you can make something like domain.com/username. Instead you could do domain.com/u/username or domain.com/user/username. For example, to make the second route in you application.ini you could put something similar to the following:
resources.router.routes.user.route = "/user/:user"
resources.router.routes.user.type = "Zend_Controller_Router_Route"
resources.router.routes.user.defaults.module = default
resources.router.routes.user.defaults.controller = user
resources.router.routes.user.defaults.action = user
resources.router.routes.user.defaults.user =
resources.router.routes.user.reqs.user = "\s+"
http://framework.zend.com/manual/en/zend.controller.router.html covers quite well all the different ways you can add routes. Keep in mind, once you add custom routes, the default one will not work anymore unless you explicitly define it (as well as in url view helpers etc.).

module specific routes in Zend Framework without specifying module name in route

I need to create some module specific routes, but without explicitly mentioning module name in route. Right now I have separate config file for each module (MODULE/configs/module.ini) and in the module bootstrap I push those routes into Zend Framework. The INI file holds routes information but it mention the module name in the route. e.g.
routes.contents.route = "Contents/(.*)"
routes.contents.defaults.module = Contents
routes.contents.defaults.controller = index
routes.contents.defaults.action = index
+other details regarding the route.
You can see that the module name ("Contents") is explicitly mentioned in the route. What I want is that in the routes I just mention the portion after the module name and it automatically prepend the module name before the route. So later if I rename the module to lets say CMS, I don't ve to change every route into "CMS/xxxx".
The 'route' you specify can be anything you want. If Zend Framework matches it, it will execute the route based on the defaults set below.
resources.router.routes.products.regex = "somethingawesome/(.*)"
resources.router.routes.products.defaults.module = "ModuleName"
resources.router.routes.products.defaults.controller = "awesome"
resources.router.routes.products.defaults.action = "cool"
The above 'route' uses the regex match for - mysite.com/somethingawesome/whatever and will route it to the module: ModuleName, controller AwesomeController.php and run the coolAction()
There are lots of other matches you can do within this regex, but the string 'somethingawesome' is entirely up to you. It's all about what you want to match in the URL and where you want to send it to.

Translate asp.net mvc 2 application?

I'm hoping this is a rather simple question, but I'm pretty new to MVC and can't see clearly how it should be done. I have a site that I need to translate to another language. I've tried to search on this, but all I found was pretty complex translations about how to handle strings etc in resx files. That may be something for later, but for now all I want is to be able to let the user switch language (by links I can place in the master page), and then based on that choice have different pages shown in different languages.
From my search it seemed this could be achieved by routing somehow. As suggested in another post:
routes.MapRoute(
"Default",
"{language}/{controller}/{action}/{id}",
new { language = "en", controller = "Home", action = "Index", id = "" }
);
And the master page switch links:
<li><%= Html.ActionLink(
"Spanish",
ViewContext.RouteData.Values["action"].ToString(),
new { language = "es" })%></li>
<li><%= Html.ActionLink(
"French",
ViewContext.RouteData.Values["action"].ToString(),
new { language = "fr" })%></li>
<li><%= Html.ActionLink(
"English",
ViewContext.RouteData.Values["action"].ToString(),
new { language = "en" })%></li>
I could try this, but what I don't understand is, what type of routes does this create? Is it "language/controllername/actionname"? And if so, where does it lead? I mean, usually, with just a controller and an action, all I have is one controller and one view, and as long as that view exists it will work. But what is the language in this? Is it just as a folder, so if I have a folder say en-GB/Home such a route would work? That doesn't make sense, so I guess not. So how do I actually make these routes lead somewhere? Where do I place the translated views?
I think using resource files instead will be easier in the long run and not that hard to get going with.
Check out this link for more information.
Here's a quick how to on it.
Here's some gotchas to using resources in .Net MVC with solutions.
re the url, it is like you said / like it reads - language/controllername/actionname
re what it calls - what you need to focus on to understand it is in this bit of the route definition:
new { language = "en", controller = "Home", action = "Index", id = "" }
{controller}/{action}, matches the corresponding controller and action like before. Language and id matches those parameters in the action method you define. Those could also be properties of the (view)model, if that's the parameter you have in the method.
I don't think there is anything automatically hooked for the languages in mvc, so you have to explicitly decide how you want to handle it. One way would be for your action methods to return a view in a subfolder for each language or by adding the language as part of the file name.
Another way to go about it, is to define a handler in the route that sets the thread ui culture as you would in classic asp.net. From then on you use the asp.net mvc resources like in klabranche links.

Custom ASP.NET MVC Route In Nested Folders

I want sub-folders in my MVC application, so the current routes just don't cut it.
I've got a folder structure such as
Views/Accounts/ClientBalances/MyReport.aspx
and I'm wanting a URL such as http://myapp/Accounts/ClientBalances/MyReport. How do you achieve this with mapping routes? I've had a bash but I'm not very savvy with them. I thought it'd be along the lines of
routes.MapRoute( _
"Accounts/ClientBalances", _
"Accounts/ClientBalances/{controller}/{action}/{id}", _
New With {.controller = "Home", .action = "Index", .id = ""} _
)
I've had no luck though. Any ideas?
Take a look at ASP.NET MVC 2's areas; they look like very similar to what you're trying to achieve. You can watch a quick, 3-minutes video introducing them here.
If you can't (or don't want to) use them, then check this answer about nested view folders. In summary:
You can just return the appropriate view like this (from the action method):
return View("~/Views/controllername/modulename/actionname.ascx", [optional model]);
The location of the view has nothing to do with the route.
Your views should be in Views/[ControllerName]