Crie sua primeira Extension¶
O que você vai construir¶
Uma extension chamada demo que registra uma página acessível no browser. Ao final, você tera:
- Uma classe extension registrada no framework.
- Um controller com rota
#[Route]. - Uma página Moodle renderizada em
/local/middag/index.php/democom o heading "Hello MIDDAG".
Tempo estimado: ~15 minutos.
Pre-requisitos¶
| Requisito | Versao minima |
|---|---|
| PHP | 8.2+ |
| Moodle | 4.5+ |
local_middag |
Instalado e ativo |
Você precisa de acesso ao filesystem do Moodle e de uma conta admin para acessar a página.
Passo 1: Criar o arquivo da extension¶
Crie o arquivo:
Cole o conteúdo abaixo:
<?php
declare(strict_types=1);
namespace local_middag\extensions\demo;
defined('MOODLE_INTERNAL') || exit;
use local_middag\base\extension;
class demo_extension extends extension
{
public const EXTENSION_IDNUMBER = 'demo';
public function get_icon(): string
{
return 'app';
}
}
O que esta acontecendo¶
demo_extensionestende\local_middag\base\extension, a classe-base pública do SDK.EXTENSION_IDNUMBERdefine o slug único da extension. É obrigatório.- O método
get_icon()retorna o identificador do icone exibido na UI de administração. - Não é necessário implementar
register()nemboot()por enquanto; os defaults da classe-base são suficientes.
Auto-discovery: O framework descobre extensions automaticamente pelo sufixo
_extensionemclasses/extensions/. Não é necessário registrar manualmente.
Passo 2: Criar o controller¶
Crie o arquivo:
Cole o conteúdo abaixo:
<?php
declare(strict_types=1);
namespace local_middag\extensions\demo\controller;
defined('MOODLE_INTERNAL') || exit;
use local_middag\base\controller;
use local_middag\facade\context;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class demo_controller extends controller
{
#[Route(path: '/demo', name: 'demo_index', methods: ['GET'])]
public function index(): Response
{
$this->set_require_login();
$this->set_context(context::system());
$this->set_url_from_route('demo_index');
$this->set_page_title('Demo MIDDAG');
$this->set_page_heading('Demo MIDDAG');
$this->set_page_layout('standard');
return $this->render('<h2>Hello MIDDAG</h2><p>Sua extension esta funcionando.</p>');
}
}
O que esta acontecendo¶
demo_controllerestende\local_middag\base\controller, a classe-base pública para controllers HTTP.- O attribute
#[Route](Symfony Routing) declara o path, nome e métodos HTTP aceitos. set_require_login()garante que apenas usuários autenticados acessam a página.set_context(context::system())define o contexto Moodle como system.set_page_title(),set_page_heading()eset_page_layout()configuram a$PAGEdo Moodle.render()retorna umResponsecom o conteúdo HTML embrulhado no layout Moodle (header + footer).
Descoberta de controllers: A classe-base
abstract_extensionescaneia automaticamente o diretoriocontroller/da extension duranteboot()e registra as rotas dos attributes#[Route].
Passo 3: Habilitar a extension¶
Acesse a administração do Moodle:
- Va em Administracao do site > Plugins > Plugins locais > MIDDAG.
- Localize a extension demo na lista.
- Ative a extensão clicando no toggle.
Se a extension não aparecer, limpe o cache do Moodle:
Passo 4: Testar no browser¶
Abra no browser:
Resultado esperado¶
Você deve ver uma página Moodle padrão com:
- O layout
standarddo tema ativo. - O título da página: Demo MIDDAG.
- O conteúdo: um heading
<h2>com o texto Hello MIDDAG seguido do paragrafo "Sua extension esta funcionando."
Se você vir essa página, parabens: sua primeira extension MIDDAG esta funcionando.
Estrutura final de arquivos¶
Resumo do que você aprendeu¶
| Conceito | O que faz |
|---|---|
base\extension |
Classe-base para declarar uma extension |
EXTENSION_IDNUMBER |
Slug único da extension |
base\controller |
Classe-base para controllers HTTP |
#[Route] |
Attribute Symfony para declarar rotas |
render() |
Retorna Response HTML dentro do layout Moodle |
| Auto-discovery | Extensions são descobertas pelo sufixo _extension |
Proximo passo¶
No Tutorial 02 -- Persistencia EAV, você vai expandir esta extension adicionando um item type, CRUD completo e busca via query engine.