Skip to content

Plugins ​

Un plugin és la manera que té un paquet de Composer d'afegir pàgines, scripts, fulls d'estil, textos i rutes a un panell, sense que l'aplicació hagi de copiar res. L'aplicació decideix a quins panells l'activa. Disponible des de la 1.2.

php
Panel::make('admin')
    ->plugins([BillingPlugin::make()])

Un mateix plugin no es pot registrar dues vegades al mateix panell: Arrel llança una excepció.

Escriure un plugin ​

Un plugin estén Arrel\Plugins\Plugin. Només cal id(); la resta de mètodes retornen una llista buida si no els sobreescrius.

php
use Arrel\Pages\CustomPage;
use Arrel\Plugins\Plugin;

final class BillingPlugin extends Plugin
{
    public static function make(): self
    {
        return new self;
    }

    public function id(): string
    {
        return 'billing';
    }

    public function customPages(): array
    {
        return [
            CustomPage::make('billing', __('billing::billing.navigation_label'))
                ->icon('credit-card')
                ->visible(fn (): bool => Gate::allows('billing.manage')),
        ];
    }

    public function scripts(): array
    {
        return [asset('vendor/billing/billing.js')];
    }

    public function stylesheets(): array
    {
        return [asset('vendor/billing/billing.css')];
    }

    public function translations(): array
    {
        return ['title' => __('billing::billing.title')];
    }
}
MètodeQuè aporta
id()L'identificador del plugin. Fa de prefix dels textos i de les rutes.
customPages()Pàgines personalitzades, amb la seva entrada de navegació.
scripts()Scripts que el panell carrega després dels seus.
stylesheets()Fulls d'estil que el panell carrega després dels seus.
translations()Textos per al frontend.

El panell llegeix aquests mètodes cada vegada que serveix una pàgina, no quan es registra el plugin. Per això l'ordre de plugins() i customPages() a la definició del panell no importa, i __() ja retorna el text en l'idioma de l'usuari.

La pàgina ​

L'script del plugin registra la seva pàgina igual que ho faria l'aplicació, normalment amb registerMountablePage i la seva pròpia instància de Vue. Si el paquet fa servir el kit de components d'Arrel, l'incorpora al seu propi build.

Si construeixes l'script amb Vite en mode llibreria, defineix process.env.NODE_ENV. Vite no el substitueix en aquest mode, i Vue el llegeix: sense el define, l'script falla en carregar-se i la pàgina no es registra.

js
// vite.config.js
export default defineConfig({
    define: {
        'process.env.NODE_ENV': JSON.stringify('production'),
    },
    build: {
        lib: { entry: 'resources/js/main.ts', formats: ['es'], fileName: () => 'billing.js' },
    },
})

Textos ​

Els textos de translations() arriben a window.Arrel.translations amb el prefix de l'identificador del plugin. Així, title d'un plugin billing és billing.title, i mai substitueix un text del panell.

ts
const title = window.Arrel.translations?.['billing.title']

Els textos de PHP (missatges de validació, la navegació) el paquet els carrega amb loadTranslationsFrom() com qualsevol paquet de Laravel. Arrel no hi intervé.

Rutes ​

ArrelRoutes::plugin() registra les rutes del paquet amb la mateixa pila de middleware que l'API autenticada d'Arrel, inclosos arrel.middleware i arrel.authenticated_middleware. Si la teva aplicació identifica el tenant en aquest middleware, les rutes del plugin ja el tenen.

php
use Arrel\Http\ArrelRoutes;

ArrelRoutes::plugin('billing', function (): void {
    Route::get('/', [BillingController::class, 'context'])->name('context');
    Route::post('checkout', [BillingController::class, 'checkout'])->name('checkout');
});

Les rutes queden a /arrel-plugins/{id} i es diuen arrel.plugins.{id}.*: l'exemple serveix GET /arrel-plugins/billing amb el nom arrel.plugins.billing.context.

El prefix és fora de /arrel/api i del prefix del panell expressament. Les rutes d'Arrel que hi pengen capturen qualsevol camí, i l'ordre en què Laravel arrenca els paquets no està garantit: una ruta que un paquet registrés al darrere quedaria tapada.

Com a qualsevol endpoint propi, autoritza cada petició. Que visible() amagui l'entrada de navegació no impedeix que algú cridi la ruta a mà.