What is an extension?
An extension is a structured data object that follows the Kubernetes resource model. Extensions have a predictable structure with metadata, specification, and status sections.If you’re familiar with Kubernetes, Halo extensions work similarly to Kubernetes Custom Resources.
Extension structure
Every extension has four key components:API version and kind (GVK)
Every extension is identified by its GroupVersionKind (GVK):- Group: Organizes related resources (e.g.,
content.halo.run,plugin.halo.run) - Version: API version, typically
v1alpha1orv1 - Kind: Resource type (e.g.,
Post,User,Plugin)
The GVK pattern enables API versioning and evolution without breaking existing clients.
Metadata
Metadata contains identifying information and system-managed fields:- name: Unique identifier for the extension (required)
- labels: Key-value pairs for filtering and selection
- annotations: Key-value pairs for storing arbitrary metadata
- creationTimestamp: When the extension was created (system-managed)
- deletionTimestamp: When deletion was requested (system-managed)
- version: Optimistic concurrency control version (system-managed)
- finalizers: Prevent deletion until cleanup is complete
Spec (specification)
The spec defines the desired state of the resource. This is where you declare what you want:Status
The status reflects the current observed state. Controllers update the status to report what’s actually happening:Users modify spec; controllers modify status. This separation enables clear responsibility boundaries.
Working with extensions in code
Halo provides Java interfaces for working with extensions:Defining an extension
Extensions implement theExtension interface and use the @GVK annotation:
Using ExtensionClient
TheExtensionClient provides CRUD operations for extensions:
Labels and selectors
Labels enable powerful querying capabilities:Label selectors
Filter extensions using label selectors:Field selectors
Filter by specific fields:Indexing and querying
Halo provides an indexing system for efficient queries:Indexing dramatically improves query performance for large datasets.
Controllers and reconciliation
Controllers watch extensions and reconcile them to their desired state:Extension lifecycle
Extensions move through a defined lifecycle:Finalizers and deletion
Finalizers prevent deletion until cleanup is complete:Core extensions
Halo includes several built-in extensions:Content extensions
Content extensions
- Post: Blog posts with categories and tags
- SinglePage: Standalone pages
- Comment: Comments on posts and pages
- Category: Content categories
- Tag: Content tags
System extensions
System extensions
- User: User accounts
- Role: Permission roles
- Plugin: Installed plugins
- Theme: Installed themes
- Setting: Configuration settings
- ConfigMap: Configuration data
- Secret: Sensitive data
Best practices
Follow these guidelines when working with extensions: Use meaningful names: Extension names should be descriptive and URL-safe. Leverage labels: Use labels for categorization and filtering, not for storing large amounts of data. Keep specs immutable: Avoid frequent spec changes. Use status for dynamic data. Implement reconcilers: For complex logic, use controllers to maintain consistency. Handle errors gracefully: Controllers may be retried, so ensure idempotency.Next steps
Plugins
Learn how plugins use extensions
Custom models
Create your own extension types
Reconcilers
Build controllers to manage extensions
Indexing
Optimize queries with indexing