mirror of
https://gitlab.unicamp.br/infimecc_drupal11_modules/structural_pages.git
synced 2026-03-08 01:27:42 -03:00
Renames the module from site_structure to structural_pages and pluralizes the taxonomy vocabulary machine name from site_section to site_sections, updating all config, PHP, translations, and documentation references while preserving field_site_section, clears_site_section, and $site_section_id. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7.5 KiB
7.5 KiB
Plano: Sistema de Plugins ParentEntityHandler
Problema
O módulo structural_pages tem dependências hardcoded para diferentes tipos de entidade pai (taxonomy_term, user, group, node) espalhadas em múltiplos arquivos:
StructuralPagesSettingsForm.php:46-51- Array hardcoded$supportedEntityTypesstructural_pages.module:55-59-in_array($parent_entity_type, ['user', 'group'])StructuralPagesMenuBlock.php:14-use Drupal\group\Entity\GroupInterface;(causa erro sem o módulo group)StructuralPagesMenuBlock.php:274-290- Verificaçõesinstanceofpara cada tipoSectionBreadcrumbBuilder.php:82-100- Switch statement para tipos de contexto
Consequência: Adicionar um novo tipo de entidade requer modificar múltiplos arquivos, e o import do GroupInterface causa erro quando o módulo group não está instalado.
Solução
Implementar um sistema de plugins Drupal (Attribute-based para D10+) onde cada handler define:
- Tipo de entidade que gerencia
- Módulo provedor (para dependências opcionais)
- Como detectar a entidade na rota
- Como construir breadcrumbs
- Se deve limpar
field_site_section - Campo de ordenação
Nova Estrutura de Arquivos
structural_pages/
├── src/
│ ├── Attribute/
│ │ └── ParentEntityHandler.php # NOVO
│ ├── ParentEntityHandler/
│ │ ├── ParentEntityHandlerInterface.php # NOVO
│ │ ├── ParentEntityHandlerManagerInterface.php # NOVO
│ │ ├── ParentEntityHandlerBase.php # NOVO
│ │ └── ParentEntityHandlerManager.php # NOVO
│ ├── Plugin/
│ │ ├── Block/
│ │ │ └── StructuralPagesMenuBlock.php # REFATORAR
│ │ └── ParentEntityHandler/ # NOVO
│ │ ├── TaxonomyTermHandler.php # NOVO
│ │ ├── UserHandler.php # NOVO
│ │ └── NodeHandler.php # NOVO
│ ├── Breadcrumb/
│ │ └── SectionBreadcrumbBuilder.php # REFATORAR
│ └── Form/
│ └── StructuralPagesSettingsForm.php # REFATORAR
├── modules/
│ └── structural_pages_group/ # NOVO (submódulo)
│ ├── structural_pages_group.info.yml
│ └── src/Plugin/ParentEntityHandler/
│ └── GroupHandler.php
├── structural_pages.module # REFATORAR
└── structural_pages.services.yml # ATUALIZAR
Componentes Principais
1. Attribute (src/Attribute/ParentEntityHandler.php)
#[\Attribute(\Attribute::TARGET_CLASS)]
class ParentEntityHandler extends Plugin {
public function __construct(
public readonly string $id,
public readonly TranslatableMarkup $label,
public readonly string $entity_type_id,
public readonly ?string $provider_module = NULL,
public readonly bool $clears_site_section = FALSE,
public readonly string $sort_field = 'title',
public readonly ?string $route_parameter = NULL,
public readonly array $bundle_restrictions = [],
public readonly int $weight = 0,
) {}
}
2. Interface (src/ParentEntityHandler/ParentEntityHandlerInterface.php)
Métodos principais:
getEntityTypeId(): stringisAvailable(): boolclearsSiteSection(): boolgetSortField(): stringgetEntityFromRoute(RouteMatchInterface): ?EntityInterfacehandlesEntity(EntityInterface): boolbuildBreadcrumb(Breadcrumb, EntityInterface): voidgetSiteSectionId(EntityInterface): int|string|null
3. Manager (src/ParentEntityHandler/ParentEntityHandlerManager.php)
Métodos principais:
getAvailableHandlers(): array- Retorna handlers com módulos instaladosgetHandlerForEntityType(string): ?ParentEntityHandlerInterfacegetSupportedEntityTypes(): array- Para o formulário de configuraçõesclearsSiteSection(string): boolgetSortField(string): stringgetEntityFromRoute(RouteMatchInterface): ?EntityInterfacebuildBreadcrumbForEntity(Breadcrumb, EntityInterface): bool
4. Handlers Built-in
| Handler | entity_type_id | clears_site_section | sort_field | bundle_restrictions |
|---|---|---|---|---|
| TaxonomyTermHandler | taxonomy_term | false | name | ['site_sections'] |
| UserHandler | user | true | name | [] |
| NodeHandler | node | false | title | ['content_page', 'section_page'] |
5. Submódulo structural_pages_group
# structural_pages_group.info.yml
name: 'Structural Pages Group Integration'
type: module
dependencies:
- structural_pages:structural_pages
- group:group
GroupHandler: entity_type_id: group, clears_site_section: true, sort_field: label
Refatorações
structural_pages.module (linhas 53-66)
Antes:
if (in_array($parent_entity_type, ['user', 'group'])) {
$entity->set('field_site_section', NULL);
return;
}
Depois:
$handler_manager = \Drupal::service('plugin.manager.parent_entity_handler');
if ($handler_manager->clearsSiteSection($parent_entity_type)) {
$entity->set('field_site_section', NULL);
return;
}
StructuralPagesMenuBlock.php
- Remover
use Drupal\group\Entity\GroupInterface; - Injetar
ParentEntityHandlerManagerInterface - Substituir
getAncestorFromRoute():
protected function getAncestorFromRoute(): ?EntityInterface {
return $this->handlerManager->getEntityFromRoute($this->routeMatch);
}
SectionBreadcrumbBuilder.php
- Injetar
ParentEntityHandlerManagerInterface - Substituir switch statement:
if ($context) {
$this->handlerManager->buildBreadcrumbForEntity($breadcrumb, $context['entity']);
}
- Remover métodos
addUserBreadcrumb()eaddGroupBreadcrumb()
StructuralPagesSettingsForm.php
- Injetar
ParentEntityHandlerManagerInterface - Substituir
$supportedEntityTypes:
$supportedEntityTypes = $this->handlerManager->getSupportedEntityTypes();
- Substituir match statement de sort_field:
$sort_field = $this->handlerManager->getSortField($entity_type);
structural_pages.services.yml
services:
plugin.manager.parent_entity_handler:
class: Drupal\structural_pages\ParentEntityHandler\ParentEntityHandlerManager
arguments:
- '@container.namespaces'
- '@cache.discovery'
- '@module_handler'
structural_pages.breadcrumb.section:
class: Drupal\structural_pages\Breadcrumb\SectionBreadcrumbBuilder
arguments:
- '@entity_type.manager'
- '@plugin.manager.parent_entity_handler'
tags:
- { name: breadcrumb_builder, priority: 100 }
Verificação
-
Sem módulo group instalado:
- O módulo structural_pages deve funcionar normalmente
- Formulário de configurações não deve mostrar opção "Groups"
- Nenhum erro de classe não encontrada
-
Com submódulo structural_pages_group ativado:
- Opção "Groups" aparece no formulário de configurações
- Groups funcionam como entidades pai
- Breadcrumbs mostram nome do grupo
-
Extensibilidade:
- Criar handler de teste em módulo custom
- Verificar que é descoberto automaticamente pelo manager
-
Cache:
- Limpar cache após mudanças (
drush cr) - Verificar que handlers são cacheados corretamente
- Limpar cache após mudanças (
Compatibilidade
- Configuração existente (
allowed_parent_targets) continua funcionando - Nenhuma alteração no schema de configuração necessária
- Backwards compatible - apenas mudança interna de implementação