Bloco de ícone
O bloco icon-block combina um asset de imagem com título e descrição em um cartão pequeno, com suporte a alinhamento horizontal ou empilhado. É comum em seções de destaques, features ou listas de serviços.
Como foi construído
Identificação
| Item | Valor |
|---|---|
| Classe | SGMBlocks\Site\BlockLayout\IconBlock |
block_layout | icon-block |
| Form | SGMBlocks\Form\IconBlockForm |
| Factory | SGMBlocks\Service\BlockLayout\IconBlockFactory |
| Partial | common/block-layout/icon-block |
Formulário
O IconBlockForm define quatro campos:
$this->add(['name' => 'o:block[__blockIndex__][o:data][icon]',
'type' => OmekaElement\Asset::class,
'options' => ['label' => 'Ícone'],
'attributes' => ['required' => true]]);
$this->add(['name' => 'o:block[__blockIndex__][o:data][title]',
'type' => Element\Text::class,
'options' => ['label' => 'Título'],
'attributes' => ['required' => true]]);
$this->add(['name' => 'o:block[__blockIndex__][o:data][description]',
'type' => Element\Textarea::class,
'options' => ['label' => 'Descrição'],
'attributes' => ['rows' => 4]]);
$this->add(['name' => 'o:block[__blockIndex__][o:data][alignment]',
'type' => Element\Select::class,
'options' => ['label' => 'Alinhamento',
'value_options' => [
'left' => 'Esquerda',
'center' => 'Centralizado',
]],
'attributes' => ['value' => 'left']]);
icon e title são marcados como obrigatórios no atributo HTML. A validação server-side não está registrada em form.add_input_filters, então o campo só reforça a obrigatoriedade pelo browser.
Classe do bloco
IconBlock::prepareForm anexa admin.css para o preview do asset no editor:
public function prepareForm(PhpRenderer $view)
{
$view->headLink()->appendStylesheet($view->assetUrl('css/admin.css', 'SGMBlocks'));
}
IconBlock::form popula os quatro campos com populateValues, aplicando fallback left para alignment.
IconBlock::render lê o asset com try catch e delega ao partial:
$iconId = $block->dataValue('icon');
$icon = null;
if ($iconId) {
try {
$icon = $view->api()->read('assets', $iconId)->getContent();
} catch (\Exception $e) {
// asset apagado
}
}
return $view->partial('common/block-layout/icon-block', [
'icon' => $icon,
'title' => $block->dataValue('title'),
'description' => $block->dataValue('description'),
'alignment' => $block->dataValue('alignment') ?: 'left',
]);
Partial
<?php
$this->headLink()->appendStylesheet($this->assetUrl('css/style.css', 'SGMBlocks'));
if (!$icon && empty($title)) return;
$alignClass = ($alignment === 'center')
? 'sgm-icon-block--center'
: 'sgm-icon-block--left';
?>
<div class="sgm-icon-block <?= $this->escapeHtmlAttr($alignClass) ?>">
<?php if ($icon): ?>
<div class="sgm-icon-block__icon">
<img src="<?= $this->escapeHtmlAttr($icon->assetUrl()) ?>"
alt="<?= $this->escapeHtmlAttr($icon->altText() ?: $title) ?>">
</div>
<?php endif; ?>
<div class="sgm-icon-block__content">
<?php if (!empty($title)): ?>
<h3 class="sgm-icon-block__title"><?= $this->escapeHtml($title) ?></h3>
<?php endif; ?>
<?php if (!empty($description)): ?>
<p class="sgm-icon-block__description"><?= $this->escapeHtml($description) ?></p>
<?php endif; ?>
</div>
</div>
Pontos do partial:
- Aborta o render quando não há ícone nem título.
- Deriva a classe CSS por comparação estrita com
center. - Define o
altdo<img>comoaltTextdo asset, ou o próprio título como fallback.
Persistência
Chave em o:data | Tipo | Default | Observação |
|---|---|---|---|
icon | inteiro id de asset | vazio | Validado apenas no required do HTML. |
title | string | vazio | Obrigatório via atributo HTML. Escapado no partial. |
description | string | vazio | Opcional. Escapado no partial. |
alignment | string | left | Valores válidos: left, center. |
Assets carregados
- Frontend:
asset/css/style.css. Define.sgm-icon-block,.sgm-icon-block--left,.sgm-icon-block--center,.sgm-icon-block__icon,.sgm-icon-block__title,.sgm-icon-block__description. - Admin:
asset/css/admin.css. Ajusta o preview do asset.
Regras de CSS importantes
O style.css aplica:
.sgm-icon-blockcomdisplay: flexegap: 1.25rem..sgm-icon-block--leftcomflex-direction: row..sgm-icon-block--centercomflex-direction: columnetext-align: center..sgm-icon-block__icon imgcomwidth: 64px; height: 64px; object-fit: contain. Isso limita o tamanho do ícone independente do tamanho do asset carregado.
Para ícones maiores, o tema precisa sobrescrever a regra ou o partial.
Como usar como desenvolvedor
Sobrescrever o partial no tema
Copie view/common/block-layout/icon-block.phtml para themes/<tema>/view/common/block-layout/icon-block.phtml. O tema pode trocar a tag <h3> por <h4>, usar SVG inline em vez de <img>, ou alinhar o conteúdo de forma diferente.
Usar SVG como ícone
O Asset do Omeka aceita SVG. O partial renderiza com <img> apontando para assetUrl. Para inlining do SVG, crie um helper de view próprio do tema que carregue o arquivo do asset e emita o XML no HTML. O partial do módulo mantém o <img> genérico.
Trocar o tamanho do ícone
Três caminhos:
- Edite
asset/css/style.csse ajuste a regra.sgm-icon-block__icon img. - Sobrescreva o partial no tema com
style="width: 80px; height: 80px". - Adicione um campo de tamanho no
IconBlockForm, persista emo:data[size], e aplique uma classe variável.
Adicionar um novo alinhamento
Estenda as value_options do select com uma terceira entrada e trate-a no partial:
$alignClass = match ($alignment) {
'center' => 'sgm-icon-block--center',
'right' => 'sgm-icon-block--right',
default => 'sgm-icon-block--left',
};
Acrescente .sgm-icon-block--right em asset/css/style.css com flex-direction: row-reverse.
Validar o asset no submit
O atributo required só age no browser. Para validar no servidor, anexe um listener a form.add_input_filters do IconBlockForm:
$inputFilter->add([
'name' => 'o:block[__blockIndex__][o:data][icon]',
'required' => true,
'validators' => [
['name' => 'Laminas\Validator\NotEmpty'],
],
]);
Ler o bloco em outros templates
foreach ($page->blocks() as $block) {
if ($block->layout() === 'icon-block') {
$iconId = $block->dataValue('icon');
$title = $block->dataValue('title');
}
}
Depurar
- Se o bloco some sem motivo aparente, confirme que o asset ainda existe. A leitura da API cai em
catche orendersegue com$icon = null; o partial ainda emite se houvertitle, mas o<img>fica ausente. - Se o ícone aparece grande no site, inspecione
.sgm-icon-block__icon imgno navegador. O tema pode estar sobrescrevendowidthouheight. - Se
alignmentnão bate com as classes, confirme que o valor persistido éleftoucenter. O fallback do render normaliza valores vazios paraleft.
Observações
- Não é ícone no sentido estrito. O campo aceita qualquer asset de imagem. Nada impede carregar uma foto inteira e ela será reduzida para 64 por 64.
altbaseado no título. Se o asset não temaltText, o partial usatitleno<img>. Isso evitaaltvazio, mas pode ser redundante quando título e alt repetem a mesma informação. Considere omitir oaltviaalt=""para ícones puramente decorativos em um partial customizado do tema.- Obrigatoriedade frouxa.
requiredno atributo HTML impede submit no browser, mas não sobrevive a submissões programáticas. Use input filters para garantias server-side.