Linha do Tempo
O bloco timeline-block exibe marcos cronológicos em uma seção com cabeçalho e lista de itens. No admin aparece como SGM: Linha do Tempo. Cada item tem data, subtítulo e descrição. As datas são texto livre: o PHP não parseia nem reordena os itens.
Para o guia de administração, veja Linha do Tempo.
Como foi construído
Identificação
| Item | Valor |
|---|---|
| Classe | SGMBlocks\Site\BlockLayout\TimelineBlock |
block_layout | timeline-block |
| Label no admin | SGM: Linha do Tempo |
| Form | SGMBlocks\Form\TimelineBlockForm |
| Factory | SGMBlocks\Service\BlockLayout\TimelineBlockFactory |
| Partial | common/block-layout/timeline-block |
| JS admin | asset/js/timeline-block-admin.js |
Formulário estático
TimelineBlockForm define três campos de cabeçalho:
$this->add(['name' => 'o:block[__blockIndex__][o:data][subtitle]',
'type' => Element\Text::class,
'options' => ['label' => 'Subtítulo']]);
$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 (opcional)'],
'attributes' => ['rows' => 3]]);
Os itens dinâmicos não entram no Fieldset. O JavaScript gera os inputs em runtime.
Classe do bloco
TimelineBlock::prepareForm anexa admin.css e timeline-block-admin.js.
TimelineBlock::form popula os três campos estáticos e concatena o gerenciador de itens com o array existente serializado em data-items:
$itemsHtml = <<<HTML
<div class="timeline-items-manager" data-items="{$itemsJson}">
<div class="field">
<div class="field-meta"><label>Itens da Linha do Tempo</label></div>
<div class="inputs">
<div class="timeline-items-container"></div>
<button type="button" class="timeline-add-item o-icon-add button">Adicionar item</button>
</div>
</div>
</div>
HTML;
Cada item persiste em:
o:block[__blockIndex__][o:data][items][i][date]
o:block[__blockIndex__][o:data][items][i][subtitle]
o:block[__blockIndex__][o:data][items][i][description]
O JS reindexa os índices ao remover um item (reindexItems).
TimelineBlock::render passa subtitle, title, description e items ao partial.
JavaScript do admin
O timeline-block-admin.js:
- Lê
data-itemse monta entradas com campos Data, Subtítulo e Descrição (textarea simples, sem CKEditor). - Adiciona itens vazios via Adicionar item.
- Remove itens e reindexa names dos inputs.
- Reinicializa em
o:block-added.
Partial
O partial filtra itens sem date preenchida antes de renderizar:
$validItems = array_values(array_filter($items, function ($item) {
return !empty($item['date']);
}));
Se não houver itens válidos e o título estiver vazio, o partial retorna sem output.
Layout responsivo:
- Mobile (
sgm-timeline-mobile): lista vertical empilhada. - Tablet+ (
sgm-timeline-tablet): carrossel Swiper comslidesPerView: 'auto'efreeMode: true. Swiper só inicializa em viewportmin-width: 768px.
Assets carregados no frontend: style.css, vendor/swiper/swiper-bundle.min.css, vendor/swiper/swiper-bundle.min.js.
A ordem dos itens no site segue a ordem definida no admin. Não há sort automático por data.
Persistência
Chave em o:data | Tipo | Observação |
|---|---|---|
subtitle | string | Cabeçalho opcional |
title | string | Cabeçalho; required no form HTML |
description | string | Cabeçalho opcional |
items | array | Lista de { date, subtitle, description } |
Como usar como desenvolvedor
Sobrescrever o partial no tema
Copie view/common/block-layout/timeline-block.phtml para o tema. O Swiper e o script inline de breakpoint vêm junto.
Validar itens no render
Hoje só itens com date não vazia entram em $validItems. Para exigir subtítulo ou descrição, ajuste o filtro no partial.
Ordenar por data
O bloco não ordena. Se precisar de ordem cronológica automática, parse date no render ou no partial antes do loop. O admin grava strings como "2020", "Março de 2021" ou "15/03/2022" sem validação.
Ler o bloco em outros templates
foreach ($page->blocks() as $block) {
if ($block->layout() === 'timeline-block') {
$items = $block->dataValue('items') ?: [];
$title = $block->dataValue('title');
}
}
Depurar
- Bloco vazio no site: confirme que pelo menos um item tem
dateou quetitleestá preenchido. - Carrossel não aparece: Swiper só ativa a partir de 768px; abaixo disso usa layout mobile.
- Itens somem após salvar: item sem
dateé filtrado no partial.
Observações
- Datas como rótulo. O campo Data é texto exibido tal qual. Não há date picker nem ordenação automática.
- Mesmo padrão do acordeão. Fieldset estático + gerenciador JS + reindexação ao remover.
- Swiper no partial. A inicialização fica inline no partial, não em asset separado do frontend.
- Item sem data não renderiza. Mesmo com subtítulo ou descrição preenchidos, o item é ignorado se
dateestiver vazio.