CodeIgniter 2 not allowing multiple level subfolders for controllers - codeigniter

As I read the doc, controllers in CodeIgniter are supposed to support multiple level subfolders, but as far as I have tested, it is impossible to work after first a first level folder.
By example:
mysite.dev/ (index page, default controller home.php, works)
mysite.dev/admin/ (admin section, in admin/home.php, works)
mysite.dev/admin/manage/ (in admin/manage/home.php, do not work)
I am trying to know why and how to make it work on multiple level sub folders?
Thanks in advance!

CI only allows one sub-dir level. However, you can emulate this pattern with routes file as #Brendan says:
Controllers:
welcome.php
admin/admin.php
admin/manage.php
Routes file:
$route['admin/manage/:any'] = "admin/manage/$1";
$route['admin/admin'] = 'admin/home.php';
You can implement some changes to the hardcode to get works as expected: http://codeigniter.com/forums/viewthread/190563/

Related

Codeigniter subfolder named like controller

I'm trying to make folder in controller folder with exact name like controller in Codeigniter. Is it possible by some trick or something?
Screenshot here: http://i.imgur.com/vrQ1J9V.png
If it will be like
/controllers/manage/manage.php
you should add in /config/routes.php
$route['manage/(.*)'] = "manage/manage/$1";
$route['manage'] = "manage/manage";
There is no problem in using the same name, but it is confusing. The best solution would be to change the name, but you can use just fine.
Remember to use the routes with 'manage/manage/function'.
EDIT
I incorrectly viewed the first time and thought manage.php was outside the manage folder.
It will work, but your URL will just have "manage" twice. You could change the routes config to remove the first "manage", but it will be less confusing and time-consuming to just name manage.php something different.

Redirection rules in codeigniter

I want to create location pages in my codeigniter site. So I have one contrller named locations and index method. So all the requests http://mysite.com/location_name should be landed to http://mysite.com/index.php/locations/index. And all other should work as it is like http://mysite.com/login should be landed to http://mysite.com/index.php/home/login. Contact us http://mysite.com/contact-us should be landed to http://mysite.com/index.php/home/contact.
I tried to achieve this by writing following line route rule (route.php):
$route['(:any)'] = 'locations'; //location name can be anything around the world
So locations are working fine, but http://mysite.com/login and http://mysite.com/contact-us are not working, they redirecting continuously in infinite loop.
Please suggest the solution. Thank.
The routes are applied from top to bottom, so you need to have your more specific rules listed first, then your more generic rules last:
$route['login'] = 'home/login';
$route['contact-us'] = 'home/contact';
$route['(:any)'] = 'location/index';
I see that you mentioned you've tried changing the order of rules in your route file. So If you have done this and it's not working - you have something else going on.
I would check these things:
.htaccess file (if you're using it)
controllers that are causing the infinite loop (any redirections in there, _remap method, etc. )

How to build CodeIgniter URL with hierarchy?

I know this doesn't exactly match the form of www.example.com/class/function/ID/, but what I want to display to the user would make more sense.
This is what I would like to do:
www.example.com/project/id/item/item_id/
So, an example would be:
www.example.com/project/5/item/198237/
And this would be the behavior:
www.example.com/project/ --> This would show a list of projects (current implementation)
www.example.com/project/5/ --> This would show a list of items on project 5 (current implementation)
www.example.com/project/5/item/ --> This wouldn't really mean anything different than the line above. (Is that bad?)
www.example.com/project/5/item/198237/ --> This would show details for item 198237.
So, each item is directly associated with one and only one project.
The only way I can think how to do this is to bloat the "project" controller and parse the various parameters and control ALL views from that "project" controller. I'd prefer not to do this, because the model and view for an "item" are truly separate from the model and view of a "project."
The only other solution (that I am currently implementing and don't prefer) is to have the following:
www.example.com/project/5/
www.example.com/item/198237/
Is there any way to build a hierarchical URL as I showed at the beginning without bloating the "project" controller?
There are 3 options, sorted by how practical they can be:
Use URI Routing. Define a regular expression that will use a specific controller/method combination for each URL.
Something like that could help you, in routes.php:
$route['project/'] = 'project/viewall';
$route['project/(.+)'] = 'project/view/$1';
$route['project/(.+)/item/'] = 'project/view/$1';
$route['project/(.+)/item/(.+)'] = 'item/view/$2';
That is, considering your controllers are item and project respectively. Also note that $n in the value corresponds to the part matched in the n-th parenthesis.
Use the same controller with (or without) redirection. I guess you already considered this.
Use redirection at a lower level, such as ModRewrite on Apache servers. You could come up with a rule similar to the one in routes.php. If you are already using such a method, it wouldn't be a bad idea to use that, but only if you are already using such a thing, and preferably, in the case of Apache, in the server configuration rather than an .htaccess file.
You can control all of these options using routes.php (found in the config folder). You can alternatively catch any of your URI segments using the URI class, as in $this->uri->segment(2). That is if you have the URL helper loaded. That you can load by default in the autoload.php file (also in the config folder).

codeigniter routing issue

I had my users profile at
www.domain.com/user/username
and moved it at
www.domain.com/username
but this required to add most classes functions into the routes.php file in the config and if i want to add new features to my app i will need to add all the functions into the routes.php file which doesnt sound good practice...
What is the best way that other deal with it on CodeIgniter ?
Perhaps, you can do it the other way round - make a whitelist of usernames that can't be taken (those would be names of your controllers, like admin, contact, etc...) and route anything except the whitelist items.
seems i got the answer
what i did is add the below code for every controller i have
$route['controller'] = "controller";
$route['controller/(:any)'] = "controller/$1";
and this code at the bottom
$route['(:any)'] = "user/$1";

Separate layouts and namespaces for frontend/backend in Zend application

I had to develop a CMS using Zend Framework and I used the default namespace defined in my boostrap for my backend:
autoloaderNamespaces[] = "Application_"
Now I want to develop the frontend, but I don't know how to do it, since I have access to my backend from the /public/ directory.
Then I would like to use a different layout for my frontend than the one I use for the backend access. So I found this post but I don't know if I have to change/add (and then how to change) the module of my backend, or if I have to create a second module that I will use for my frontend
my file tree is like this :
So if I create a frontend module, shall I create a frontend directory next to the applicationdirectory ?
EDIT : I created 2directories pub and frontend next to the application directory. In pub/index.php I instanciated the bootstrap with the application/configs/application.ini file with a different APPLICATION_FRONT_ENV :
[frontprod : production]
bootstrap.path = APPLICATION_FRONT_PATH "/bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_FRONT_PATH "/controllers"
autoloaderNamespaces[] = "Frontend_"
resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_FRONT_PATH "/layouts/scripts"
[frontdev: frontprod]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1
and in the frontend/bootstrap.php I loaded models from applicationdirectory :
public function _initAutoloader(){
$baseAutoload = new Zend_Loader_Autoloader_Resource(array(
'namespace' => 'Application',
'basePath' => realpath(dirname(__FILE__).'/../application')
)
);
}
And it seems to be working fine =)
thank you !
In Zend Framework you can organise your app in modules, wich suits very well to your needs. Unfortunately the doc doesn't emphasize enough the importance of this concept, and how you should implement it from day one.
Modules allows you to regroup under a same module folder everything that is related to this module only, and this way to isolate "parts" of your app in logical groups.
In your case it would be "back" and "front", but you could also have a "forum" module or let's say a "shop" module.
In the urls point of view, the default routing of a modular structure is example.com/module/controller/action, but using hostname routes you can also have www.example.com pointing to your "front" module and admin.example.com pointing to your backend.
Have a look at the poor documentation section about modules, and don't panic, you won't have to rename everything if you move your current controllers, views and models in the "default" module.
There is an other alternative that could suit well for a backend/frontend logic, but not if you want to split your code in more logical parts (forum, blog, shop,...). You just create a second application folder (you would name 'frontend') next to the 'application' folder, and a second public directory (where you can symlink your assets folder if you use the sames), and a different namespace.
To be able to autoload your 'Application_' classes in your frontend code, just add and configure a Module Autoloader in your frontend bootstrap. The code is quite simple :
//in your frontend/Bootstrap.php
public function _initAutoloader(){
new Zend_Loader_Autoloader_Resource( array(
'namespace' => 'Application_',
'path' => realpath(dirname(__FILE__).'/../application'
)
);
}
For the application.ini config file i would recommend, instead of duplicating it, that you create a section [frontprod : production] section where you override your backend settings (and a matching [frontdev: frontprod] for your local settings).
I hope this helped. There is so much to say about all the topics introduced here that you should first have a look at this, then comment this answer with more specific questions about the problems you may encounter, and i'll extend the answer.

Resources