VOOZH about

URL: https://deepwiki.com/calevans/staticforge/3.3-event-system

⇱ Event System | calevans/staticforge | DeepWiki


Loading...
Last indexed: 11 February 2026 (5f6a2a)
Menu

Event System

The Event System is StaticForge's publish-subscribe mechanism that enables loose coupling between the core processing pipeline and feature plugins. This document covers the EventManager class, the event lifecycle, event registration patterns, and the data flow architecture that allows features to hook into specific stages of site generation.

For information about creating features that use events, see Creating Custom Features. For the overall architecture context, see Bootstrap & Initialization and Feature System.


Core Components

EventManager

The EventManager class implements a priority-based event bus. Features register event listeners during initialization, and the core system fires events at specific lifecycle stages. Each listener receives a Container instance and a $data array, which it can modify and return to the next listener.

Key characteristics:

  • Priority-based execution order (lower numbers execute first)
  • Sequential data passing (bucket brigade pattern)
  • Support for both system-wide and feature-specific events
  • Container access for all listeners

Event Lifecycle Diagram


Sources: content/development/events.md1-179 content/development/bootstrap.md1-246


Event Registration

Features register event listeners by defining an eventListeners array in their class. The BaseFeature class automatically processes this array and registers each listener with the EventManager.

Registration Pattern


Example from MarkdownRenderer:

src/Features/MarkdownRenderer/Feature.php36-38 shows the standard registration pattern:


Example from MenuBuilder:

content/features/menu-builder.md13 indicates that MenuBuilder listens to POST_GLOB at priority 100.

Priority System

The priority value determines execution order within an event. Listeners are sorted in ascending order (lowest priority executes first).

Priority RangeUsage
0-100System-critical operations that must run first
100-500Standard feature operations
500-900Operations that depend on other features
900-999Cleanup and finalization operations

Priority Dependencies Example:


The CategoryIndex feature runs at priority 50 to create category index pages before MenuBuilder (priority 100) scans for menu items. This ensures index pages are included in navigation.

Sources: src/Core/FeatureManager.php1-391 content/development/architecture.md104-112


Event Lifecycle

StaticForge fires events in a specific sequence during site generation. Understanding this sequence is critical for determining where to hook feature logic.

Complete Event Sequence


Sources: content/development/events.md31-51 content/development/architecture.md64-102


Built-in Event Reference

System Events

Event NamePhaseWhen FiredCommon Use Cases
CREATEInitializationApplication startup, before file discoveryInitialize feature state, generate build IDs
PRE_GLOBDiscoveryBefore file scanningPrepare for discovery
POST_GLOBPlanningAfter file discovery, before renderingBuild menus, create index pages, analyze site structure
PRE_LOOPProcessingBefore rendering loop startsInitialize loop-specific state
PRE_RENDERProcessingBefore each file rendersEnrich metadata, calculate derived fields
RENDERProcessingDuring file renderingConvert Markdown to HTML, process content
POST_RENDERProcessingAfter each file rendersCollect URLs, build search index, move files
POST_LOOPAggregationAfter all files processedGenerate sitemap, RSS feeds, search index files
DESTROYCleanupApplication shutdownClose connections, write logs
UPLOAD_CHECK_FILEDeploymentDuring site:upload, per fileOverride upload logic, send to S3 instead of SFTP

Event Data Structure

Each event receives a $data array with context-specific keys:

POST_GLOB data:


RENDER data:


UPLOAD_CHECK_FILE data:


Sources: content/development/events.md64-148 content/development/architecture.md64-102


Event Data Flow (Bucket Brigade Pattern)

Events implement a sequential data-passing pattern where each listener modifies the $data array and passes it to the next listener. This creates a processing pipeline where data is enriched at each stage.

Data Flow Diagram


Example: Metadata Enrichment Flow


Critical Rule: Always Return Data

Breaking the chain causes failures:


If a listener doesn't return $data, subsequent listeners receive an empty array, causing the build to fail.

Sources: content/development/events.md150-167 content/development/architecture.md64-102


Feature-Specific Events

Some features fire their own events to allow other features to extend their functionality. These events follow the naming convention FEATURE_ACTION.

RSS Feed Events

EventWhen FiredData ProvidedUse Case
RSS_BUILDER_INITBefore building RSS XMLbuilder, category_metadataConfigure RSS builder (e.g., add podcast tags)
RSS_ITEM_BUILDINGPer item during RSS generationitem, fileAdd custom fields to RSS items

Example from RSSFeed:

src/Features/RssFeed/Services/RssFeedService.php180-183 fires RSS_BUILDER_INIT to allow configuration:


src/Features/RssFeed/Services/RssFeedService.php212-215 fires RSS_ITEM_BUILDING per item:


Menu Collection Event

EventWhen FiredData ProvidedUse Case
COLLECT_MENU_ITEMSDuring POST_GLOBMenu items arrayAdd external links or computed menu items

Example Usage:


Markdown Conversion Event

EventWhen FiredData ProvidedUse Case
MARKDOWN_CONVERTEDAfter Markdown parsing, before templatecontent (HTML), metadataPost-process HTML (add classes, transform tables)

Sources: content/development/events.md129-147 src/Features/RssFeed/Services/RssFeedService.php180-220


Registration Code Patterns

Pattern 1: Simple Event Listener


Pattern 2: Multiple Event Listeners


Pattern 3: Service-Based Event Handling

Features often delegate event handling to service classes for better separation of concerns.


Real Example - Sitemap Feature:

src/Features/Sitemap/Services/SitemapService.php32-78 shows collectUrl method collecting data during POST_RENDER.

src/Features/Sitemap/Services/SitemapService.php87-122 shows generateSitemap method writing output during POST_LOOP.

Sources: src/Features/RssFeed/Services/RssFeedService.php1-306 src/Features/Sitemap/Services/SitemapService.php1-123 src/Features/CategoryIndex/Services/CategoryService.php1-135


Event Timing and Dependencies

POST_GLOB Priority Order

The POST_GLOB event is the most complex due to inter-feature dependencies. Features must execute in a specific order to ensure dependent features have the data they need.

POST_GLOB Execution Order:


Why this order matters:

  1. CategoryIndex (50) creates category index pages first
  2. MenuBuilder (100) scans all files including newly created index pages
  3. Tags/RobotsTxt (150) can process complete file list with menu data
  4. Categories (250) modifies output paths after menu building is complete

RENDER Event Priority

Multiple renderers can coexist at the same priority level because each renderer checks file extensions:


Both MarkdownRenderer and HtmlRenderer listen at priority 100, but each only processes files with matching extensions.

Sources: content/development/architecture.md104-153 content/features/menu-builder.md193-200


Best Practices

1. Always Return Event Data


2. Check for Key Existence


3. Choose Appropriate Priorities


4. Use Service Classes for Complex Logic


5. Document Feature Dependencies

If your feature depends on another feature's data, document it and consider using appropriate priorities:


Sources: content/development/events.md170-175 content/development/features.md143-148


Event System Architecture Mapping

Class to Event Flow Mapping


Sources: src/Core/FeatureManager.php41-96 content/development/features.md20-48 content/development/events.md80-109

Refresh this wiki

On this page