Welcome Guest, Not a member yet? Register   Sign In
any way to auto-route to a directory under controller?
#1

[eluser]Chillahan[/eluser]
I could not find anything on this, but it doesn't seem to work:

Code:
$route['article/(:any)/(:any)'] = "articledirectory/$2/index";

As an explanation, I have a directory "articledirectory" under controllers, and the second part of the URI (the first ANY expression) has a slug that I match in the constructor to set up the id the code needs to work.

The third part of the URL I would like to automatically route to any of many class files within the articledirectory:

/controllers/articledirectory/controllerclass1.php
/controllers/articledirectory/controllerclass2.php
/controllers/articledirectory/controllerclass3.php

But so far the only way I can get this to work is to specifically define each one in routes, like so:

Code:
$route['article/(:any)/cclass1'] = "articledirectory/controllerclass1/index";
$route['article/(:any)/cclass2'] = "articledirectory/controllerclass2/index";
$route['article/(:any)/cclass3'] = "articledirectory/controllerclass3/index";

I've searched and can't see any answers to this. I assume it's due to the auto-lookup in directory "magic" only working for the first level, and thus there is no way to route it without hacking the core files, right?
#2

[eluser]theprodigy[/eluser]
show me some real examples of urls you would like to see, and real examples you want them routed to. It's somewhat hard to see what exactly you are wanting with the examples you gave.

Your first example:
Code:
$route['article/(:any)/(:any)'] = "articledirectory/$2/index";
doesn't do anything with the first (:any), but your explanation states that it's a slug you need in order to get the id.
You also state that the second (:any) needs to route to certain classes, and that you don't want to have to hard code them, but your examples aren't really showing much way of doing that since they don't match up (cclass1 !== controllerclass1).

If you can show either some real examples, or at least real-like examples, it may be easier to help you.
#3

[eluser]Chillahan[/eluser]
Right, the first (:any) is a slug. I don't pass its value to the class method, instead I access it directly with the URI helper from the class's constructor, looking it up in the db at that point to get the true id.

As for a real-life example, let's say that I have a "video store". The media store publishes its catalog items like this:

http://www.videostore.com/video/chillin-like-a-villain/
http://www.videostore.com/video/two-down-one-to-go/

Now, there are also some other features beyond viewing the sell page for each video (which the above URLs would go to). Let's say "purchase" for the end user, and "orders" for the store owner, to view the orders that need filling on that item. (not so realistic, but humor me) Let's say another for adding a review for a video. So we would have:

http://www.videostore.com/video/chillin-...llain/buy/
http://www.videostore.com/video/chillin-...ieworders/
http://www.videostore.com/video/chillin-...addreview/

Now on the server, I want to have a controller directory like this:

/controllers
/controllers/video
/controllers/video/buy.php
/controllers/video/vieworders.php
/controllers/video/addreview.php

Now yes, I know that if I put all of these features into one file "video.php" in the root, then it would all auto-magically resolve itself.

But I don't want to, because not only are some features customer-facing and others private for admins, but some might be restricted to different types of admins - perhaps repeat customers can add reviews for instance, but only the store owner can review the orders. Furthermore, it's better to keep the code segregated because it will keep the files smaller (so the bootstrap won't be loading a giant 10,000 line file all the time for any ONE controller method), and it will not affect other controllers from loading at all if some bug gets uploaded to production in, say, the vieworders.php file.

Anyway right now, the only way I see to do it is:

Code:
$route['video/(:any)/buy'] = "video/buy/index";
$route['video/(:any)/vieworders'] = "articledirectory/vieworders/index";
$route['video/(:any)/addreview'] = "articledirectory/addreview/index";

(index is optional on the end there, I know, just adding for posterity)

I hope this makes it more clear!
#4

[eluser]theprodigy[/eluser]
Quote:Now on the server, I want to have a controller directory like this:

/controllers
/controllers/video
/controllers/video/buy.php
/controllers/video/vieworders.php
/controllers/video/addreview.php
I hope you also plan to have a
Quote:/controllers/video.php
to handle the
Quote:http://www.videostore.com/video/chillin-like-a-villain/
type URLs.

As for the rest of your problem
Code:
$route['video/:any/(:any)'] = "video/$1/index"; //this one should lead to your nested controllers
$route['video/(:any)'] = "video/$1"; //this one should handle the video.php (title-only) urls
I don't see why that shouldn't work for you.

Quote:I could not find anything on this, but it doesn’t seem to work
Are you getting errors?
Is it not routing at all?
Do you have other routes prior to these that it may be catching on?
#5

[eluser]Chillahan[/eluser]
Right, there would be another controller in that directory, say "summary.php", to handle the root request. (it's just a fictitious example, anyway)

Correct, I have tried it just like you say -

$route['video/:any/(:any)'] = "video/$2/index";

...and it simply does not route. (Note I changed it to $2, it's the second expression that is the name of the class/file that I am trying to route to, the first is the slug.) I've tried with and without the index (and naming the method index or other names), and have also tried removing all other routes.

I am pretty sure it just doesn't do the auto-magic file-to-URI resolution for anything beyond the first level normally, so I am assuming it also doesn't do it with custom routing either. So pretty much just looking for verification that that is how it is, along with any pointers if anyone has seen any solutions to this. Otherwise, manually defining the routes is not that bad for this project, there are not that many routes in total, nor are they being automatically generated - just would have been a little cleaner to have it be automatic.

EDIT: I see you didn't include the first in parentheses, and thus used $1. I don't think that's affecting my case, but I will try it anyway.
#6

[eluser]theprodigy[/eluser]
Quote:I am pretty sure it just doesn’t do the auto-magic file-to-URI resolution for anything beyond the first level normally
CodeIgniter by default allows 1 level extra on nested folders for controllers:
Quote:application/controllers/file.php //allows
application/controllers/folder/file.php //allows
application/controllers/folder/subfolder/file.php //does NOT allow
And what exactly do you mean by "...and it simply does not route"?
Are you getting errors? If so, what are they?
Are you getting a 404? If so, what does the error say the file is that it can't find?
It's a little easier to debug your issue, if you can tell me what is being outputted. I'm walking blind here :coolcheese:
#7

[eluser]Chillahan[/eluser]
Right, I just get the standard 404 error, same as if you type in some made up first level controller name.

I know that it normally allows the auto lookup within that first level down, but my issue is I want to have the slug before the name of the file/class, so while yes, your example works by default:

application/controllers/folder/file.php //allows

Mine would not, because it would be looking for:

application/controllers/folder/[SLUG-VALUE].php

I am still unclear though - are you saying you HAVE set up sites where it has something similar and still does the autolookup by using an expression and passing it on in the route definition?
#8

[eluser]theprodigy[/eluser]
are you getting a CodeIgniter 404 or a regular 404?
have you tried both with and without 'index.php'?
do you have parts of the site that work without routing (and only this routing section is failing)?
#9

[eluser]Chillahan[/eluser]
CI 404. I didn't try with index.php, because it all works otherwise. But I went back and tried something - it seems you found the fix when you used the expression without the () - i.e., this works!

Code:
$route['video/:any/(:any)/(:any)'] = "video/$1/$2";
$route['video/:any/(:any)'] = "video/$1";

I tried back and forth, and it definitely does not work like this:

Code:
$route['video/(:any)/(:any)/(:any)'] = "video/$2/$3";
$route['video/(:any)/(:any)'] = "video/$2";

So I guess if one is not going to reference an expression as an input on a route, it's an error to use parentheses around it? (or it's a bug in the router class?) I mean, I guess I could always try it and put the $1 at the end of both lines, but I never access that part of the URI like that anyway, so I am pretty happy to have it working!

Thanks for brainstorming with me, hopefully it will save others some time with similar routes. Much cleaner this way to not have to define routes for new classes/methods that should be auto-routed!
#10

[eluser]Chillahan[/eluser]
For posterity, one should use these three routes, because then it will also accommodate passing a value directly to a method at the end if needed (i.e., the $3 will be the value passed into the method if desired). Also they have to be in this order of more specific to least specific, otherwise the less specific one will catch all the other cases and prevent them from routing successfully.

Code:
$route['video/:any/(:any)/(:any)/(:any)'] = "video/$1/$2/$3";
$route['video/:any/(:any)/(:any)'] = "video/$1/$2";
$route['video/:any/(:any)'] = "video/$1";

(now I wonder if there's a way to automatically still assign the remainder of the URL to the method called?)




Theme © iAndrew 2016 - Forum software by © MyBB