I have a template admin.blade.php that contains this code:
#yield('breadcrumbs', Breadcrumbs::render(Request::route()->getName()))
And in my child files I either ignore breadcrumbs or I would like to do something like:
#section('breadcrumbs')
{{ Breadcrumbs::render(Request::route()->getName(), $event) }}
#endsection
The problem is that it seems that the default yield content is still being triggered and when the function gets called I get an error.
Too few arguments to function
DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider::{closure}(), 1
passed in
C:\xampp\htdocs\msu\vendor\davejamesmiller\laravel-breadcrumbs\src\BreadcrumbsGenerator.php
on line 68 and exactly 2 expected (View:
C:\xampp\htdocs\msu\resources\views\event\station\edit.blade.php)
Which I understand, so my question is how do I achieve what I am trying to do in blade?
I also tried doing #section #show and section #stop but that seems to just hide the sections and give me the same error.
Any help is greatly appreciated.
You could create a component to handle the if case you are going to need:
<!-- resources/views/breadcrumb.blade.php -->
#if (isset($slot) && !is_null($slot))
#section ('breadcrumbs')
{{ Breadcrumbs::render(Request::route()->getName(), $slot) }}
#endsection
#endif
Then inside your child view, you can call your component:
<!-- resources/views/child.blade.php -->
#component('breadcrumb', ['slot' => $event]) #endcomponent
You can update the variable name in the component to whatever you like.
For more information about components: https://laravel.com/docs/5.6/blade#components-and-slots
Related
I am using livewire 2.2 with laravel 7.24 in my laravel project. When i load component using
Route::get('/path', ComponentClassPath);
it works, but when i load my livewire component inside a blade view. For instance, test.blade.php like this:
#extends('layouts.app')
#section('content')
#livewire("my-livewire-component")
#endsection
it doesn't work and shows the below error:
Undefined variable: slot (View:
E:\xampp\htdocs\lw\resources\views\layouts\app.blade.php) .
app.blade.php
<head>
#livewireStyles
</head>
<body>
<div class="container">
{{ $slot }}
</div>
#livewireScripts
</body>
Any solution ?
Since you're using the #section directive (where you #extend a layout, and use sections), and not the component $slot approach (see https://laravel.com/docs/8.x/blade#slots), you should be using #yield instead of echoing the "special" $slot variable.
Alternatively you could go with the slots-approach, but you would generally choose one or the other. Going with that approach means a different structure to your blade files, and there's nothing wrong with either way -- just be consistent about which one you choose.
To continue using sections and extending layouts, simply replace {{ $slot }} with #yield('content'), like
<div class="container">
#yield('content')
</div>
If you still want to use slot please create component php artisan make:component Layouts/Login and on render function in Livewire controller Http/Livewire/... add layout
public function render()
{
return view('livewire.pages.login')
->layout('components.layouts.login');
}
I use davejamesmiller Breadcrumbs package. I am wondering how to pass a parameter to a breadcrumb, something like an id.
In the docs (here) it says that is possible, but can't find the way to do it.
My goal es to do a breadcrumb like this: Dashboard \ User \ New Model. Where New Model its a form to add model data with some relationship with the user. Without the user_id param the link for User won't work.
Any idea?
You can pass global variable
\View::share ( 'variable2', $variable2 );
if render breadcrumbs in layout
or You need render breadcrumbs in `user.new_model.blade
#section('content')
{!! Breadcrumbs::render('page', $page) !!}
#stop`
my way
Create template
breadcrumbs.blade.php
with content
#if(!empty($breadcrumbs))
<ol class="breadcrumb">
<li>{!! link_to_route('main', 'Home') !!}</li>
#foreach($breadcrumbs as $bread)
#if(isset($bread['url']))
<li>{!! link_to($bread['url'], $bread['name']) !!}</li>
#else
<li>{!! $bread['name'] !!}</li>
#endif
#endforeach
</ol>
#endif
and connect it to layout
#include('breadcrumbs')
and in your action pass array of links
\View::share('breadcrumbs', [
['url' => route('collection.show', ['id'=>$data->collection, 'url'=>$data->collection]), 'name' => $data->collection->name],
['name' => $data->article]
]);
There is another way. As general, in each view just calling Breadcrumbs::render() should create the hierarchy of the breadcrumbs links depending on the routes defined in routes/breadcrumbs.php.
There are two essential points that you have keep in mind to go further with this solution:
The callback function that found in breadcrumbs.php routs definition is the place from which you should pass your parameters.
Giving correct name to your web route from routes/web.php which will be used later in routes/breadcrumbs.php
Checkout the following code snippets that demonstrates the above two points:
//Point1: routes/breadcrumbs.php
Breadcrumbs::register('job.edit', function($breadcrumbs, $job, $title)
{
$breadcrumbs->parent('job','job');
$breadcrumbs->push($title, route('job.edit', $job));
});
Breadcrumbs::register('job.edit.install', function($breadcrumbs, $job, $title)
{
$breadcrumbs->parent('job.edit',$job, $title);
$breadcrumbs->push('Job Install Equipments', route('job.edit.install','job'));
});
In the above code we passed $job and $title through the callback function.
//Point2 routes/web.php
Route::get('/job/edit/{job}', 'JobController#edit')->name('job.edit');
Route::get('/job/install-equipments/{job}', 'JobController#installEquipments')->name('job.edit.install');
We give a name to the route through the name method , Laravel 5.4, which allow us to define the routes correctly in Point1.
The last step, is what you have do in the view file. Here I will show you the last one regarding /job/install-equipments which should be rendered in the breadcrumb as the last element and its parent is job/edit with parameter job which handles the primary key id
//install.equipments.blade.php
#extends('layouts.main')
#section('content')
{!! Breadcrumbs::render('job.edit.install',$job->id, __('Edit').': '.$job->title) !!}
The above will render a breacrumbs look like:
Home / Job / Edit: title of
job / Job Install Equipment
The required parameters that handles breadcrumbs render are supplied un the above render method i.e through $job->id and __('Edit').': '.$job->title) , the last just adjusting the text and it could be done inside the callback function of breadcrumbs routes.
I have a master template which has a section for breadcrumbs (using davejamesmiller/laravel-breadcrumbs)
#yield('breadcrumbs',,Breadcrumbs::render())
In my departments.blade.php I then overwrite the breadcrumbs to dynamically load in my department names
#section('breadcrumbs')
{{ Breadcrumbs::render($department) }}
#stop
I get the error
ErrorException
Trying to get property of non-object (View: /var/www/vhosts/test/app/views/layouts/master.blade.php) (View: /var/www/vhosts/test/app/views/layouts/master.blade.php)
Now what I'm not sure of is if this is a "feature" of laravel to render the master and then do replacements or whether this is something stupid I'm doing.
I am using Laravel 4 and blade templates, and running into an issue when I try and extend a template.
In my layout I have
#yield('content')
and in my page I have
#section('content')
Welcome {{ $name }}
#stop
which works fine, I've created another page very similar to my first, and just want to change override the admin content section. The other sections in the template are fine.
so I extend my page, and do
#section('content')
Hello!
#stop
I get an undefined notice with the $name variable.
I tried
#section('content')
Hello!
#overwrite
and same deal, I get the notice error.
I checked my controller and it IS using the correct template. I am not calling #parent so I don't understand, how can I overwrite a section in a template with out notice errors?
Blade layouts work their way up the tree to the route or master view before rendering any of the children. Thus, nested views that extend others must always have their parent rendered before they are. As a result, parent views that contain sections will always be rendered prior to the child.
To overcome the problem you are experiencing it is a good idea to only ever nest pages that don't overwrite parents sections that contain variables, as the parents content will always be rendered before the child.
As the above ideal can't always be adhered to or a parents section content is still required, a good alternative method would be to use view composers. View composers give you an opportunity to declare variables for any specific view whenever they are rendered.
View::composer(array('pages.admin'), function($view)
{
$view->with('name', Auth::user()->username);
});
Another alternative would be to use a view creator. Creators are fired the moment a view is instantiated rather than rendered. This method allows you to overwrite the variable should you so wish prior to the view being rendered.
View::creator(array('pages.admin'), function($view)
{
$view->with('name', Auth::user()->username);
});
You can read up more about these methods in the documentation here. (Or here for the Laravel 5 documentation.)
I can't guarantee support for Laravel 4 but for those looking for a solution that works in Laravel 5.5 (and probably a fair bit further back – hard to check) is to define the variables you need when #extending.
E.g. in the example in the question:
#extend('my.parent.view', ['name' => ''])
This approach can be especially useful if the data needed is available to the child-view, but under a different name.
E.g. if a parent-view needed a $parent variable, but the child view only has a $child variable which has a property referencing the parent, you might do:
#extend('my.parent.view', ['parent' => $child->parent])
I am not sure if this is a bug or intentional, but it seems like Laravel renders the variables before interpreting blade instructions.
The workaround would be this:
views/layouts/testlayout.blade.php:
<html>
<body>
#yield('sidebar', 'This is the master sidebar. {{ $name }}' )
<div class="container">
#yield('content')
</div>
</body>
</html>
actual view: views/test.blade.php
#extends('layouts.testlayout')
#section('sidebar')
No variable in the child
#stop
#section('content')
This is a child content
#stop
This prevents the variable $name to get rendered if there is a section with that name in the actual view. It seems like this is the approach if the content in the layout file contains a variable
In your page try this :
#section('content')
#hasSection('content')
#yield('content')
#else
Welcome {{ $name }}
#endif
#stop
And read this post for more inspiration https://laracasts.com/discuss/channels/laravel/laravel-blade-layouts-inheritence-problem
I found an easy solution for this problem :)
Just add the # symbol before the variable/method you call in the parent view. If there is an error (notice/warning) PHP will ignore that and continue the execution.
It's not perfect, but save us to code view/composers.
Hope this help!
I was wondering if it is possible to nest templates inside of templates in Laravel 4. I would like to have a master wrapper template that would include things like the doctype, header and footer and then be able to load in templates into the master templates body section.
This would give me the flexibility of having a nested template for my application pages without having to duplicate code while giving me the ability to use the master template for non-application pages.
Can someone please provide an example as to how this would be done using blades templating engine? Is it possible to pass in a value from the router and then have that value be pushed down to your nested template?
EDIT:
Here is my code for index.blade.php
#extends('layouts.master')
#section('title')
Some page
#endsection
#section('content')
#include('layouts.app')
#endsection
You can try this for multiple level nesting
//index.blade.php
#extends('layouts.master')
#section('title')
#parent
:: new title
#stop
#section('content')
<p>some static contents here</p>
#stop
//app.blade.php
#section('content')
#parent
<p>Add here what ever you want to add</p>
#stop
now either from your Route or Controller you can nest the index and app, ex-
return View::make('index')->nest('content','layouts.app');
And in case you want to pass data to child view you can do this by passing the data as third parameter to nest()
return View::make('index')->nest('content','layouts.app',$data);