I have an issue with the new x- blade syntax.
This is working.
<x-contact-form/>
This is not.
<x-{{ $model->component }}/>
Can I achieve it somehow, to name it dynamically from database?
I guess this is not possible as the template would need to be parsed twice.
You can try this:
1 - Add a sample route
~php
// ./routes/web.php
Route::view('sample', 'sample');
~
2 - Create a base component
~bash
$ php artisan make:component Component
~
3 - Accept the base view as a prop
~~~php
// ./app/View/Components/Component.php
namespace App\View\Components;
// need to rename as our component is named Component
use Illuminate\View\Component as BaseComponent;
class Component extends BaseComponent
{
public $is;
public function __construct($is)
{
$this->is = $is;
}
public function render()
{
return "components.{$this->is}";
}
}
~~~
4 - Create the sample blade file (./resources/views.blade.php)
~~~blade
World
There
~~~
5 - Create the expected components files (./resources/components/hello.blade.php)
~~~blade
~~~
and (./resources/components/hi.blade.php)
~~~blade
~~~
6 - Navigate to the /sample route and check the results.
As you can see we don't use the generated component blade files we are determining the template when the component renders, you can remove it (./resources/views/ components/component.balde.php).
The big con is that you might not be able to use class-based components dynamically (at least not with this approach).
The good part is that for simple components you don't need to know beforehand all of them, just add the needed view into the ./resources/views/components directory.
Also, please consider posting this kind of question in one of the support forums:
In general Laravel team advises to use this issue tracker for reporting bugs with the library itself.
Reference: https://github.com/laravel/framework/issues/31729#issuecomment-594578603
I like this approach with all of it's limitations. That's enough for me now. Thank you for your quick answer.
Or maybe this approach (in my case):
@switch($model->component)
@case('contact-form')
<x-contact-form />
@break
@case('faq')
<x-faq />
@break
@endswitch
Or maybe this approach (in my case):
@switch($model->component) @case('contact-form') <x-contact-form /> @break @case('faq') <x-faq /> @break @endswitch
I believe this would work but might quickly grow out of scale. I'd opt for the dynamic return value on the Component::render() method.
I've experimented using @switch before writing my answer. The problem I found is forwarding attributes ( style="..."), which worked well with class-less components, but not with class-based components. I don't know if it is intended behavior or something that can be fixed.
Also, as noted by @ryangjchandler , the approach I proposed has the advantage of not needing a long switch block if you have many derived components and reduces maintenance when you need to add new components.
<x-component is="hi" style="color: green">
There
</x-component>
On second tought it doesn't solve my main problem.
The same issue appears:
<x-component is="{{ $model->component }}" style="color: green">
There
</x-component>
Dynamic attributes in components have a special syntax:
https://laravel.com/docs/7.x/blade#passing-data-to-components
Try this:
~php
There
~
EDIT updated docs link to correct section
Also, per docs guidelines:
https://laravel.com/docs/7.x/contributions#support-questions
And also shown when you create a new issue, please consider posting this kind of question in one of the support forums:
In general Laravel team advises to use this issue tracker for reporting bugs with the library itself.
Reference: https://github.com/laravel/framework/issues/31729#issuecomment-594578603
Shouldn鈥檛 the old @component syntax still work as well?
My understanding of BladeX and it鈥檚 subsequent implementation in Laravel 7 has been that it works as a preprocessor, but still uses the old component syntax under the hood.
Shouldn鈥檛 the old
@componentsyntax still work as well?My understanding of BladeX and it鈥檚 subsequent implementation in Laravel 7 has been that it works as a preprocessor, but still uses the old component syntax under the hood.
Correct. The old @component syntax does still work for regular Blade components. The new tag compiler converts the tag into the old style syntax behind the scenes also.
Can find that inside of the ComponentTagCompiler class I believe.
@avanember In that case you should be able to just use:
@component($model->component)
@endcomponent
Unless I misunderstood how the parser works.
The same is likely not possible with the tag component syntax as it relies on a regexp to efficiently match things. (And the idea to use x- as prefix to efficiently find all components is genius)
Most helpful comment
Shouldn鈥檛 the old
@componentsyntax still work as well?My understanding of BladeX and it鈥檚 subsequent implementation in Laravel 7 has been that it works as a preprocessor, but still uses the old component syntax under the hood.