Zend Framework - Set No Layout for Controller - php

I have a Controller that I want to use for ajax scripts to call and set session variables, get information, etc. How do I set it so that that particular controller doesn't use the default layout (specifically NO layout) so that it can send XML/JSON messages back and forth?

Like anything to do with Zend_Framework and Zend_Application, there are multiple ways to do this, but on the last few pure Zend gigs I've done, I've seen people using the following (from an action method in you controller)
$this->_helper->layout()->disableLayout();
This shuts off of the layout. If you wanted to turn off your view as well, you could use
$this->_helper->viewRenderer->setNoRender(true);
again, from an action method in the controller.

in your controller ...
public function init() {
if ($this->getRequest()->isXmlHttpRequest()) {
// no Layout
$this->_helper->layout()->disableLayout();
// no views
$this->_helper->viewRenderer->setNoRender(true);
}
}

In your controller action, try
$this->_helper->layout->disableLayout();

Related

CodeIgniter - Attach functions to View to be called on all pages

I'm currently working on a e-commerce using codeigniter. I'm done with almost all the views and I am starting the coding (controllers and models) now.
For the login, my ideia is set its form on the "top view".
The problem is that I have to call the "top view" in every controller and configure the form_validation everytime I call it.
There is a proper way to dealing with it?
There are a lot of different ways to solve the problem of how to handle commonly recurring html snippets that load on many different pages.
One solution is to add a helper function to each controller like the render_page() function shown below. [NOTE: Any dynamic data that is needed in any of the views to be loaded should be passed via the $data argument.]
protected function render_page($main_view, $data=null){
$this->load->view('top_view', $data);
$this->load->view('menu_view');
if(isset($main_view)){
$this->load->view($main_view);
}
$this->load->view('footer_view');
}
Elsewhere in the same controller
public function index(){
//do stuff including setting $data as needed
$this->render_page('some_view', $data);
}
The problem with this approach is that you need to define render_page() in every controller. To get around this, use the render_page() idea in a custom library (class) that works in a similar fashion. You then autoload that library and use its render_page() method in any controller you want.
If you made such a library and named it Viewmaster then you would use it in a controller as follows (assumes it was autoloaded)
public function index(){
//do stuff including setting $data as needed
$this->viewmaster->render_page("some_view", $data);
}
I'll leave it to you to figure out the implementation details of the Viewmaster class.

Code Igniter - Best Practice for views to not violate DRY

Trying to determine the best way to handle views in codeigniter. Right now anything I consider seems too messy.
Currently I have 3 relevent views:
1) Header
2) Content
3) footer
Every single controller has something like this. Some controllers even have this several times (different functions in the same controller):
$this->load->view('head', $data);
$this->load->view('volunteers/add_profile.php',$content_data);
$this->load->view('foot');
It seems pretty silly to have to load header and footer on EVERY single page. However, each page will have slightly different data in the header (meta tags, style sheets, loaded scripts, etc).
Is there a cleaner way for me to do this?
Thanks!
I like to create a parent controller with a method like renderPage('content_view', $data). That method can include the header, menu, footer, ... That way, all the view loading stuff is kept in the controller and I don't have to bother with header, menu or footer on every action or view. It's also flexible as your child controllers can redefine the renderPage() method to fit their purposes.
If you need to load multiple content views, you could create a renderPage() method that takes in an array of string instead of a string.
Yes - have a template view. In your controller:
$data['header'] = xxx;
$data['content'] = xxx;
$this->load->view('my_template', $data);
Then in your my_template.php view file:
$this->load->view('head', $header);
$this->load->view('volunteers/add_profile.php',$content);
$this->load->view('foot');
Either what #TheShiftExchange suggested, or, if your application allows it, you can call header and footer views from each content view (which is the only view called from the controller then).
I've created my own controller where I create MY_Controller extends CI_Controller class then in MY_Controller I use access modifier $data and $loadviewArray.
public $data = array();
public $loadviewArray = array();
after this I create function in MY_Controller
public function loadview() {
foreach ($this->loadviewArray as $key => $val) {
$this->load->view($val, $this->data);
}
}
then I create controller Admin and extends MY_Controller like this Admin extends MY_Controller in Admin controller create function index.
public function index() {
$this->data["page_title"] = "Login";
$this->data["records"] = $data; // You can pass data
$this->loadviewArray = array("admin/header", "admin/login", "admin/footer");
$this->loadview();
}
In $data access modifier array I pass data at views and in $loadviewArray load views then call a function for loading views you can do like this also its very helpful for me now. And create header and footer views seperate...
please check https://github.com/alzalabany/codeigniter-base-controller/tree/master
So you can always use a templating lib. yet i dont like them for some reason !
codeigniter allow you to extend its core; if you go to link mentioned above u can see a small example
in this example every controller that will extend MY_controller will start with these defauls
protected $body='base/body',
$title='Codeigniter Z master',//txt
$js=array(),//filename
$inline_js='',//script
$css=array(),
$inline_css='',//style
$breadcrumb=FALSE,//<li><a>
$content=array(),//html
$noEcho = FALSE;
so if u chose to change them in MY_controller its effect will be default, otherwise use $this->title = 'Codeigniter - welcome page'; in ur controller constructor for example;
loading assist is a very easy job just call $this->_assets() and location of asset (edit MY_controller.php default location to you assets folder); if its an inline_js/css just call
$this->_assets('alert("hi");','js');
if you want to load a view into a page section use $this->outv(view_path,view_data,section_name);
and if you want to just load html into a variable u can use
$this->out('Footer','footer');
at end just call ->_flush();
some other options i use like
$noEcho ; if set it will clear all buffer to remove any echo's before it send your view content to browser;
you can also set functions like log-out or log-in inside MY_controller and it will be accessible by any of ur controllers http://localhost/ci/welcome/logout
any way :) i hope that answers your question !

Zend Framework: Method after controller action, but before view rendered

I'm new to Zend framework and can't find a clear answer on this. I essentially want some code to execute after a controller's logic for a page, but before the layout and view are rendered.
For example, I want to auto-refresh the flash messages and provide them to the layout/view automatically, so that I don't need to do so in every controller. This obviously needs to happen after the controller code has executed since it might add messages.
$this->view->messages = $this->_helper->flashMessenger->getMessages();
The easiest way to do this is with a controller plugin, see http://framework.zend.com/manual/1.12/en/zend.controller.plugins.html. The postDispatch() method runs after your controller code but before the page is rendered.
I just use:
public function init()
{
if ($this->getHelper('FlashMessenger')->hasMessages()) {
$this->view->messages = $this->getHelper('FlashMessenger')->getMessages();
}
}
I use this in init() and it works fine. You could use it in postDispatch(), preDispatch() or dispatchLoopShutdown() if you like. A controller plugin would not be out of line, I just haven't gotten around to doing one yet.

view loading "by hand" in zend

I am using the zend framework and trying to create and render a view from inside a controller. Normally this process is handled by the framework but I thought I could do it myself too as this part of the documentation states.
Unfortunately there is something wrong as the framework is still trying to load the default view as well. Here's my controller
<?php
class ViewController extends Zend_Controller_Action {
private $viewsFolder = null;
public function init()
{
$this->viewsFolder = realpath(dirname(__FILE__)) . '/../views/custom/';
}
public function indexAction()
{
// using a custom view (initialization and rendering executed by hand)
$view = new Zend_View();
$view->setScriptPath($this->viewsFolder);
$view->assign(array(
"dev_name" => "Fabs",
"framework" => "Zend frmwrk"
));
echo $view->render('customView.phtml');
}
}
and here is the error I get
Message: script 'view/index.phtml' not found in path (/home/ftestolin/stuff/rubrica/application/views/scripts/)
It looks like the normal view rendering cannot be suppressed. Any idea how to do it?
Probably better to disable the ViewRenderer rather than remove it. In controller:
$this->_helper->viewRenderer->setNoRender(true);
Remember that the ViewRenderer is where Zend_Form instances pull their default view for their own rendering. Removing the ViewRenderer means that it has to be re-instantiated later when the form needs to render. But when it does so, it recreates a brand new Zend_View instance. Any settings you have applied to your view - say, at bootstrap, setting doctype, etc - will be lost.
ok I will answer myself :)
one has to prevent the normal behaviour which is handled by Zend_Controller_Action_Helper_ViewRenderer
you can do it like that in the controller and then do your View instantiation business.
$this->_helper->removeHelper('viewRenderer'); // stop the default views rendering process
cheers

Controllers and Views - MVC in Zend Framework

I am using MVC in PHP based Zend Framework. This is more of a design question. I have a controller that has a couple of actions. These actions are accessed via AJAX from the controller's view. The controller's actions, perform Business logic by accessing data from functions inside a model, and construct or echo HTML. This HTML is spit back to view in the AJAX response. My understanding of controllers is they are not supposed to contain any HTML at all. But given the AJAX in the views, I feel I don't have a choice except to generate HTML on the fly in the controller. Is this a good design? How can I improve it?
There are two action helpers for doing exactly this.
you can re-use your actions for multiple contexts with the ajaxContext or contextSwitch action helpers.
The context switch is generally the more useful in my experience, and it can even automatically serialize the data you assign to the view in your action for json responses so there is no need for a view script.
you initialise the context switch like this:
class MyController extends Zend_Controller_Action
{
public function init()
{
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('index', 'json')
->initContext();
}
public function indexAction()
{
$this->view->items = My_Model::fetchAll();
}
}
The above will add a context of json to the context switch, and when the action is called with the request parameter 'format' set, it will automatically serialize the content, in this case giving a json array of the items returned by My_Model::fetchAll();
The format parameter can either be passed in the url "/my/index/format/json" or with a get query "/my/index?format=json"
The real magic is that the context switch also sets the appropriate headers for the response type, such as content-type.
You can even specify your own contexts, and the headers to send.
Read more about the context switch here
First of all, the business logic should be in the Model, not the Controller.
Secondly, My ajax requests commonly have this sort of format:
if ($ajax = $this->getRequest()->isXMLHttpRequest()) {
$this->_helper->layout->disableLayout();
};
// then later - if its responding with json:
if ($ajax)
{
$this->_helper->viewRenderer->setNoRender(true);
$this->getResponse()->setHeader('Content-Type', 'text/json');
echo $this->view->json($some_return_values);
return;
}
Also - don't forget you can use $this->view->render('controller/action.phtml'); to capture a rendered phtml into a string to return via the controller. This will allow you to keep presentation in the view.
Always try to leave any presentational logic inside a view. I think a correct design approach for your application would be something like :
AjaxController.php :
public function AjaxAction() {
//do some logic
//set content to a variable
}
ajax.phtml :
<p><?php //display the content of the variable setted in the controller ?></p>
You can later edit the view or the action separately, perhaps even rehuse the view for some similar ajax generated content, etc. Always try to separate things this way, that is the way MVC pattern is designed to work with.

Categories