Criando um Módulo
v4Um módulo é um pacote completo: rotas, telas, banco de dados e arquivos próprios. É assim que a MuCRM organiza funcionalidades como loja, notícias, rankings e doações. Tudo fica dentro de app/modules/nome_do_modulo/.
Pense no módulo como um "mini-app" dentro do site. Você cria uma pasta, define as URLs, escreve a lógica no handler e monta a tela na view. O framework cuida do resto: segurança, sessão, layout e conexão com o banco.
Passo 1 — Estrutura de pastas
Crie a pasta do módulo com esta organização:
app/modules/billing/
├── routes.php # Rotas do módulo (obrigatório para URLs)
├── handlers/
│ ├── web_handler.php # Páginas públicas
│ └── admin/
│ └── settings_handler.php
├── models/
│ └── billing_plan.php # Tabelas do banco
└── views/
├── index.mucrm.php # Telas do módulo
└── assets/
├── css/billing.css
└── js/billing.jsPasso 2 — Model (banco de dados)
O model representa uma tabela. Fica sempre dentro do módulo, em models/. Estenda a classe schema — é o padrão da MuCRM v4.
<?php
namespace MUCRM\modules\billing\models;
use MUCRM\engine\database\schema;
class billing_plan extends schema
{
protected string $table = 'mucrm_billing_plans';
protected string $primaryKey = 'id';
protected array $fillable = ['name', 'description', 'price', 'active'];
}Saiba mais em Models.
Passo 3 — Handler (lógica da página)
O handler é quem recebe a requisição, busca os dados e escolhe qual tela mostrar. É o equivalente ao "controller" — mas na MuCRM chamamos de handler.
<?php
namespace MUCRM\modules\billing\handlers;
use MUCRM\engine\support\{request, responder};
use MUCRM\http\handler;
use MUCRM\modules\billing\models\billing_plan;
class web_handler extends handler
{
protected string $layout = '_layouts.app';
public function index(request $req, responder $res)
{
$plans = billing_plan::where('active', 1)->order_by('name')->get();
return $this->view('Billing.index', compact('plans'))
->title('Planos');
}
}$layout— casca da página (ex:_layouts.appoupanels.admin._layouts.app)$this->view('Billing.index')— renderizaviews/index.mucrm.phpdo módulo->title('Planos')— define o título da aba do navegador
Passo 4 — View (a tela)
Arquivo views/index.mucrm.php. É HTML com PHP simples — use <?= e($var) ?>para exibir dados com segurança.
<?php foreach ($plans as $plan): ?>
<article class="card">
<h2><?= e($plan->name) ?></h2>
<p><?= e($plan->description) ?></p>
<span><?= e($plan->price) ?> moedas</span>
</article>
<?php endforeach; ?>Passo 5 — Rotas (URLs)
O arquivo routes.php diz qual URL chama qual método do handler. É carregado automaticamente quando o site inicia — não precisa registrar em outro lugar.
<?php
use MUCRM\engine\support\facades\uri;
use MUCRM\http\middlewares\user_auth;
use MUCRM\modules\billing\handlers\web_handler;
uri::get('/billing', [web_handler::class, 'index'])->name('billing.index');
uri::group(['middleware' => [user_auth::class]], function () {
uri::post('/billing/subscribe', [web_handler::class, 'subscribe'])
->name('billing.subscribe');
});Detalhes em Rotas de Módulos eRotas HTTP.
Passo 6 — Autoload
Depois de criar classes novas, rode no terminal:
composer dump-autoload -oBônus — Widget na home com plug()
Quer mostrar um pedaço do módulo em outra página (ex: últimos planos na home)? Crie um método que retorna dados e chame com plug() na view do tema.
// Handler que retorna DADOS (não uma página inteira):
public function latest()
{
return billing_plan::where('active', 1)->limit(3)->get();
}
// Na home do tema:
<?php $plans = plug('billing::web@latest'); ?>
<?php foreach ($plans as $plan): ?>
<span><?= e($plan->name) ?></span>
<?php endforeach; ?>Checklist final
- Pasta em
app/modules/nome_modulo/ - Namespace
MUCRM\modules\nome_modulo\... - Handler estende
MUCRM\http\handler - Model estende
schemae fica emmodels/ - Views com extensão
.mucrm.php routes.phpcomuri::get/post/...- CSS/JS em
views/assets/— veja Assets