Release notes¤
v0.137¤
Feat¤
-
Each Component class now has a
class_idattribute, which is unique to the component subclass.NOTE: This is different from
Component.id, which is unique to each rendered instance.To look up a component class by its
class_id, useget_component_by_class_id(). -
It's now easier to create URLs for component views.
Before, you had to call
Component.as_view()and pass that tourlpatterns.Now this can be done for you if you set
Component.Url.publictoTrue:Then, to get the URL for the component, use
get_component_url():This way you don't have to mix your app URLs with component URLs.
Read more on Component views and URLs.
-
Per-component caching - Set
Component.Cache.enabledtoTrueto enable caching for a component.Component caching allows you to store the rendered output of a component. Next time the component is rendered with the same input, the cached output is returned instead of re-rendering the component.
class TestComponent(Component): template = "Hello" class Cache: enabled = True ttl = 0.1 # .1 seconds TTL cache_name = "custom_cache" # Custom hash method for args and kwargs # NOTE: The default implementation simply serializes the input into a string. # As such, it might not be suitable for complex objects like Models. def hash(self, *args, **kwargs): return f"{json.dumps(args)}:{json.dumps(kwargs)}"Read more on Component caching.
-
@djc_testcan now be called without first callingdjango.setup(), in which case it does it for you. -
Expose
ComponentInputclass, which is a typing forComponent.input.
Deprecation¤
-
Currently, view request handlers such as
get()andpost()methods can be defined directly on theComponentclass:Or, nested within the
Component.Viewclass:In v1, these methods should be defined only on the
Component.Viewclass instead.
Refactor¤
Component.get_context_data()can now omit a return statement or returnNone.
🚨📢 v0.136¤
🚨📢 BREAKING CHANGES¤
-
Component input validation was moved to a separate extension
djc-ext-pydantic.If you relied on components raising errors when inputs were invalid, you need to install
djc-ext-pydanticand add it to extensions:
Fix¤
- Make it possible to resolve URLs added by extensions by their names
v0.135¤
Feat¤
- Add defaults for the component inputs with the
Component.Defaultsnested class. Defaults are applied if the argument is not given, or if it set toNone.
For lists, dictionaries, or other objects, wrap the value in Default() class to mark it as a factory function:
```python
from django_components import Default
class Table(Component):
class Defaults:
position = "left"
width = "200px"
options = Default(lambda: ["left", "right", "center"])
def get_context_data(self, position, width, options):
return {
"position": position,
"width": width,
"options": options,
}
# `position` is used as given, `"right"`
# `width` uses default because it's `None`
# `options` uses default because it's missing
Table.render(
kwargs={
"position": "right",
"width": None,
}
)
```
-
{% html_attrs %}now offers a Vue-like granular control overclassandstyleHTML attributes, where each class name or style property can be managed separately.{% html_attrs style="text-align: center; background-color: blue;" style={"background-color": "green", "color": None, "width": False} style="position: absolute; height: 12px;" %}Read more on HTML attributes.
Fix¤
- Fix compat with Windows when reading component files (#1074)
- Fix resolution of component media files edge case (#1073)
v0.134¤
Fix¤
- HOTFIX: Fix the use of URLs in
Component.Media.jsandComponent.Media.css
v0.133¤
⚠️ Attention ⚠️ - Please update to v0.134 to fix bugs introduced in v0.132.
Fix¤
- HOTFIX: Fix the use of URLs in
Component.Media.jsandComponent.Media.css
v0.132¤
⚠️ Attention ⚠️ - Please update to v0.134 to fix bugs introduced in v0.132.
Feat¤
-
Allow to use glob patterns as paths for additional JS / CSS in
Component.Media.jsandComponent.Media.css
Fix¤
- Fix installation for Python 3.13 on Windows.
v0.131¤
Feat¤
-
Support for extensions (plugins) for django-components!
- Hook into lifecycle events of django-components
- Pre-/post-process component inputs, outputs, and templates
- Add extra methods or attributes to Components
- Add custom extension-specific CLI commands
- Add custom extension-specific URL routes
Read more on Extensions.
-
New CLI commands:
components list- List all componentscomponents create <name>- Create a new component (supersedesstartcomponent)components upgrade- Upgrade a component (supersedesupgradecomponent)components ext list- List all extensionscomponents ext run <extension> <command>- Run a command added by an extension
-
@djc_testdecorator for writing tests that involve Components.- The decorator manages global state, ensuring that tests don't leak.
- If using
pytest, the decorator allows you to parametrize Django or Components settings. - The decorator also serves as a stand-in for Django's
@override_settings.
See the API reference for
@djc_testfor more details. -
ComponentRegistrynow has ahas()method to check if a component is registered without raising an error. -
Get all created
Componentclasses withall_components(). -
Get all created
ComponentRegistryinstances withall_registries().
Refactor¤
-
The
startcomponentandupgradecomponentcommands are deprecated, and will be removed in v1.Instead, use
components create <name>andcomponents upgrade.
Internal¤
- Settings are now loaded only once, and thus are considered immutable once loaded. Previously, django-components would load settings from
settings.COMPONENTSon each access. The new behavior aligns with Django's settings.
v0.130¤
Feat¤
-
Access the HttpRequest object under
Component.request.To pass the request object to a component, either: - Render a template or component with
RequestContext, - Or set therequestkwarg toComponent.render()orComponent.render_to_response().Read more on HttpRequest.
-
Access the context processors data under
Component.context_processors_data.Context processors data is available only when the component has access to the
requestobject, either by: - Passing the request toComponent.render()orComponent.render_to_response(), - Or by rendering a template or component withRequestContext, - Or being nested in another component that has access to the request object.The data from context processors is automatically available within the component's template.
Read more on HttpRequest.
v0.129¤
Fix¤
- Fix thread unsafe media resolve validation by moving it to ComponentMedia
__post_init(#977 - Fix bug: Relative path in extends and include does not work when using template_file (#976
- Fix error when template cache setting (
template_cache_size) is set to 0 (#974
v0.128¤
Feat¤
-
Configurable cache - Set
COMPONENTS.cacheto change where and how django-components caches JS and CSS files. (#946)Read more on Caching.
-
Highlight coponents and slots in the UI - We've added two boolean settings
COMPONENTS.debug_highlight_componentsandCOMPONENTS.debug_highlight_slots, which can be independently set toTrue. First will wrap components in a blue border, the second will wrap slots in a red border. (#942)Read more on Troubleshooting.
Refactor¤
- Removed use of eval for node validation (#944)
Perf¤
-
Components can now be infinitely nested. (#936)
-
Component input validation is now 6-7x faster on CPython and PyPy. This previously made up 10-30% of the total render time. (#945)
v0.127¤
Fix¤
- Fix component rendering when using
{% cache %}with remote cache and multiple web servers (#930)
v0.126¤
Refactor¤
- Replaced BeautifulSoup4 with a custom HTML parser.
- The heuristic for inserting JS and CSS dependenies into the default place has changed.
- JS is still inserted at the end of the
<body>, and CSS at the end of<head>. - However, we find end of
<body>by searching for last occurrence of</body> - And for the end of
<head>we search for the first occurrence of</head>
- JS is still inserted at the end of the
v0.125¤
⚠️ Attention ⚠️ - We migrated from EmilStenstrom/django-components to django-components/django-components.
Repo name and documentation URL changed. Package name remains the same.
If you see any broken links or other issues, please report them in #922.
Feat¤
@template_tagandBaseNode- A decorator and a class that allow you to define custom template tags that will behave similarly to django-components' own template tags.
Read more on Template tags.
Template tags defined with @template_tag and BaseNode will have the following features:
-
Accepting args, kwargs, and flags.
-
Allowing literal lists and dicts as inputs as:
key=[1, 2, 3]orkey={"a": 1, "b": 2}- Using template tags tag inputs as:{% my_tag key="{% lorem 3 w %}" / %}- Supporting the flat dictionary definition:attr:key=value- Spreading args and kwargs with...:{% my_tag ...args ...kwargs / %}- Being able to call the template tag as:{% my_tag %} ... {% endmy_tag %}or{% my_tag / %}
Refactor¤
-
Refactored template tag input validation. When you now call template tags like
{% slot %},{% fill %},{% html_attrs %}, and others, their inputs are now validated the same way as Python function inputs are.So, for example
will raise an error, because the positional argument
nameis given twice.NOTE: Special kwargs whose keys are not valid Python variable names are not affected by this change. So when you define:
The
data-idwill still be accepted as a valid kwarg, assuming that yourget_context_data()accepts**kwargs:
v0.124¤
Feat¤
-
Instead of inlining the JS and CSS under
Component.jsandComponent.css, you can move them to their own files, and link the JS/CSS files withComponent.js_fileandComponent.css_file.Even when you specify the JS/CSS with
Component.js_fileorComponent.css_file, then you can still access the content underComponent.jsorComponent.css- behind the scenes, the content of the JS/CSS files will be set toComponent.js/Component.cssupon first access.The same applies to
Component.template_file, which will populateComponent.templateupon first access.With this change, the role of
Component.js/cssand the JS/CSS inComponent.Mediahas changed:- The JS/CSS defined in
Component.js/cssorComponent.js/css_fileis the "main" JS/CSS - The JS/CSS defined in
Component.Media.js/cssare secondary or additional
See the updated "Getting Started" tutorial
- The JS/CSS defined in
Refactor¤
-
The canonical way to define a template file was changed from
template_nametotemplate_file, to align with the rest of the API.template_nameremains for backwards compatibility. When you get / settemplate_name, internally this is proxied totemplate_file. -
The undocumented
Component.component_idwas removed. Instead, useComponent.id. Changes:- While
component_idwas unique every time you instantiatedComponent, the newidis unique every time you render the component (e.g. withComponent.render()) - The new
idis available only during render, so e.g. from withinget_context_data()
- While
-
Component's HTML / CSS / JS are now resolved and loaded lazily. That is, if you specify
template_name/template_file,js_file,css_file, orMedia.js/css, the file paths will be resolved only once you:- Try to access component's HTML / CSS / JS, or
- Render the component.
Read more on Accessing component's HTML / JS / CSS.
-
Component inheritance:
- When you subclass a component, the JS and CSS defined on parent's
Mediaclass is now inherited by the child component. - You can disable or customize Media inheritance by setting
extendattribute on theComponent.Medianested class. This work similarly to Django'sMedia.extend. - When child component defines either
templateortemplate_file, both of parent'stemplateandtemplate_fileare ignored. The same applies tojs_fileandcss_file.
- When you subclass a component, the JS and CSS defined on parent's
-
Autodiscovery now ignores files and directories that start with an underscore (
_), except__init__.py -
The Signals emitted by or during the use of django-components are now documented, together the
template_renderedsignal.
v0.123¤
Fix¤
- Fix edge cases around rendering components whose templates used the
{% extends %}template tag (#859)
v0.122¤
Feat¤
- Add support for HTML fragments. HTML fragments can be rendered by passing
type="fragment"toComponent.render()orComponent.render_to_response(). Read more on how to use HTML fragments with HTMX, AlpineJS, or vanillaJS.
v0.121¤
Fix¤
- Fix the use of Django template filters (
|lower:"etc") with component inputs #855.
v0.120¤
⚠️ Attention ⚠️ - Please update to v0.121 to fix bugs introduced in v0.119.
Fix¤
- Fix the use of translation strings
_("bla")as inputs to components #849.
v0.119¤
⚠️ Attention ⚠️ - This release introduced bugs #849, #855. Please update to v0.121.
Fix¤
- Fix compatibility with custom subclasses of Django's
Templatethat need to accessoriginor other initialization arguments. (https://github.com/django-components/django-components/pull/828)
Refactor¤
- Compatibility with
django-debug-toolbar-template-profiler: -
Monkeypatching of Django's
Templatenow happens atAppConfig.ready()(https://github.com/django-components/django-components/pull/825) -
Internal parsing of template tags tag was updated. No API change. (https://github.com/django-components/django-components/pull/827)
v0.118¤
Feat¤
- Add support for
context_processorsandRenderContextinside component templates
Component.render() and Component.render_to_response() now accept an extra kwarg request.
```py
def my_view(request)
return MyTable.render_to_response(
request=request
)
```
-
When you pass in
request, the component will useRenderContextinstead ofContext. Thus the context processors will be applied to the context. -
NOTE: When you pass in both
requestandcontexttoComponent.render(), andcontextis already an instance ofContext, therequestkwarg will be ignored.
v0.117¤
Fix¤
- The HTML parser no longer erronously inserts
<html><head><body>on some occasions, and no longer tries to close unclosed HTML tags.
Refactor¤
- Replaced Selectolax with BeautifulSoup4 as project dependencies.
v0.116¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
Fix¤
- Fix the order of execution of JS scripts:
- Scripts in
Component.Media.jsare executed in the order they are defined -
Scripts in
Component.jsare executed AFTERMedia.jsscripts -
Fix compatibility with AlpineJS
- Scripts in
Component.Media.jsare now again inserted as<script>tags - By default,
Component.Media.jsare inserted as synchronous<script>tags, so the AlpineJS components registered in theMedia.jsscripts will now again run BEFORE the core AlpineJS script.
AlpineJS can be configured like so:
Option 1 - AlpineJS loaded in <head> with defer attribute:
<html>
<head>
{% component_css_dependencies %}
<script defer src="https://unpkg.com/alpinejs"></script>
</head>
<body>
{% component 'my_alpine_component' / %}
{% component_js_dependencies %}
</body>
</html>
Option 2 - AlpineJS loaded in <body> AFTER {% component_js_depenencies %}:
<html>
<head>
{% component_css_dependencies %}
</head>
<body>
{% component 'my_alpine_component' / %}
{% component_js_dependencies %}
<script src="https://unpkg.com/alpinejs"></script>
</body>
</html>
v0.115¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
Fix¤
- Fix integration with ManifestStaticFilesStorage on Windows by resolving component filepaths (like
Component.template_name) to POSIX paths.
v0.114¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
Fix¤
- Prevent rendering Slot tags during fill discovery stage to fix a case when a component inside a slot fill tried to access provided data too early.
v0.113¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
Fix¤
- Ensure consistent order of scripts in
Component.Media.js
v0.112¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
Fix¤
- Allow components to accept default fill even if no default slot was encountered during rendering
v0.111¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
Fix¤
- Prevent rendering Component tags during fill discovery stage to fix a case when a component inside the default slot tried to access provided data too early.
🚨📢 v0.110¤
⚠️ Attention ⚠️ - Please update to v0.117 to fix known bugs. See #791 and #789 and #818.
General¤
🚨📢 BREAKING CHANGES¤
-
Installation changes:
- If your components include JS or CSS, you now must use the middleware and add django-components' URLs to your
urlpatterns(See "Adding support for JS and CSS")
- If your components include JS or CSS, you now must use the middleware and add django-components' URLs to your
-
Component typing signature changed from
to
-
If you rendered a component A with
Component.render()and then inserted that into another component B, now you must passrender_dependencies=Falseto component A:
Feat¤
- Intellisense and mypy validation for settings:
Instead of defining the COMPONENTS settings as a plain dict, you can use ComponentsSettings:
# settings.py
from django_components import ComponentsSettings
COMPONENTS = ComponentsSettings(
autodiscover=True,
...
)
- Use
get_component_dirs()andget_component_files()to get the same list of dirs / files that would be imported byautodiscover(), but without actually importing them.
Refactor¤
-
For advanced use cases, use can omit the middleware and instead manage component JS and CSS dependencies yourself with
render_dependencies -
The
ComponentRegistrysettingsRegistrySettingswere lowercased to align with the global settings: RegistrySettings.CONTEXT_BEHAVIOR->RegistrySettings.context_behaviorRegistrySettings.TAG_FORMATTER->RegistrySettings.tag_formatter
The old uppercase settings CONTEXT_BEHAVIOR and TAG_FORMATTER are deprecated and will be removed in v1.
-
The setting
reload_on_template_changewas renamed toreload_on_file_change. And now it properly triggers server reload when any file in the component dirs change. The old namereload_on_template_changeis deprecated and will be removed in v1. -
The setting
forbidden_static_fileswas renamed tostatic_files_forbiddento align withstatic_files_allowedThe old nameforbidden_static_filesis deprecated and will be removed in v1.
Tags¤
🚨📢 BREAKING CHANGES¤
-
{% component_dependencies %}tag was removed. Instead, use{% component_js_dependencies %}and{% component_css_dependencies %}-
The combined tag was removed to encourage the best practice of putting JS scripts at the end of
<body>, and CSS styles inside<head>.On the other hand, co-locating JS script and CSS styles can lead to a flash of unstyled content, as either JS scripts will block the rendering, or CSS will load too late.
-
-
The undocumented keyword arg
preloadof{% component_js_dependencies %}and{% component_css_dependencies %}tags was removed. This will be replaced with HTML fragment support.
Fix¤
- Allow using forward slash (
/) when defining custom TagFormatter, e.g.{% MyComp %}..{% /MyComp %}.
Refactor¤
{% component_dependencies %}tags are now OPTIONAL - If your components use JS and CSS, but you don't use{% component_dependencies %}tags, the JS and CSS will now be, by default, inserted at the end of<body>and at the end of<head>respectively.
Slots¤
Feat¤
- Fills can now be defined within loops (
{% for %}) or other tags (like{% with %}), or even other templates using{% include %}.
Following is now possible
{% component "table" %}
{% for slot_name in slots %}
{% fill name=slot_name %}
{% endfill %}
{% endfor %}
{% endcomponent %}
- If you need to access the data or the default content of a default fill, you can set the
namekwarg to"default".
Previously, a default fill would be defined simply by omitting the {% fill %} tags:
But in that case you could not access the slot data or the default content, like it's possible for named fills:
{% component "child" %}
{% fill name="header" data="data" %}
Hello {{ data.user.name }}
{% endfill %}
{% endcomponent %}
Now, you can specify default tag by using name="default":
{% component "child" %}
{% fill name="default" data="data" %}
Hello {{ data.user.name }}
{% endfill %}
{% endcomponent %}
- When inside
get_context_data()or other component methods, the default fill can now be accessed asComponent.input.slots["default"], e.g.:
class MyTable(Component):
def get_context_data(self, *args, **kwargs):
default_slot = self.input.slots["default"]
...
- You can now dynamically pass all slots to a child component. This is similar to passing all slots in Vue:
class MyTable(Component):
def get_context_data(self, *args, **kwargs):
return {
"slots": self.input.slots,
}
template: """
<div>
{% component "child" %}
{% for slot_name in slots %}
{% fill name=slot_name data="data" %}
{% slot name=slot_name ...data / %}
{% endfill %}
{% endfor %}
{% endcomponent %}
</div>
"""
Fix¤
-
Slots defined with
{% fill %}tags are now properly accessible viaself.input.slotsinget_context_data() -
Do not raise error if multiple slots with same name are flagged as default
-
Slots can now be defined within loops (
{% for %}) or other tags (like{% with %}), or even other templates using{% include %}.
Previously, following would cause the kwarg name to be an empty string:
Refactor¤
- When you define multiple slots with the same name inside a template, you now have to set the
defaultandrequiredflags individually.
<div class="calendar-component">
<div class="header">
{% slot "image" default required %}Image here{% endslot %}
</div>
<div class="body">
{% slot "image" default required %}Image here{% endslot %}
</div>
</div>
This means you can also have multiple slots with the same name but different conditions.
E.g. in this example, we have a component that renders a user avatar - a small circular image with a profile picture of name initials.
If the component is given image_src or name_initials variables, the image slot is optional. But if neither of those are provided, you MUST fill the image slot.
<div class="avatar">
{% if image_src %}
{% slot "image" default %}
<img src="{{ image_src }}" />
{% endslot %}
{% elif name_initials %}
{% slot "image" default required %}
<div style="
border-radius: 25px;
width: 50px;
height: 50px;
background: blue;
">
{{ name_initials }}
</div>
{% endslot %}
{% else %}
{% slot "image" default required / %}
{% endif %}
</div>
- The slot fills that were passed to a component and which can be accessed as
Component.input.slotscan now be passed through the Django template, e.g. as inputs to other tags.
Internally, django-components handles slot fills as functions.
Previously, if you tried to pass a slot fill within a template, Django would try to call it as a function.
Now, something like this is possible:
class MyTable(Component):
def get_context_data(self, *args, **kwargs):
return {
"child_slot": self.input.slots["child_slot"],
}
template: """
<div>
{% component "child" content=child_slot / %}
</div>
"""
NOTE: Using {% slot %} and {% fill %} tags is still the preferred method, but the approach above may be necessary in some complex or edge cases.
- The
is_filledvariable (and the{{ component_vars.is_filled }}context variable) now returnsFalsewhen you try to access a slot name which has not been defined:
Before:
{{ component_vars.is_filled.header }} -> True
{{ component_vars.is_filled.footer }} -> False
{{ component_vars.is_filled.nonexist }} -> "" (empty string)
After:
{{ component_vars.is_filled.header }} -> True
{{ component_vars.is_filled.footer }} -> False
{{ component_vars.is_filled.nonexist }} -> False
-
Components no longer raise an error if there are extra slot fills
-
Components will raise error when a slot is doubly-filled.
E.g. if we have a component with a default slot:
Now there is two ways how we can target this slot: Either using name="default" or name="content".
In case you specify BOTH, the component will raise an error:
{% component "child" %}
{% fill slot="default" %}
Hello from default slot
{% endfill %}
{% fill slot="content" data="data" %}
Hello from content slot
{% endfill %}
{% endcomponent %}
🚨📢 v0.100¤
BREAKING CHANGES¤
-
django_components.safer_staticfilesapp was removed. It is no longer needed. -
Installation changes:
- Instead of defining component directories in
STATICFILES_DIRS, set them toCOMPONENTS.dirs. -
You now must define
STATICFILES_FINDERS
- Instead of defining component directories in
Feat¤
- Beside the top-level
/componentsdirectory, you can now define also app-level components dirs, e.g.[app]/components(SeeCOMPONENTS.app_dirs).
Refactor¤
- When you call
as_view()on a component instance, that instance will be passed toView.as_view()
v0.97¤
Fix¤
- Fixed template caching. You can now also manually create cached templates with
cached_template()
Refactor¤
-
The previously undocumented
get_templatewas made private. -
In it's place, there's a new
get_template, which supersedesget_template_string(will be removed in v1). The newget_templateis the same asget_template_string, except it allows to return either a string or a Template instance. -
You now must use only one of
template,get_template,template_name, orget_template_name.
v0.96¤
Feat¤
-
Run-time type validation for Python 3.11+ - If the
Componentclass is typed, e.g.Component[Args, Kwargs, ...], the args, kwargs, slots, and data are validated against the given types. (See Runtime input validation with types) -
Render hooks - Set
on_render_beforeandon_render_aftermethods onComponentto intercept or modify the template or context before rendering, or the rendered result afterwards. (See Component hooks) -
component_vars.is_filledcontext variable can be accessed from withinon_render_beforeandon_render_afterhooks asself.is_filled.my_slot
0.95¤
Feat¤
- Added support for dynamic components, where the component name is passed as a variable. (See Dynamic components)
Refactor¤
- Changed
Component.inputto raiseRuntimeErrorif accessed outside of render context. Previously it returnedNoneif unset.
v0.94¤
Feat¤
-
django_components now automatically configures Django to support multi-line tags. (See Multi-line tags)
-
New setting
reload_on_template_change. Set this toTrueto reload the dev server on changes to component template files. (See Reload dev server on component file changes)
v0.93¤
Feat¤
-
Spread operator
...dictinside template tags. (See Spread operator) -
Use template tags inside string literals in component inputs. (See Use template tags inside component inputs)
-
Dynamic slots, fills and provides - The
nameargument for these can now be a variable, a template expression, or via spread operator -
Component library authors can now configure
CONTEXT_BEHAVIORandTAG_FORMATTERsettings independently from user settings.
🚨📢 v0.92¤
BREAKING CHANGES¤
Componentclass is no longer a subclass ofView. To configure theViewclass, set theComponent.Viewnested class. HTTP methods likegetorpostcan still be defined directly onComponentclass, andComponent.as_view()internally callsComponent.View.as_view(). (See Modifying the View class)
Feat¤
-
The inputs (args, kwargs, slots, context, ...) that you pass to
Component.render()can be accessed from withinget_context_data,get_templateandget_template_nameviaself.input. (See Accessing data passed to the component) -
Typing:
Componentclass supports generics that specify types forComponent.render(See Adding type hints with Generics)
v0.90¤
Feat¤
-
All tags (
component,slot,fill, ...) now support "self-closing" or "inline" form, where you can omit the closing tag: -
All tags now support the "dictionary key" or "aggregate" syntax (
kwarg:key=val): -
You can change how the components are written in the template with TagFormatter.
The default is
django_components.component_formatter:While
django_components.shorthand_component_formatterallows you to write components like so:
🚨📢 v0.85¤
BREAKING CHANGES¤
-
Autodiscovery module resolution changed. Following undocumented behavior was removed:
-
Previously, autodiscovery also imported any
[app]/components.pyfiles, and usedSETTINGS_MODULEto search for component dirs.To migrate from:
-
[app]/components.py- Define each module inCOMPONENTS.librariessetting, or import each module inside theAppConfig.ready()hook in respectiveapps.pyfiles. -
SETTINGS_MODULE- Define component dirs usingSTATICFILES_DIRS
-
-
Previously, autodiscovery handled relative files in
STATICFILES_DIRS. To align with Django,STATICFILES_DIRSnow must be full paths (Django docs).
-
🚨📢 v0.81¤
BREAKING CHANGES¤
- The order of arguments to
render_to_responsehas changed, to align with the (now public)rendermethod ofComponentclass.
Feat¤
-
Component.render()is public and documented -
Slots passed
render_to_responseandrendercan now be rendered also as functions.
v0.80¤
Feat¤
- Vue-like provide/inject with the
{% provide %}tag andinject()method.
🚨📢 v0.79¤
BREAKING CHANGES¤
- Default value for the
COMPONENTS.context_behaviorsetting was changes from"isolated"to"django". If you did not set this value explicitly before, this may be a breaking change. See the rationale for change here.
🚨📢 v0.77¤
BREAKING¤
-
The syntax for accessing default slot content has changed from
to
v0.74¤
Feat¤
-
{% html_attrs %}tag for formatting data as HTML attributes -
prefix:key=valconstruct for passing dicts to components
🚨📢 v0.70¤
BREAKING CHANGES¤
-
{% if_filled "my_slot" %}tags were replaced with{{ component_vars.is_filled.my_slot }}variables. -
Simplified settings -
slot_context_behaviorandcontext_behaviorwere merged. See the documentation for more details.
v0.67¤
Refactor¤
- Changed the default way how context variables are resolved in slots. See the documentation for more details.
🚨📢 v0.50¤
BREAKING CHANGES¤
-
{% component_block %}is now{% component %}, and{% component %}blocks need an ending{% endcomponent %}tag.The new
python manage.py upgradecomponentcommand can be used to upgrade a directory (use--pathargument to point to each dir) of templates that use components to the new syntax automatically.This change is done to simplify the API in anticipation of a 1.0 release of django_components. After 1.0 we intend to be stricter with big changes like this in point releases.
v0.34¤
Feat¤
- Components as views, which allows you to handle requests and render responses from within a component. See the documentation for more details.
v0.28¤
Feat¤
- 'implicit' slot filling and the
defaultoption forslottags.
v0.27¤
Feat¤
- A second installable app
django_components.safer_staticfiles. It provides the same behavior asdjango.contrib.staticfilesbut with extra security guarantees (more info below in Security Notes).
🚨📢 v0.26¤
BREAKING CHANGES¤
-
Changed the syntax for
{% slot %}tags. From now on, we separate defining a slot ({% slot %}) from filling a slot with content ({% fill %}). This means you will likely need to change a lot of slot tags to fill.We understand this is annoying, but it's the only way we can get support for nested slots that fill in other slots, which is a very nice feature to have access to. Hoping that this will feel worth it!
v0.22¤
Feat¤
-
All files inside components subdirectores are autoimported to simplify setup.
An existing project might start to get
AlreadyRegisterederrors because of this. To solve this, either remove your custom loading of components, or set"autodiscover": Falseinsettings.COMPONENTS.
v0.17¤
BREAKING CHANGES¤
-
Renamed
Component.contextandComponent.templatetoget_context_dataandget_template_name. The old methods still work, but emit a deprecation warning.This change was done to sync naming with Django's class based views, and make using django-components more familiar to Django users.
Component.contextandComponent.templatewill be removed when version 1.0 is released.