Skip to main content

PluginRegistrationAPI Reference

The PluginRegistrationAPI is the primary interface provided to plugins for interacting with Castlecraft Architect's core component registration and path resolution systems. An instance of this API is passed to your plugin's registration function by the PluginManager.

Overview

The API allows plugins to:

  • Register new component types.
  • Override existing component types (both core and those from other plugins).
  • Provide custom path resolution logic for component types.

Initialization

You do not need to initialize PluginRegistrationAPI yourself. An instance is created by the PluginManager and provided to your plugin's registration function.

It is initialized with instances of ComponentRegistryService and ComponentLocatorService:

# Simplified internal representation
class PluginRegistrationAPI:
def __init__(
self,
registry_service: "ComponentRegistryService",
locator_service: "ComponentLocatorService",
):
self._registry = registry_service
self._locator = locator_service
# ... methods ...

Methods

register_component()

This is the main method used to register or override a component type.

def register_component(
self,
component_type_key: str,
meta: "ComponentMeta",
handler_class: Type["ComponentTypeHandler"],
path_resolver: Optional[Callable[[str, Dict[str, Any]], Optional[str]]] = None,
is_override: bool = False,
plugin_name: str = "unknown_plugin",
):

Parameters:

  • component_type_key (str): A unique string identifier for the component type (e.g., "custom_widget", "dto"). This key is case-insensitive internally.
  • meta (ComponentMeta): A dictionary containing metadata for the component. Refer to the ComponentMeta type definition (typically found in ComponentRegistryService) for the expected structure. Key fields include component_slug, file_name_template, required_context, class_suffix, and description.
  • handler_class (Type[ComponentTypeHandler]): The class responsible for handling this component type. It must be a subclass of ComponentTypeHandler. This class defines logic for code generation, schema validation, etc.
  • path_resolver (Optional[Callable[[str, Dict[str, Any]], Optional[str]]], default: None): An optional callable function that determines the file path for instances of this component type.
    • Signature: resolver(component_name: str, context_kwargs: Dict[str, Any]) -> Optional[str]
    • If None, and the component is new, path resolution will fall back to PROJECT_STRUCTURE_DEFINITION if a match is found. If overriding, and None is provided, an existing custom resolver for this component_type_key will not be removed or changed unless the original registration also had no resolver. To explicitly remove/reset a custom resolver during an override, you'd need a mechanism in ComponentLocatorService (not currently implemented via this API directly).
  • is_override (bool, default: False):
    • If True, this registration will override any existing component definition (metadata, handler, and custom path resolver if path_resolver is provided) for the given component_type_key. A log message will indicate the override.
    • If False (default), and a component with component_type_key already exists, this registration attempt will be skipped, and an error will be logged.
  • plugin_name (str): The name of the plugin performing the registration. This is automatically supplied by the PluginManager when it calls your plugin's registration function.

Usage Example (within your plugin's registration function):

# In your plugin's registration function, which now also receives the container:
# def register_my_plugin_components(
# api: "PluginRegistrationAPI",
# container: "punq.Container", # The DI container
# plugin_name: str
# ):


# api.register_component(
# component_type_key="my_new_component",
# meta=MY_NEW_COMPONENT_META,
# handler_class=MyNewComponentHandler,
# path_resolver=my_new_component_path_resolver,
# plugin_name=plugin_name
# )

# api.register_component(
# component_type_key="core_component_to_override", # e.g., "dto"
# meta=OVERRIDDEN_CORE_COMPONENT_META,
# handler_class=MyOverriddenCoreComponentHandler,
# path_resolver=my_overridden_path_resolver,
# is_override=True,
# plugin_name=plugin_name
# )

This API provides a focused way for plugins to integrate their custom components and behaviors into the Architect framework.