Using the code from this forum post, I was able to pull off something I really wanted from my CodeIgniter application: if the first segment of the URI doesn’t have a matching controller, send the request to a page controller and check for content in the page database. I did it by extending the Router.php library, as described in that post, and changing _validate_requests() as so:
show_404($segments[0]);
became
return array('page', 'index', $segments[0]);
Here’s my page controller:
class Page extends Controller {
function __construct()
{
parent::Controller();
$this->load->model('Page_model');
}
function index($link)
{
$data['page'] = $this->Page_model->get_page($link);
if (!$data['page']) show_404($this->uri->uri_string());
$data['section'] = array(
'title' => $data['page']['page_title'],
'class' => $data['page']['page_link']
);
$data['page']['page_primary'] = markdown(smartypants($data['page']['page_primary']));
$data['page']['page_secondary'] = markdown(smartypants($data['page']['page_secondary']));
// print_r($data);
$this->load->view('global/head_view', $data);
$this->load->view('global/nav_view');
$this->load->view('page_view');
$this->load->view('global/foot_view');
}
}
Here’s where it gets interesting and I turn to you: I also wanted the content of my 404 page stored in the same pages database table so it could be edited by a user in an admin panel. So I created MY_Exceptions.php:
class MY_Exceptions extends CI_Exceptions {
function MY_Exceptions()
{
parent::CI_Exceptions();
}
function show_404($page = '')
{
// Allows me to use information from database to make 404 page that matches site
$CI =& get_instance();
$CI->load->model('Page_model');
$data['page'] = $CI->Page_model->get_page('404');
$CI->output->set_header("HTTP/1.1 404 Not Found");
$data['section'] = array(
'title' => $data['page']['page_title'],
'class' => $data['page']['page_link']
);
$data['page']['page_primary'] = markdown(smartypants($data['page']['page_primary']));
$data['page']['page_secondary'] = markdown(smartypants($data['page']['page_secondary']));
$CI->load->view('global/head_view', $data);
$CI->load->view('global/nav_view');
$CI->load->view('page_view');
$CI->load->view('global/foot_view');
echo $CI->output->get_output();
log_message('error', '404 Page Not Found --> '.$page);
exit;
}
My question to the always brilliant CodeIgniter community: My solution to this 404 thing feels like a total hack. I had to manually invoke the output class to get the views to appear and, worst of all, I had to reuse an entire block of code which I would have to change in two places should I need to make adjustments.
Any ideas on how I could improve on this idea? Can I actually call the page controller from the library item, or is that a terrible idea?
UPDATE: It should also be noted that, while I’m not a total n00b, my programming skills are somewhere between novice and intermediate. I apologize now if I follow up your kind answer with a bunch of seemingly stupid questions. Thanks. ![]()
ANOTHER UPDATE: Fixed link to forum post in first paragraph.
