Skip to main content
In this guide you build acme/hello, a plugin that adds a settings page to the admin panel, stores a setting, and links to itself from the settings index. It takes about 15 minutes and touches every part of the plugin system you’ll use again later.

Prerequisites

  • A local Aikeedo installation with DEBUG=true and CACHE=false. See Local development.
  • Composer 2 and terminal access to the installation root.
  • Administrator access to the admin panel.

Step 1: Create the package

Plugins live in extra/extensions/{vendor}/{name}, and the directory path must match the package name.

Step 2: Write the manifest

extra/extensions/acme/hello/composer.json
See the manifest reference for every supported field.

Step 3: Write the entry class

The entry class is resolved from the container, so declare the core services you need as constructor parameters.
extra/extensions/acme/hello/src/Plugin.php
p__('nav', '...') is a gettext call with a context. Wrapping strings this way lets you translate the plugin later. See Localization.

Step 4: Add a settings page

Routes are declared with attributes on a request handler. Extending AbstractAdminViewRequestHandler puts the route under /admin and applies the admin middleware, so only administrators reach it.
extra/extensions/acme/hello/src/SettingsRequestHandler.php
The #[Inject('option.hello.greeting')] attribute reads a stored option by dot path. It resolves to null until the option exists.

Step 5: Add the template

Admin pages extend the core layout. Setting xdata to settings binds the page to Aikeedo’s settings component, which submits the form to the options API for you.
extra/extensions/acme/hello/templates/settings.twig
The field name hello[greeting] decides where the value is stored: the top-level key becomes the option hello, and the value is merged into its JSON, so the template and your handler both read it as option.hello.greeting.

Step 6: Install the plugin

The installation’s composer.json already treats extra/extensions/*/* as a path repository, so Composer finds your package by name. From the installation root:
Composer registers the package’s autoloader, which is what makes Acme\Hello\Plugin loadable.

Step 7: Activate and verify

1

Activate the plugin

In the admin panel, open Plugins, find Hello, and activate it. Activation writes extra.status back to your composer.json and clears the cache.
2

Open the settings page

Go to Settings. Your entry appears in the list, marked as a plugin addition. Open it, or go straight to /admin/settings/hello.
3

Save a value

Type a greeting and select Save changes. A toast confirms the save.
4

Confirm it was stored

Reload the page. The input keeps its value, which means the option was written and injected back into the handler.
Your plugin registers templates, a route, a menu entry and a setting.

Step 8: Use the setting

Anywhere else in your plugin, read the option the same way:
Or dispatch a command to write one:

Troubleshooting

Check that the directory path matches the package name, that type is aikeedo-plugin, and that require includes heyaikeedo/composer. An invalid manifest is skipped.
The package isn’t registered with Composer’s autoloader. Run composer require acme/hello, or composer dump-autoload if it’s already required.
Routes are scanned from the directories you pass to AttributeMapper::addPath(), and the result is cached when CACHE=true. Set CACHE=false, or clear the cache from Status → Clear cache.
The namespace in addPath(__DIR__ . '/../templates', 'acme-hello') must match the @acme-hello/... reference, and boot() must have run, which means the plugin has to be active.

Next steps

Routes and request handlers

Base classes, middleware, responses and validation.

Admin settings pages

Forms, option storage and secrets.

Events and cron

React to domain events and run scheduled work.

Packaging

Ship your plugin as an installable archive.
For a complete public example, see the Currency Beacon plugin.