Plugin Architecture
KolibriPluginBase
Every plugin must subclassKolibriPluginBase and define a kolibri_plugin module:
Plugin Properties
URL Configuration
untranslated_view_urls: Module containing API URL patterns (no language prefix)translated_view_urls: Module containing UI URL patterns (with language prefix)root_view_urls: Module for URLs attached to domain root (use with caution)
Settings and Options
django_settings: Module exposing additional Django settingskolibri_options: Module withoption_specfor plugin-specific configurationkolibri_option_defaults: Module to override default values of core options
Management Properties
can_manage_while_running: Whether the plugin can be enabled/disabled via GUI while Kolibri is running
Singleton Pattern
All plugin classes use a singleton pattern (viaSingletonMeta), ensuring only one instance exists:
Core vs. Plugins Decision Guide
Understanding when to add code to core versus plugins is crucial:Use Core When:
- Functionality is fundamental to Kolibri’s operation
- Code provides shared infrastructure used across multiple plugins
- Code defines base models, APIs, or utilities that plugins extend
- Feature cannot be disabled without breaking Kolibri
kolibri.core.auth: User authentication and permissionskolibri.core.content: Content channel and metadata managementkolibri.core.logger: Event logging and analyticskolibri.core.tasks: Background task queuekolibri.core.device: Device-level settings and management
Use Plugins When:
- Feature can be optionally enabled/disabled by administrators
- Code provides a specific user interface or workflow
- Feature is self-contained with minimal dependencies on other plugins
- Different deployments might want different combinations of features
kolibri.plugins.learn: Learner interface for browsing and accessing contentkolibri.plugins.coach: Coach tools for managing classes and assignmentskolibri.plugins.facility: Facility management and user administrationkolibri.plugins.device: Device configuration interface
Decision Flowchart
Managing Plugins
Enabling Plugins
Enable one or more plugins:Disabling Plugins
Disable a plugin:Setting Exact Plugin List
Disable all plugins except the specified ones:Environment Variables
Override plugin configuration via environment variables:Plugin Configuration Storage
Plugins are configured inKOLIBRI_HOME/plugins.json:
ConfigDict class manages this configuration:
Creating a Plugin
Project Structure
A typical plugin structure:Example: Learn Plugin
The Learn plugin demonstrates best practices:Plugins are automatically added to Django’s
INSTALLED_APPS when enabled, so they work like standard Django apps.Frontend Integration
Plugins can define frontend bundles using hooks:app.js entry point:
External Plugins with PEX
When using externally-built plugins with a PEX distribution:Plugin Hooks
Plugins can register hooks to extend Kolibri behavior:- NavigationHook: Add items to navigation menus
- WebpackBundleHook: Define frontend asset bundles
- RoleBasedRedirectHook: Configure role-based redirects
- ContentNodeDisplayHook: Customize content node display
kolibri.plugins.hooks module and individual hook classes for more details.
Best Practices
Keep plugins self-contained
Keep plugins self-contained
Minimize dependencies on other plugins. Use core modules for shared functionality.
Use proper URL namespacing
Use proper URL namespacing
Plugin URLs are automatically namespaced:
reverse('kolibri:mypluginclass:url_name')Document plugin options
Document plugin options
Provide clear documentation for any plugin-specific configuration options.
Test plugin enable/disable
Test plugin enable/disable
Ensure your plugin can be safely enabled and disabled without breaking other functionality.
Next Steps
Architecture Overview
Learn about Kolibri’s overall architecture
Frontend Development
Understand frontend plugin development
Backend Development
Learn backend development patterns
Testing Guide
Write tests for your plugin