Botão
O bloco button-block emite um <a> estilizado com texto, URL e um estilo entre filled e outline. É um bloco autônomo que pode aparecer em qualquer layout e foi adicionado na versão 1.3 junto com os blocos de ícone, acordeão e barra de pesquisa.
Como foi construído
Identificação
| Item | Valor |
|---|---|
| Classe | SGMBlocks\Site\BlockLayout\ButtonBlock |
block_layout | button-block |
| Form | SGMBlocks\Form\ButtonBlockForm |
| Factory | SGMBlocks\Service\BlockLayout\ButtonBlockFactory |
| Partial | common/block-layout/button-block |
Formulário
ButtonBlockForm tem três campos, todos não obrigatórios no required do atributo HTML, mas a renderização é condicional aos dois primeiros estarem preenchidos:
$this->add(['name' => 'o:block[__blockIndex__][o:data][button_text]',
'type' => Element\Text::class,
'options' => ['label' => 'Texto do Botão'],
'attributes' => ['required' => false]]);
$this->add(['name' => 'o:block[__blockIndex__][o:data][button_url]',
'type' => Element\Text::class,
'options' => ['label' => 'URL do Botão'],
'attributes' => ['required' => false]]);
$this->add(['name' => 'o:block[__blockIndex__][o:data][button_style]',
'type' => Element\Select::class,
'options' => ['label' => 'Estilo do Botão',
'value_options' => [
'filled' => 'Preenchido',
'outline' => 'Sem fundo (contorno)',
]],
'attributes' => ['value' => 'filled']]);
Classe do bloco
ButtonBlock não implementa prepareForm. Não injeta CSS nem JS no admin.
ButtonBlock::form popula os três campos a partir de $block->dataValue(...). button_style tem fallback para filled quando o valor é falsy.
ButtonBlock::render aplica um contrato de curto-circuito:
$buttonText = $block->dataValue('button_text');
$buttonUrl = $block->dataValue('button_url');
$buttonStyle = $block->dataValue('button_style') ?: 'filled';
if (empty($buttonText) || empty($buttonUrl)) {
return '';
}
return $view->partial('common/block-layout/button-block', [
'button_text' => $buttonText,
'button_url' => $buttonUrl,
'button_style' => $buttonStyle,
]);
Sem texto ou sem URL, o bloco retorna string vazia antes mesmo de delegar ao partial. Isso previne botões mudos ou links quebrados no frontend.
Partial
<?php
$escape = $this->plugin('escapeHtml');
$buttonText = isset($this->button_text) ? $this->button_text : null;
$buttonUrl = isset($this->button_url) ? $this->button_url : null;
$buttonStyle = isset($this->button_style) ? $this->button_style : 'filled';
if (empty($buttonText) || empty($buttonUrl)) {
return;
}
$buttonClasses = ($buttonStyle === 'outline')
? 'sgm-button sgm-button-outline'
: 'sgm-button sgm-button-filled';
?>
<div class="sgm-button-block">
<a href="<?php echo $escape($buttonUrl); ?>" class="<?php echo $buttonClasses; ?>">
<?php echo $escape($buttonText); ?>
</a>
</div>
O partial duplica a verificação de empty por precaução. Também aplica escapeHtml no href, o que é uma escolha conservadora: o canônico para atributos HTML é escapeHtmlAttr. Veja observações abaixo.
Persistência
Chave em o:data | Tipo | Valores possíveis | Default efetivo |
|---|---|---|---|
button_text | string | qualquer string | vazio |
button_url | string | URL absoluta ou âncora | vazio |
button_style | string | filled ou outline | filled |
Assets carregados
- Frontend: o partial não chama
headLink. O CSS das classessgm-button,sgm-button-filled,sgm-button-outlineentra por outro bloco que já carregoustyle.cssna página, ou pelo tema. Se o botão for o único bloco SGM da página, o CSS pode não ser carregado automaticamente. - Admin: nenhum asset específico.
Como usar como desenvolvedor
Garantir que o CSS seja carregado
Se a página usa apenas button-block sem nenhum outro bloco SGM que anexe style.css, o <a> sai sem estilo. Duas estratégias resolvem:
- Adicionar
$this->headLink()->appendStylesheet($this->assetUrl('css/style.css', 'SGMBlocks'))ao partial do bloco. - Anexar o CSS no layout do tema uma vez por site, independente dos blocos.
A primeira opção é mais coerente com os demais partials do módulo.
Adicionar um novo estilo de botão
Edite ButtonBlockForm para acrescentar a opção:
'value_options' => [
'filled' => 'Preenchido',
'outline' => 'Sem fundo (contorno)',
'ghost' => 'Fantasma',
],
Atualize o partial para mapear a nova string:
switch ($buttonStyle) {
case 'outline': $buttonClasses = 'sgm-button sgm-button-outline'; break;
case 'ghost': $buttonClasses = 'sgm-button sgm-button-ghost'; break;
default: $buttonClasses = 'sgm-button sgm-button-filled';
}
Acrescente a classe .sgm-button-ghost em asset/css/style.css.
Sobrescrever o partial no tema
Copie view/common/block-layout/button-block.phtml para themes/<tema>/view/common/block-layout/button-block.phtml. O tema passa a ditar a estrutura do botão inteira.
Ler o bloco em outros templates
foreach ($page->blocks() as $block) {
if ($block->layout() === 'button-block') {
$text = $block->dataValue('button_text');
$url = $block->dataValue('button_url');
}
}
Validar URL
Anexe um listener a form.add_input_filters do ButtonBlockForm com o validator Uri do Laminas:
$inputFilter->add([
'name' => 'o:block[__blockIndex__][o:data][button_url]',
'required' => false,
'validators' => [
['name' => 'Uri', 'options' => ['allowRelative' => true, 'allowAbsolute' => true]],
],
]);
Observações
escapeHtmlemhref. O correto para atributos HTML éescapeHtmlAttr. O escape atual funciona para URLs comuns porque<,>e&são os alvos, mas quebras de entidade com aspas ainda passam. Ao editar o partial, prefiraescapeHtmlAttrno atributo.- Bloqueio silencioso de render. Quando
button_textoubutton_urlestão vazios, o bloco some. O admin não avisa. Para orientar editores, torne os dois campos obrigatórios no form ou avise via mensagem customizada no editor. - Assets fora do partial. O bloco não carrega
style.css. Se o botão aparece sem borda ou fundo, é esse o motivo. - Rótulo do select. O valor traduzível do
ButtonBlockFormpara a opçãooutlineé a string literal'Sem fundo (contorno)'. Está novalue_optionsdoSelecte aparece assim no admin. Em revisões futuras pode-se decidir se o texto exibido deve ser simplificado, mas a colunabutton_stylepersistida continua sendooutline.