Ir para o conteúdo
Bondry

Anatomia de um módulo e module.json

O layout de pasta, todo campo do manifesto, e os métodos de ciclo de vida que o kernel chama.

Um módulo é um diretório autocontido, carregável em tempo de execução e instalável a partir de um zip. Os módulos de fábrica usam exatamente esse contrato.

Layout de pasta#

Código
modules/directory/
  module.json                 manifesto (obrigatório)
  src/
    DirectoryServiceProvider.php
    Models/
    Http/Controllers/
    Http/Requests/
    Support/
  database/
    migrations/               as tabelas do módulo
    seeders/
  resources/
    views/                    Blade, sobrescrevível por um tema
    lang/                     as traduções do módulo
    assets/                   css e js, JÁ COMPILADOS
  routes/
    web.php
    admin.php
  config/directory.php

O manifesto#

JSON
{
  "name": "Directory",
  "slug": "directory",
  "version": "1.2.0",
  "description": "A configurable catalogue.",
  "author": { "name": "You", "url": "https://example.com" },
  "requires": {
    "bondry": ">=1.0 <2.0",
    "php": ">=8.2",
    "extensions": ["gd"],
    "modules": { "payments": ">=1.0" }
  },
  "provider": "Modules\\Directory\\DirectoryServiceProvider",
  "provides": {
    "permissions": ["directory.view", "directory.manage"],
    "hooks": ["profile.tabs", "admin.menu", "search.sources"]
  },
  "settings": "admin.directory.settings",
  "assets": { "css": ["assets/directory.css"], "js": ["assets/directory.js"] },
  "parent": null,
  "tested_up_to": "1.4.0",
  "official": false,
  "licensing": { "product_slug": "your-directory" }
}
Campo Significado
slug A identidade. [a-z0-9-], único, e nunca muda entre versões.
version Semver. É o que dispara onUpdate.
requires Faixas semver. O kernel recusa a instalação quando não são atendidas.
provider A classe raiz. Ela precisa existir e estender o provider base.
provides.permissions Registradas na matriz de grupo na instalação.
settings Um nome de rota. A lista de módulos aponta para ela quando o módulo está ativo.
parent O slug do módulo que este estende. Ausente significa que estende o core.
tested_up_to A versão mais nova do core contra a qual você testou.
official Só é aceito para pacotes assinados por nós.
licensing.product_slug Presente só num módulo pago. Veja License API.

O service provider#

Seu provider estende Bondry\Kernel\Modules\ModuleServiceProvider e implementa o ciclo de vida:

PHP
interface ModuleContract
{
    // Toda requisição, só enquanto o módulo está ativo:
    public function register(): void;   // bindings do container
    public function boot(): void;       // rotas, views, migrações, traduções, hooks

    // Chamado pelo instalador em tempo de execução, não a cada requisição:
    public function onInstall(): void;
    public function onUninstall(bool $purge): void;
    public function onEnable(): void;
    public function onDisable(): void;
    public function onUpdate(string $from, string $to): void;
}

boot() é onde você chama loadRoutesFrom, loadViewsFrom com seu namespace, loadMigrationsFrom, loadTranslationsFrom e registra seus hooks.

register() roda antes de qualquer coisa ser resolvida: só bindings, sem banco de dados.

Aviso boot() roda em toda requisição. Qualquer coisa custosa ali é um custo que seus compradores pagam a cada visualização de página, em hospedagem compartilhada.

Views e o tema#

Registre suas views com um namespace:

PHP
$this->loadViewsFrom(__DIR__.'/../resources/views', 'directory');

Renderizar directory::item.show então resolve primeiro pela cadeia de tema, então um comprador pode sobrescrever qualquer tela do seu módulo a partir do tema dele sem editar seus arquivos. Veja Temas.

Fluxo de instalação#

O que o painel faz com o seu zip, em ordem:

  1. abre-o num diretório temporário isolado;
  2. module.json e valida o schema;
  3. verifica requires e qualquer conflito de slug ou versão;
  4. verifica a assinatura quando official está definido;
  5. move para modules/<slug>/ e roda onInstall(), ou onUpdate() quando já havia uma versão presente;
  6. publica os assets em public/modules/<slug>/;
  7. registra na tabela de módulos;
  8. limpa os caches de rota, view e config.