Lista de Recursos
O bloco resource-list-block lista coleções, itens de uma coleção ou páginas do site em um grid paginado com thumbnail e título. Um único bloco cobre os três modos via campo mode. No admin aparece como SGM: Lista de Recursos. O tema SGM pode sobrescrever o partial padrão do módulo com layout Tailwind.
Para o uso editorial no template de exibição de coleções, veja Template para coleções. Para o guia de administração, veja Lista de Recursos.
Como foi construído
Identificação
| Item | Valor |
|---|---|
| Classe | SGMBlocks\Site\BlockLayout\ResourceListBlock |
block_layout | resource-list-block |
| Label no admin | SGM: Lista de Recursos |
| Form | SGMBlocks\Form\ResourceListBlockForm |
| Factory | SGMBlocks\Service\BlockLayout\ResourceListBlockFactory |
| Partial | common/block-layout/resource-list-block |
| Partial (SGM) | themes/sgm/view/common/block-layout/resource-list-block.phtml |
| JS admin | asset/js/resource-list-block-admin.js |
| Sidebars admin | view/common/resource-list-block-sidebars.phtml |
Formulário
ResourceListBlockForm expõe dois campos estáticos. Os pickers de recursos são renderizados em HTML por ResourceListBlock::form e controlados pelo JavaScript.
$this->add([
'name' => 'o:block[__blockIndex__][o:data][mode]',
'type' => Element\Select::class,
'options' => [
'label' => 'Tipo de listagem',
'value_options' => [
'collections' => 'Coleções',
'items' => 'Itens de uma coleção',
'pages' => 'Páginas',
],
],
]);
$this->add([
'name' => 'o:block[__blockIndex__][o:data][ordenacao]',
'type' => Element\Select::class,
'options' => [
'label' => 'Permitir ordenação?',
'value_options' => [
'none' => 'Sem ordenação',
'date' => 'Por data',
'alpha' => 'Alfabética',
],
],
]);
As opções de ordenacao no DOM são substituídas em runtime pelo JS conforme o mode. O form PHP declara none, date e alpha; para pages o JS troca por none e user (label Crescente ou decrescente).
| Campo | Tipo no form | Modo ativo | Comportamento |
|---|---|---|---|
mode | Select | sempre | Default collections |
ordenacao | Select | sempre | Opções e default variam por mode (ver abaixo) |
item_set_ids | hidden[] | collections | Vazio = todas as coleções públicas do site |
page_ids | hidden[] | pages | Vazio = todas as páginas públicas; ordem = sequência do array |
item_set_id | hidden | items | Obrigatório para render |
Pickers condicionais (sidebar + lista sortable):
| Modo | Label no admin | Sidebar | Chave persistida |
|---|---|---|---|
collections | Coleções a listar | #sgm-resource-list-add-item-sets | item_set_ids |
pages | Páginas a listar | #sgm-resource-list-add-pages | page_ids |
items | Coleção dos itens | #sgm-resource-list-select-item-set | item_set_id |
Ordenação
A chave ordenacao controla se o visitante pode reordenar a listagem no site público e qual critério usar. A normalização fica em resolveOrdenacaoValue().
Modos collections e items
| Valor | Label admin | Default | Comportamento no render |
|---|---|---|---|
none | Sem ordenação | Ordem da API; sem controles públicos | |
date | Por data | sim | Ordena por dcterms:created; controles asc/desc na URL |
alpha | Alfabética | Ordena por título; controles asc/desc na URL |
Constante no PHP:
private const DATE_CREATED_TERM = 'dcterms:created';
sortResourcesByDateCreated() lê o valor Dublin Core via $resource->value('dcterms:created'). Se o metadado estiver vazio, cai para $resource->created(). Anos isolados (2025) viram timestamp de 1 de janeiro. Empates de data desempatam alfabeticamente e, por fim, por id.
sortResourcesByAlpha() usa getResourceSortLabel(): título da página no modo pages; browse_heading_property_term ou displayTitle() nos demais. A comparação passa por foldAlphaSortTitle() com mapa de acentos e strnatcasecmp.
Default efetivo: date. sort_order default: desc para date, asc para alpha.
Modo pages
| Valor | Label admin | Default | Comportamento no render |
|---|---|---|---|
none | Sem ordenação | Ordem fixa definida no admin | |
user | Crescente ou decrescente | sim | Ordem manual + visitante inverte via ?sort_order= |
Ordem manual: sequência de page_ids persistida pelo picker. reorderResourcesByIds() reordena o resultado da API conforme essa sequência. Itens retornados pela API mas ausentes em page_ids vão ao final.
Drag-and-drop no admin: só no modo pages. O JS expõe .sortable-handle em cada linha e usa Sortable.js (initPickerSortable). Ao soltar, syncHiddenInputs() regrava os hidden inputs na nova ordem.
Com ordenacao === 'user' e sort_order === 'desc', o render faz array_reverse() sobre a lista já ordenada manualmente.
Valores legados asc/desc em blocos antigos são normalizados para user em resolveOrdenacaoValue().
Controles públicos
showSortControls é true quando:
collectionsouitemscomordenacaoemdateoualphapagescomordenacao === 'user'
O partial recebe sortControlType (date, alpha, pages ou null) e monta links ?sort_order=asc|desc. Labels variam: Mais recentes / Mais antigos para data, Ordem crescente / decrescente para alfabética e páginas.
Captions no admin (JS):
none: "A ordem definida aqui será fixa e o visitante não poderá alterá-la."- demais: "Permite que o visitante reordene a lista conforme a opção escolhida."
Classe do bloco
ResourceListBlock::prepareForm anexa admin.css, resource-list-block-admin.js e sidebars via Module.php.
ResourceListBlock::form popula defaults:
$defaults = [
'mode' => 'collections',
'item_set_ids' => [],
'page_ids' => [],
'item_set_id' => null,
'item_ids' => [],
'ordenacao' => null,
'sort_order' => 'desc',
];
ResourceListBlock::render busca todos os recursos em lotes de 100 (fetchAllResources), aplica ordenação em memória e pagina com array_slice:
flowchart TD
BlockData["o:data mode + ids + ordenacao"] --> Fetch["fetchAllResources api search"]
Fetch --> ModePages{mode pages?}
ModePages -->|sim| ManualOrder["reorderResourcesByIds page_ids"]
ModePages -->|nao| OrdenacaoCheck{ordenacao?}
ManualOrder --> UserReverse{user + desc?}
UserReverse -->|sim| Reverse["array_reverse"]
UserReverse -->|nao| Paginate
Reverse --> Paginate
OrdenacaoCheck -->|date| SortDate["sortResourcesByDateCreated dcterms:created"]
OrdenacaoCheck -->|alpha| SortAlpha["sortResourcesByAlpha"]
OrdenacaoCheck -->|none| Paginate
SortDate --> UrlSort["?sort_order asc|desc"]
SortAlpha --> UrlSort
UrlSort --> Paginate["array_slice paginação"]
Paginate --> Partial["partial resource-list-block"]
Modo collections: busca item_sets com site_id e is_public. Se item_set_ids não está vazio, filtra por id.
Modo pages: busca site_pages com os mesmos critérios. Se page_ids não está vazio, filtra por id.
Modo items: exige item_set_id. Sem ele, retorna o partial com error = 'Nenhuma coleção selecionada.' e lista vazia.
Headings fixos por modo via getHeading() e getSubheading():
| Modo | Heading | Subheading |
|---|---|---|
collections | Navegue pelas Coleções | Selecione uma coleção |
pages | Navegue pelas Exibições | Selecione uma exibição |
items | Navegue pelos itens da coleção | Selecione um item e acesse as mídias |
JavaScript do admin
O resource-list-block-admin.js cobre:
- Alternar classe
resource-list-mode-*e opções deordenacaoquandomodemuda. - Pickers com sidebar: adicionar/remover recursos, hidden inputs, filtro de busca.
- Sortable só em
pages: handle.sortable-handle, persistência da ordem empage_ids. - Modo
items: seletor de coleção única com hiddenitem_set_id. - Reinicialização em
o:block-added.
var ORDENACAO_OPTIONS = {
collections: [
{ value: 'none', label: 'Sem ordenação' },
{ value: 'date', label: 'Por data' },
{ value: 'alpha', label: 'Alfabética' }
],
pages: [
{ value: 'none', label: 'Sem ordenação' },
{ value: 'user', label: 'Crescente ou decrescente' }
]
};
Partial do módulo
O partial em view/common/block-layout/resource-list-block.phtml expõe controles de ordenação quando $showSortControls é verdadeiro. Thumbnail via helper thumbnail(). No modo pages, título via $resource->title().
Variáveis relevantes passadas pelo render:
| Variável | Tipo | Descrição |
|---|---|---|
ordenacao | string | none, date, alpha ou user |
sortControlType | string|null | date, alpha, pages ou null |
showSortControls | bool | Exibe links asc/desc |
sortOrder | string | asc ou desc; lê ?sort_order= da URL |
Partial do tema SGM
O tema pode sobrescrever o partial com layout Tailwind. Diferenças comuns:
- Paginação via
common/pagination-modern. - Modo
pages: thumbnail lido do blocothumbnail-blockda página listada. - Modo
collections/items: fallback percorrendo$resource->media()sethumbnail()falhar.
Persistência
Chave em o:data | Tipo | Modo | Default efetivo | Observação |
|---|---|---|---|---|
mode | string | todos | collections | |
ordenacao | string | todos | date ou user | Normalizado por resolveOrdenacaoValue |
item_set_ids | int[] | collections | [] | vazio lista todas |
page_ids | int[] | pages | [] | ordem manual; vazio lista todas |
item_set_id | int|null | items | null | obrigatório para render |
Assets carregados
- Admin:
admin.css,resource-list-block-admin.js, sidebars,Sortable.js(Omeka core). - Frontend (módulo):
style.csscom seções.sgm-resource-list-*. - Frontend (tema SGM): classes Tailwind; partial sobrescrito.
Como usar como desenvolvedor
Sobrescrever o partial no tema
Copie view/common/block-layout/resource-list-block.phtml para themes/<tema>/view/common/block-layout/resource-list-block.phtml. O Omeka resolve o partial do tema antes do módulo.
Trocar os headings
Os textos de cabeçalho não são configuráveis no form. Edite getHeading() e getSubheading() em ResourceListBlock.php ou passe strings customizadas alterando o render para aceitar campos extras em o:data.
Alterar itens por página
O bloco lê pagination_per_page das configurações globais do Omeka. Ajuste em Configurações do painel principal, não no bloco.
Customizar os cards
Edite o partial do tema para mudar grid, campos exibidos ou lógica de thumbnail.
Ler o bloco em outros templates
foreach ($page->blocks() as $block) {
if ($block->layout() === 'resource-list-block') {
$mode = $block->dataValue('mode', 'collections');
$ordenacao = $block->dataValue('ordenacao');
$itemSetIds = $block->dataValue('item_set_ids', []);
$pageIds = $block->dataValue('page_ids', []);
$itemSetId = $block->dataValue('item_set_id');
}
}
Estender a ordenação
Para novo critério:
- Acrescente valor em
ORDENACAO_OPTIONSno JS e emresolveOrdenacaoValue()no PHP. - Implemente método de sort em
ResourceListBlock::renderapósfetchAllResources. - Ajuste
showSortControlsesortControlTypenorender. - Atualize labels no partial.
Depurar
- Modo
itemssem resultado: confirmeitem_set_idnoo:data. - Modo
pagescom ordem errada: confira a sequência depage_idsapós drag-and-drop no admin. - Ordenação por data sem efeito visível: vários recursos com o mesmo
dcterms:created(ex.: Colação de Grau, mesma turma). Usealphaounone. - Ordenação pública não aparece:
ordenacaodeve serdate,alphaouuser, nãonone. ?sort_order=não muda a lista: confirmeshowSortControls === true.- Thumbnail de página ausente: a página listada precisa de bloco
thumbnail-blockcom asset.
Observações
- Um bloco, três modos. Coleções, itens e páginas usam o mesmo
resource-list-blockcommodediferente. - Ordenação em memória. A API não recebe
sort_by; o bloco busca todos os recursos e ordena no PHP antes de paginar. dcterms:createdvs data do recurso. Coleções e itens ordenam pelo metadado Dublin Core, não pelo timestamp interno do Omeka, salvo fallback.- Drag-and-drop só em pages. Coleções e itens não têm handle sortable no admin.
- Headings fixos. Título e subtítulo não vêm do form.
- Thumbnail de páginas. Depende do bloco
thumbnail-blockna página listada. - Listener legado.
Module::handlePropertySortWithFallbacktrata ordenação por propriedade na API com flagsgmblocks_property_sort. Esse caminho não é usado pelo bloco atual, que não expõe sort por propriedade no form.