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: Refactored slot handling logic by moving slot processing from
BirdNode
toBoundComponent
. - Internal: Simplified component context management in
BirdNode
by offloading context prep toBoundComponent
. - Internal: Refactored prop rendering in
Params
to take aComponent
instance instead of the rawNodeList
.
- Internal: Removed standalone
Slots
dataclass abstraction in favor of handling inBoundComponent
.
- Fixed default slot content handling when using
only
keyword for component context isolation.
- Added
data-bird-<component_name>
data attribute to theattrs
template context variable for components whenENABLE_BIRD_ATTRS
is enabled.
- Internal: Refactored component rendering by introducing a new
BoundComponent
class and moving some of the rendering logic fromComponent
andBirdNode
to this new class. - Renamed
ENABLE_BIRD_ID_ATTR
setting toENABLE_BIRD_ATTRS
to reflect its expanded functionality. - Moved setting the
data-bird-id
data attribute in theattrs
template context variable toBoundComponent
and added a sequence number to better uniquely identify multiple instances of the same component.
- The
ENABLE_BIRD_ID_ATTR
setting is deprecated and will be removed in the next minor version (v0.13.0). UseENABLE_BIRD_ATTRS
instead.
- Internal: Removed
Component.render
method in favor of newBoundComponent.render
method.
- Improved component context handling by using
Context
objects directly when a component uses the outside template context, instead of flattening the contextdict
. - Internal: Renamed
only
argument forBirdNode
toisolated_context
. This doesn't affect the public API of passingonly
to the template tag. - Standardized component names to use dots instead of slashes for nested paths (e.g., "nested.button" instead of "nested/button").
- Internal: Changed component ID generation to use MD5 hash of name, path, and normalized source instead of Python's built-in hash function. This provides more consistent IDs across different Python processes.
- Added
ENABLE_BIRD_ID_ATTR
setting (default:True
) to control whether components receive an automaticdata-bird-id
attribute. This is to help with component identification in the DOM and for a future planned feature around JS/CSS asset scoping.
- Fixed the potential for duplicate asset tags in the
{% bird:css %}
and{% bird:js %}
templatetags by using aset
instead of alist
when collecting a template's component assets.
- Internal: Refactored asset rendering logic by centralizing tag name parsing and HTML tag generation to the
django_bird.staticfiles
module.
- Changed asset URLs to use django-bird's asset view instead of file paths.
- Fixed asset serving view to properly stream files using
FileResponse
instead of reading file contents directly.
- Added built-in view and URLs for serving component assets in development. Note: This is not recommended for production use.
- Changed component name handling to preserve quotes, allowing literal string names to bypass dynamic resolution (e.g.
{% bird "button" %}
will always use "button" even ifbutton
exists in the context).
- Fixed attribute name handling in components to properly convert underscores to hyphens (e.g.
hx_get
becomeshx-get
) for better HTML compatibility.
- Added
only
keyword to{% bird %}
tag for isolating component context that, when used, components cannot access their parent template's context, e.g.,{% bird button only %}
.
- Changed handling of self-closing indicator (
/
) in{% bird %}
tag to always treat it as a syntax marker rather adding to the component's template context.
- 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 [email protected] (maintainer)