1

So I read somewhere that your views should not contain any logic in them.

But let's say you pull back a query from your model which displays four boxes two of them need to be checked in the view.

I'd pass this as an array into the view but in the view I would write

if array[someindex] = '1'

writed html code for checked box.

Does that not include logic in the view.

And isn't using a foreach (which I believe every does) in the view using PHP logic?

4
Contributors
8
Replies
69
Views
3 Years
Discussion Span
Last Post by veedeoo
1

I assume you need some presentation logic in the view, as with templates? Otherwise, you're just serving static data. Aren't you?

1

So I read somewhere that your views should not contain any logic in them.

I assume they are referring to business logic. Enabling/disabling items in the view is not a problem.

1

All these confusions about MVC pattern architecture began at the CakePHP's bakery and then followed by pretty much everyone. Some of the frameworks that are versatile enough to follow or not to follow the true MVC pattern are the CI and Kohana frameworks. In CI and Kohana, we can pretty much write an application giving much emphasis on the Controller and the Model. By doing so, the View has become almost a distant member of the group. However, we can also write an application that will adhere to the true MVC doctrines under these frameworks.

By doctrines, the user sends request to the Controller, then the controller triggers an instance of the model, the model sends the output to the view. It is clear that the communication between the Model and the View are direct in terms of output transmission, instead of Controller to Model -response- Model to Contoller --output--Controller to View. So, pretty much the intetion is clear to deliver the output from Model to View.

Example of an acceptable M V C pattern based on doctrines. Most MVC's base controllers are abstract, but not all. In this example, the base controller or the parent is not an Abstract class.

Filename: Test.php Type: Application Controller file (child)

Class Test extends Controller{

    private $model;

    public function __construct(){

        parent::__construct();
        $this->model = new TestModel();


        }

    public function index(){

        $this->model->get_content();

        }
        }

Filename: TestModel.php Type: Application Model file (child)

   Class TestModel extends Model{

       private $load; 

       public function __construct(){
           parent::__construct();
           $this->load = new View(); // this class is a template loader class

           }

       public function get_content(){

           $data = array(

               'title' => ' This is title',
               'description' => 'This is description',
               'poster' => 'This is poster',
               'date' => 'some date',
               'status' => TRUE
               );

           $this->load->view('test.php',$data);

           }

           }

Filename: test.php Type: Application View file. Example below addresses your questions. We have an array and statements.

        <html>
        <title></title>
        <body>

        <h3> Article </h3>
        <?php 

            if($data['status']){

            echo 'Title: ' .$data['title'].'<br/>';
            echo 'Description: ' .$data['description'].'<br/>';
            echo 'Poster: ' .$data['poster'].'<br/>';
            }

            else{

                echo 'There is no article to load, sorry';

                }
            ?>

            </body>
            </html>

Looking at our simplified and minified MVC application above, we can easily draw our conclusion that our model is doing much of the responsibilities, while the Controller is practically doing nothing, but route the request.

What will happen if the Model will have to do the database query preparation, binding, validations, executions, and loading the View? I guess we can all agree that the model can be prone to overload which can translates to application errors.

Since we cannot have any business logic in the View, why not create a division of business logic labor between the Controller and the Model. We can allow the controller to load files, instantiate libraries, call functions,communicate with the router, prepare the output from the model, and then ultimately load the View.

Side Note 1: Some box confined and overly educated book Authors will probably say "Hmmm, it shows the classic signs of violations of M V C doctrines. It must be written by under educated developers". Just saying :) :)...

In this last example (shown below), I will attempt to demonstrate the division of labor among the three patterns. Most importantly, the division of business logic between the Model and the Controller.

Side Note 2 If given the proper router, both examples are capable of handling this type of uri pattern domain.com/controller_name/method_name/

Example of a Simple twisted M V C , but highly responsible and fair.

Filename: Test.php Type: Application Controller file (child)

Class Test extends Controller{

    private $model;

    public function __construct(){

        parent::__construct();

        $this->model = new TestModel();

        ## the model object must be instantiated before the view object

        $this->load = new View(); // this class is a template loader class


        }

    public function index(){

        $data = $this->model->get_content();

        ## we add responsibility to load the view 
        $this->load->view('test.php',$data);

        }
        }

Filename: TestModel.php Type: Application Model file (child)

Class TestModel extends Model{

       private $load; 

       public function __construct(){
           parent::__construct();
          ## we free this model class from loading the view class

           }

       public function get_content(){

           $data = array(

               'title' => ' This is title',
               'description' => 'This is description',
               'poster' => 'This is poster',
               'date' => 'some date',
               'status' => TRUE
               );
            ## we removed the responsibility for loading the view

            return $data;       


           }

           }

The view file or the template file, will remain the same. In the second example, we allow the Controller to share responsibilities with the model. Because of the distribution of labor, the model's method get_content() can process another requests as soon as it return the output.

I sincerely apologize for such a lengthy response. The ideas were just pouring out of my forehead and I have no way of containing them. It must be just the coffee I had this morning or the stress over my school's thesis. Either way, I hope I contributed just a little :).

Edited by veedeoo: info added.

0

Thank you for the reply veedeo. Unfortunately your mastery of MVC frameworks goes slightly above my head and is probably due to my newbie-ness rather than anything else.

I just feel slightly torn. Ideally, I see it from a 'romantic' point of view.

I think that the backend programmers should be able to work in isolation from the 'view' or designers.

In other words the designers or coders writing the view shouldn't have to worry about anything to do with logic coding.

Let's imagine the coders set the task of creating the views have no idea about PHP programming. Let us assume they only know HTML and javascript and css.

Within the view you might have an if statement or some other logic.

http://stackoverflow.com/questions/4698880/mvc-how-much-code-should-be-in-a-view

^^As an example, although the example is highly trivial to us the designated view coder might find this PHP notation perplexing so he/she has to communicate with the backend programmers to understand what is going.

This, to me separates or detaches the idealistic or romantic notation of MVC being truly separate and independant of one another. In the above link the author says this can be alleviated by creating a helper class in the view.

To me, this still contravenes the MVC. Now the backend coders or business logic coders are interfering with the view. They have to write these helper classes. What happens if sometime down the line the helper function doesn't have a div class = red? Shouldn't this be the job of the view coders.

As mentioned in the link this adds an extra layer of maintenance complexity. Instead of just doing units test on the controllers and business logic you have to maintain the views as well - if there is logic in there.

Let us not forget that views don't necessarily mean HTML+CSS but could also be adobe flash - I know this is a bad example given the fate of flash, but you get the idea.

Personally, I can't see how writing some logic in the view can NOT be avoided. It seems an inevitability.

But in the theoretical world views should only display dumps of data, I guess this is why codeigniter doesn't allow you to pass your own classes to the view from the controller and loop through it... We know in the real world this is hardly the case, some logic is needed.

These are just my ramblings and thoughts from my head.

2

Creating a helper for the view will make things more complicated to maintain. However, I always escape the so called "MVC conundrum" by just implementing template engine on my MVC framework. This may sound a little bloated as far as application disc size is concern, but the template engine will actually protect your codes from the accidental deletion by the front-end developer. I added a simple diagram below for the clarification. In real world, MVC has evolved and because of this more and more variants are coming into the league.

a449cb8026f8f969d458840a85bfea5e

The framework in variant two is well protected from the front-end developer. They can literally delete everything on the template file and the source codes are always safe.

The Cons:
The biggest drawback in using template engine. Most template engines are bloated to the size of almost 3MB or higher. Template engine parse and recompile the source output so that it can create a new PHP equivalent output to the browser. So, the process time and server resources is almost 2X compared to the plain PHP as template.

There is some learning required in implementing template engine. This is the most excruciating to some, even Fabien Potencier the founder and author of the Symfonny2 once said "PHP does need a template engine", but later on changed his thoughts about templating engine and then he eventually creating his own template engine called TWIG.

If not carefull, application can end-up doing double iterations. Using template engine requires some lesser degree of cleverness on how to pass those arrays coming from the model --- to --- controller --- template engine --- and to the template file to do the single iteration.

Memory consumption of template engine. In most cases, Smarty can suck up about 799Kb of server's memory, while the plain PHP will only consume at the low 100kb. Other tempate engines like TBS, Rain TPL, and Savant has a very small footprint.

The Pros:
1. We can literally tell the front-end what design we want. Let them develop the design. Once the html, css, and javascript are honed, we can then introduced our application's output to the template file.

  1. We can set some arguments on the template file.. In fact, we can set some conditions from the controller and pass them to the template. One of the most common is the form input error checking.

My recommended Templating engines for CI are as follows
1. Smarty
2. TBS
3. DWOO
4. TWIG

Personally, I would use TBS over Smarty or Twig because it is the lightest template engine ever developed.

Below is the sample codes on CI utilizing smarty template engine. This is from the actual application I wrote in the past. Utilizing the YouTube library I wrote for CI. It was intended to deliver content through YouTube API V2.

Controller file passing array to smarty

class Youtube extends CI_Controller {

  public function __construct() {

    parent::__construct();

    /*
    * define smarty settings first!
    *
    */

    $this->smarty->smarty_options( 1 , true , 3600 , '{% ',' %}');

    /*
    * @load youtube model only applies to PDO implementation
    * returns video info. from the database
    */

    //$this->load->model('youtube_model');
    $this->load->helper("url");
    $this->load->library("pagination");
    $this->load->library("youtubevideo");
    $this->index = (($this->uri->segment(2) == null)) ?  1 : $this->uri->segment(2);

}

public function index() {

$this->smarty->assign(array(
                                'video'=> $this->youtubevideo->getVideo($this->xml),
                                'searchq'=> $st,
                                'name' => 'Veedeoo',
                                'count'=> $count,
                                'paginate'=>$this->pagination->create_links(),
                                'theme_style'=>base_url().'web/styles/default/css/style.css',
                                'playurl'=>base_url().'play/video/',
                                'searchurl' => base_url().'/youtube/'
                                ));

    $this->smarty->view('youtube');

}

The template file that can do the iteration

<h4>Video Count {% $count %}</h4>

<div id = "thumb2">
<ul>
    {% section name=item loop=$video %}

<li>
<a href="{% $playurl %}{% $video[item].v_id %}/{% $video[item].title_url|escape:'url' %}"><img  src="{% $video[item].thumb %}"/></a>

<br/>

{% $video[item].title %}

<br/>

{% $video[item].desc|truncate:100:"...":true %}

<br/>

</li>
{% /section %}
</ul>
</div>

The template file is reponsible for looping the array called video from the controller which picked picked-up the array from the library called youtube.

Looking at the template file, we can literally delete everything on it, but the logic of our application remains in the controller and the Model. This makes the life of the back-end and front-end a lot easier and nobody gets fired because someone deleted the template file.

Allow me to recreate the session question in one of your posted question. I will use the example as presented in CI's user's manual.

public function index(){
$newdata = array(
               'username'  => 'johndoe',
               'email'     => 'johndoe@some-site.com',
               'logged_in' => TRUE,
               'admin' => TRUE
           );

$this->smarty->assign(

    'credentials'=>$this->session->set_userdata($newdata),
    'console' => $this->admin_only()

    );

  }

public function admin_only(){

    /*
     * @memthod get_members()
     * returns members info. from database
    */ 

    $admin_console = array(
                            'members' => $this->model->get_members(),
                            'posts' => $this->model->get_posts(),
                            'comments'=> $this->model->get_comments()

                            );

                            return ($admin_console);
    }                        

We can deliver those contents to the template file

{% if $credentials.admin eq=true %}

    <h3> Hello {% $credentials.username %}</h3>
    <h4> Members </h4>
    <ul>

    {% section name=info loop=$console.members %}

        <li>
        {% $consoler.members[info].member_username %}
        </li>

    {% /section %}

    </ul>

     <h4> Members </h4>
     <!-- do the remaining iteration here -->

     {% /if %}

Looking at the template file above, the logic is pass from controller to the smarty. The CI core view in this case is still in the background as a view object collaborating with the smarty engine.

What is good about an application written this way is that it gives us more control in template styling, template file cache, protection, and most importantly we don't have to fire our front-end developer or designer.

Years back, I wrote a simple registration and login scripts based on CI and Smarty. If I ever find the source code from source codes bin, I will share it here on DaniWeb. I believe that it will help a lot of people in exploring how these MVC frameworks work.

My thoughts and opinions about Hierarchical MVC or HMVC as shown on my diagram above :

Kohana framework slowly evolved from simple CI like framework to something truly special type of framework. Any MVC design patterns fanatic can truly admire the HMVC design patterns. HMVC does not overload the main controller, but rather it will deligate part of the requested method to the other controller groups.

When the main controller does this, the sub-controllers will create an instance of its own model and then eventually assign the output to its own view object. For a single request, the views can optionally use ONE template file. However, this will only work effeciently with templating engine due to the boolean response needed to serve as the triggering mechanism.

Again, my sincere apology for the readers for having an etremely lengthy response. It is not because I had too much coffee this time of the day or being stressed out over my school thesis ( I am done with my thesis), it is rather for the love of this subject matter. I really love the level of complexity of the MVC design patterns.

1

Hmmm, to me... the jury is still out. Perhaps it is a lack of experience but I just came across the following article.

http://stackoverflow.com/questions/5888089/when-to-use-php-template-engines

The salient points resonated a lot with me. Learning another syntax which is harder to explain to designers than saying 'Don't mess with the PHP', harder to spot as well.

I think I can get away with a simple foreach/if statements in the view.

Still not sure about using html helpers in the view, especially if the helper contain styling options though.

From a verbose POV I can see how using helpers makes the code 'pretty'

But on the other hand this isn't the point. This wrecks MVC.

At the moment I'm a one man band. So I'm having to write the views, (something I don't particularly enjoy) means I can easily understand the logic as I write the backend too.

...Interesting, none the less.

1

With regard to designers/front-end developers, you're assuming that they're not able to understand simple template markup. I would imagine that most designers working with an MVC environment would be familiar with this. As the template markup is usually just variable placeholders with a few conditionals and loops throw in, I don't think it would be beyond the simplest-minded designer to deal with it.

I see your point with regard to bleeding of roles in the MVC pattern, but I don't think that the odd bit of conditional/loop markup is that bad. In the end, you use and develop a system that is convenient yet robust. If people blindly stuck to rigid rules, then we'd probably still be 20 years behind with regard to diversity and new practices. I'm not advocating that you tear up the rule book, but its interesting that you use CI, which is one of the loosest MVC framweorks I've used. Things may have changed since I last used it, but I remember the model being almost optional!

With regard to speed, most of the templaters I've used create cached pages, so the hit is usually minimised.

Edited by diafol

1

I do understand the concerns over the learning of a new syntax, Diafol already explained it pretty well. I hope you will reconsider template engine in the future.

Although there were one or two people who disagreed, I also respect the point of views and expressed opinions of the person on stackoverflow.

As already mentioned by Diafol, the ultimate finished product of your labor is a robust, highly extensible, and a convenient to use application. Once you achieved this type of product, you can literally throw anything in it e.g. have a forum, a blog, e-commerce section, a company landing page. This can be easily added by just directing the requests to the new controllers.

On the side track, have you guys heard the new programming language called "HACK" by facebook? This is aimed to boost code safety in PHP.

I just downloaded the HHVM virtual machine to try it out. This maybe the next revolution in web development. I think I will invest my entire Spring break learning how to write codes in HACK.

Edited by veedeoo: info added.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.