mirror of
https://github.com/django-components/django-components.git
synced 2025-08-31 03:07:19 +00:00
refactor: Instantiate component when rendering, and remove metadata stack (#1212)
* refactor: Instantiate component when rendering, and remove metadata stack * refactor: update test * refactor: fix linter errors * docs: remove example from changelog
This commit is contained in:
parent
2e08af9a13
commit
bae0f28813
33 changed files with 1123 additions and 707 deletions
|
@ -12,10 +12,6 @@ Render API is available inside these [`Component`](../../../reference/api#django
|
|||
- [`on_render_before()`](../../../reference/api#django_components.Component.on_render_before)
|
||||
- [`on_render_after()`](../../../reference/api#django_components.Component.on_render_after)
|
||||
|
||||
!!! note
|
||||
|
||||
If you try to access the Render API outside of these methods, you will get a `RuntimeError`.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
|
@ -46,16 +42,31 @@ rendered = Table.render(
|
|||
|
||||
The Render API includes:
|
||||
|
||||
- [`self.args`](../render_api/#args) - The positional arguments for the current render call
|
||||
- [`self.kwargs`](../render_api/#kwargs) - The keyword arguments for the current render call
|
||||
- [`self.slots`](../render_api/#slots) - The slots for the current render call
|
||||
- [`self.input`](../render_api/#component-inputs) - All the component inputs
|
||||
- [`self.id`](../render_api/#component-id) - The unique ID for the current render call
|
||||
- [`self.request`](../render_api/#request-object-and-context-processors) - The request object (if available)
|
||||
- [`self.context_processors_data`](../render_api/#request-object-and-context-processors) - Data from Django's context processors (if request is available)
|
||||
- [`self.inject()`](../render_api/#provide-inject) - Inject data into the component
|
||||
- Component inputs:
|
||||
- [`self.args`](../render_api/#args) - The positional arguments for the current render call
|
||||
- [`self.kwargs`](../render_api/#kwargs) - The keyword arguments for the current render call
|
||||
- [`self.slots`](../render_api/#slots) - The slots for the current render call
|
||||
- [`self.context`](../render_api/#context) - The context for the current render call
|
||||
- [`self.input`](../render_api/#other-inputs) - All the component inputs
|
||||
|
||||
## Args
|
||||
- Request-related:
|
||||
- [`self.request`](../render_api/#request-and-context-processors) - The request object (if available)
|
||||
- [`self.context_processors_data`](../render_api/#request-and-context-processors) - Data from Django's context processors
|
||||
|
||||
- Provide / inject:
|
||||
- [`self.inject()`](../render_api/#provide-inject) - Inject data into the component
|
||||
|
||||
- Template tag metadata:
|
||||
- [`self.registry`](../render_api/#template-tag-metadata) - The [`ComponentRegistry`](../../../reference/api/#django_components.ComponentRegistry) instance
|
||||
- [`self.registered_name`](../render_api/#template-tag-metadata) - The name under which the component was registered
|
||||
- [`self.outer_context`](../render_api/#template-tag-metadata) - The context outside of the [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
|
||||
- Other metadata:
|
||||
- [`self.id`](../render_api/#component-id) - The unique ID for the current render call
|
||||
|
||||
## Component inputs
|
||||
|
||||
### Args
|
||||
|
||||
The `args` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
@ -65,8 +76,6 @@ then the [`Component.args`](../../../reference/api/#django_components.Component.
|
|||
|
||||
Otherwise, `args` will be a plain list.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
**Example:**
|
||||
|
||||
With `Args` class:
|
||||
|
@ -99,7 +108,7 @@ class Table(Component):
|
|||
assert self.args[1] == 10
|
||||
```
|
||||
|
||||
## Kwargs
|
||||
### Kwargs
|
||||
|
||||
The `kwargs` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
@ -109,8 +118,6 @@ then the [`Component.kwargs`](../../../reference/api/#django_components.Componen
|
|||
|
||||
Otherwise, `kwargs` will be a plain dictionary.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
**Example:**
|
||||
|
||||
With `Kwargs` class:
|
||||
|
@ -143,7 +150,7 @@ class Table(Component):
|
|||
assert self.kwargs["per_page"] == 10
|
||||
```
|
||||
|
||||
## Slots
|
||||
### Slots
|
||||
|
||||
The `slots` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
@ -153,8 +160,6 @@ then the [`Component.slots`](../../../reference/api/#django_components.Component
|
|||
|
||||
Otherwise, `slots` will be a plain dictionary.
|
||||
|
||||
Raises `RuntimeError` if accessed outside of rendering execution.
|
||||
|
||||
**Example:**
|
||||
|
||||
With `Slots` class:
|
||||
|
@ -190,7 +195,27 @@ class Table(Component):
|
|||
assert isinstance(self.slots["footer"], Slot)
|
||||
```
|
||||
|
||||
## Component inputs
|
||||
### Context
|
||||
|
||||
The `context` argument as passed to
|
||||
[`Component.get_template_data()`](../../../reference/api/#django_components.Component.get_template_data).
|
||||
|
||||
This is Django's [Context](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Context)
|
||||
with which the component template is rendered.
|
||||
|
||||
If the root component or template was rendered with
|
||||
[`RequestContext`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.RequestContext)
|
||||
then this will be an instance of `RequestContext`.
|
||||
|
||||
Whether the context variables defined in `context` are available to the template depends on the
|
||||
[context behavior mode](../../../reference/settings#django_components.app_settings.ComponentsSettings.context_behavior):
|
||||
|
||||
- In `"django"` context behavior mode, the template will have access to the keys of this context.
|
||||
|
||||
- In `"isolated"` context behavior mode, the template will NOT have access to this context,
|
||||
and data MUST be passed via component's args and kwargs.
|
||||
|
||||
### Other inputs
|
||||
|
||||
You can access the most important inputs via [`self.args`](../render_api/#args),
|
||||
[`self.kwargs`](../render_api/#kwargs),
|
||||
|
@ -255,7 +280,7 @@ class Table(Component):
|
|||
assert self.id == "c1A2b3c"
|
||||
```
|
||||
|
||||
## Request object and context processors
|
||||
## Request and context processors
|
||||
|
||||
Components have access to the request object and context processors data if the component was:
|
||||
|
||||
|
@ -306,3 +331,32 @@ class Table(Component):
|
|||
data = self.inject("some_data")
|
||||
assert data.some_data == "some_data"
|
||||
```
|
||||
|
||||
## Template tag metadata
|
||||
|
||||
If the component is rendered with [`{% component %}`](../../../reference/template_tags#component) template tag,
|
||||
the following metadata is available:
|
||||
|
||||
- [`self.registry`](../../../reference/api/#django_components.Component.registry) - The [`ComponentRegistry`](../../../reference/api/#django_components.ComponentRegistry) instance
|
||||
that was used to render the component
|
||||
- [`self.registered_name`](../../../reference/api/#django_components.Component.registered_name) - The name under which the component was registered
|
||||
- [`self.outer_context`](../../../reference/api/#django_components.Component.outer_context) - The context outside of the [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
|
||||
```django
|
||||
{% with abc=123 %}
|
||||
{{ abc }} {# <--- This is in outer context #}
|
||||
{% component "my_component" / %}
|
||||
{% endwith %}
|
||||
```
|
||||
|
||||
You can use these to check whether the component was rendered inside a template with [`{% component %}`](../../../reference/template_tags#component) tag
|
||||
or in Python with [`Component.render()`](../../../reference/api/#django_components.Component.render).
|
||||
|
||||
```python
|
||||
class MyComponent(Component):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
if self.registered_name is None:
|
||||
# Do something for the render() function
|
||||
else:
|
||||
# Do something for the {% component %} template tag
|
||||
```
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue