# Structural Pages Drupal 11 module that implements hierarchical editorial structure and contextual navigation for institutional sites. Designed for higher education institutions but generic enough for other institutional contexts. ## Problem In Drupal, content is added in a flat manner (non-hierarchical), and menus are traditionally used to organize content into hierarchical structures. This creates user experience problems because content editors typically do not have permission to administer menus. ## Solution The module implements two complementary structures: 1. **Taxonomic Structure** (primary) — Organization based on the `site_sections` hierarchical taxonomy vocabulary, applied to the `section_page` content type. Governs breadcrumbs and URLs via Pathauto. 2. **Parent-Child Structure** (subsidiary) — Direct hierarchy between pages via `field_parent_page` (Dynamic Entity Reference), applied to the `content_page` content type. Supports multiple parent entity types: nodes, taxonomy terms, users, and groups. ## Requirements - Drupal 11 - Core modules: `node`, `taxonomy`, `views`, `field`, `text` - Contrib modules: - [Token](https://www.drupal.org/project/token) - [Pathauto](https://www.drupal.org/project/pathauto) - [Dynamic Entity Reference](https://www.drupal.org/project/dynamic_entity_reference) - Optional: - `content_translation` — for multilingual taxonomy term names - [Group](https://www.drupal.org/project/group) — for group entity support (via `structural_pages_group` submodule) ## Installation ```bash drush en structural_pages -y drush cr ``` The module automatically creates: - Taxonomy vocabulary `site_sections` with default hierarchical terms - Content types `section_page` and `content_page` with configured fields - Pathauto patterns for both content types and taxonomy terms - A `child_pages` View (block display) - Content translations for term names (if `content_translation` is enabled) ### Group support ```bash drush en structural_pages_group -y ``` Requires the Group module. Adds group entities as a parent type for content pages. ## Configuration **Settings form**: `/admin/config/local-modules/structural-pages` Allows administrators to select which entity types and bundles can be used as parents for content pages. Changes automatically update the `field_parent_page` field configuration. ## Content Types ### section_page Pages organized by site section. Each page belongs to a `site_sections` taxonomy term. | Field | Type | Required | Description | |-------|------|----------|-------------| | `field_site_section` | Entity reference (taxonomy) | Yes | Site section | | `body` | Formatted text | No | Page content | ### content_page Pages with hierarchical parent-child structure. The parent can be a node, taxonomy term, user, or group. | Field | Type | Required | Description | |-------|------|----------|-------------| | `field_parent_page` | Dynamic entity reference | No | Parent entity | | `field_site_section` | Entity reference (taxonomy) | Conditional | Site section (inherited or manual) | | `body` | Formatted text | No | Page content | **Site section inheritance rules:** - Parent is a `taxonomy_term` → uses the term as site section - Parent is a `node` → inherits `field_site_section` from the parent node - Parent is a `user` or `group` → clears `field_site_section` (context is the entity itself) - No parent (root page) → must be filled manually ## Features ### Automatic breadcrumbs Custom breadcrumb builder for `section_page` and `content_page` that traverses the parent chain: - **Taxonomy context**: Home > Term Hierarchy > Parent Nodes > Current Page - **User context**: Home > User Name > Parent Nodes > Current Page - **Group context**: Home > Group Name > Parent Nodes > Current Page ### Pathauto tokens | Token | Description | Example | |-------|-------------|---------| | `[node:site-section-path]` | Hierarchical path from taxonomy | `undergraduate/courses` | | `[term:hierarchy-path]` | Term path including ancestors | `institutional/news` | Suggested URL pattern: `[node:site-section-path]/[node:title]` → `/undergraduate/courses/software-engineering` ### Structural Pages Menu block Dynamic menu block that renders hierarchical navigation based on content structure. | Option | Default | Description | |--------|---------|-------------| | Maximum depth | 3 | Number of levels to display (1-10) | | Show ancestor title | Yes | Display ancestor entity title as header | | Expand active trail | Yes | Highlight the path to current page | ### Child Pages View Block display that lists child pages of the current `content_page`, filtered by `field_parent_page`. ## Extensibility The module uses an attribute-based plugin system (`ParentEntityHandler`) to support different parent entity types. Built-in handlers: | Handler | Entity Type | Clears Site Section | Bundle Restrictions | |---------|-------------|---------------------|---------------------| | TaxonomyTermHandler | taxonomy_term | No | site_sections | | NodeHandler | node | No | content_page, section_page | | UserHandler | user | Yes | - | | GroupHandler* | group | Yes | - | *Provided by the `structural_pages_group` submodule. To add support for a new entity type, create a plugin in `src/Plugin/ParentEntityHandler/`: ```php #[ParentEntityHandler( id: 'my_entity', label: new TranslatableMarkup('My Entities'), entity_type_id: 'my_entity', clears_site_section: FALSE, sort_field: 'title', )] class MyEntityHandler extends ParentEntityHandlerBase { // Override methods as needed. } ``` See `docs/DESIGN.md` for full architecture details and `docs/PLUGIN_SYSTEM_PLAN.md` for the plugin system design.