Acorn, Plugins, and Service Providers without Bedrock

Note: Playing with Acorn as a plugin in a stock WP install that has a Sage10 theme— no bedrock, no root composer.

I know we’re able to add explicit service providers through the main theme’s config, however it seems backwards to have to do that to add features from a plugin. Since the company uses the Sage10 Parent, with client level child themes, and multiple plugins, for many clients. Where the base Sage10 parent theme can not be used to control all of the plugin views for every plugin added.

In this case, what is the best method of instantiating a plugin with a ServiceProvider? I did not get results adding the provider in “extras” in composer, and wp acorn package:discover did not list it.

Attempted Solution

I feel like my current implementation is weak but here’s a run down in pseudocode.
ATM I am hooking into the bootstrap filter:

add_filter('acorn/bootstrap', function ($classes) {
    return [AddPluginServiceProvider::class] + $classes;
});

Which looks something like:

class AddPluginServiceProvider
    public function bootstrap(Application $app)
    {
        $app->register(new PluginServiceProvider($app));
    }
}

Which works and allows me to add my plugin views to the theme’s view list but seems clunky.

Thanks for any tips on improving this solution!

And for visitors from the future, this works with Acorn v2.0.5 and Sage v10.1.4.

Few different routes you could go with this.

If you have any trouble getting any of these to work, try running wp acorn optimize:clear to see if that resolves your issue.

add composer.json extra config to your plugin

You mentioned that you tried adding it to “extras”, but the correct property is “extra.” This should work, and if it’s not loading even after clearing cache, then I’d recommend that you enable logging to see if Acorn is automatically recovering from a failure to boot the provider.

The other thing that this requires is package to be referenced in vendor/composer/installed.json (i.e., run composer install) and the plugin needs to be activated.

wp-content/plugins/my-awesome-plugin/composer.json

{
  "extra": {
    "acorn": {
      "providers": [
        "My\\Awesome\\Plugin\\ServiceProvider"
      ]
    }
  }
}

Add it to config/app.php

I know you mentioned that you’re not too keen on doing it this way, but for others out there who come across this discussion, this is the easiest and most reliable way to do it.

config/app.php

return [
    // ...
    'providers' => [
        // ...
        \My\Awesome\Plugin\ServiceProvider::class,
    ]
];

Access Application::register() directly.

You can access Acorn anytime after it boots.

wp-content/plugins/my-awesome-plugin/my-awesome-plugin.php

add_action('after_setup_theme', function () {
    \Roots\app()->register(\My\Awesome\Plugin\ServiceProvider::class);
}, 20);

Use the bootloader() callback

This will work fine for now, but it will break with Acorn v3.

wherever-you-want.php

\Roots\bootloader(function ($app) {
    $app->register(\My\Awesome\Plugin\ServiceProvider::class);
});
4 Likes

You mentioned that you tried adding it to “extras”, but the correct property is “extra.” This should work…

I just added the acorn bit. I already have bedrock-esque base extras for testing so just needed the acorn provider snippet which I copied from one of Log1x’s plugins. But, clearly did something wrong!

After de-implementing the example solution, and refreshing the composer installs this method is working.

What might have been my issue was “[a]corn is automatically recovering from a failure to boot the provider.” However, since my provider is now fine that would not be an issue anymore.

Thanks!

PS: The after_theme_setup is probably what I was hoping for as a secondary solution. Definitely saves a step accessing app() directly!

TL;DR: :man_facepalming:

1 Like