Search code examples
phpcodeignitercodeigniter-3

How do I load a view from outside the default views folder in this Codeigniter 3 application?


I am working on a CMS with CodeIgniter 3.1.8 and Bootstrap 4. I have decided to add themes to it. The application is not HMVC, only MVC.

The themes directory is outside application as can be see in the image below:

enter image description here

Inside themes I have the theme directory (of course) which contains the "master view", layout.php:

enter image description here

In application/core I have added a Loader.php file with the following contents:

<?php defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH."../system/core/Loader.php";

    class MY_Loader extends CI_Loader {
    
      function ext_view($folder, $view, $vars = array(), $return = FALSE) {
        $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH . $folder . '/' => TRUE));
        return $this->_ci_load(array(
                '_ci_view' => $view,
                '_ci_vars' => $this->_ci_prepare_view_vars($vars),
                '_ci_return' => $return
            ));
      }
    
}?>

In my Posts controller's index() method, I load the view passing it the data:

public function index() {
    //more code here
     $this->load->ext_view('third_party', 'themes/caminar/layout', $data);
}

I get this error message:

Call to undefined method CI_Loader::ext_view();

What am I doing wrong?


Solution

  • Here is how I solved the problem:

    In application/core I have added a MY_Loader.php file with the following contents:

    <?php defined('BASEPATH') OR exit('No direct script access allowed');
    
      class MY_Loader extends CI_Loader {
    
        function theme_view($folder, $view, $vars = array(), $return = FALSE) {
          $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(FCPATH . $folder . '/' => TRUE));
          return $this->_ci_load(array(
                  '_ci_view' => $view,
                  '_ci_vars' => $this->_ci_prepare_view_vars($vars),
                  '_ci_return' => $return
              ));
        }
    
    }
    

    In my Posts controller's index() method, I load the view passing it the data:

    public function index() {
       //more code here
       $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
        $this->load->theme_view('/themes/caminar/', 'layout', $data);
    }