Difference between #aware and #props directives in laravel 9 - laravel

The #aware Laravel Blade template directive was introduced in Laravel 8, but I still don't understand what it does differently from the already existing #props directive.
For instance, if I use a Blade template like this:
<x-view-content :page="$page ?? ''" />
and the component used above is defined in views/components/view-content.blade.php like this:
#aware(['page'])
<div>
{{ $page }}
</div>
I get the page successfully rendered inside the component. However, replacing #aware(['page']) with #props(['page']) produces the same result.
I would like to know what the differences between them are.

#aware is for accessing data from a parent component where you have #props. You can find here all relevant information. In your case you don't have child component.

Related

Laravel: Conditional rendering with dynamic components not working

I want to have a dynamic component that can conditionally render child dynamic components.
Let's imagine having a parent component Parent.php
In my view blade this is then called something like this
(Of course, this wouldn't be parent but a method that resolves that name)
<x-dynamic-component :elements="$elements" component="parent" />
Within that component, based on the $elements variable, it should render other dynamic components
$element could be for instance Radio.php or Checkbox.php
So what I'm trying to do within my parent component is this:
<div>
#foreach($elements as $element)
#if($element->hasDynamicComponent())
<x-component-dynamic :component="$element->getComponentName()" />
#endif
#endforeach
The problem is, that Laravel nevertheless parses those lines regardless of this if statement.
I'm getting the following error message:
Unable to locate a class or view for component [component-dynamic]. (View: .....)
This is because $element->hasDynamicComponent() is false and therefore getComponentName is empty. Of course Laravel cannot resolve a component without a name.
The thing is Laravel shouldn't even try to resolve this, because hasDynamicComponent is false.

How to render multiple livewire component as string?

I have multiple livewire components e.g. opd.patient-count, opd.visit-count, opd.checkup-count and so on. I would like to store these components name into database then call by user role. Anyway, It does not work once I tried as below.
foreach ...
echo '<livewire:opd.patient-count />';
endforeach ...
Any advice or guidance on this would be greatly appreciated, Thanks.
As I understand your problem, You can achieve using this syntax instead
#foreach($components as $eachComponent)
#livewire($eachComponent,['componentData' => $data])
#endforeach
in this code above, the component name is assigned accordingly using a blade #foreach directive and iterate over each element and make the component.

New component not found

I've a problem with custom component for email in Laravel 5.8
I'have create a new file : /resources/vendor/mail/html/training.blade.php
In my view file (folder : /resources/views/emails/training/) i have :
#component('mail::training')
instead of :
#component('mail::message')
But i've got this error :
View [training] not found ...
Note : if i edit a file like : /resources/views/emails/header.blade.php
I see the modification in the email.
I miss somethings how create a new component ?
Thanks.
EDIT :
I found the solution. You need to duplicate the file in each dir :
/vendor/mail/html AND /vendor/mail/text
Every vendor component is registred in the serviceProvider of that package. If you want to make your own blade component follow the documentation.
https://laravel.com/docs/5.8/blade#components-and-slots
Components and slots provide similar benefits to sections and layouts; however, some may find the mental model of components and slots easier to understand. First, let's imagine a reusable "alert" component we would like to reuse throughout our application:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
The {{ $slot }} variable will contain the content we wish to inject into the component. Now, to construct this component, we can use the #component Blade directive:
#component('alert')
<strong>Whoops!</strong> Something went wrong!
#endcomponent
if you put your component in "views" folder and remove the prefix 'mail::' in #component('mail::training') it should work successfully.
to make Laravel reads views from "views/vendor/mail/html" you can simply add this line resource_path('views/vendor/mail/html') to view.php in config folder.

How to include blade tempate in another file?

I have two fiels:
landing.blade.php
And block comments.blade.php.
How can I include comments.blade.php inside landing.blade.php?
You can include one blade template into other by following syntax:
Including Sub-Views
#include('view.name')
You may also pass an array of data to the included view:
#include('view.name', array('some'=>'data'))
For more details you can follow:
https://laravel.com/docs/5.0/templates
Thanks
According to the documentation you need to #include it:
landing.blade.php:
<div>
Some content
#include('comments', ['comments' => $comments])
</div>
simple way,
if landing.blade.php and comments.blade.php are on the same directory, let's assume they are both on ressource/view
So on landing.blade.php you can write #include('comments')

Nesting Layouts within Layouts in Laravel 5

My question is about nesting layouts in Laravel. I am trying to do so as seen below, which works in most cases but produces unwanted results in others.
\\MasterLayout
--code for header, navbar, etc.
#yield('content)
#yield('scripts)
\\SubLayout
#extends('layouts.MasterLayout')
#section('content')
<div>
#yield('sidebar')
#yield('main')
</div>
#endsection
#section('scripts')
<script>scripts needed in all the relevant views</script>
#yield('scripts.sub')
#endsection
\\Views
#extends('layouts.SubLayout')
--some code
#section('sidebar')
--sidebar code
#endsection
#section('main')
--main code
#endsection
#section('scripts.sub')
<script>scripts only needed in this view</script>
#endsection
In my own case, I have a further layer of nesting (a subsublayout). My controller simply redirects to the view without doing anything special. E.g.,
public function start()
{
return view('createproject/start');
}
This works pretty well in many cases, but there are some problems. For example, I can't simply include php files in the SubLayout that are needed in the views. Those includes have to go in the file in which they are being used in order to gain access to their functions. Also, placing <div></div> tags directly outside an #yield sometimes has a different effect than placing them directly inside the #section to which the #yield points. Also, while the pages work, I have gotten some strange warning messages such as that I have declared DOCTYPE multiple times or not at all, when neither is true as far as I can tell. So while the method of nesting seems to work, it's a bit unwieldy and I'm not convinced it represents best practice.
Hence, my question for the community is this: Is my suggested method of nesting layouts generally appropriate (perhaps with some caveats that address the problems I'm having) or does it exhibit some fundamental problem/confusion?
There is a related Stack Q&A that I've found here: Laravel multiple nested views but the nest() function referenced there is no longer discussed in more recent versions of the Laravel documentation (have I missed it?), so I wonder if it's still needed.
you can use components and slots for that
components-and-slots

Resources