I have a partial view with a script I want to include in all my views, I dont't wanna #include this partial in all my layouts and blade views but instead add it to all rendered views, my partial looks like this:
<script type="text/javascript">window.$app = {!! json_encode(app(App\Helpers\Javascript::class)->app) !!};</script>
How can I do this?
You could:
include it in your main(s) layout template (the one(s) handling <html> and <body> tags)
you could use a Laravel View Composer to add the JSON data to the required views. Those views would so include the JSONed data, that you'd echo in the right place to be handled by your JS.
you could check the Php-Vars-To-Js package that allows you to put some data from PHP in a custom JS namespace (eg window.yourNameSpace). And then use it from a View Composer or the specific controller's methods concerned by your views.
Related
I am working on Laravel for the first time
i have to make a Front End Menu Dynamic in Header and Footer [ list of categories will come from database ]. which controller I have to use for this.?
any common controller available in this framework to send data to header and footer.
When I receive the data in HomeController index Action its available for the home page only.
class HomeController {
public function index()
{
$categories = Category::get();
return view('home', compact('categories'));
}
}
Thanks.
This is a perfect case for View Composers:
View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.
You may attach a view composer to multiple views at once by passing an array of views as the first argument to the composer method:
View::composer(['partials.header', 'partials.footer'], function ($view) {
$view->with('categories', [1, 2, 3]); // bind data to view
});
Now you could simply retrieve $categories within your view (blade template).
Tip: Common practice is to create a new service provider called ComposerServiceProvider and place the abovementioned composer logic in the boot() method.
I assume you are using the Header and Footer in a master layout file. In this case you need to send all header/footer info every request. Which would be silly so instead use View Composers:
Define them in your appServiceProvider in the boot() method
view()->composer('home', function($view) {
$view->with('categories', App\Category::all());
});
In my example i made 'home' the name of the view, since it is in your example. But i would make a master file called layout and include a header and footer partial. If you want categories inside your header you could make a view()->composer('layout.header') with only header data.
which controller I have to use for this.?
Any
any common controller available in this framework to send data to header and footer
No.
You control what is returned from the Controller to be the response. You can design layouts and break them up into sections and have views that extend them. If you setup a layout that has the header and footer and your views extend from it, you can use a View Composer to pass data to that layout when it is rendered so you don't have to do this every time you need to return a view yourself.
Laravel Docs 5.5 - Front End - Blade
Laravel Docs 5.5 - Views - View Composers
In case of this u can use components
https://laravel.com/docs/8.x/blade#components
php artisan make:component Header
View/Component.Header.php
public function render()
{
$category = [Waht you want];
return view('views.header', ['category'=>$category]);
}
Then include Header.php to your blade like this
views/front.blade.php
<html>
<body>
<x-header/> <!-- like this -->
#yield('content')
#include('footer')
<body>
My app.blade.php file is my main file that will #yield all my other blade template files. I noticed that the Auth class is available to this file. I cant figure out how to add one of my custom classes, Projects so it is available to app.blade.php.
app.blade.php contains a drop down menu where I need to list all my projects, but if I try something like
Projects::where('user_id','=',Auth::user()->id)->get()
I get an error saying the Projects class is not found. How can I add this to my master template just like how Auth is available? Or, do I need to go about this differently?
You do it by injecting the class into your template.
#inject('project', 'App\Project')
{{ $project->where('user_id','=',Auth::user()->id)->get() }}
Just make sure your namespace is correct.
http://laravel.com/docs/5.1/blade#service-injection
I have a layout in which I want to add classes to the body depending on which view is being displayed, i.e.:
<body class="layout-default page-index">
I can do this in Twig quite easily (OctoberCMS uses Twig) but I can't see a way to do it with Laravel's Blade templates (which I prefer anyway).
I'd rather not have to pass a variable to every View::make with the view name as this seems redundant.
Good question, very smart way to work with css.
You would use this typically by adding classes to the body tag, or the main container div.
within your routes or filters file:
View::composer('*', function($view){
View::share('view_name', $view->getName());
});
Within your view:
<?php echo str_replace('.','-',$view_name);?>
<?php echo str_replace('.','-',Route::currentRouteName());?>
These should get you everything you need.
I have to add a feature to a quite big app using zend framework.
i have a view. in that view, i have a if and want to include an other .phtml on the same location.
so, at the moment i got something like
if (x = true)
require_once(the other file);
that works, but isnt in the meaning of zend. i've been told i should use view helpers, more specific, the partial. so, how do i include a phtml file with the partial? i dont get it.
Use the render() view helper like this:
<?=$this->render('the other.phtml')?>
All view variables available in the current .phtml script will be available in the other.phtml too.
If you want to render the other view script with specific view variables, use partial instead:
<?=$this->partial('the other.phtml', array(
'var'=>'value',
'var2'=>'value2',
...
))?>
Attempting to learn CI and going through the docs to get a better understanding. Without getting a separate library, I could make a template by including a list of views like so:
$this->load->view('header');
$this->load->view('navigation');
$this->load->view('sidenav_open');
$this->load->view('blocks/userinfo');
$this->load->view('blocks/stats');
$this->load->view('sidenav_close');
$this->load->view('content',$data);
$this->load->view('footer');
This makes sense but would I actually have that on each of my controllers (pages)? Not sure if there is a way to include this in the initial controller (welcome) and then in the others somehow reference it? Or perhaps there is something I am missing completely
You can load views from within a view file. for example, consider a generic page template called page_template.php:
<html>
<body>
<div id = "header">
<?php $this->load->view('header');?>
<?php $this->load->veiw('navigation');?>
</div>
<div id = "sidenav">
<?php $this->load->view('sidenav');?>
</div>
<div id = "content">
<?php echo $content;?>
</div>
<div id = "footer">
<?php $this->load->view('footer');?>
</body>
</html>
Load your more dynamic areas by making use of codeigniter's abiltiy to return a view as a variable in your controller:
$template['content'] = $this->load->view('content',$data,TRUE);
$this->load->view('page_template',$template);
By passing TRUE to the load function, CI will return the data from the view rather than output to the screen.
Your sidenav section could be it's own view file, sidenav.php, where you have your 'blocks' hard-coded or loaded similar to the above example.
I've done it both ways, including every stinking bit of views in each controller method, and by using a page template that loads sub-views and dynamic areas, and by far, the second method makes me happier.
Loading views from within views can lead to confusion.
Extending the Controller class hides much of the complexity that comes from that approach, but still utilises the idea of generating common views (footer, header, navigation bars, etc) by rendering them once on every page load.
Specifically, consult the CI User Guide and wiki for references to MY_Controller - you extend this by creating a MY_Controller.php file in the ./libraries directory.
In there you can call view fragments, also utilising the third-parameter=true feature of the load->view() call. You load these into $this->data - for example loading the footer into $this->data['footer']. In your various controllers, continue adding view data to $this->data. In your views - I typically use a template that does little other than skeleton HTML and some basic CSS, and then echos the entire header, footer, nav and main content lumps as variables taken from $this->data
Added bonus - if you're new to CI, you'll likely soon be looking for how to do other things that a MY_Controller will make easy for you :)
I've got a wiki page on simplifying the generation and display of view partials, as you're trying to do here, using MY_Controller at:
https://github.com/EllisLab/CodeIgniter/wiki/Header-and-Footer-and-Menu-on-every-page---jedd