Welcome Guest, Not a member yet? Register   Sign In
Custom, database-driven 404 page -- can this be improved?
#1

[eluser]arlodesign[/eluser]
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:

Code:
show_404($segments[0]);

became

Code:
return array('page', 'index', $segments[0]);

Here's my page controller:
Code:
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:

Code:
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. Wink

ANOTHER UPDATE: Fixed link to forum post in first paragraph.


Messages In This Thread
Custom, database-driven 404 page -- can this be improved? - by El Forum - 07-13-2008, 07:42 PM



Theme © iAndrew 2016 - Forum software by © MyBB