In the Zend Framework is it possible to have a controller which executes some logic and then sets some view variables ready for the partial to display?
To clarify I have a view which implements a partial.
I have logic in my partial to get some items from the database. It then displays the items.
At the moment the logic is in the partial's view (.pthml file).
Is there a controller or something I can use to execute this logic outside the partial view?
As I understand the MVP pattern, I shouldn't have logic like this in the view.
Keeping logic out of your view is a good thing and that is what view helpers are designed for.
The section on writing your own will be of particular interest to you.
This will allow you to keep logic out of the view by writing something like:-
<?php echo $this->getItems(); ?>
in your view rather than having the logic there.
Creating a helper called getItems for example is quite easy. Create application/views/helpers/GetItems.php and create your helper:-
class Zend_View_Helper_GetItems extends Zend_View_Helper_Abstract
{
public function getItems()
{
//Do some stuff
return $this->view->escape("Did some stuff!");
}
}
Then call it as above, you don't have to do anything else.
Related
I have been using joomla more than for a year now and familiar with the MVC pattern as well. But I'm unclear how Joomla uses MVC when showing a view. In the components deveopers use below two method.
1st method
class myView extends JView
{
function display($tpl = null)
{
//HTML & PHP goes here
}
}
2nd method
class myView extends JView
{
function display($tpl = null)
{
parent::display($tpl);
}
}
In the 2nd method they create a tmpl folder and place a default.php inside of it. All the HTML and PHP code then goes inside that file.
Now problem is why they use 2nd method when we can right away use 1st method? What's the industry standard? What are the pros and cons of above methods? What should be used and why and depending on what? Thanks
There is no "industry standard". But MVC has such concept as "separation of concerns".
The second approach is much closer to the spirit of MVC-inspired patterns. Views are supposed to be responsible for UI logic. And, if this logic require to generate response, views multiple templates to create it. Or it might choose just to sent an HTTP header.
The first approach is "quick'n'dirt" version. It often means, that UI logic has leaked in controller. Or, that developer does not understand why spaghetti code is a bad thing.
It looks like the second method is calling a parent so it's calling the base part of the template. Often times you have a base template and then individual content (pages) that uses that base template.
First just look at my code than i will explain my problem.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Category extends CI_Controller {
function Category()
{
parent::__construct();
$this->load->model('category_model');
}
public function index()
{
}
public function _left()
{
echo "side";
$data['all_categories'] = $this->category_model->getallcategory();
$this->load->view('include/left', $data);
}
}
this is my category controller, i have a left() function in which i listed all category in the left bar of my website.
I just want to know that how can i show left() function data in another php file ?
You really shouldn't have a function you would call repeatedly or from another file in a controller... typically you would want to put them in a Helper library or as a Plugin...
For the function you have created, I am wondering if you know that you can have a view, that calls other views. For example, you have a template view that would load the header view, the view referenced in $data from your controller, and your left view, etc...
I would read more about MVC and how it's setup and how you lay out your files a bit more as it will save you a huge headache and some messy code.
Best of luck!
you call create one function and call many view from this.
or create one main view and other top,left ,right,center view and load from main view
I would consider writing a helper and autoloading it in your config file
For more information about creating helpers go here CodeIgniter: Create new helper? or check CodeIgniter's user guide.
DISCLAIMER: THIS IS A RANT
I know everyone is trying to be "helpful" but please, please, please stop using "helper" classes and "helper" files. Models get there own data, they persist their own data, in short, they do the helping!!
Ex:
DO NOT create a file called "userhelper.php", just put the methods in a file called "user.php". This is called a model. You might say at this point, "What if I need to share the model with another part of my project or just somewhere else but make it look different or something or whatever??" That's where you would use a viewmodel. The viewmodel has no persistence information in it, in fact it should be significantly different from the model enough to justify its own existence.
To wrap up, just put the CRUD into the model itself. Don't build "managers" or "helpers' or whatever the hell you want to call them.
And I don't care if CodeIgniter encourages this with it's "helper" framework. It's still WRONG and is not OOP. You will end up writing messy code and duplicating effort all over the place.
I need to call some library functions in order to correctly display some data in my header view - what is the best/correct way to approach this?
I take it I'm supposed to call this in all my controllers but it seems a bit redundant. Should I take this route? What sort of non 'hacky' method do you suggest?
Edit:
I have a view which outputs the header portion of the page. In this view I have a menu which varies depending whether you're logged in, have any favorites etc. To determine what to display in the menu, I must refer to some libraries, for example, an authentication and favorites library.
I tried calling the library from the view, but it gives me an error.
I suppose I could load the controller and pass the data to the view in every controller but I would have a lot of repetitive code. Is this the way to go?
Yes, manually assigning the same data to a partial view in every controller or method is redundant. You want to avoid this.
Any decent template library should be able to handle this for you. You can google up a solution or write your own.
Here, in mockup code, is what it may resemble:
class Template {
public $data = array();
function area($area_name)
{
$CI =& get_instance();
$data = isset($this->data[$area_name]) : $this->data[$area_name] ? NULL;
$CI->load->view('templates/'.$area_name, $data);
}
function set_data($area_name, $data)
{
$this->data[$area_name] = $data;
}
}
Then in the controller, something like this:
$this->template->set_data('header', $my_data);
Then in the view, something like this:
<header><?php echo $this->template->area('header'); ?></header>
<div><?php echo $this->template->area('content'); ?></div>
<footer><?php echo $this->template->area('footer'); ?></footer>
This is over-simplified, and there are a million ways to handle it, but I definitely suggest writing some kind of class to handle your templates rather than just using $this->load->view() for everything, even if it is just a wrapper for loading views.
To avoid manually setting that same data in every controller, use a MY_Controller, set it in the template class __construct(), or call it directly from the view file from whatever the source is (model, library, etc.). Father MVC may shed a tear, but sometimes this is easiest or even makes the most sense.
Quick example of how to use a controller extension:
// File: application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
$data['var_name'] = $this->some_lib->get_data();
$data['var_name2'] = $this->some_model->get_more_data();
$this->template->set_data('header', $data);
}
}
Then, all your controllers would extend MY_Controller rather than CI_Controller and the header data would already be loaded. This is just a simplified glimpse into another topic altogether, much much more is possible with this method.
I tried calling the library from the view, but it gives me an error.
This shouldn't happen if the library is loaded and you are calling it correctly. The syntax is $this->library_name->method().
In any case, I definitely recommend writing or borrowing some kind of Template class.
You don't have to follow the MVC model, but if you want to, the "correct" way is to call the functions in the controller, then pass the data to the view where it's printed out.
You should be able to just autoload the library or else load it in the controller before the view. Then you'll have access to the library methods in your views and can access them the same way you would in your controllers.
I've written a small MVC in PHP5 and desire a pagination module to be added to some files in my views section/folder..
I was wondering.. would the Pagination class be included in the Controller or Models section/folder?
Currently i've included it in the Models folder and called the function when needed..
The way I see it, pagination is a control, allowing user to tell your database (model), which portion of data he or she wants to see.
So I would go with the Controllers module.
Well, I think a better approach would be to make a helpers folder and then load them into your application like this :
function use_helper()
{
static $helpers = array();
foreach (func_get_args() as $helper)
{
if (in_array($helper, $helpers)) continue;
$helper_file = HELPER_PATH.DIRECTORY_SEPARATOR.$helper.'.php';
if (!file_exists($helper_file))
throw new Exception("Helper file '{$helper}' not found!");
include $helper_file;
$helpers[] = $helper;
}
}
Then all you have to do is build a pagination.php file with your Pagination class.
When you need it, you call the function
use_helper('pagination');
From here of course it depends on you Pagination class.
Hope this helps.
i guess the best approach is to call the pagination from the view, referring to this MVC
A view queries the model in order to generate an appropriate user interface
(for example the view lists the shopping cart's contents).
The view gets its own data from the model.
In some implementations, the controller may issue a general instruction to the view to render itself.
In others, the view is automatically notified by the model of changes in state (Observer) that require a screen update.
and because you will be using this class almost in every view, you should make a helper and include this class inside that helper so that all the views can share its methods
For projects written in php, can I call more than one (or multiple) controller in class controller? Example in http://img192.imageshack.us/img192/7538/mvc03.gif
ASK: I need to call an action from another controller... And if I do like the picture above, I'm being out-ethics?
Thanks,
Vinicius.
I'm sure that you can do what you want with whichever framework you're using. If you can't do it natively for whatever reason, then you can extend your framework as required.
Having said that, I personally don't like the idea of a controller calling another controller. It seems to somewhat break the MVC paradigm if only from a theoretical standpoint. What I might do instead is build a library class that contains the functionality required and then have both controllers instantiate that class as a member and call the functions required.
For example, using CodeIgniter:
libraries/MyLib.php:
class MyLib
{
public function MyFunc()
{ /* do whatever */ }
}
controllers/ControllerA.php:
class ControllerA extends Controller
{
public function index()
{
$this->load->library('MyLib');
$this->mylib->MyFunc();
}
}
controllers/ControllerB:
class ControllerB extends Controller
{
public function index()
{
$this->load->library('MyLib');
$this->mylib->MyFunc();
}
}
out-ethics? Anywhose... back to reality.
Yes, a controller can call another controller's action. For instance, in cakePHP, this functionality is afforded via requestAction
// pass uri to request action and receive vars back
$ot3 = $this->requestAction('/stories/xenu');
If you're rolling your own, the details of how to implement it will be very specific to your framework.
then you need to modify framework, find place where controller is lounched and add there your second controller.
what framework you are using?
You can do it any way that you want. You don't have to use MVC if you don't want to. However, in MVC you really should only have one controller active at a time. You probably want multiple Views or Models, not another Controller. There is nothing at all wrong in loading, say, a header and footer view for the menu and footer of the site.
If you are building another Controller, then feel that you need to access the functionality of a previous Controller to access its functionality (because it works with a specific / desired Model), then the Model you developed for the latter probably needs to be refactored. IN plain speak, your target Model may be doing too much. Break it up.
You are trying to avoid repeating yourself (DRY) by using calling the methods of a Controller that has already been developed, but in doing so your are creating TIGHT coupling between both controllers! If something changes in the borrowed controller, it will have an effect on the borrowing controller. Not good, Dr. Jones.