Livewire 2.2: Undefined variable slot in app.blade.php - php

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');
}

Related

Convert or Use Laravel Routes from Blade file to be used in Vue Component

How to convert a laravel/blade route to be used in a Vue.js file.
I am in the process of converting a blade template into a vue component. In the index.blade.php I have a route that is used throughout the file that looks like:
Now I want to be able to use the {{ route('product.show', ['id' => $product->id]) }} in my Vuejs file like so:
<template>
<div>
<h1>My Products</h1>
</div>
</template>
In my index.blade.php file I am calling the component like so with the routing bound:
<product :route={{ route('product.show' ['id' => $product->id]) }}"></product>
I am unsure how to use this in my Vue file though. What is the best way to do this without installing external packages or libraries?
The best way to do this is to pass the route as a property to the component.
<MyComponent :route="{{ route('product.show', ['id' => $product->id]) }}"></MyComponent>
So in your component
<template>
<div>
<h1>My Products</h1>
<a :href="route" target=""></a>
</div>
</template>
<script>
export default {
props: {
route: {
type: String,
required: true
},
},
}
</script>
If you don't want to do it this way you can simply put the static route in your js file. Usually the routes do not change often
MrEduar's answer works well for smaller cases. As the number of routes you're sharing grows, consider using something like Ziggy, which generates a JS-friendly version of your routes, along with an API for interacting with them.

How to know the controller and method name inside blade file in Laravel 6?

I am new to Laravel. I was practicing setting up a blog in Laravel 6. I have a layout.blade.php file where all the basic HTML is written. In the content section of the layout.blade file, I want to #include other blade file depending on the controller and method name.
I have 2 controllers, HomeController and ArticleController. In HomeController file, there is a method index() which returns the view home.blade.php. Again, home.blade.php #extends layout.blade.php. Now I want to know which controller and method called the view file inside from layout.blade.php file.
I want something like this-
<!-- This is layout.blade.php file -->
<html>
<head>
</head>
<body>
#if (Controller == HomeController AND Method == index)
#include('home')
#endif
#if (Controller == ArticleController AND Method == index)
#include('articles')
#endif
</body>
</html>
I didn't find any answer on Google. I got some questions in StackOverflow, but they have very confusing answers and those versions are older also.
Thank you.
EDIT 1:
Due to the low reputation score, I cannot reply in comments. As I am
new, I know some basic tags of blade, so if there is any other
solution to achieve this, please share it with me.
I found
Get Laravel 5 controller name in view
before making this question. But I don't think it answers my
question.
I know Controller == HomeController AND Method == index is crazy.
I just illustrated what I need. I know basic #yield and #section
tags, but I don't want to use this in my case. Because, if I make a
card/home section entirely in a different file, I can call it in
other files later. If I use #yield, I will have to use #section in
different files also, which I don't want to do.
Route::currentRouteAction() method seems to be what you want. It's in the api documentation.
string|null currentRouteAction()
Get the current route action.
Return Value
string|null
https://laravel.com/api/6.x/Illuminate/Routing/Router.html#method_currentRouteAction
if I understand you correctly, you do not need to do this crazy thing like this
Controller == HomeController AND Method == index
If all you want is to setup a master page. Laravel makes it really easy.
This is the master page.
<!-- Stored in resources/views/layouts/app.blade.php -->
<html>
<head>
<title>App Name</title>
</head>
<body>
<div class="container">
#yield('content')
</div>
</body>
</html>
For other pages
<!-- Stored in resources/views/index.blade.php -->
#extends('layouts.app')
#section('content')
<p>This is my body content. From index page.</p>
#endsection
And for the controller, you just return the blade.php view file name.
public function index()
{
return view('index');
}
I run this one to know the controller. You can try it.
{{ dd(request()->route()->getAction()) }}

Laravel Blade Template With Breadcrumbs

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

Override section in a laravel blade template throwing undefined variable errors

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!

Nest templates inside of templates in Laravel 4?

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);

Categories