Views - separating program logic from output, how far do you go?

#1
[eluser]markowe[/eluser]
I am learning to apply MVC thanks to Codeigniter (I daren't look at any of my old projects now!) and can absolutely see the value of this model. But how far do you take it? Some would say there should be NO HTML produced in any of your controllers/libraries etc, that should all be done in your views.

But most examples of views have really simple logic like <?=$title?> or foreach loops. What about a bit of code like this (don't ask, it's a snippet from a function producing a hierarchical unordered list for a sidebar menu):

Code:
foreach ($childArray as $parentKey => $childArray) { // loop to create the hyperlinks for the top parent level
    $urlCatString = $parentKey;
    $uriAssocArray[$catSegment] = strtolower($urlCatString);
    $newCatUrl = site_url($uriAssocArray);
    $menuArray[anchor($newCatUrl, $parentKey)] = $childArray;
}

return ul($menuArray);

This routine HAS to produce HTML, using the anchor() function, the ul() function etc.

What do the MVC purists say - I am all for delegating all this work to a view, but I have no idea how, surely I am not supposed to put all this logic into the view? It seems to me the view should just have:
Code:
<div id="sidebarmenu">&lt;?=$sidebarmenu?&gt;</div>

and not all this code. How do I implement MVC in this situation?

#2
[eluser]Mareshal[/eluser]
Is not necessary to apply the standard MVC everywhere. Honestly, I don't. Sometimes in my views, I take data from a model directly, without involving the controller. Sometimes the controller only renders the view, and there is all processing made, depends on every situation.

How do you implement that in MVC? let's see...

1. Put the entire code into a view.

Make a controller method which has this code: $this->load->view('your_view');

Create your_view and paste that foreach, but make sure to have all the variables.


2. put that code into a controller, replace "return ul($menuArray)" with $return['menu'] = ul($menuArray); and render the view like this: $this->load->view('your_view', $return);

In your_view.php you will create a code like this:

Code:
foreach($menu as $item) echo $item;
and you're done.

TIP: In PHP don't use long variable names like $uriAssocArray, this is mostly seen in Java. But, if you like them, use them with underscore: $uri_assoc_array . There's no problem with those variables, is just a simple styling matter: check this link for more details, cleaner code, better writing, better understanding: http://ellislab.com/codeigniter/user-gui...able_names

#3
[eluser]markowe[/eluser]
Thanks for the pointers. About variable names, I must say that naming conventions are something I never got round to getting to grips with but I assure you I have never developed in Java so I have no idea where I picked this bad habit up! Sigh, something for the to-do list... I do like to have descriptive names though, so I can figure out my own code in a week's time (never mind a year!)

As for your proposed implementation, thanks, I think I will do something like that. That would allow me to easily conditionally display 'subviews', for use as kind of plugin, which is what I had in mind actually. I am not sure if I quite followed though, i.e. where you meant to put the main logic? In the controller (wouldn't, say, a helper be better?) or in the view? I thought of putting it (in this case the complicated foreach loop that produces the UL, or maybe a routine that pulls a feed from somewhere, or whatever) into a subview called, say, "menu_view.php", then conditionally call it from my main view, like (assuming menu parameters were passed as $menuParams, sorry, $menu_params Smile ):

Code:
//main_view.php
&lt;?php

<div id="main">
// main content
</div>
<div id="sidebar">
if ($menu_params) {
  $this->load->view('menu_view.php', $menu_params);
</div>

That way there WOULD be a lot of logic in the view itself, but it would be confined to a subview. However, I am not sure if that is what you meant, or whether that is a good idea. Also I am not even sure you can instantiate classes from views, i.e. load libraries that you might need, or helper functions like anchor() etc?

#4
[eluser]Mareshal[/eluser]
But keep in mind, if you use many subviews in a large project, this means &lt;?php include()?&gt;, and every include wastes memory Wink for small projects is nothing...

And if you want to know what a variable means in 1 year, try to make a small comment after it.

Code:
//create a new "whatever"
function tmt(int $r){ //$r = user ID from URL
    $drt = $this->aml($r); //clean the variable using aml()
    $return['srt'] = "action : ".$drt;
    $this->load->view('my_view', $return');
}

You can use those variable, but without my comments how much would you understand? even if you use long names, you will won't understand.


2nd question: I don't think you can load libraries/models/helpers from a view(last time I tried in 1.7.2 I couldn't, maybe I missed something), but in CI you have 3 possibilities to load them:
- using config/autoload.php and load them global
- in your constructor __construct() and make them available only for your class
- in the function that renders the view, and make them available only for your method.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.