I load the multiple views from the controller, in order to display a page.
$this->load->view('header');
$this->load->view('content', $data);
$this->load->view('sidebar1', $data1);
$this->load->view('sidebar2', $data2);
$this->load->view('footer');
However I think its not a clean approach. Can it be improved by creating a single main view, for example "views/page" which includes all above views in it. Then instead of calling all the above views, i can call only main view, for example:
$this->load->view('main');
In this case how can I pass the variables for the content, sidebar1 and sidebar2?
Thanks
Pass the data for each view as an array to your main view, then pass those arrays on as your main view loads the subviews.
$data['sidebar1_data'] = array($one => 'one');
$data['sidebar2_data'] = array($two => 'two');
Then in your main view:
$this->load->view('sidebar1', $sidebar1_data);
$this->load->view('sidebar2', $sidebar2_data);
Within my projects, I have a tendency to do:
$this->load->vars($data);
$this->load->view('template_name');
Where my template loads in other views within itself.
The CodeIgniter documentation states the following for the method $this->load->vars():
"This function takes an associative array as input and generates variables using the PHP extract function. This function produces the same result as using the second parameter of the $this->load->view() function above. The reason you might want to use this function independently is if you would like to set some global variables in the constructor of your controller and have them become available in any view file loaded from any function. You can have multiple calls to this function. The data get cached and merged into one array for conversion to variables. "
Using $this->load->vars($data) helps in not having to load data for each view within my template.
use like this
$newData = array_merge($data, $data1, $data2);
$this->load->view('main', $newData);
If there are no key with same name in $data, $data1, $data2 then, it will work without modifying any of view for variable name change.
Related
I want to create a global variable and pass this into all view, so I can get this variable into all blade template
basically, my need is to pass my general setting controller value into my common blade view like header.blade.php
Thanks in advance
For that you will need to add some code in the App->Providers->AppServiceProvider.php like this:
public function boot()
{
view()->composer('*',function($view){
$settings = Settings::firstOrNew(['id' => '1']);
$view->with('settings', $settings );
});
}
According to Laravel documentation you can use view composer:
https://laravel.com/docs/5.8/views#view-composers
for using this feature in app > AppServiceProvider and in boot method you can use this approach for passing parameter to specific view If you have data that you want to be bound to a view each time that view is rendered. this approach meet your need perfectly. for example you want to pass a parameter named userName to header.
View()->composer('header', function ($view){
$userName= "username"
$view->with(['userName'=>$userName]);
});
At first, I had just one view file that contained all codes for showing a page. but now I decided to split code sections.
So, as I learned, I would make a child view, write my section codes to that file and now return the child view in Laravel Controller. So now passed data goes to child view and in parent view, I have no access to them until I call yield function. But in parent view I need some of that data before calling yield. So How can I pass data which would be available both in parent view and sub view?
I've already tried passing data in extends() as a second parameter but this way
data will be available just when I call yield.
Controller :
class walletsController extends Controller
{
function name(){
return view("subview", ["somedata" => $somedata])
}
}
subview blade file :
#extends('parentview',["somedata" => $somedata] )
#section('wallet')
// some codes here
#endsection
parentview blade file :
// some codes
#yield('wallet')
when I try to use data that being passed in extends() before calling yield it gives me a garbage value.
In this case I would recommend using Laravel's View Composers.
View Composers allow you to pass variables to any view the you want (id doesn't matter if it's a parent or child view).
In your case, you will pass a variable that will be used only on parentview, right?
The code in the AppServiceProvider (boot() method) would be like this:
view()->composer(['parentview', 'folder.another-view-that-you-want'], function ($view) {
$someVar = 'some var value';
$view->with(['someVar' => $someVar]);
});
You can also pass a variable to every single view, using *:
view()->composer('*', function ($view) {
$someVar = 'some var value';
$view->with(['someVar' => $someVar]);
});
Of course, you can read further in the docs: https://laravel.com/docs/5.8/views#view-composers
Ive been working with CI and I saw on the website of CI you can load a view as a variable part of the data you send to the "main" view, so, according the site (that says a lot of things, and many are not like they say ...ej pagination and others) i did something like this
$data['menu'] = $this->load->view('menu');
$this->load->view ('home',data);
the result of this is that I get an echo of the menu in the top of the site (before starts my body and all) and where should be its nothing, like if were printed before everything... I have no idea honestly of this problem, did anybody had the same problem before?
Two ways of doing this:
Load it in advance (like you're doing) and pass to the other view
<?php
// the "TRUE" argument tells it to return the content, rather than display it immediately
$data['menu'] = $this->load->view('menu', NULL, TRUE);
$this->load->view ('home', $data);
Load a view "from within" a view:
<?php
// put this in the controller
$this->load->view('home');
// put this in /application/views/home.php
$this->view('menu');
echo 'Other home content';
Create a helper function
function loadView($view,$data = null){
$CI = get_instance();
return $CI->load->view($view,$data);
}
Load the helper in the controller, then use the function in your view to load another one.
<?php
...
echo loadView('secondView',$data); // $data array
...
?>
Real basic CI question here, which I cant find anything on in the documentation. I think I may need some further configuration?? I have a function which loads a view and it works correctly, but when I send it parameters its doesn't load the view, any ideas??
Heres code with params (view does not load)
function grid($height,$width)
{
echo $height."x".$width;
$this->load->view("grid");
}
and here's without (view does load)
function grid()
{
//echo $height."x".$width;
$this->load->view("grid");
}
So Height and width is the only thing that echos in the first example, in the second the view is loaded.
Thanks ahead of time!
You are supposed to have your controller pass parameters to the view as an array:
function grid($height,$width)
{
$data = array();
$data['height'] = $height;
$data['width'] = $width;
$this->load->view("grid", $data);
}
Then your view can render them:
echo $height."x".$width;
This allows for a clean separation of concerns between the Controller and View objects.
For more information see the section Adding Dynamic Data to the View in the CI User Guide.
I'm coming from CodeIgniter, and the terminology overlap between it and other MVC frameworks (particularly Zend) is giving me a mental block of some kind.
I want my users to visit http://mysite.com/do/this.
I understand that "do" is the Controller, and "this" is a function (well, method) within that Controller.
My site will have common elements like a header and sidebar; I understand that those go into a Layout, which will be incorporated into the final output.
I want the /do/this page to display three visual blocks of information (I'm deliberately not using the word "modules"). Let's call them BlockA, BlockB, and BlockC. Maybe one is a list of "new events" and another is a list of "new posts" and another is something else. Whatever. The trick is, these blocks of information will also be displayed on other pages of the site - say, http://mysite.com/did/that.
Both the "did" and the "do" Controllers (and the "this" and "that" methods, obviously) would be arranging BlockA, BlockB, and BlockC differently. Each Controller would have different criteria for what went into those blocks, too - one might be current information, while another might be archived information from the past.
I want to ensure that future programmers can easily alter the appearance of BlockA, BlockB, and/or BlockC without having to touch the code that populates their data, or the code which arranges them on each page.
So my general feeling is that BlockA, BlockB, and BlockC need to have their visual layout defined in a View - but that View wouldn't be specifically associated with either the "do" or the "did" Controllers. And the code which populates those blocks - that is, queries information from a database, selects the bits that are to be displayed, and whatnot - shouldn't reside entirely in those Controllers, either.
I started down the path of putting the logic - that is, assembling what will be displayed in each block - into Models. I feel I'm on the right path, there; both the "do" and "did" Controllers can thus summon the block-creation code via Models. But how (and where) do I abstract the visual element of those blocks, in such a way that the visual elements can also be shared by these two Controllers? Do the Models somehow load a View and output HTML to the Controllers (that doesn't feel right)? Or is there a way for the Controllers to run the Model, get the data to display, and then somehow feed it to a common/centralized View?
I know how I'd do this in CodeIgniter. But... what's the correct architecture for this, using Zend Framework? I'm convinced that it's very different than what CodeIgniter would do, and I want to start writing this application with the right architecture in mind.
One small naming thing: /:controller/:action/* => /do/this = this is an action (although also both a function and a method in the controller, action is the proper name)
Your blocks to me sound like "partial views". There are a few ways to approach this problem, and depending on how the views work, or what information they need to know, you adapt your strategy
Rendering Partials
You want to use this method when you have some view code you want to be used by multiple views. There are two different approaches using the view helpers Zend_View_Helper::render or Zend_View_Helper_Partial* The render($phtmlfile) view helper is more efficient, the partial($phtmlfile, $module, $params) view helper clones a new view, unseting all parameters, and setting the ones you pass in. An example of how to use them:
case/list.phtml:
<?php
$this->headTitle($this->title);
// works because our controller set our "cases" property in the view, render
// keeps our variables
echo $this->render("case/_caseListTable.phtml");
case/view.phtml
<?php
$this->headTitle($case->title);
?><!--- some view code showing the case -->
<?php if ($cases = $case->getChildren()): ?>
<h3>Children</h3>
<?php echo $this->partial("case/_caseListTable.phtml", "default", array(
"cases"=>$cases,
)); ?>
<?php endif; ?>
case/_caseListTable.phtml
// table header stuff
<?php foreach ($this->cases as $case): ?>
// table rows
<?php endforeach; ?>
// table footer stuff
Custom View Helpers
Sometimes the controller has no business knowing what information is being displayed in the block, and preparing it for your view would be silly, at this point you want to make your own view helpers. You can easily add them to the global view in application.ini:
resources.view.doctype = "XHTML1_STRICT"
resources.view.helperPath.My_View_Helper = APPLICATION_PATH "/../library/My/View/Helper"
I have a tendency to use this method for things that will require additional information from the model not provided by the controller, or blocks of reusable formatting code for the view. A quick example, from a project that I used: Olympic_View_Helper_Ontap grabs the draught beer list and renders it:
class Olympic_View_Helper_Ontap extends Zend_View_Helper_Abstract {
public function Ontap()
{
$view = $this->view;
$box = Olympic_Db::getInstance()->getTable('box')->getBoxFromName('Draught-Beer');
if ($box) $menu = $box->getMenu(); else $menu = null;
$content = "";
if ($menu)
{
$content = "<h1>".$view->escape($menu->title)."</h1>";
$content .= "<ul>";
foreach($menu->getItems() as $item) {
$content .= "<li>".$view->escape($item->name)."</li>";
}
$content .= "</ul>";
}
return $content;
}
}
Then in my layout:
<?php echo $this->ontap(); ?>
Your View Helpers can also accept arguments (of course), can call other view helpers (including partial). Consider them template functions. I like using them for short tasks that are required a lot, for instance $this->caseLink($case) generates a properly formatted <a href='/case/2' class='case project'>Project</a> tag.