Skip to content
This repository has been archived by the owner on Jul 16, 2021. It is now read-only.

Rendering Blade Components Outside of Views #2649

Open
godismyjudge95 opened this issue Jun 24, 2021 · 1 comment
Open

Rendering Blade Components Outside of Views #2649

godismyjudge95 opened this issue Jun 24, 2021 · 1 comment

Comments

@godismyjudge95
Copy link

godismyjudge95 commented Jun 24, 2021

Sometimes one might have need of rendering a blade component directly from say a controller or maybe a customized component instance from a model method.

For example:

public function getIconAttribute()
{
    return view('components.icon', ['name' => $this->icon_name]);
}

This works for simpler components; however, if the component looks like the following, it fails:

@props(['name'])
<i {{ $attributes->merge(['class' => 'icon']) }} data-icon="{{ $name }}"></i>

The reason why this fails is because the $attributes variable is never instantiated when the component is rendered directly.
To get around this one might just pass an attribute variable from the view method, however this also fails due to the attributes variable needing to be an instance of ComponentAttributeBag.

My current solution - albeit a poor one - is to have a helper method instantiate an AnonymousComponent and then proceed to render that:

function view_component(string $view, array $slot, array $attributes): View
{
    $component = new AnonymousComponent($view,  compact('slot'));
    $component->withAttributes($attributes);

    return view($component->render(), $component->data());
}

It would be nice if there was a built in solution to this use case and one that also allowed for rendering of class based components.

I realize this might be a really niche case, but I have not found any other way to re-use the code from the blade components outside a view file.

@tobyzerner
Copy link

tobyzerner commented Jul 2, 2021

Keen for this. What would we want the API to look like? I'm not sure it warrants a whole new helper, but maybe a new method on the Illuminate\View\Factory class, so it could be used like this:

public function getIconAttribute()
{
    return view()->component('icon', ['name' => $this->icon_name]);
}

This new Illuminate\View\Factory::component($name, $attributes, $slots) method would ultimately return a string via the existing renderComponent method.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants