Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.x] allow guessing of nested component #52669

Merged
merged 7 commits into from
Oct 11, 2024

Conversation

browner12
Copy link
Contributor

sometimes components will be part of a larger component grouping, and you may wish to group those components in a folder.

as a simple example we'll use the classic "Card" component, which may be organized as such:

  • App\View\Components\Card\Card
  • App\View\Components\Card\Header
  • App\View\Components\Card\Body

to utilize these in your Blade file you would:

<x-card.card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card.card>

while this is fine, it doesn't read as nice as it could. with this commit, we can now omit the trailing duplicated word, as long as the class name matches the folder name.

<x-card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card>

we do something similar with Anonymous components

If a component at the root level exists with the same name as the folder, it will take precedence.

Tried to write a test for this, but was honestly a little lost.

sometimes components will be part of a larger component grouping, and you may wish to group those components in a folder.

as a simple example we'll use the classic "Card" component, which may be organized as such:

- `App\View\Components\Card\Card`
- `App\View\Components\Card\Header`
- `App\View\Components\Card\Body`

to utilize these in your Blade file you would:

```blade
<x-card.card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card.card>
```

while this is fine, it doesn't read as nice as it could. with this commit, we can now omit the trailing duplicated word, as long as the class name matches the folder name.

```blade
<x-card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card>
```

we do something similar with [Anonymous components](https://laravel.com/docs/11.x/blade#anonymous-index-components)
@bert-w
Copy link
Contributor

bert-w commented Sep 7, 2024

This feels like magic; how about creating App\View\Component\Card.php so you dont have this issue?

@browner12
Copy link
Contributor Author

@bert-w the point of this is to avoid that, and be able to group you components appropriately. it's the same as what we do with anonymous components.

@bert-w
Copy link
Contributor

bert-w commented Sep 7, 2024

hm this does introduce a conflict however if you have both App\View\Component\Card.php and App\View\Component\Card\Card.php defined.

@taylorotwell taylorotwell marked this pull request as draft September 9, 2024 14:25
@taylorotwell
Copy link
Member

Think we would probably want a test here.

@browner12
Copy link
Contributor Author

@bert-w correct. I addressed that in my original comment.

someone please check my work on this test. I was not able to figure out how to get it to work with the aliases

@browner12 browner12 marked this pull request as ready for review September 9, 2024 20:40
@devajmeireles
Copy link
Contributor

@browner12, I have a sincere question! Won't we have some kind of "conflict" with this PR? I mean, your example:

<x-card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card>

... won't it result in the component being understood as anonymous, possibly invoking card/index.blade.php if exists?

@browner12
Copy link
Contributor Author

From how I'm reading the class, the anonymous check happens after my check, and all the other class based checks.

Let me know if you're reading it differently.

However, you might be able to consider this a BC break (?) under the following scenario:

  • /App/View/Components/Card/Card.php
  • /resources/views/components/card/index.blade.php
  • /resources/views/components/card/header.blade.php
  • /resources/views/components/card/body.blade.php
  • /resources/views/components/card/card.blade.php

Prior to the change if you included <x-card></x-card>, it would anonymously render the index.blade.php view. After the change, it would use the Card.php class.

Although that seems like a very unlikely contrived example. I'll leave it to @taylorotwell to judge if that justifies pushing to 12.x

@taylorotwell
Copy link
Member

@browner12 do you think it's possible to make anonymous components consistent? Right now we require the anon component to be named index instead of the name of the folder. Could we support the folder name convention for anon components too or does that have bigger BC implications?

@taylorotwell taylorotwell marked this pull request as draft September 18, 2024 17:30
@browner12
Copy link
Contributor Author

@taylorotwell it definitely looks possible to support the folder name convention for anonymous components. I believe we would just need to adjust the guessAnonymousComponentUsingNamespaces and guessAnonymousComponentUsingPaths methods.

It seem unlikely, and very odd that someone would intentionally use both the "index" and "folder" name in their view folder for anonymous components as it doesn't make a ton of sense semantically.

  • /resources/views/components/card/index.blade.php
  • /resources/views/components/card/card.blade.php
  • /resources/views/components/card/header.blade.php
  • /resources/views/components/card/body.blade.php

However, I believe we would still be okay as long as we give the index view higher priority than the card view in the compiler. This would cause the <x-card> component to still render the index.blade.php view if it exists, and only render the card.blade.php view when the index.blade.php doesn't exist.

I will say I don't use the alias feature for 3rd party custom components, so I'm not sure if that would be affected any differently.

I would propose we add this feature in a separate PR if you'd like to go forward with it.

@browner12 browner12 marked this pull request as ready for review September 18, 2024 17:49
@taylorotwell
Copy link
Member

I think I would rather see it in this PR if that's alright - since I wouldn't merge this one without the other change because of the inconsistency.

@taylorotwell taylorotwell marked this pull request as draft September 19, 2024 11:20
@browner12
Copy link
Contributor Author

gotcha, fair. I'll work on that.

per @taylorotwell s request, allow users to name their root components with `index.blade.php` OR the name of the component folder.
the code changes add an extra `exists()` call, so we'll adjust our numbers here.
these are copy/paste adjustments of the existing "index" tests.
@browner12 browner12 marked this pull request as ready for review October 10, 2024 16:57
@browner12
Copy link
Contributor Author

@taylorotwell the anonymous components now support using the folder name instead of index.blade.php. so you could structure your accordion like

  • /accordion/accordion.blade.php
  • /accordion/accordion-item.blade.php

and then use it like this still:

<x-accordion>
    <x-accordion.item>Item 1</x-accordion.item>
    <x-accordion.item>Item 2</x-accordion.item>
    <x-accordion.item>Item 3</x-accordion.item>
</x-accordion>

the index.blade.php view will still take precedence if it is present, and we'll only use the folder name if the index is missing.

@taylorotwell taylorotwell merged commit 3c501ee into laravel:11.x Oct 11, 2024
31 checks passed
@taylorotwell
Copy link
Member

Thanks!

@browner12 browner12 deleted the AB-class-component-default branch October 11, 2024 15:15
timacdonald pushed a commit to timacdonald/framework that referenced this pull request Oct 15, 2024
* allow guessing of nested component

sometimes components will be part of a larger component grouping, and you may wish to group those components in a folder.

as a simple example we'll use the classic "Card" component, which may be organized as such:

- `App\View\Components\Card\Card`
- `App\View\Components\Card\Header`
- `App\View\Components\Card\Body`

to utilize these in your Blade file you would:

```blade
<x-card.card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card.card>
```

while this is fine, it doesn't read as nice as it could. with this commit, we can now omit the trailing duplicated word, as long as the class name matches the folder name.

```blade
<x-card>
    <x-card.header>Title</x-card.header>
    <x-card.body>lorem ipsum</x-card.body>
</x-card>
```

we do something similar with [Anonymous components](https://laravel.com/docs/11.x/blade#anonymous-index-components)

* minor formatting

* add test for nested default component parsing

* minor formatting

* allow using folder name for anonymous index components

per @taylorotwell s request, allow users to name their root components with `index.blade.php` OR the name of the component folder.

* fix tests

the code changes add an extra `exists()` call, so we'll adjust our numbers here.

* add some tests

these are copy/paste adjustments of the existing "index" tests.
@royduin
Copy link
Contributor

royduin commented Oct 16, 2024

This doesn't seem to work with correctly with vendor prefixes, when I've <x-prefix::input> it's working fine with vendorpackage/resources/components/input/index.blade.php but it doesn't resolve vendorpackage/resources/components/input/input.blade.php. When I add some dumps it should end up with: prefix::components.input.input but comes with prefix::components.input.prefix::input

More info: rapidez/blade-components#6

@browner12
Copy link
Contributor Author

thanks for catching that @royduin . I was curious how the vendor prefixes would do with this. Luckily it looks like it doesn't break any existing behavior, so we just need to fix it for the new behavior.

@royduin
Copy link
Contributor

royduin commented Oct 23, 2024

Hey @browner12, do we needs some docs on this? Currently it's undocumented.

@browner12
Copy link
Contributor Author

Hey @browner12, do we needs some docs on this? Currently it's undocumented.

yup, was just thinking about that today. i'll get on it

browner12 added a commit to browner12/docs that referenced this pull request Oct 23, 2024
we can now use either `index.blade.php` or `{directory}.blade.php` for our anonymous index components.

laravel/framework#52669
browner12 added a commit to browner12/docs that referenced this pull request Oct 23, 2024
taylorotwell added a commit to laravel/docs that referenced this pull request Oct 24, 2024
* new allowed filename for anonymous index components

we can now use either `index.blade.php` or `{directory}.blade.php` for our anonymous index components.

laravel/framework#52669

* Update blade.md

---------

Co-authored-by: Taylor Otwell <[email protected]>
taylorotwell added a commit to laravel/docs that referenced this pull request Oct 24, 2024
* document "index" class components

laravel/framework#52669

* formatting

---------

Co-authored-by: Taylor Otwell <[email protected]>
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.

5 participants