VOOZH about

URL: https://deepwiki.com/calevans/staticforge/7.4-external-features

⇱ External Features | calevans/staticforge | DeepWiki


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

External Features

Purpose and Scope

This document explains how to install, configure, and use external features distributed via Composer packages. External features extend StaticForge with specialized functionality not included in the core installation, such as podcast support, social metadata, and S3 media management.

For information on creating custom features within your project, see Creating Custom Features. For an overview of the feature system architecture, see Feature Architecture. For documentation on built-in features, see Built-in Features Reference.


Composer Feature Discovery System

StaticForge automatically discovers features from installed Composer packages by reading metadata from vendor/composer/installed.json. This allows third-party packages to register themselves as features without manual configuration.

Discovery Mechanism

Discovery Flow


Sources: src/Core/FeatureManager.php286-327

Feature Priority Hierarchy

StaticForge loads features in a three-tier priority system. If multiple features share the same name, only the highest-priority version is loaded:

PrioritySourceDirectory/LocationUse Case
HIGHESTUser Featuressrc/Features/Project-specific customizations
MEDIUMComposer Featuresvendor/*/composer.jsonThird-party packages
LOWESTLibrary Featuresvendor/eicc/staticforge/src/Features/Built-in core features

This priority system enables override semantics: a user feature with the same name as a Composer feature will prevent the Composer feature from loading. This allows projects to customize external features by creating local versions with the same class name.

Sources: src/Core/FeatureManager.php52-96


Package Structure

External features must follow a specific structure to be discoverable by StaticForge.

Composer Manifest Requirements

The package's composer.json must declare the feature class in the extra.staticforge.feature field:


The feature value must be a fully-qualified class name that implements FeatureInterface.

Sources: src/Core/FeatureManager.php322-326

Feature Class Implementation

The feature class must implement FeatureInterface and define getName() and register() methods:


Sources: src/Core/FeatureManager.php339-344

Directory Structure

Typical external feature package structure:

vendor/package-name/
├── src/
│ ├── Feature.php # Main feature class
│ ├── Services/ # Service classes
│ │ └── SomeService.php
│ └── Models/ # Data models (if needed)
├── config/ # Example configuration files
│ ├── .env.example.package-name
│ └── siteconfig.yaml.example.package-name
├── composer.json # Package manifest
└── README.md # Documentation

Installing External Features

Installation Process

Installation and Configuration Workflow


Sources: src/Core/FeatureManager.php286-369 content/features/external-features.md36-56

Step-by-Step Installation

1. Install via Composer


This downloads the package to vendor/ and registers it in vendor/composer/installed.json.

2. Run Feature Setup Command

Most external features include example configuration files. The feature:setup command copies these to your project root:


This creates files like:

  • .env.example.package-name
  • siteconfig.yaml.example.package-name

3. Configure the Feature

Review the example files and add required settings to your main configuration files:

From .env.example.package-name to .env:


From siteconfig.yaml.example.package-name to siteconfig.yaml:


4. Verify Installation

Run the build to confirm the feature is loaded:


Check the logs for a message like:

[INFO] Loaded composer feature: FeatureName from vendor/package-name

Sources: content/features/external-features.md36-56


Configuration Management

Disabling External Features

External features can be disabled without uninstalling them by adding their name to siteconfig.yaml:


When a feature is disabled:

  1. FeatureManager checks disabled_features during loadFeatures()
  2. The feature class is still instantiated to get its name
  3. register() is never called
  4. Feature status is set to 'disabled'

Sources: src/Core/FeatureManager.php59-63 src/Core/FeatureManager.php209-214

Feature-Specific Configuration

External features typically read configuration from two sources:

Environment Variables (.env):

  • API keys and secrets
  • Service URLs
  • Boolean flags

Site Configuration (siteconfig.yaml):

  • Feature-specific settings
  • Display options
  • Content rules

Example configuration for the RSS Feed feature with Podcast extension:


Sources: src/Features/RssFeed/Services/RssFeedService.php115-142


Available External Features

The StaticForge ecosystem includes several official and community-maintained external features.

Official External Features

PackageComposer NamePurpose
Chapter Navigationcalevans/staticforge-chapternavSequential prev/next navigation for documentation
Google Analyticscalevans/staticforge-google-analyticsGoogle Analytics tracking code injection
Podcastcalevans/staticforge-podcastiTunes/Apple Podcast RSS extensions
Popupcalevans/staticforge-popupModal popup support
S3 Media Offloadcalevans/staticforge-s3Move media files to AWS S3
Social Metadatacalevans/staticforge-social-metadataOpen Graph and Twitter Card tags

Sources: content/features/external-features.md17-34

Example: Installing Podcast Feature

The Podcast feature extends the built-in RSS Feed feature to add iTunes podcast metadata:

Installation:


Configuration in siteconfig.yaml:


How It Works:


Sources: src/Features/RssFeed/Services/RssFeedService.php176-218


Creating Distributable Features

External features follow the same structure as built-in features but include additional packaging requirements.

Package Creation Checklist

1. Feature Class Structure

Create a feature class that extends BaseFeature or implements FeatureInterface:


2. Composer Configuration

Create composer.json with proper autoloading and feature declaration:


3. Example Configuration Files

Include example configuration files in config/ directory:

config/.env.example.feature-name:


config/siteconfig.yaml.example.feature-name:


4. Documentation

Create a comprehensive README.md:


Sources: src/Core/FeatureManager.php332-344


Feature Discovery Implementation

Installed.json Parsing

The discoverComposerFeatures() method reads package metadata from Composer's installed packages registry:

Discovery Algorithm:


Sources: src/Core/FeatureManager.php286-369

Class Name Resolution

When loading a Composer feature, the system performs several validation checks:

  1. Class Existence Check: class_exists($className) verifies the class is autoloadable
  2. Interface Validation: Confirms the class implements FeatureInterface
  3. Name Extraction: Calls getName() to get the feature's registered name
  4. Disabled Check: Verifies the feature is not in disabled_features list
  5. Duplicate Check: Ensures no feature with the same name is already loaded

If validation passes, the feature is registered by calling its register() method with EventManager and Container instances.

Sources: src/Core/FeatureManager.php332-369


Integration with Core Features

External features can extend or interact with built-in features through the event system.

Extending RSS Feed

The Podcast feature demonstrates how external features can extend built-in functionality:

RssFeed Events:


The RssFeed feature fires custom events (RSS_BUILDER_INIT, RSS_ITEM_BUILDING) that other features can listen to. This creates a sub-event ecosystem where features can define extension points for other features.

Sources: src/Features/RssFeed/Services/RssFeedService.php176-218

Extending Search

External features can add content to the search index by listening to the same events:


The Search feature automatically indexes all content processed during the render loop, so external features that add metadata to files will have that metadata available for search.


Troubleshooting

Feature Not Loading

Problem: Composer feature is installed but not loading.

Diagnosis Steps:

  1. Check composer.json declaration:

    
    

    Verify extra.staticforge.feature is defined.

  2. Verify class exists:

    
    
  3. Check if disabled:

    
    
  4. Check for duplicates: Look for a feature with the same name in src/Features/ (user features have priority).

  5. Review logs:

    
    

Sources: src/Core/FeatureManager.php332-369

Configuration Not Applied

Problem: Feature configuration is not being used.

Common Causes:

  1. Configuration in wrong file:

    • Environment variables go in .env
    • Feature settings go in siteconfig.yaml
  2. Incorrect YAML syntax:

    
    
  3. Configuration not read by feature: Check the feature's documentation for exact key names.

  4. Cache issues:

    
    

Summary

External features extend StaticForge through Composer packages that declare themselves in extra.staticforge.feature. The FeatureManager automatically discovers and loads these features with medium priority (between user and library features). Features are installed via composer require, configured through .env and siteconfig.yaml, and can be disabled without uninstalling. The official external features ecosystem includes packages for podcasting, social metadata, S3 media offload, and more. External features can interact with built-in features through the event system, creating a composable architecture for specialized functionality.