Welcome Guest, Not a member yet? Register   Sign In
How to organize views?
#1

[eluser]Mr. Pickle[/eluser]
Situation
I find myself struggling with the organistation of views and controllers. I have read the main documentation about views but this is not actually diving into my problem, uhhhh challenge Wink My website exists of a few main templates. Within these templates I have several views ('content blocks' as I call it myself) Some parts are the same for every controller but others may differ.

View management
What is the best practise for view management? I can think of the following possibilities, but I'm not confident enough they actually make life easier:
(1) Main template which checks for the passed views and shows only those filled.
Check within view what page is loaded so what content to view.
Downside: lots of coding within views.
(2) Several templates, having some views shared, for the rest the same as (1)
Downside: lots of if and elses
(3) Calling the views seperately from within the controller (so no template) and use shared views in which I check what page is loaded to determine the content to view
(4) Calling views seperately and have them unique for each controller (lots of duplicate coding, but again, some (small!) parts may differ throughout controllers)

Controller specific styles/scripts
Also I thought of setting a config array within my passed data array, summing up the styles and scripts I'd like to loop in the header file. Is this an 'accepted' way of using CI?

Help!
Hope someone can give me some good advice to start with or some good resource to find more info because I didn't manage to find them yet.
#2

[eluser]Mr. Pickle[/eluser]
Let's put it different at first:

Is it better to manage views individually via controller or combined via template if you have lots of combinations of shared and controller specific blocks/views?
#3

[eluser]mddd[/eluser]
I like to make views for all the main kinds of pages in my application. So there is a 'home' view, a 'text page' view (for displaying things like 'about us', 'terms&conditions;' etc), a 'list' view for displaying lists / search results. Each of these main views calls the blocks they need. For instance, a 'text page' view could look like:
Code:
<?php
// this is simplified code
$this->load->view('parts/header');
$this->load->view('parts/menu');
?>

<h1>&lt;?=$title?&gt;</h1>
&lt;?=$content?&gt;

&lt;?php
$this->load->view('parts/sidebar');
$this->load->view('parts/footer');
?&gt;

I have a 'parts' folder in my views folder that contains those blocks that can be called by the views that need them.

I like this approach more than using a 'generic template' view, because if you use a generic template, that template must handle every kind of page. And then you do get a lot of 'if/then' structures going on. They can make the template hard to read.

Note: this doesn't mean you have to have a view for each controller. In this example: any controller that outputs some kind of text page can use the 'textpage' view. And a controller 'search' could use different views for its initial search form and its results page.
#4

[eluser]Mr. Pickle[/eluser]
Hi mddd, thanks for your insight.

How would you best handle additional stylesheets and javascripts which might apply to specific controllers only, where the controller should -apart from that- be able to use one of your existing view?. It would be a waist to generate yet another header part only for some additional javascripts for example.
#5

[eluser]mddd[/eluser]
I would keep een array in my controller (say, $this->scripts or $this->css) and everytime I have a piece of code that needs a a script or stylesheet, I would add it. Then make your header view so that it puts any scripts or css files in there if needed.
Code:
class SomeController extends Controller()
{

var $css = array();

function __construct()
{
  parent::Controller();
  // this controller needs a special css file. add it.
  $this->css[] = '/css/myspecialcssfile.css';
}

function mymethod()
{
  $content = $this->some_model->get_some_content();
  // this method does something, and needs another css file for its output
  $this->css[] = '/css/cssformymethod.css';
  // load the view
  $this->load->view('list', array('content'=>$content, 'css'=>$this->css));
}

}

In the parts/header view:
Code:
&lt;body&gt;
&lt;head&gt;
...
&lt;?php if (isset($css) foreach($css as $cssfile) { ?&gt;
&lt;link rel="stylesheet" type="text/css" href="&lt;?=$cssfile?&gt;" /&gt;
&lt;?php } ?&gt;
&lt;/head&gt;

Well, you get the idea.
#6

[eluser]Mr. Pickle[/eluser]
Yeah, I get the idea!
#7

[eluser]msteudel[/eluser]
[quote author="mddd" date="1273852953"]I would keep een array in my controller (say, $this->scripts or $this->css) and everytime I have a piece of code that needs a a script or stylesheet, I would add it. Then make your header view so that it puts any scripts or css files in there if needed. .... [/quote]

I like that method too. If you need to have more content in your views, say if designers need to have easier access to things:

Code:
// in my html header file<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html &gt;
    &lt;head&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/&gt;
        &lt;title&gt;&lt;?php echo $title ?&gt;&lt;/title&gt;
     &lt;link rel="stylesheet" href="&lt;?php echo base_url(); ?&gt;css/style.css" type="text/css" media="all" /&gt;
     &lt;?php echo $this->uri->segment(2) == 'student' ? '<scrip type="text/javascript" src="' . base_url() . 'js/admin/student.js">[removed]' : '' ?&gt;
    &lt;/head&gt;
    &lt;body&gt;

I've been playing with a more dynamic templating system where the controller/action dictates my view organization:

e.g.

http://domain.com/admin/object/create

would look for a template located

views
...|_admin
......|_object
.........|_create.php

I do this through a main_template:
Code:
&lt;?php
// normal html page header up to openning of body tag
$this->load->view( 'includes/header' );

// loads navigation consistent across admin area
$this->load->view( 'admin/navigation' );

// explodes url
$uri = explode( '/', uri_string() );

// figures out what file to include
if( $uri[1] == 'admin' ) {
    $template = '/' . $uri[1] . '/' . $uri[2] . '/' . ( isset( $uri[3] ) && strlen( $uri[3] ) > 0 ? $uri[3] : 'index' ) . '.php';
}
else {
    $template = '/' . $uri[1] . '/' . $uri[2] . '.php';
}

// loads tempaltes
$this->load->view( $template );

// ends body and html tag
$this->load->view( 'includes/footer' );
?&gt;

This is still new so I may have some issues ahead of me, but so far it helps me keep things consistent organized
#8

[eluser]mddd[/eluser]
@msteudel: The way you are describing it, you would need a separate view file for every method in every controller..
I think that is not really efficient. For instance: www.example.com/about/the_company could very well have the same layout as www.example.com/about/privacy.
And even www.example.com/dealers/map could have the same basis as www.example.com/offices/map.
I think you need to keep things flexible. If every method in every controller is going to have a certain view linked to it, you might as well load that view directly from the controller and not need the 'in between template' to figure out what view to load!
#9

[eluser]Cesar Kohl[/eluser]
This topic is really interesting. I tried to apply this method of mddd and it works just fine.

Just to add to the conversation:
It makes the code elegant to use one 'framework' to various similar pages (or controller's functions). And more: this approach is in align with the CI's Architectural Goals: (http://www.ellislab.com/codeigniter/user...goals.html) which IMO is essential.

Thanks for sharing!




Theme © iAndrew 2016 - Forum software by © MyBB