codeigniter - loading a library from a view? - codeigniter

I have some data that I have to display as a table.
I think I should pass the data from the controller as $data['events'] = array(.....
and then load the view to display them.
<?php
$this->load->library('table');
echo $this->table->generate($events);
?>
this doesn't work though - it gives a Fatal error: Call to a member function generate() on a non-object
If I paste the same code in the controller, obviously using ->generate($data['events'] the table gets displayed correctly.
Should I get that views can't load libraries, or I am doing something wrong?
Or maybe should I capture the output of the library in the controller and send that to the view?

If you need to call a library (and its functions) within a view, you can do this:
$CI =& get_instance();
$CI->load->library('library_name');
$CI->library_name->yourFunction();

You should run below code in the controller:
<?php
$this->load->library('table');
echo $this->table->generate($events);
?>
and store the data in variable and then send to the view.

To answer what you are doing wrong, you should know that the CodeIgniter class isn't declared in the view, and that this is the case for a reason - to abstract your PHP code from your HTML. Views should contain minimal PHP code (basic loops, conditions).
With this in mind, you should include your library as normal in the controller as follows;
controller
$this->load->library('table');
$data['events_table'] = $this->table->generate($events);
$this->load->view(....);
In the view, you simple echo the data. Although CodeIgniter allows short-hand tags, you should use standard PHP tags to keep to a convention that will work anywhere you keep your code.
view
<?php echo $events_table; ?>

You can auto-load the library in config/autoload.php
$autoload['libraries'] = array('database','session','table');
Then you can simply call the functions in your view .
echo $this->table->generate($events);
This was useful for me when i was creating a dynamic menu header . i auto-loaded the library which has the function for dynamic menu creation and then i simply called that function from the view , by the way it is bad practice .

That is one wrong approach to MVC. You don't need to load the library in the view, because all views are loaded from one CONTROLLER, so every external Helper or Library should be loaded from the controller and the used or send to the views
Regards,
Pedro

Note the shoulds: CodeIgniter is flexible in that it lets you do things the wrong way. It just makes it a little more difficult. You can do almost everything in the view, even when you shouldn't; but loading helpers, models, and views has to be done in the controller.

In controller or model use
$this->load->library('mylib');
$mylib=$this->mylib;
$data['mylib']=$mylib;
$this->load->view('myview',$data,false);
and than in view you can use library directly:
$mylib->myfunction();
It's not MVC like solution but works if you need.

Simply load library on controller, then use it view.
Controller:
$this->load->library('table');
$data = array(
array(1,2,3,4,5),
array(1,2,3,4,5),
array(1,2,3,4,5),
);
$this->load->view('the_view', compact('data'));
View:
echo $this->table->generate($data);

Related

Sending a complete lang file to a view [CodeIgniter]

Is there any way to send a complete lang file to a view, so that I can access the $lang-variable inside the view.
At the moment the only thing I can find is sending seperate lines to the view (using $this->lang->line('lang_key')) which sounds very antagonizing if I have a few dozen lines I want to print in the view.
My question is if there's a way to select a specific language file and make the whole $lang array in that language file accessible from a view.
Try this in you view in order to see all your lang array.
print_r($this->lang);
You should put :
$this->load->lang('your lang file name');
in the constructor of the controller from which you load your view.
and use it in the view as :
<?php lang->line('key');?>
Load the translation file in the constructor:
$this->lang->load('trans_file', 'spanish');
An then on the view, you can echo each line by:
<?php echo $this->lang->line('prod_not_found'); ?>

What is the difference between view and render?

What is the difference between view and render in codeigniter?
some template libraries use $this->template->render(); to output the rendered content based on your template. (you must have the template library installed obviously)
function index()
{
$this->template->set_template('main_template');
$data['content'] = 'hello this is my content';
$this->template->write_view('content', $data);
$this->template->render();
}
is in effect the same as
function index()
{
$data['content'] = 'hello this is my content';
$this->load->view('template/header');
$this->load->view('template/content', $data);
$this->load->view('template/footer');
}
template libraries save the need to load each partial view every time.
Render is not an out-of-the-box Codeigniter function for loading view files. Render is primarily used by Codeigniter template libraries like Collin William's Template Library or Phil Sturgeon's Template Library.
The following two methods for view files are supported by Codeigniter right in the core code without using third party libraries or core extensions.
$this->load->view()
The standard and most used way of loading a view file. Does not support any fancy syntax except alternative control syntax structured PHP code or standard PHP code.
$this->parser->parse()
Using the in-built Codeigniter parser which supports a Smarty like syntax only not as powerful. Also allows you to code view files using standard PHP and HTML as well.

Dynamic layouts in CakePHP

Sorry about the question title, but I couldn't find a more appropriate way to phrase this.
I am currently building a CakePHP powered website and I'm not quite sure how to approach the following issue. The website looks something like the follwing mockup:
.
The greyed out areas are part of the layout, because their content does not change between views. In the sidebar, I have a collection of ads who are linked to several models. I need controller logic to determine the picture associated with an ad. Also, the ad list needs to be dynamic. Where should I put the logic for building the sidebar?
I've thought about:
putting the logic into the AppController (beforeFilter / afterFilter) - the problem is I can't use the controller logic I need (the other controllers inherit from AppController, I'm not sure how to use them there).
making a component - is it okay to build components that rely on controllers?
replicating the sidebar code in all controllers that render views - this seems kind of stupid to me.
What is the Cake way for this?
Update
After some reading and experimenting, I've gotten to refactoring most of it.
I obtained the best performance by moving the logic for building my ads in the model (eliminating the component that retrieved the pictures) and not using requestAction. It's almost three times faster and the code looks much better.
I've done something similar for data-driven navigation. I put my logic in AppController::beforeRender and haven't had any problems. I'm not sure I understand your concern related to controller inheritance. I retrieve my menus via:
$menus = $this->NavMenuItem->groupByMenu();
$this->set( compact( 'menus' ) );
I then created an element that renders the menu. It's executed by the layout via:
<?php echo $this->element( 'navigation', array( 'id' => 'secondary', 'menu' => $menus['SECONDARY'] ) ) ?>
If that doesn't help, maybe you can further explain your issue with controller inheritance in a comment.
I guess the answer is requestAction in case the results are cachable:
http://book.cakephp.org/view/434/requestAction
It can be done in this way:
Create an element that will help in layout of the Ad Block
Create one or more controller that will generate the data required for rendering of the block
Use requestAction for getting the data out of the models and into the element.
Check the cake book, there is an example of an element where data from Post Model is used to display top/latest 5 posts. Your requirement, I feel, is very similar to it.
Alex,
you're getting a SQL error because the build() function has to be in the Sidebar model, not controller. Also, you don't necessarily need to use $user = array('Sidebar'); you could calling Sidebar in all of your models with this:
$Sidebar = ClassRegistry::init('Sidebar'); and then $Sidebar->find();, $Sidebar->build(); etc.
Or, if you only need to call the build() function from the Sidebar model, you could do this:
$sidebar = ClassRegistry::init('Sidebar')->build();
$this->set('sidebar', $sidebar);
Cheers.

What is the best practice for displaying multiple views in Codeigniter?

I'm trying to determine the best practice for calling multiple views from the same method in a controller.
Is it preferable in the controller to make one view call, then have that view call all the views it needs, or call all the views you need in sequence in the controller?
Example:
function index(){
//set all data variables
//then send them to the view
$this->load->view($index_view, $data);
}
or
function index(){
//set variables
//then call each view
$this->load->view($header_view, $header_data);
$this->load->view($body_view, $body_data);
$this->load->view($footer_view, $footer_data);
The Codeigniter guide shows both ways, but does not seem to advise to the best practice...is there one?
I didn't like the way of including the header/footer within the view, and I didn't like loading the footer and header each time in every single Controller function.
To fix this, I extended the Controller class with my own view display function.
<?php
// in application/libraries/MY_Controller.php
class MY_Controller extends Controller {
function _displayPage($page, $data = array()) {
$this->view->load('header', $data);
$this->view->load($page, $data);
$this->view->load('footer', $data);
}
}
?>
// in application/controllers/home.php
<?php
class Home extends MY_Controller {
function index() {
$this->_displayPage('home/index', array('title' => 'Home'));
}
}
?>
Not sure if this is CodeIgniter "best practice" but it makes sense to me.
I don't think there is a definitive answer for that. Choose one and stick with it, it's important to be consistent.
Anyway, I'd prefer the second one.
I would say that the controller should only display one view. Then it's up to the view if it wants to show a header, footer, sidebar or whatever. The controller shouldn't have to care, its job is to get data from a model and hand it to a view. Not decide if the view should have a header and a footer.
Agree with Christian Davén: its view / display logic not data or business / logic. essentially its the same as using php includes for snippets like navigation, footer etc. you're just embedding markup.
This is expected behavior. Once variables are set they become available within the controller class and its view files. Sending an array in $this->load->view() is the same as sending an array directly to $this->load->vars() before calling the view file. This simplifies things for most people using multiple views in a controller. If you are using multiple view files in a single controller and want them to each have their own set of variables exclusively, you’ll need to manually clear out the $this->load->_ci_cached_vars array between view calls.
A code comment in the Loader class describes another situation showing why this is the desired default behavior:
You can either set variables using the dedicated $this->load_vars()
function or via the second parameter of this function. We'll merge
the two types and cache them so that views that are embedded within
other views can have access to these variables.

CI: Use view/controller in another included view?

I'm new to CI & PHP.
I have an auth library included, and works great stand-alone.
I simply want to have the login form load as a view inside another view...is that weird?:
I'm quasi-templating:
index:
$this->load->view('head_content');
$this->load->view('stuff');
$this->load->view('footer');
Inside the stuff view:
<stuff></>
$this->load->view('login_view');
<morestuff></>
I just want the login form to show up on the front page, and then tie into the auth system...
You have to load the login view in the controller, and then pass the data to the stuff view.
In the controller:
$this->load->view('head_content');
// the line below will save the output of the login view to $data['login']
// instead of outputting to the screen
$data['login'] = $this->load->view('login_view', '', TRUE);
$this->load->view('stuff');
$this->load->view('footer');
In the stuff view:
<stuff>
<?php echo $login; ?>
<morestuff>
In the page Views, at the bottom, check out the section Returning views as data
I've just recommended this but I'm going to recommend it again:
http://codeigniter.com/forums/viewthread/77279/
Django-like template inheritance helper for CodeIgniter.
I use this on ALL of my CI projects and it makes things like this stupidly easy.

Resources