Welcome Guest, Not a member yet? Register   Sign In
Best way to avoid duplicating html in views
#1

[eluser]mortifrog[/eluser]
Would someone be kind enough to help me with this. I just watched the blog tutorial which was very informative - however, Derek copied html from one view to another. How can I keep the views consistent without duplicating html?

I thought of having one main view used by many controllers which has the content passed to it by way of an array or an object as talked about. Something, doesn't feel quite right about that approach to me though.

Could I create a standard page controller then have each of my subsequent page controllers extend my original definition? If I did that, would I need to include or require my original page class for each new controller.

Or... am I barking up the wrong tree entirely.

Many thanks in advance for your patient guidance.
#2

[eluser]alaa007[/eluser]
Thats very easy Smile
first create the html files you wanna use in each view
for an example let say you wanna use the same header and footer in every view you wanna load
in the view directory create
header.php
and
footer.php

in case you are sending variables from controller, make sure to load them with the desired view, the array should include the variables you wanna print inside header.php and footer.php

ok let say in your controller you call this
Code:
$this->load->view('mainpage_view' , $data)

now in your mainpage_view.php file do the following
Code:
include 'header.php';
//your html code
//.......
//....

include 'footer.php';

and so on,
hope this is helpful Smile
#3

[eluser]mortifrog[/eluser]
Thanks for your response. OK... using includes was the way I'd always done it before discovering CI. I'm probably wrong but it seems somehow to me, that using includes in the view like this is the not the most CI way of doiing things.

In the tutorial, it talks about loading multple view

e.g:

$this->load->view('header');
$this->load->view('nav');
$this->load->view('content');
$this->load->view('footer');

I'm guessing that the html contained in say the nav view continues the html in the header view - so that if you put those 4 views in one file - they would make a cohesive and valid html page.

Now if I used these same loaders in each control file I want to make - I guess I can pass parameters to the header view appropriate to the controller I'm using.

The content view page could be empty bydefault until I have pieced together the $content parameter to pass to it.

- and I could also load other views into the $content parameter before passing it to the content view as needed.

Am I starting to get it at all? or is it easier just to include other views within views?
#4

[eluser]ericsodt[/eluser]
if you click the 'DTE template'link on my signature and scroll to the bottom of the post, I give an easy example of how to do a template shceme
#5

[eluser]nhm tanveer hossain khan (hasan)[/eluser]
hi,
we have solved this problem on our project without using any other libraries.
we kept "templates" directory under views. where we are keeping layout related design.

check out our base-template-1.php which is used for rendering the common layout.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
&lt;html &gt;
  &lt;?= $this->load->view('common/top_header') ?&gt;
  &lt;body&gt;
    <div id="wrapper" >
      <div id="masthead">
        <div class="logo"></div>
        <div class="headcont">
          &lt;?= alt_site_url() ?&gt;
          &lt;?= $this->load->view('common/menu') ?&gt;
        </div>
        &lt;!-- END: headcont --&gt;
        <div class="seperater"></div>
      </div>
      &lt;!-- END: masthead --&gt;

      &lt;!-- loading status panel --&gt;
      &lt;?= $this->load-view("common/message") ?&gt;

      &lt;? if (is_authenticated() && !isset($no_activity_update_panel)): ?&gt;
        &lt;?= $this->load->view('.... some other stuffs ....') ?&gt;
      &lt;? endif; ?&gt;

      &lt;!-- base content area --&gt;
      <div id="content">
        &lt;? if (!empty($content_src)): ?&gt;
          &lt;?= $this->load->view($content_src); ?&gt;
        &lt;? endif; ?&gt;
      </div>
      &lt;!-- ends base content area --&gt;
    </div>
  
   &lt;? $this->load->view('common/analytics')?&gt;
  &lt;/body&gt;
&lt;/html&gt;

example usages from the controller action -
Code:
// send view the list of retrieved result
    $data = array(
      "items" => $items,
      "content_src" => "search/index"
    );

    // render search result
    $this->load->view("templates/base-template-1", $data);

hope that would help.

best wishes Smile
#6

[eluser]mortifrog[/eluser]
OK, to the last two responders, thank you for your time. I can see how flexible CI is from what you are doing - but somehow, I am under the impression that to put
Code:
$this->load->view($whatever)
in a view is not the CI way - or am I wrong?. It's good to know that there are many ways to skin a cat - but what I'm getting at is - what is the recommended CI methodology of achieving page consistency with injectable dynamic elements? I do quite like the concept of keeping a template directory under view - with sub directories for different themes - but what I want to avoid at the outset, is doing things the wrong way or the hard way. What seems sensible to me for an OO approach, is extending the controller with a page definition class of my own, then extending that page class for each new page, so that each page inherits from my master page.
#7

[eluser]ericsodt[/eluser]
Do whatever you feel most comfortable with. I know from my experience with other programming languages that 'injecting' your views through a template is very common practice. As a matter of fact, J2EE development is highly dependent on this practice. Struts Tiles essentially does exactly what we've displayed to you.

If you're still in doubt, why not use CodeIgniters Template class?? (Notice the similarities between what we've shown you and what's in the class. IE. putting the content into the $data variable) I havent used it, but they have examples and seems straight forward.

Goodluck

[quote author="mortifrog" date="1229649027"]OK, to the last two responders, thank you for your time. I can see how flexible CI is from what you are doing - but somehow, I am under the impression that to put
Code:
$this->load->view($whatever)
in a view is not the CI way - or am I wrong?. It's good to know that there are many ways to skin a cat - but what I'm getting at is - what is the recommended CI methodology of achieving page consistency with injectable dynamic elements? I do quite like the concept of keeping a template directory under view - with sub directories for different themes - but what I want to avoid at the outset, is doing things the wrong way or the hard way. What seems sensible to me for an OO approach, is extending the controller with a page definition class of my own, then extending that page class for each new page, so that each page inherits from my master page.[/quote]
#8

[eluser]Polarity[/eluser]
I had the same problem. what i did it was the following.

i created one view that i called layout. that view contains the complete site layout. header, content, sidebar footer.
every section have a variable like that:
Code:
<div id="ss_sidebar">
    &lt;?=$sidebar?&gt;
</div>

<div id="ss_content">
    <h1>&lt;?=$site_title?&gt;</h1>
    &lt;?=$content?&gt;
</div>

then i created a helper function. that function do nothing more, than render this layout view and fill it with code at the regions. put this helper in the autoload to have it global.

Code:
function layout($array)
    $layout['site_title'] = (!isset($array['site_title']))?'standard text':$array['site_title'];
    $layout['site_name'] = (!isset($array['site_name']))?'standard text':$array['site_name'];
    $layout['content'] = $array['content'];
    $layout['sidebar'] = $array['sidebar'];
    $CI->load->view('layout',$layout);
}

so in the controllers i have nothing more to create an array an pass it to my helper function

Code:
function blog {
    $data = array(
        'content'=>$this->load->view('forum/list',$data,true),
        'sidebar'=>$this->load->view('forum/newArticles',$data,true),
        'site_title'=>'My Website'
    );
    layout($data);
}

the good thing on this method is, that you dont have view calls inside the view and you can use views for ajax calls (updating only the content, would be a problem because you call a view inside the view.). And you can always add widgets or new regions to your layout without changing many views or run into a including chaos. i think its always a good practice too keep code duplication minimal.

Edit: if you ever want to put ajax (jquery etc) on your site and you want to refresh the content only, you can just do something like
Code:
function blog {
    $data = array(
        'content'=>$this->load->view('forum/list',$data,true),
        'sidebar'=>$this->load->view('forum/newArticles',$data,true),
        'site_title'=>'My Website'
    );

    // render the site
    if($ajax) // ajax call?
    {
        // yes, only the content please
        echo $data['content'];
    else
    {
        // rende the complete site
        layout($data);
    }
}
#9

[eluser]Colin Williams[/eluser]
There is no reason to not use include or require just because you have some queasy feeling that it's not the "CI way." There can be pitfalls to using include in your views, yes, but it has nothing to do with the imaginary "CI way." (And anyway, replacing it with $this->load->view() can be seen as a really roundabout way of doing include.)

Think through the potential downsides. They may or may not exist for your application or desired methodology.
#10

[eluser]ericsodt[/eluser]
You said:
[quote author="Polarity" date="1229665461"] ..(updating only the content, would be a problem because you call a view inside the view.)...[/quote]


This is not true, you can instantiate a view and pass in true as the third argument to get the content returned. This is great for ajax calls. You can take the returned content and shove it in a <div>'s innerHTML property.


FROM LOADER CLASS
Quote:The third optional parameter lets you change the behavior of the function so that it returns data as a string rather than sending it to your browser. This can be useful if you want to process the data in some way. If you set the parameter to true (boolean) it will return data. The default behavior is false, which sends it to your browser. Remember to assign it to a variable if you want the data returned:


Secondly, I don't know why you think having a call to render a view inside a "template view" is bad coding practice. Yes, it says within the class page that views should be called from controllers, but you are. You're telling your template class to load a particular view. If you think of your view as a template then your really just calling a view from a "middle-end" controller. This may shed some light on what I mean and how it is used in the Java realm.




Theme © iAndrew 2016 - Forum software by © MyBB