Welcome Guest, Not a member yet? Register   Sign In
HMVC custom 404 pages
#11

[eluser]CISCK[/eluser]
[quote author="kaola" date="1250138236"].htaccess

ErrorDocument 404 /404.html[/quote]

@kaola: Won't that redirect users to 404.html? The benefit to extending CI's 404 behavior is that you're still using the correct 404ed URL in the browser.

[quote author="Dan Horrigan" date="1250147223"]Why go through all of this to show a 404 page when CI already does one? Simply modify the error_404.php file in the errors folder in the application folder. This is by far the easiest way to do it.[/quote]

@Dan Horrigan: You're probably right, but this method doesn't allow you to route through a controller (without a redirect or breaking MVC). That's why I extend the CI_Router class like so. This technique solves the controller problem, but I can't figure out how to make it work with the show_404('page') method (in CI_Exceptions). Calling show_404 will use CI's default error_404.php view. Any thoughts? I do agree that there should be a better way though.

[quote author="Mikle" date="1250154554"]My application has widgets and I use HMVC. I use main template with widgets and sitemap in content zone for 404 pages.[/quote]

@Mikle: I have yet to try HMVC, so I don't really follow you. Does your method involve redirecting the URL at all?
#12

[eluser]Mikle[/eluser]
[quote author="CISCK" date="1250546976"]
[quote author="Mikle" date="1250154554"]My application has widgets and I use HMVC. I use main template with widgets and sitemap in content zone for 404 pages.[/quote]

@Mikle: I have yet to try HMVC, so I don't really follow you. Does your method involve redirecting the URL at all?[/quote]

My method redirects from error pages to 404 controller and output '404 error' header for search engines. In 404 controller I add:

Code:
header("HTTP/1.1 404 Not Found");
#13

[eluser]renownedmedia[/eluser]
With most of my pages, every page has the same layout. Preferably, I'd like to display the error message within the content area of my main template file (while still sending the 404 header). That way, the user can still browse the website without having to use the history or change the URL.
#14

[eluser]CISCK[/eluser]
I just came across this site with an nice solution. It only requires extending a single method from CI_Exceptions, and an additional controller method for routing (as you would for any other view).

My example is slightly modified for my own purposes, so take a look at Kelvin's example too.

libraries/MY_Exceptions.php
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Exceptions extends CI_Exceptions {

    public $error_controller = 'error';
    public $error_method_404 = 'error_404';

    function __construct()
    {
        parent::CI_Exceptions();
        log_message('debug', 'MY_Exceptions Class Initialized');
    }
    
    function show_404($page = '')
    {
        // log the error
        log_message('error', '404 Page Not Found --> ' . $page);    
        
        // get the CI base URL
        $this->config =& get_config();
        $base_url = $this->config['base_url'];    
        
        // see: http://www.kelvinluck.com/2009/04/custom-404-error-messages-with-codeigniter/
        
        // create new cURL resource
        $ch = curl_init();
        
        // set URL and other options
        curl_setopt($ch, CURLOPT_URL, $base_url . "$this->error_controller/$this->error_method_404");
        curl_setopt($ch, CURLOPT_HEADER, 0); // note: the 404 header is already set in the error controller
        
        // pass URL to the browser
        curl_exec($ch);
        
        // close cURL resource, and free up system resources
        curl_close($ch);
    }
  
}

/* End of file MY_Exceptions.php */
/* Location: ./system/application/libraries/MY_Exceptions.php */

controllers/error.php
Code:
<?php

class Error extends Controller {

    function error_404()
    {
        // 404 Header!
        $this->output->set_status_header('404');
        
        // debug
        //$this->output->enable_profiler(TRUE);

        // data
        // some data ...

        // View
        $this->load->view('error_404', $data);
    }
}

/* End of file error.php */
/* Location: ./system/application/controllers/error.php */

Note that any time a user encounters a 404, or you send a 404 using the show_404 method, the URL will not change. For example, when a user goes to http://example.com/this-page-does-not exist, they will get a 404 error without being redirected to a different URL. This is the expected behavior for most users (and search engines). Thanks, Kelvin!
#15

[eluser]renownedmedia[/eluser]
Why do we need to use cURL for this?
#16

[eluser]Mikle[/eluser]
CISCK

Change:

parent::CI_Exceptions();

to:

parent::__construct();
#17

[eluser]asylmottaket[/eluser]
[quote author="wiredesignz" date="1247705235"]
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* Base Controller Extension
*/
class Base_Controller extends Controller
{    
    function Base_Controller() {
        parent::Controller();
    }
    
    function _remap($action) {
        
        if (method_exists($this, $action) OR method_exists($this, $action = 'index')) {
            call_user_func_array(array(&$this, $action), array_slice($this->uri->segments, 1));
        } else {    
            show_404(); //modules::run('error/error_404');
        }

    }
}

/* End of file MY_Controller.php */
/* Location: ./application/libraries/MY_Controller.php */
[/quote]


Than you route the base_controller to something like "home", so you dont have http://localhost/base_controller/some_method in the url?
#18

[eluser]Peng Kong[/eluser]
hi wiredesignz,

how do we use your base_controller?

do we just simply extend base_controller instead of controller?
#19

[eluser]hot_sauce[/eluser]
Create new file "MY_Exceptions.php" in application/core
and paste this
Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require APPPATH."third_party/MX/Exceptions.php";

class MY_Exceptions extends MX_Exceptions {}

Create new file "Exceptions.php" in third_party/MX/
and paste this
Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MX_Exceptions extends CI_Exceptions {

function show_404($page = '', $log_error = TRUE)
{
  
  $heading = "404 Page Not Found";
  $message = "The page you requested was not found.";

  // By default we log this, but allow a dev to skip it
  if ($log_error)
  {
   log_message('error', '404 Page Not Found --> '.$page);
  }

  echo $this->show_error($heading, $message, 'error_404', 404);
  exit;
}

// --------------------------------------------------------------------

/**
  * General Error Page
  *
  * This function takes an error message as input
  * (either as a string or an array) and displays
  * it using the specified template.
  *
  * @access private
  * @param string the heading
  * @param string the message
  * @param string the template name
  * @param  int  the status code
  * @return string
  */
function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
  set_status_header($status_code);

  $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';

  if (ob_get_level() > $this->ob_level + 1)
  {
   ob_end_flush();
  }
  
  $module = CI::$APP->router->fetch_module();
  $found = false;
  foreach (Modules::$locations as $location => $offset) {
   if (is_dir($source = $location.$module.'/errors/') && !$found) {
    $found = true;
    ob_start();
    include($source.$template.'.php');
    $buffer = ob_get_contents();
    ob_end_clean();
    return $buffer;
    break;
   }
  }
  if (!$found)
  {
   ob_start();
   include(APPPATH.'errors/'.$template.'.php');
   $buffer = ob_get_contents();
   ob_end_clean();
   return $buffer;
  }
}

// --------------------------------------------------------------------

/**
  * Native PHP error handler
  *
  * @access private
  * @param string the error severity
  * @param string the error string
  * @param string the error filepath
  * @param string the error line number
  * @return string
  */
function show_php_error($severity, $message, $filepath, $line)
{
  $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];

  $filepath = str_replace("\\", "/", $filepath);

  // For safety reasons we do not show the full file path
  if (FALSE !== strpos($filepath, '/'))
  {
   $x = explode('/', $filepath);
   $filepath = $x[count($x)-2].'/'.end($x);
  }

  if (ob_get_level() > $this->ob_level + 1)
  {
   ob_end_flush();
  }
  ob_start();
  include(APPPATH.'errors/error_php.php');
  $buffer = ob_get_contents();
  ob_end_clean();
  echo $buffer;
}


}
// END Exceptions Class

/* End of file Exceptions.php */
/* Location: ./system/core/Exceptions.php */

application/"modules"/"mysite"/errors/error_404.php
and in your modules folders create a "errors "folder with your error_404.php file




Theme © iAndrew 2016 - Forum software by © MyBB