I am using CodeIgniter framework. I have files in my controllers folder like this:
- Controllers
--- admin.php - Admin Controller
--- /Admin - Admin Folder
----- category.php - Category Controller in Admin folder.
The Url: mysite.com/index.php/admin/category says that page not found because it is trying to call the category function of admin controller but I want it to call the index function of category controller in Admin folder.
Also I am using the admin controller for create, edit etc. functions of admin controller like mysite.com/index.php/admin/create.
I think, I should use the $route array in config file. What routing should I use?
This is the default behavior of the CI core. See function _validate_request($segments) in system/core/Router.php. This function attempts to determine the path to the controller. It goes through different conditions one by one and returns the result once a given condition is met. Besides the other, there are two conditions involved:
Is it a file? (system/core/Router.php line 271, CI 2.1.2)
// Does the requested controller exist in the root folder?
if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
{
return $segments;
}
Is it a folder? (system/core/Router.php line 277, CI 2.1.2)
// Is the controller in a sub-folder?
if (is_dir(APPPATH.'controllers/'.$segments[0]))
{
// ...
In your case the function will return once the first of the two conditions is met, i.e. when admin.php file is found.
There are two solutions:
Rename the file or the folder and refactor the application respectively.
Change the default behavior by extending the core. Basically that would conclude in changing the sequence of conditions checking. This can be accomplished by creating MY_Router class:
class MY_Router extends CI_Router
{
// ...
}
and rewriting the original _validate_request() function with changed sequence of conditions. So first checking for directory and then for function.
I would suggest the first solution, if it does not require too much refactoring.
At the bottom of your application/config/routes.php file, add something like this:
$route['admin/create'] = 'admin/category';
Related
I am trying to intregrate HMVC to codeigniter. I have installed the MX files to thrid_party and uploaded the MY_Loader , MY_Loader and MY_Model to the application/core folder. it is working fine
I have two issues
1) How to add the module routes that overide the application routes
I am accessing module through the link localhost/domain/admin/portfolio
I have tried adding routes.php to the modules config application/modules/portfolio/config/routes.php with below details
$route['admin/portfolio'] = 'portfolio/admin/portfolio';
$route['admin/portfolio/add'] = 'portfolio/admin/portfolio/edit';
$route['admin/portfolio/edit/(:num)'] = 'portfolio/admin/portfolio/edit/$1';
On my root application config already added a routes
$route['admin'] = 'admin/login';
Because of this route 'admin/login' in the application/config/routes.php it is showing page not found. To fix this I have currently added the module/portfolio/config/routes`` above the 'admin/login'. Is there any other method instead of adding it to theapplication/config/routes`.
2) How to access the module view files
I have controller accessing the view files from application/controlles/admin/
$this->load->view('admin/view_header',$data);
$this->load->view('admin/view_portfolio',$data);
$this->load->view('admin/view_footer');
You have placed your Portfolio Controller under
application/modules/portfolio/controllers/admin
which is fine.
Your route (which will hit the index by default) should be
$route['admin/portfolio'] = 'portfolio/admin/portfolio';
Aside: other naming considerations
What I tend to do is to create a controller with admin in the name...
So I would have PortfolioAdmin.php or something along those lines, so I know by the file name, it's admin "Stuff", when I am playing with it in my Editor/IDE.
UPDATE:
In regards to your
Nor this works Modules::run('admin/portfolio', $data);
So you would then use the full controller name... Do not use routes, they are for URLs. Any module you want to call from another module you always use the full name.
Modules::run('portfolio/admin/portfolio', $data);
Ok, guys, this is the case...
I am working in an old porject made it with CodeIgniter v2 (currently all is in localhost). For new features I created a folder called v1 inside the api folder
The structure of the project:
controllers
api
v1
visit.php
orders.php
controller1.php
controller2.php
The problem is that I can not access to the visit.php controller
to test purposes I set the visit controller in the api folder an access it whit this:
localhost/projectname/index.php/api/visit/visits
visits is the function in the visit controller
With this way everything works!! but, when I set the visit controller in the v1 folder I get a 404 page not found error.
localhost/projectname/index.php/api/v1/visit/visits
Extra
Another think that have keep in mind is. This project is using a library to the REST API so, in the visit controller are tho functions
public function visits_get(){
// return an arrays of visits
}
public function visits_post(){
// to add a new visit in a bd
}
So, the function will be called depends on the request method
I have been reading and I found that I have to configure the route.php, actually I did it but without success.
Thanks and I hope you understand what I am asking!
ROUTE.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$route['default_controller'] = "welcome";
$route['404_override'] = '';
This is all that the route.php has in it ._.
To my knowledge, any controllers falling outside the application/controllers/controller_name.php naming convention need to be explicitly defined inside the routes.php file, otherwise CI will not look inside subfolders. It's not much of a problem, actually, add something like this for your controllers:
//You'll need to do this for all of your API controllers, unfortunately
$route['api/v1/(:any)'] = 'api/v1/$1';
//If you have controllers taking arguments, eg. /api/v1/stuff/1
$route['api/v1/(:any)/(:any)'] = 'api/v1/$1/$2';
//Catch-all route for 404's, recommended
$route['api/(:any)'] = 'api/v1/error_api';
Have a look at the routing docs for CodeIgniter 2 for more info.
I am building a cms in codeigniter and i want to remove controller name and function name form the url and just print the alias.
I will be having two controllers one for static pages and other for blog posts with categories.
Please help, Suggestions reagrding modification of two controllers are also welcome.
You will need to override the default 404 controller in application/config/routes.php.
$route['404_override'] = 'content';
Any request that can't be mapped to a controller will be passed to the application/controllers/content.php controller
Your Content controller, or whatever you decide to call it, will parse the uri [$this->uri->segment(1)] and check for a matching reference in your CMS database.
If there is no match in the database, then you can look for a static view in the views folder and load it.
if(is_file(FCPATH.'views/'.$this->uri->segment(1).'.php')) {
$this->load->view($controller,$this->data);
}
If no static view is found, and there is no matching content in the db, call the show_404() function.
Using this method, you will keep the default CI functionality of uri mapping, so at any time, you can add controllers as you normally would and the app will perform like a vanilla CI install.
I am working in Codeigniter with smarty templates.
Problem is that if i go about 2nd subfolder in view or controller, the Codeigniter stops working...
e-g here
application/controllers/main.php - works
application/controllers/admin/dashboard.php - works
application/controllers/admin/manageUsers/ListUsers.php - not working
I have searched the web, and they said that i can work with routes, which might do work with controller..
but it is views that i am concern of..
i mean admin views should go under admin folder, but i can not create subfolder in admin, if i put all views in admin folder, it will be a mess, nothing organized. i hope you are understanding what i am trying to say.
e-g
themes/default/views/home.tpl - works
themes/default/views/admin/dashboard.tpl works
themes/default/views/admin/site_settings/preferences.tpl not working
please can anyone guide me how to fix these issues.
Your problem is quite common. I've had it when I started working with CodeIgniter as well. What I found out to be the best way to overcome it, was to create a Custom_Router, which extends the CI_Router class. Doing that allows you to overwrite the controller class include/require logic and allow the usage of subdirs. This is a working example:
<?php
class Custom_Router extends CI_Router
{
public function __construct()
{
parent::__construct();
}
public function _validate_request($segments)
{
if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
{
return $segments;
}
if (is_dir(APPPATH.'controllers/'.$segments[0]))
{
$this->set_directory($segments[0]);
$segments = array_slice($segments, 1);
while(count($segments) > 0 && is_dir(APPPATH.'controllers/'.$this->directory.DIRECTORY_SEPARATOR.$segments[0]))
{
// Set the directory and remove it from the segment array
$this->directory = $this->directory . $segments[0] .DIRECTORY_SEPARATOR;
$segments = array_slice($segments, 1);
}
if (count($segments) > 0)
{
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
{
show_404($this->fetch_directory().$segments[0]);
}
}
else
{
$this->set_class($this->default_controller);
$this->set_method('index');
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
{
$this->directory = '';
return array();
}
}
return $segments;
}
show_404($segments[0]);
}
}
?>
The code above works fine with as many subdirs as you'd want, although I wouldn't advice using this approach. I usually specifically state the path to my controllers in the route.php file.
Regarding your second problem - the templates. I never liked messy code and even messier viewers which contain <?php echo $something; for(...){}; foreach(){}... ?> all over the place. For me, that makes the code really hard to read and specially harder to debug. That's why I've been using the Twig template engine. There are tutorials how to get it working in CodeIgniter (I've used this one). Once you're done with it, in your controller you would simply need to write:
class Login extends Custom_Controller
{
/**
* Index Page for this controller.
*/
public function index() {
$data = array();
$error_message = "Invalid user!";
if($this->session->getUserId() != null){
redirect('/welcome');
}
// other logic....
// depending on how you configure twig, this will search for "login.html.twig"
// in "application/views/". If your file is located somewhere in the subdirs,
// you just write the path:
// admin/login.html.twig => application/views/admin/login.html.twig
$this->twig->display('login.html.twig', $data);
}
}
If Twig is not an option for you, then you will need to create a new class which extends the CI_Loader class and overwrite the public function view(){} method.
By the way, if you're creating a web application with a backend, you might find it easier to manage and maintain your code if you separate your applications in different directories. If you choose to go this way, you will need to create application/public and application/admin folders preserving the directory structure of a CodeIgniter "application". Here are the steps:
Create separate applications
/applications
-- public (a standard application directory structure)
---- cache
---- config
---- controllers
---- models
---- views
---- ...
-- admin (a standard application directory structure)
---- cache
---- config
---- controllers
---- models
---- views
---- ...
Open /index.php and change $application_folder to point to applications/public
Create a copy of /index.php, name it backend.php (or whatever you want). Open the file and change $application_folder to point to the applications/admin folder.
Open .htaccess and add a rule to pass all URI starting with /admin to backend.php
# Route admin urls
RewriteCond %{REQUEST_URI} admin([/])?(.*)
RewriteRule .* backend.php?$1 [QSA,L]
Put THIS file into application/core/
Filename must be MY_Router.php
I'm creating a simple blog with Codeigniter. But I'm having trouble calling another controller besides the default controller.
The following URL takes me to the default controller as specified in my config/routes.php.
blog/index.php
According to the documentation, simply appending the name of another controller saved in controllers/ is all that is needed:
blog/index.php/blog_login
Here is my controller class, named blog_login.php:
class Blog_login extends CI_Controller {
public function index()
{
echo 'It works!';
}
}
But doing this throws a 404 error, which makes me feel that I'm missing something. Is there something else that I am supposed to configure before trying to access a different controller?
http://codeigniter.com/user_guide/general/routing.html Read this properly, it couldn't be clearer.
According to the documentation, simply appending the name of another
controller saved in controllers/ is all that is needed
This is not true. If you want to call another controller 'Blog_login', you simply put the name of the controller as the first segment of the url:
domain.com/index.php/blog_login
This will never work:
blog/index.php/blog_login
Index.php (unless you remove it via .htaccess) always follows right after your domain.com
Finally, you don't need to specify routes unless you're doing something non standard. So
domain.com/index.php/blog_login - calls the index() function in your Blog_login controller
domain.com/index.php/blog - calls the index() function in your blog controller
domain.com/index.php/blog/search - calls the search() function in your blog controller.
None of the above examples need an entry in routes.php
When u call:
blog/index.php/blog_login
you're really calling a method called "blog_login" in your "blog" controller. If you want to call another controller, it must have the following structure:
controller_name/controller_method
So, if you wanna call your blog_login controller just call it like this:
blog_login/
Note: Sometimes it's necessary to add the base_url() to your URL in order to make CI understand correctly the URL.