No Code Attached Yet
avatar counterpoint
counterpoint
19 Aug 2025

Feature Request: Event-Driven Plugin Loading

Summary

Allow plugins to handle events regardless of their folder/group location, while maintaining full backward compatibility with the existing group-based system.

Problem Statement

The current plugin system constrains event handling based on folder structure, leading to:

  1. Plugin Multiplication: Developers are forced to create multiple related plugins (e.g., separate plugins for user events, content events, and API handling for the same feature)
  2. System Plugin Abuse: Developers circumvent the system by cramming unrelated functionality into system plugins
  3. Poor Code Organization: Related functionality is artificially scattered across multiple plugins
  4. Developer Friction: The current system fights against logical code organization

Real-World Example

A listmonk integration requires:

  • A content plugin for membership handling
  • A user plugin for user deletion cleanup
  • A webservices plugin for REST API endpoints
  • Currently solved by cramming everything into a system plugin

Proposed Solution

Enhance the event dispatcher to load plugins based on method availability rather than just folder location.

Implementation Approach

  1. Maintain Backward Compatibility: Existing group-based loading continues to work unchanged
  2. Add Method-Based Discovery: When triggering events, scan all enabled plugins for matching methods
  3. Performance Optimization: Cache method availability during plugin discovery
  4. Developer Choice: Developers can choose folder structure based on organization preferences, not technical constraints

Technical Implementation

// Enhanced event dispatcher (simplified)
public function trigger(string $event, array $params = [])
{
    $handlers = [];
    
    // Legacy: Load by group (existing behavior)
    $handlers = array_merge($handlers, $this->getPluginsByGroup($event));
    
    // New: Load by method availability (new behavior)  
    $handlers = array_merge($handlers, $this->getPluginsByMethod($event));
    
    // Remove duplicates and execute
    $handlers = array_unique($handlers);
    return $this->executeHandlers($handlers, $event, $params);
}

private function getPluginsByMethod(string $event): array
{
    // Check cached method map or scan enabled plugins
    return $this->pluginMethodCache[$event] ?? [];
}

Benefits

For Developers

  • Logical Code Organization: Keep related functionality together
  • Reduced Plugin Count: One plugin can handle multiple event types
  • Better Maintainability: Single codebase for related features
  • Intuitive Development: "I want to handle event X" → "I implement method X"

For Performance

  • Selective Loading: Plugins still only load when events fire
  • Reduced System Plugin Bloat: Less pressure to stuff everything into system plugins
  • Cacheable Discovery: Method availability can be cached during installation

For Architecture

  • Separation of Concerns: Folder structure becomes purely organizational
  • Future-Proof: More flexible for complex modern plugins
  • Standards Alignment: Matches patterns from Laravel, Symfony, WordPress

Backward Compatibility

Zero breaking changes:

  • Existing plugins work unchanged
  • Current group-based behavior remains default
  • Migration is optional and gradual
  • No changes required to existing plugin installations

Implementation Phases

Phase 1: Core Enhancement

  • Enhance event dispatcher with method-based scanning
  • Add plugin method caching during discovery
  • Maintain existing group-based behavior as primary

Phase 2: Developer Tools

  • Update plugin generator to offer new organizational options
  • Documentation updates for best practices
  • Code examples showing modern organization patterns

Phase 3: Core Adoption (Optional)

  • Gradually refactor core plugins to use logical organization
  • Demonstrate best practices in core codebase

Configuration

Introduce optional plugin manifest setting:

<extension type="plugin" group="content">
    <!-- Existing attributes -->
    <config>
        <fields name="params">
            <field name="event_discovery" type="list" default="group" 
                   label="Event Discovery Method"
                   description="How this plugin should be discovered for events">
                <option value="group">Group-based (legacy)</option>
                <option value="method">Method-based (modern)</option>
                <option value="both">Both (maximum compatibility)</option>
            </field>
        </fields>
    </config>
</extension>

Success Metrics

  1. Developer Adoption: Plugins using method-based discovery
  2. Code Quality: Reduction in single-purpose plugins
  3. Performance: No degradation in plugin loading times
  4. Compatibility: Zero reports of broken existing plugins

Conclusion

This enhancement addresses a fundamental limitation that has grown more problematic as the Joomla plugin ecosystem has matured. It provides a clear migration path toward more logical code organization while respecting the existing ecosystem.

The current system made sense when plugins were simple and few. Today's complex, multi-functional plugins deserve a more flexible architecture that supports developer productivity and maintainable code organization.


Priority: Medium
Complexity: Medium
Breaking Changes: None
Target Version: Joomla 6.x (allows thorough testing and community feedback)

avatar counterpoint counterpoint - open - 19 Aug 2025
avatar counterpoint counterpoint - change - 19 Aug 2025
Labels Removed: ?
avatar joomla-cms-bot joomla-cms-bot - change - 19 Aug 2025
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 19 Aug 2025
avatar brianteeman
brianteeman - comment - 19 Aug 2025

I do not agree that you should be able to dump everything for different events in a single plugin for the same reason as you shouldn't abuse the system plugins. There are too many technical/architectural reasons to list why this is a bad idea.

Joomla 6.x reaches feature freeze TODAY so none of this could even be considered until Joomla 7

avatar HLeithner HLeithner - change - 19 Aug 2025
Status New Closed
Closed_Date 0000-00-00 00:00:00 2025-08-19 12:03:50
Closed_By HLeithner
avatar HLeithner HLeithner - close - 19 Aug 2025

Add a Comment

Login with GitHub to post a comment