Skip to content

[6.x]: Plugin Path Adjustments#18747

Open
AugustMiller wants to merge 11 commits into6.xfrom
plugin-paths
Open

[6.x]: Plugin Path Adjustments#18747
AugustMiller wants to merge 11 commits into6.xfrom
plugin-paths

Conversation

@AugustMiller
Copy link
Copy Markdown
Contributor

@AugustMiller AugustMiller commented Apr 23, 2026

Proposing a slight re-restructuring of the recommended plugin package…

  • config/ is now a top-level directory;
  • resources/ is now a top-level directory, and this is standardized by a new Plugin::getResourcesPath() method;
  • Template roots are registered based on the new resources/ location;
  • Icons and icon “masks” (InteractsWithCp) are now expected to be in the resources/ directory (not floating, adjacent to the base plugin class);
  • The new HasFrontendAssets::getPublishablePath() method consolidates a number of instances in which we were building paths in the public/vendor/ dir;
vendor/org/package-name/
    src/
        Plugin.php
        ...
    config/
        plugin-name.php
    resources/
        views/
        templates/
        build/
        js/
        css/
        ...

The main issue I see here is that if a plugin’s base class is at the top level of its package (not in a src/ directory), we'll be traversing above its root while looking for config and resources. (This is a preexisting assumption that we make elsewhere in the plugin architecture!) If a plugin has this structure, it should override getResourcesPath().

Current implementation looked in a directory at the same level as the base plugin class (typically `src/config/`
(This is unrelated to the other *resources* path changes; just tidying up!)
… use when registering scripts + styles.

Vite still has its own URL generating scheme…? 🤷

This makes it easier to generate URLs to publishable assets:

```php
public function register(HtmlStack $htmlStack): void
{
    $path = Plugin::getInstance()->getPublishablePath('js/editFs.js');

    $htmlStack->jsFile(asset($path));
}
```

If it's not too ambiguous, we could make an additional helper akin to `craftAsset()`… say:

```
pluginAsset('handle', 'js/editFs.js');
// -> https://my-project.ddev.site/vendor/craftcms/aws-s3/js/editFs.js
```
@AugustMiller AugustMiller requested a review from riasvdv April 23, 2026 18:07
@riasvdv
Copy link
Copy Markdown
Contributor

riasvdv commented Apr 24, 2026

Seems good to me, we’ll have to make sure the structure of existing plugins still works to make it easier on devs porting their plugins

@brandonkelly
Copy link
Copy Markdown
Member

@AugustMiller can you review the failing checks?

@AugustMiller
Copy link
Copy Markdown
Contributor Author

We’re already requiring that templates be moved into a resources/ folder, so that shouldn’t be any additional work.

Plugin config files have historically only provided as stubs for developers to copy into their local project, not for plugins to interact with… and while this is technically not "compatible" with that convention, discovery + publishing of config files is a new feature in 6.x.

The only additional "breaking" change ends up being that icon.svg and icon-mask.svg need to be relocated to the top-level resources/ directory!

(Re: checks—sorry for all the noise. I will spend some time next week getting them to run locally.)

@AugustMiller
Copy link
Copy Markdown
Contributor Author

I don't think I can get the failing test to pass, because it's only doing a string comparison. Is it appropriate to use realpath() in test in situations like this?

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