2

I'm building a small PHP MVC, and I've hit a wall with a small area of the coding. I think I need "partial views", but I might be able to achieve something with the existing code.

My controller in it's simplest form currently:

  • Instantiates an object
  • Checks if a POST variable isset
  • Displays view 1 or displays view 2 as necessary

The view(s) currently:

  • Displays HTML markup
  • Use and echos the models get functions such as getUserInfo()

Everything is working great, however the code is now getting fairly large in both the controllers and views, and I've reached a situation where I need to include "modules" or sub views inside the main views (1 and 2).

For example if view2 is loaded, then I need to display (as part of the view2) another view, say a 3 part sign up registration form. This registration form comes with it's own controller file too.

I can do something like this, which will work and give you some idea of what I am trying to do, but I acknowledge this breaks MVC design patterns.

View

<div id="mydiv">Some content</div>
<div id="mysignup"> <?php include('controller_signup.php'); ?></div>
<div id="content"> The views main page content </div>

The view is then pulled in from the controller, in the right place.

As mentioned, I think I need to use partial views, however most of the info I've found is for ASP, and I'm slightly lost!

I would have thought this is a fairly common problem, so I assume there is an obvious solution!

Thanks!

Craig Wilson
  • 463
  • 5
  • 8
  • 19
  • 1
    I have tackled and I think overcome this problem in a framework I developed https://github.com/tbd-develop/bounce if it helps you to take a look. It's not fully functionaly, but If you take a look at core/library/renderer.php the partial view stuff is in there. I don't think there's any working examples yet,I'm working on setup. – tbddeveloper Aug 07 '12 at 11:04
  • Thanks for your reply. Just taken a look at your code too, looks impressive! In it's simplest form then, you have a method which is calling an include() ? Thanks! – Craig Wilson Aug 07 '12 at 11:11
  • There are two methods,there is the include method which includes the file where it's asked for, or a way to call a controller do database logic etc and then include in the regular page output. RenderPartial and Partial being the two methods. – tbddeveloper Aug 07 '12 at 11:13
  • Okay thanks, I can't work out what they're doing so I'll have a play! Just found this http://somethingstatic.com/hierarchical-model-view-controller-planning-future - decisions! – Craig Wilson Aug 07 '12 at 13:53
  • Thanks for sharing.Let me know if I can help out,I'd be happy to. – tbddeveloper Aug 07 '12 at 14:17

2 Answers2

5

The root of you problem is fact that you do not have views. What you call a "view" is a actually a template. This in turn forces the presentation logic in the controller.

In proper MVC views are instances, which contain all of presentation logic. They acquire information from model layer and then, based in data, choose how to display this information. Each view manipulates multiple templates.

Also, it seems that your controller has gained extra responsibilities. It is supposed to change the state of model layer and current view, instead of rendering templates.

tereško
  • 58,060
  • 25
  • 98
  • 150
  • Thanks for your reply. You might well be correct in that I've not grasped views correctly! - do you know of a useful and simple reference which I can look at for more info on proper "view" design? Yes, my controller is currently picking which "template" to display, where is this supposed to be done? Thanks! – Craig Wilson Aug 07 '12 at 14:34
  • 1
    The assignment of values and rendering of templates should happen in views. Maybe [this article](http://r.je/views-are-not-templates.html) would help a bit. That's where i begun researching MVC myself. – tereško Aug 07 '12 at 14:37
  • I've just read this page http://r.je/view-helpers.html of the article, and this is the first time I've started to look at the concept of "view helpers"! Looks very informative so I'll have a full read later, keep an eye on your notifications, I'm sure there will be some! Thanks a lot! – Craig Wilson Aug 07 '12 at 15:03
  • You might also find [this old answer](http://stackoverflow.com/a/5864000/727208) quite useful. – tereško Aug 07 '12 at 15:19
  • Thanks very much. I've done a fair amount of reading on views, templates, helpers etc. I'm unable to find a solid example of a proper view though, the way I see it, this should include HTML markup for the entire page, and then have includes of smaller template files to populate the modules of content? I guess reading about how views should steer away from logic has made me think that I can't do something as simple as
    inside the overall view file? Perhaps you can link me to a "proper" view file that calls on templates? Thanks!
    – Craig Wilson Aug 08 '12 at 12:16
  • Unfortunately I have not found any well implemented views in PHP. You will have to research it on your own. But here is the the hint: what view (in web context) actually deals with is generation of response. The response can be just a header (like location header) or an XML file. Or maybe JSON. It is nowhere said that MVC's views have to just make HTMLs. – tereško Aug 08 '12 at 12:24
  • So can the view deal with the structuring of the templates? – Craig Wilson Aug 08 '12 at 12:31
2

Can't say I agree with tereško. Having the presentation logic in a separate view class might seem more proper, however it does add another layer of complexity. In many cases, this additional layer is not necessary - often a view can directly render whatever model or data you inject. So you end up with empty View classes that only pass the model from the controller to the template.

I'd say, Keep It Simple, you can do pretty complex (and maintainable) websites with simple MVC, without introducing the notion of templates.

To handle subviews, you can simply have the main view inject data into the subviews, this should be transparent to the controller (who just provide the main data without caring how it should be rendered). So in practice, you could have something like this:

Controller:

public function someAction() {
    // ...
    $view = new View('name');
    $view->data = $someList;
}

View:

<?php foreach ($someList as $item): ?>
    <?php echo (new View('subview', $item))->render();
<?php endforeach; ?>
laurent
  • 88,262
  • 77
  • 290
  • 428
  • Thanks - would you be able to provide an example of what would be in my "View" class? Currently I don't have a class dealing with views you see! Thanks! – Craig Wilson Aug 07 '12 at 15:20
  • Thing is that he already has introduced the concept of *templates*. OP just calls them "views" (which is the same mistake that you make). – tereško Aug 07 '12 at 15:43