Welcome Guest, Not a member yet? Register   Sign In
Using partial views
#1

[eluser]Madmartigan1[/eluser]
Hello,

I'm fairly new to CI and wondering what the best way to do this is.

I have a controllers/models/views set up for viewing/editing a database table called "events". OK, I have a view for events that shows the entire list.
What I would like to do is show the list on every page in my app (in a sidebar). If I just load the view file, the db values are of course not getting passed to it because the conroller/model isn't loaded. I'm not restricted to using any particular method, I'm just wondering the best way to do it.
Do I have to write a separate method/view? Normally (without CI) I would just "include" the event list file, which would have already "included" the sql stuff.

I'm sure the answer is basic CI usage, so thanks in advance.
#2

[eluser]Michael Wales[/eluser]
I recently posted how to implement partial views inspired by Ruby on Rails on my blog. If you don't want to go that far all out - just take a look at the code for views/layout.php and each individual view file.
#3

[eluser]Dam1an[/eluser]
@Michael: That was a brilliant post, inspired me to come up with a way to avoid calling view files manually in 95% of cases Smile
#4

[eluser]Michael Wales[/eluser]
@Dam1an
Yeah, I love that modification. It has narrowed down my controllers significantly.
#5

[eluser]NachoF[/eluser]
This is interesting but all of my views are always called method_view.php.... so I guess I will try this approach for my next project cause changing the file name for all those views is gonna be troublesome.
#6

[eluser]Madmartigan1[/eluser]
[quote author="NachoF" date="1241818625"]This is interesting but all of my views are always called method_view.php.... so I guess I will try this approach for my next project cause changing the file name for all those views is gonna be troublesome.[/quote]

Troublesome indeed.

@Michael: The method used in your article certainly did what it was supposed to do, but it's very tedious to implement, and in many people's cases would require restructuring the whole app.
For instance, I am already using a master view file, and since most of my page content comes directly from a database (meta tags and all), it would require me to create view files for every controller, which is unnecessary. I also don't require a partial view for every controller, just a few.

I googled the term "Codeigniter sucks" and there were several topics about partial views on the first page.

Isn't there another way to do this? I read the "Hooks" section in the CI user guide and didn't quite understand it, but it seemed like the right way to go.

Please correct me if I am mistaken.
#7

[eluser]Michael Wales[/eluser]
That article is not about implementing partial views - it is about implementing automatic discovery of partial views and models. Thus the reason it is so verbose.

Implement a partial view is as simple as this:

controller
Code:
function index() {
  $data['partial'] = 'my_partial_view';
  $this->load->view('layout', $data);
}

layout.php
Code:
<?php
  $this->load->view('header');
  $this->load->view($partial);
  $this->load->view('footer');
#8

[eluser]Madmartigan1[/eluser]
[quote author="Michael Wales" date="1241820492"]That article is not about implementing partial views - it is about implementing automatic discovery of partial views and models. Thus the reason it is so verbose.

Implement a partial view is as simple as this:

controller
Code:
function index() {
  $data['partial'] = 'my_partial_view';
  $this->load->view('layout', $data);
}

layout.php
Code:
<?php
  $this->load->view('header');
  $this->load->view($partial);
  $this->load->view('footer');
[/quote]

That, in a nutshell, is how my template is already set up, but the problem is that my "views" are not static content, and the variables that normally would get passed to them from the controller are empty because the corresponding controller is not getting loaded.

So, in that example, if 'my_partial_view' is looping through some database results, they would all be empty because the model/controller is not present.

Am I making my issue clear enough? It's so simple, it seems like I should be able to do this with codeigniter's innate methods, without installing a new library or extending anything.
#9

[eluser]Michael Wales[/eluser]
It shouldn't be empty... using the previous code example (and keeping the model out of it, just for clarity):

controller
Code:
function index() {
  $data['posts'] = NULL;

  $query = $this->db->get('posts');
  if ($query->num_rows() > 0) {
    $data['posts'] = $query->result;
  }

  $data['partial'] = 'my_partial_view';
  $this->load->view('layout', $data);
}

layout.php
Code:
<?php
  $this->load->view('header');
  $this->load->view($partial);
  $this->load->view('footer');

my_partial_view.php
Code:
<?php if ($posts !== NULL): ?>
  <?php foreach ($posts as $p): ?>
    <h2>&lt;?php echo $p->title; ?&gt;</h2>
    &lt;?php echo $p->body; ?&gt;
  &lt;?php endforeach; ?&gt;
&lt;?php else: ?&gt;
  <p>There are no posts.</p>
&lt;?php endif; ?&gt;
#10

[eluser]Madmartigan1[/eluser]
[quote author="Michael Wales" date="1241821256"]It shouldn't be empty... using the previous code example (and keeping the model out of it, just for clarity):

controller
Code:
function index() {
  $data['posts'] = NULL;

  $query = $this->db->get('posts');
  if ($query->num_rows() > 0) {
    $data['posts'] = $query->result;
  }

  $data['partial'] = 'my_partial_view';
  $this->load->view('layout', $data);
}

layout.php
Code:
&lt;?php
  $this->load->view('header');
  $this->load->view($partial);
  $this->load->view('footer');

my_partial_view.php
Code:
&lt;?php if ($posts !== NULL): ?&gt;
  &lt;?php foreach ($posts as $p): ?&gt;
    <h2>&lt;?php echo $p->title; ?&gt;</h2>
    &lt;?php echo $p->body; ?&gt;
  &lt;?php endforeach; ?&gt;
&lt;?php else: ?&gt;
  <p>There are no posts.</p>
&lt;?php endif; ?&gt;
[/quote]

This example is just a normal controller/view setup. In order to display 'posts' on every page as a partial, you would have to access the methods from the 'index' function in your example's controller. This is what I want to do. In other words, I want to load the 'my_partial_view' file in a page with a different controller.

For example, this is how I am loading views in my template. There is something similar in the template for each div (left column, header, footer, main content, left column etc).
Code:
if(is_array($content))
{
    foreach($content as $view)
    {
        echo $this->load->view($view);
    }
}

The controller will set which view to load like this:
Code:
function somepage()
{
$data['content']=array('my_view1','posts/my_posts_view');
$this->load->view('layout',$data);
}

And have some defaults set in the header of the template:
Code:
$page_elements=array(//set default views
    'header'=>'template/header',
    'menu'=>'template/menu',
    'lcol'=>'template/lcol',  //used in example below
    'content'=>'template/content',
    'rcol'=>'template/rcol',
    'footer'=>'template/footer',
);
foreach($page_elements as $item => $view)
{
    if(!isset($$item))
    {
        $$item=$view;
    }
}

So, for example, if I want a view file to appear in the left column as default on every page (which can be overridden by the controller), I would edit the 'template/lcol.php' file and load a view or file from there, or even just echo some static html or whatever. But, if I $this->load->view('my_partial') from that file, the vars would be empty.

Sorry to be a pain in the ass, I just thought this would be quite simple. Please let me know if I am WAY off track or should provide more code. I really don't think this issue is specific to any template system.

Is there some kind of $this->load->controller() or something so I can access its functions? This will work great that way, even if I have to write an extra function for the partial.




Theme © iAndrew 2016 - Forum software by © MyBB