Welcome Guest, Not a member yet? Register   Sign In
[SOLVED] practice with views
#1

[eluser]SPeed_FANat1c[/eluser]
Hi,

I am trying to do another CI project. And I had problem in first one - I made sidebar_view.php and my controllers were like this:

Code:
$this->laod->view('header_view');
$this->load->view('menu_view');
$this->load->view('something_view',$data);
$this->load->view('sidebar_view');
$this->load->view('footer_view');

I inicialy static sidebar view - did not loaded data from database. And when I wanted to change it - to load data from database. I could:

in every controler of my entire project make

Code:
$this->load->view('sidebar_view',$data);

this is a lot of work to make the same action in every controller. And I could forget to update some controller.

Don't know if it is even possible, but I guess it would be not a good practice just add code directly to the sidebar_view which loads data from database.

And another option that worked - using ajax to load content from database. This is of course bad.

The same is with header view lets say - if you want to modify, you must modify in every controller. This is so unefficient.

So when I am writing this post I started thinking, maybe I should do something like this:
make a model for sidebar. And in every controller add lines

Code:
$data = $this->sidebar_model->load_data;
$this->load->view('sidebar_view',$data);


The same do with header and footer view. Then when I want to change data in sidebar, I just modify one model and the sidebar is modified, no need to modify every controller.

How do you think about this? Or maybe there is better ways to do this?
#2

[eluser]pickupman[/eluser]
I have been using some this for a while now. I have extended the controller class by creating a file MY_Controller.php in application\libraries\
Code:
class MY_Controller extends Controller{
  
  var $data;

  public function __construct(){
    parent::__construct();

  }
  private function _display(){
     $this->load->view('header', $this->data);
     $this->load->view('menu', $this->data);
     $this->load->view('content', $this->data);
     $this->load->view('footer', $this->data);
  }
}

Then in your other controllers you need to use like
Code:
class News extends MY_Controller{
  
  public function __construct(){
    parent::__construct();
  }

  public function index(){
     $this->data['title'] = 'News Controller'; //set page title for view

     //Do other stuff saving to $this->data instead of just $data
     $this->_display(); //display page
  }

}

Once you get the hang of it, I use my _display method to auto guess the view file based on the uri, and if not found, provide a few fall backs.
#3

[eluser]SPeed_FANat1c[/eluser]
Your idea is good - if you want to add some data that is the same to all views, you simply add it in MY_Controller librarty and all views have that data (for example links on the sidebar are the same everywhere). Before I read your post I did the similar thing:

Code:
//header
        $data['title'] = '';
        $data['general'] = $this->Views_model->data_for_header();
        //most left menu - 0
        $data['current_menu'] = 0;
        $data['javascript'] = '';
        $data['meta'] = array(
                0 => '<meta name="Description" content="Information architecture, Web Design, Web Standards." />',
                1 => '<meta name="Keywords" content="your, keywords" />',
                2 => '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />',
                3 => '<meta name="Distribution" content="Global" />',
                4 => '<meta name="Robots" content="index,follow" />'
            );
        $this->load->view('header_view',$data);
        
        //main
        $data_main = array();
        $this->load->view('home_view',$data_main);
        
        //sidear and footer
        $data_sidebar['general'] = $this->Views_model->data_for_sidebar();
        $this->load->view('sidebar_view',$data_sidebar);
        
        $data_footer['general'] = $this->Views_model->data_for_footer();
        $this->load->view('footer_view',$data_footer);

The only thing I hate there is many lines for every page. But with you example it would also be similar, if you want load differrent title, javascript, metadata, other parameters for every page, you have to add many lines.

But yours looks shorter than mine eveen if we add different data, which is good Smile
#4

[eluser]SPeed_FANat1c[/eluser]
Btw there is only one variable for all views - $data. Does is not use more memory? Let's say you make

Code:
$this->data['title'] = 'News Controller'; //set page title for view

this data is only for a header. But you pass it not only to a header view, but also to menu, content and footer views. So it means you use 4 times more memory than you actually need. Or I don't know something?

Edit:
And about the content view - this is always diferent view file. So I am thinking I could pass the main content file name to the _display() function directly. Because othervise the content view file would be something like

Code:
<div class = "main">
&lt;?php echo $main_data ?&gt;
</div>

and I would have to pass big ammount of data - all the html code for main content.

Edit2: to be more clear I'll show how I modified the library.

Code:
&lt;?php
class MY_Controller extends Controller{
  
  var $data_header;
  var $data_main;
  var $data_sidebar;
  var $data_footer;

  public function __construct(){
    parent::__construct();
    
    //default data
    
    $this->data_header['meta'] = array(
                0 => '&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;',
            );
    $this->data_header['javascript'] = '';
    $this->data_header['general'] = $this->Views_model->data_for_header();
    $this->data_header['current_menu'] = 99; //for highlighting

    $this->data_sidebar['general'] = $this->Views_model->data_for_sidebar();
    $this->data_footer['general'] = $this->Views_model->data_for_footer();
  }
  
  /*
   * pass main section view file
   */
  function display($main_view){
     $this->load->view('header_view', $this->data_header);
     $this->load->view($main_view, $this->data_main);
     $this->load->view('sidebar_view', $this->data_sidebar);
     $this->load->view('footer_view', $this->data_footer);
  }
}
#5

[eluser]InsiteFX[/eluser]
This way all of $data is avaiable to all views!

Code:
$this->load->vars($data);

// load your views
$this->load->view('your_view');

InsiteFX
#6

[eluser]pickupman[/eluser]
I also have a few extra properties in MY_Controller

Code:
class MY_Controller extends Controller{
  
   public $view    = ''; //view file to set an explicit view to override magic
   public $jquery  = ''; //jquery file to add a jquery script from a view
   public $title   = ''; //page title
   public $content = ''; //page content set explicit content if not needing a view
   public $data; //store for every view to use

  public function __construct(){
    parent::__construct();
  }

  protected function _display(){
    //Guess view file
    $method = $this->uri->segment(1,'home'); //set default controller as 2nd parameter
    $action = $this->uri->segment(2,'index');

    //Pass data to all views
    $this->load->vars($this->data);

    $this->load->view('header_view');
    

    //Look for application/views/(controller name)/tpl.(action name).php
    if(empty($this->view) && file_exists(APPPATH . 'views/' . strtolower($method) . '/tpl.'. $action.'.php')) {
        $this->load->view(strtolower($method) . '/tpl.'. $action .'.php');
    //Look for application/views/($this->view)
    }elseif(!empty($this->view)){
        $this->load->view($this->view);
    //No views found lets just send something out from $content property
    }else{
        echo $this->content;
    }

    $this->load->view('sidebar_view');
    $this->load->view('footer_view');  
  }
}

Now if you name your views to match your action names like you have /blog/view create a views with a structure like:
/application
/views
/blog
tpl.view.php

This will autoload the view for you by using $this->_display(); You could a add a sidebar property to it, and try to autoguess it, explicitly load it, or have a default sidebar using the exact code above.

Storing all the data under $this->data would be the most efficient as it is one object, rather than having $data_header, $data_sidebar, etc. Either way PHP is having to store the same amount of data in its memory regardless of how many variables, but PHP doesn't have to keep track of multiple variables.
#7

[eluser]SPeed_FANat1c[/eluser]
Thanks for the answers




Theme © iAndrew 2016 - Forum software by © MyBB