Skip to content

[9.x] Discover anonymous Blade components in other folders - #41637

Merged
taylorotwell merged 8 commits into
laravel:9.xfrom
ralphjsmit:blade-component-directories
Apr 7, 2022
Merged

[9.x] Discover anonymous Blade components in other folders#41637
taylorotwell merged 8 commits into
laravel:9.xfrom
ralphjsmit:blade-component-directories

Conversation

@ralphjsmit

@ralphjsmit ralphjsmit commented Mar 23, 2022

Copy link
Copy Markdown
Contributor

Do you like anonymous components? (I like them a lot) And did you ever want to also 'enable' anonymous components for directories other than resources/views/components?

For example, resources/views/admin and resources/view/frontend? And autodiscover the components like <x-admin::component.name?

This PR introduces exactly that. It allows the developer to register a directory and a prefix, which would allow to use the files in those directories as anonymous components. This would get rid of things like @include and provide developers with the ability to use the attribute bag everywhere.

Example

In your service provider, you can register the directories you want to enable discovery for:

// Prefix <x-admin::your.component> and folder: resources/views/admin 
Blade::anonymousComponentNamespace('admin', 'admin'); 

// Second parameter is nullable and defaults to first parameter, so this means the same:
Blade::anonymousComponentNamespace('admin'); 

// Prefix <x-frontend.auth::your.component> and folder: resources/views/public/auth
Blade::anonymousComponentNamespace('public/auth', 'frontend.auth');

Now you can use this in your Blade files like this:

<!-- Looks for resources/views/admin/dashboard/widget.blade.php OR resources/views/admin/dashboard/widget/index.blade.php -->
<x-admin::dashboard.widget>

<!-- Looks for resources/views/public/auth/login/form.blade.php OR resources/views/public/auth/login/form/index.blade.php -->
<x-frontend::login.form>

I added some additional inline comments to the compiler-file just for clarity, but feel free to trim this down however you want.

I took inspiration from the original PR that introduced anonymous components (#31363). I'm a slightly unsure how this should be tested, perhaps @driesvints could give me a hint?

This is a feature I wanted for a long time and I hope this will be useful to many developers! The syntax is in line with package components.

Comment thread src/Illuminate/View/Compilers/ComponentTagCompiler.php
@taylorotwell

Copy link
Copy Markdown
Member

Do you have the ability to write tests for this?

@taylorotwell
taylorotwell marked this pull request as draft March 25, 2022 15:15
@ralphjsmit

Copy link
Copy Markdown
Contributor Author

@taylorotwell Yes, if you're okay with the idea.

@ralphjsmit
ralphjsmit marked this pull request as ready for review April 1, 2022 14:45
@ralphjsmit

Copy link
Copy Markdown
Contributor Author

I just added test coverage for this and applied the code style!

@taylorotwell

taylorotwell commented Apr 6, 2022

Copy link
Copy Markdown
Member

@ralphjsmit

I think one thing that gives me pause about this how it behaves when used via a package.

I could see package maintainer's using anonymous components and wanting to use this feature, but how would they use it? It seems to always assume the "directory" is a dot path relative to the application's main view directory.

@ralphjsmit

ralphjsmit commented Apr 7, 2022

Copy link
Copy Markdown
Contributor Author

@taylorotwell thank you for your comment!

I just tested this with a package from myself and it works out of the box when a package author uses his usual package:: prefix as the directory.

Consider the following example, where I'm loading everything in the resources/views/media directory of a package with prefix media-library:

Blade::anonymousComponentNamespace('myPrefix', 'media-library::media');
{{-- Classic, regular way: --}}
@include('media-library::media.empty-state')

{{-- New way, if authors choose for it --}}
<x-myPrefix::empty-state></x-myPrefix::empty-state>

{{-- Outputs the same component twice --}}

The point is that is doesn't really assume a view relative to the application's view directory. It mainly tries to construct a correct view name, whether or not it contains the package:: prefix.

We're just replacing myPrefix:: with media-library::media and see if that yields a valid view. So this works for both packages and the main application.

@taylorotwell
taylorotwell merged commit 5686d44 into laravel:9.x Apr 7, 2022
@taylorotwell

Copy link
Copy Markdown
Member

Thanks!

I decided to swap the order of directory and prefix - I felt that was a bit more consistent with the componentNamespace method which accepts "location" first and then "prefix".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants