All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project attempts to adhere to Semantic Versioning.
- Internal: Fixed component caching behavior to properly track assets. Components are now always cached for asset tracking, while still providing fresh templates in
DEBUG
mode.
- Fixed component discovery for nested directories and Django app templates.
- Internal: Consolidated Component and Asset registries into a single
ComponentRegistry
. - Internal: Added component discovery at app startup instead of on-demand in the template loader.
- Fixed default content not being rendered in slots when no content is provided.
- Internal: Improved handling of component parameters in loops by creating fresh
Params
instances for each render. Previously, a singleParams
instance was reused across renders, which could cause issues with attribute resolution in loops. TheBirdNode
now stores raw attributes instead of aParams
instance, and creates a newParams
instance for each render.
- Fixed an issue where nested variable resolution (e.g.,
item.url
) would fail in loops after the first iteration. This was caused by attributes being consumed during the first render and not being available for subsequent renders.
- Internal: Removed debug prints from
BirdNode
template tag node.
- Improved handling of quoted vs unquoted attribute values in
{% bird %}
components. Quoted values (e.g.,class="static-class"
) are treated as literal strings, while unquoted values (e.g.,class=dynamic_class
) are resolved from the template context. This allows for more explicit control over whether an attribute value should be treated as a literal or resolved dynamically.
- Internal: Simplified asset management by using a global registry, making it work reliably with any template loader configuration.
- When
DEBUG=True
, thedjango_bird.components.Registry
will no longer cache the retrieval ofComponent
instances.
- Fixed a
TypeError
in theBirdLoader
when scanning for assets if aTemplate
orNode
had aNone
nodelist. This could occur with self-closing{% bird component / %}
components and their correspondingBirdNode
instances.
- New
{% bird:css %}
and{% bird:js %}
template tags to automatically include component assets - Component assets are automatically discovered from matching CSS/JS files next to component templates
- Internal: Extended
BirdLoader
to track component usage and their assets during template rendering - Internal: Assets are now stored as frozensets for immutability
- Internal: Added
ComponentAssetRegistry
to manage component assets during template rendering - Internal: Refactored
AssetType
to use string values and file extensions
- Internal: Simplified asset handling by removing global registry in favor of per-component assets
- Added component caching with LRU (Least Recently Used) strategy via global
components
registry.cachetools>=5.5.0
is now a dependency of the library to support this new cache strategy
- Internal: Flattened package structure by moving files from
components/
subdirectory to root level. No public API changes. - Internal:
BirdNode
now uses cached components instead of creating new ones each time.
- Improved handling of boolean attributes to support all forms of Django template syntax and string values. The attribute name alone (
disabled
), explicit booleans (disabled=True
), or string values (disabled="True"
) all work as expected - rendering just the attribute name when true and omitting it when false.
- Created
{% bird:prop %}
tag for defining properties within components. These operate similarly to the{{ attrs }}
template context variable, but allow for setting defaults. Any attributes passed to a component will override the prop's default value, and props defined in a component template are automatically removed from the component'sattrs
. Props are accessible in templates via theprops
context variable (e.g.{{ props.id }}
)
🚨 This release contains a breaking change. See the Changed section for more information. 🚨
- Added support for dynamic component names in
{% bird %}
tag. Component names can now be variables, e.g.{% bird component_type %}
wherecomponent_type
is a variable in the template context.
-
Reversed template resolution order to prefer component-specific templates over generic ones.
For example, given a component named
button
, the previous resolution order was:button.html
button/button.html
button/index.html
The new resolution order is:
button/button.html
button/index.html
button.html
- Fixed rendering of flat attributes in
{% bird %}
component templates. Previously, a small mistake in trying to renderboolean
values caused no attributes to be rendered. E.g.{% bird foo disabled=True %}
should have been rendered using{{ attrs }}
inside thefoo
bird component as justdisabled
-- instead nothing was being rendered, evenkey="value"
attributes.
- Created
{% bird %}
tag for creating reusable components in Django templates. - Created
{% bird:slot %}
tag for defining and using named slots within components. - Included a custom template compiler for compilation and caching of Bird components. This is essentially a no-op for now and just there as a stub for future changes.
- Created a custom template loader for integration with django-bird's compiler and Django's template engine.
- Added support for nested components and dynamic slot rendering.
- Initial configuration of the library through the
settings.DJANGO_BIRD
dictionary, including these settings:COMPONENT_DIRS
- List of directories to search for componentsENABLE_AUTO_CONFIG
- Boolean to enable/disable auto-configuration
- Josh Thomas josh@joshthomas.dev (maintainer)