Can i load view from helper in codeigniter? I have been looking for a present, but it seems no one has discussed it.
Yes, you can. Create your helper, say views_helper.php:
if(!function_exists('view_loader')){
function view_loader($view, $vars=array(), $output = false){
$CI = &get_instance();
return $CI->load->view($view, $vars, $output);
}
}
$view is the view file name (as you would normally use), and $vars an array of variables you want to pass (as you would normally do), pass a true as optional third parameter to have it returned (as it would normally happen) as content instead of it just being loaded;
Just load your helper (or autoload it):
$this->load->helper('views');
$data = array('test' => 'test');
view_loader('myview', $data)
Related
I am looking for the best practise when it comes to passing data from the controller to a subview in Codeigniter, so far I have created a layout file which loads the subviews. For example, when I have been doing this, it does work but I am wondering if there is a cleaner way of doing things? Or are there any better options for templating my html and CSS without having to do this for every function?
Currently renaming each separate $data variable to $var1, $var2, $var3 etc.
Here is my code when loading pagination and passing this to the subview.
function index($start=0)
{
$var1['posts']=$this->post->get_posts(3,$start);
$this->load->library('pagination');
$config['base_url']=base_url().'posts/index/';
$config['total_rows']=$this->post->get_posts_count();
$config['per_page']=3;
$this->pagination->initialize($config);
$var2['pages']= $this->pagination->create_links();
$var3=array('subview' => 'post_index');
$data=array_merge($var1, $var2, $var3);
$this->load->view('layouts/layout',$data);
}
And in my template file I use this line of code in the body to load the subviews:
<?php $this->load->view($subview); ?>
Okay there indeed is a way to do that. Assuming you have a view called post_index in which you pass $var['posts'] and then you want to put that view in your master layout.
$var['posts'] = $this->post->get_posts(3, $start);
// setting the third parameter as true would return the view as
// data which you can pass to another view
$data['page'] = $this->load->view('post_index', $var, TRUE);
$this->load->view('layouts/layout', $data);
From codeigniter docs
Returning views as data
There is a third optional parameter lets you
change the behavior of the method so that it returns data as a string
rather than sending it to your browser. This can be useful if you want
to process the data in some way. If you set the parameter to TRUE
(boolean) it will return data. The default behavior is false, which
sends it to your browser. Remember to assign it to a variable if you
want the data returned.
I have a piece of data I want passed to every view. I am using CodeIgniter 3 and have PHP 7 available to me. The current way I do it is using something like this in every function.
$data['foobar'] = $this->general_model->foobar();
// More code
$this->load->view('homepage', $data);
I'd prefer not to have to call $data['foobar'] = $this->general_model->foobar(); on every single function.
I've tried many approaches to fix this without resorting to anything that makes the code too goofy. I've tried constructors, autoload, and hooks. The problem in each case boils down to the fact that $data is local to each function. The best I've gotten is usually something like this.
$data['foobar'] = $this->foobar;
// More code
$this->load->view('homepage', $data);
This is slightly nicer, but it still results in me placing this line in every function.
I'd like my functions to in someway inherit $data with the index foobar already set. I'd prefer to avoid a solution that requires every function receiving $data as a parameter. How can I accomplish this?
Option 1:
Not sure if you have tried this but you could set $data as a property of your class
protected $data = [];
Then in your constructor set it.
$this->data['foobar'] = $this->general_model->foobar();
This would mean your $data becomes accessible to all your methods in your controller and you would need to refer to them as $this->data['data_name'] and use it in a view like
$this->load->view('homepage', $this->data);
Option 2:
A second way is to create a method like render() which is common to all your methods that load views and replaces your existing view calls.
So you would have something like...
public function one_of_my_methods(){
$data['content'] = 'This is content 1';
$this->render('test_view',$data); // Call the new view handler
}
// All methods using views now call this to load the final view
public function render($view,$data){
$data['foobar'] = 'I am common'; // DRY
$this->load->view($view, $data);
}
I use Codeigniter Framework, and I set my program to load header and footer by default when i load the view method. In the header file I have properties like: site name, description etc.. Those proprieties fetch from the DB. Now the problem is that I need to set them every time I call the view method.
How can I set them by default correctly?
As someone said above, you should extend the Controller. I do something very simular to this, and this is my code, which is found on "MY_Controller.php" within the ./application/core directory.
public function show_view($view, $data = array())
{
// Database connection here
// add anything to the $data array
$this->load->view('header', $data);
$this->load->view($view, $data);
$this->load->view('footer', $data);
}
Now, instead of loading a view from the controller like this;
$this->load->view('view', $data);
I do this;
$this->show_view('view', $data);
FYI. I call the function "show_view" to avoid name conflicts.
I have a helper file, it has a variable that I want to pass across to a view, but it comes across as empty, so I am a bit unsure if I have the right code or I have overwritten it later on _ though I am sure I have not!
anyway say the variable in ther helper file is an array that contains a list of data, and I use:
$this->load->helper('helperfile_helper'); //contains the variable 'productList'
$data['productList'] = $productList;
$this->load->view('page', $data);
I would expect that the helper file works like an 'include' with the defined variables available once the helper has been called, is this the casee or have I missed something??
Helpers allow you to use function in your controller, have a look here: http://ellislab.com/codeigniter%20/user-guide/general/helpers.html
So you must create a function in your helper file that will return a value.
For example in your helper:
if( ! function_exists('random_number'))
{
function random_number()
{
return 4;
}
}
and in your controller you can use it:
$this->load->helper('helperfile_helper'); //contains the variable 'productList'
$data['random_number'] = random_number();
$this->load->view('page', $data);
So $data['random_number'] will contain 4
Hi out there in Stackland! Here's my problem:
I want to use my Zend controller to load an array from a database, and then pass it to javascript. I've decided the best way to do this is to use ajax to ask the controller for it's array, encode it in json, and then pass it down. However, I don't know how to pass the variable I loaded in my first action to the action that will pass it down when it gets called via ajax.
The original action which produces the view
public function indexAction()
{
$storeid = $this->getStoreId();
if(!$storeid)
{
$this->_forward('notfound');
return;
}
$store = $this->_helper->loadModel('stores');
$store->getByPrimary($storeid);
}
The action that will be called via ajax
public function getdataAction()
{
$this->_helper->Layout->disableLayout(); // Will not load the layout
$this->_helper->viewRenderer->setNoRender(); //Will not render view
$jsonResponse = json_encode($store);
$this->getResponse()->setHeader('Content-Type', 'application/json')
->setBody($jsonResponse);
}
What I want is to pass $store in indexAction to getdataAction so it can send store as the jsonResponse. Note, these are called at two different times.
Things I have tried that haven't worked:
setting $this->getRequest()->setParam('store', $store) in indexAction, and then using $this->getRequest()->getParam('store'), in getdataAction. I presume this hasn't worked because they're different http requests, so attaching a new param is useless.
using protected $_store in the controller itself, and then saving to it with indexAction, and using it in getdataAction. I'm not really sure why this isn't working.
Is there a good way to pass a variable in this manner? Is there a way to pass a variable between different controllers?(I assume the answer to one is the answer to the other). Could I store it in a controller helper? Do I have to use a session, which I know would work but seems unnecessary? Is there a better way to pass variables to javascript? Am I asking too many questions? Any help would be outstanding. Thanks.
Maybe I'm reading the question wrong, but you should be able to just move $store into the constructor:
public function __construct() {
$store = $this->_helper->loadModel('stores');
$store->getByPrimary($storeid);
}
and have it accessible in all *Action methods. Using sessions seems out of whack for this.
(disclaimer: I'm pretty new to ZF, so I'm interested in other answers found here, and have not tested the below!)
In your view, where you put the ajax call, you will probably address it like:
(See ZF Documentation)
<?= $this->ajaxLink("Example 2",
"/YourController/getdata",
array('update' => '#content',
'class' => 'someLink'),
array('store' => $this->store)); ?>
Notice that in your indexAction, you store the store via:
$this->view->store = $storeid;
Of course, you should note that a web-user could modify the store parameter as it is passed through via an URL.
It would be better architecture to simply add a method to your IndexController, a helper, or somewhere, that returns an instance of Store. Use that method within your indexAction, and your getdataAction (would be more meaningful to call it ajaxAction). Also, you're forgetting to call sendResponse() (remember, you disabled autoRender):
private function indexAction()
{
$this->getStore();
//blah blah
}
private function getStore()
{
$storeid = $this->getStoreId();
if(!$storeid)
{
$this->_forward('notfound');
return;
}
$store = $this->_helper->loadModel('stores');
$store->getByPrimary($storeid);
return $store;
}
public function ajaxAction()
{
$this->_helper->Layout->disableLayout(); // Will not load the layout
$this->_helper->viewRenderer->setNoRender(); //Will not render view
$jsonResponse = json_encode($this->getStore());
$this->getResponse()->setHeader('Content-Type', 'application/json')
->setBody($jsonResponse)
->sendResponse();
}
The manual says:
To send the response output, including
headers, use sendResponse().
http://framework.zend.com/manual/en/zend.controller.response.html
All right, for those of you who want the answer to this too, I just sucked it up and used session. I put a Zend_Session->start() in the bootstrap. I then created a plugin to add a private variable $session to each controller. Then I set $this->session to Zend_Session_Namespace. To pass something, I pass it through session, so I use $this->session->store = $store. I can then pick it up elsewhere with $this->session->store. Thanks to those who tried to help!
Just a quick addition to the comments. To output an array as JSON from within a controller, use:
$array = array('hi' => array('Hello' => 'World');
$this->_helper->json($array);
This sends the response and sets the specific headers for a JSON response