mirror of
https://github.com/django-components/django-components.git
synced 2025-07-07 17:34:59 +00:00
refactor: Update docs and tests to use get_template_data() (#1161)
* refactor: update docs and tests to use get_template_data() * refactor: fix linting * docs: add note about difference between the two methods
This commit is contained in:
parent
c69980493d
commit
28b61c1609
69 changed files with 795 additions and 725 deletions
18
README.md
18
README.md
|
@ -63,8 +63,8 @@ class Calendar(Component):
|
|||
js_file = "calendar.js"
|
||||
css_file = "calendar.css"
|
||||
|
||||
def get_context_data(self, date):
|
||||
return {"date": date}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"date": kwargs["date"]}
|
||||
```
|
||||
|
||||
Use the component like this:
|
||||
|
@ -125,9 +125,9 @@ class Calendar(Component):
|
|||
css = ["bootstrap/dist/css/bootstrap.min.css"]
|
||||
|
||||
# Variables available in the template
|
||||
def get_context_data(self, date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date
|
||||
"date": kwargs["date"]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -232,7 +232,7 @@ class Table(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, var1, var2, variable, another, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access component's ID
|
||||
assert self.id == "djc1A2b3c"
|
||||
|
||||
|
@ -247,7 +247,7 @@ class Table(Component):
|
|||
assert self.context_processors_data['user'].username == "admin"
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
# Access component's HTML / JS / CSS
|
||||
|
@ -347,9 +347,9 @@ class Calendar(Component):
|
|||
},
|
||||
)
|
||||
|
||||
def get_context_data(self, page):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"page": page,
|
||||
"page": kwargs["page"],
|
||||
}
|
||||
|
||||
# Get auto-generated URL for the component
|
||||
|
@ -381,7 +381,7 @@ Read more about [Provide / Inject](https://django-components.github.io/django-co
|
|||
class Header(Component):
|
||||
template = "..."
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
theme = self.inject("theme").variant
|
||||
return {
|
||||
"theme": theme,
|
||||
|
|
|
@ -98,8 +98,8 @@ class MyComponent(Component):
|
|||
ttl = 300 # Cache for 5 minutes
|
||||
cache_name = "my_cache"
|
||||
|
||||
def get_context_data(self, name, **kwargs):
|
||||
return {"name": name}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": kwargs["name"]}
|
||||
```
|
||||
|
||||
In this example, the component's rendered output is cached for 5 minutes using the `my_cache` backend.
|
||||
|
|
|
@ -12,7 +12,7 @@ NOTE: `{% csrf_token %}` tags need access to the top-level context, and they wil
|
|||
|
||||
If you find yourself using the `only` modifier often, you can set the [context_behavior](#context-behavior) option to `"isolated"`, which automatically applies the `only` modifier. This is useful if you want to make sure that components don't accidentally access the outer context.
|
||||
|
||||
Components can also access the outer context in their context methods like `get_context_data` by accessing the property `self.outer_context`.
|
||||
Components can also access the outer context in their context methods like `get_template_data` by accessing the property `self.outer_context`.
|
||||
|
||||
## Example of Accessing Outer Context
|
||||
|
||||
|
@ -22,14 +22,14 @@ Components can also access the outer context in their context methods like `get_
|
|||
</div>
|
||||
```
|
||||
|
||||
Assuming that the rendering context has variables such as `date`, you can use `self.outer_context` to access them from within `get_context_data`. Here's how you might implement it:
|
||||
Assuming that the rendering context has variables such as `date`, you can use `self.outer_context` to access them from within `get_template_data`. Here's how you might implement it:
|
||||
|
||||
```python
|
||||
class Calender(Component):
|
||||
|
||||
...
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
outer_field = self.outer_context["date"]
|
||||
return {
|
||||
"date": outer_fields,
|
||||
|
@ -56,7 +56,7 @@ This has two modes:
|
|||
[`{% with %}`](https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#with) tags.
|
||||
- Any loops ([`{% for ... %}`](https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#cycle))
|
||||
that the `{% fill %}` tag is part of.
|
||||
- Data returned from [`Component.get_context_data()`](../../../reference/api#django_components.Component.get_context_data)
|
||||
- Data returned from [`Component.get_template_data()`](../../../reference/api#django_components.Component.get_template_data)
|
||||
of the component that owns the fill tag.
|
||||
|
||||
- `"isolated"`
|
||||
|
@ -69,12 +69,12 @@ This has two modes:
|
|||
|
||||
- Any loops ([`{% for ... %}`](https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#cycle))
|
||||
that the `{% fill %}` tag is part of.
|
||||
- [`Component.get_context_data()`](../../../reference/api#django_components.Component.get_context_data)
|
||||
- [`Component.get_template_data()`](../../../reference/api#django_components.Component.get_template_data)
|
||||
of the component which defined the template (AKA the "root" component).
|
||||
|
||||
!!! warning
|
||||
|
||||
Notice that the component whose `get_context_data()` we use inside
|
||||
Notice that the component whose `get_template_data()` we use inside
|
||||
[`{% fill %}`](../../../reference/template_tags#fill)
|
||||
is NOT the same across the two modes!
|
||||
|
||||
|
@ -93,10 +93,10 @@ This has two modes:
|
|||
"""
|
||||
```
|
||||
|
||||
- `"django"` - `my_var` has access to data from `get_context_data()` of both `Inner` and `Outer`.
|
||||
- `"django"` - `my_var` has access to data from `get_template_data()` of both `Inner` and `Outer`.
|
||||
If there are variables defined in both, then `Inner` overshadows `Outer`.
|
||||
|
||||
- `"isolated"` - `my_var` has access to data from `get_context_data()` of ONLY `Outer`.
|
||||
- `"isolated"` - `my_var` has access to data from `get_template_data()` of ONLY `Outer`.
|
||||
|
||||
|
||||
### Example "django"
|
||||
|
@ -115,11 +115,11 @@ class RootComp(Component):
|
|||
{% endwith %}
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return { "my_var": 123 }
|
||||
```
|
||||
|
||||
Then if [`get_context_data()`](../../../reference/api#django_components.Component.get_context_data)
|
||||
Then if [`get_template_data()`](../../../reference/api#django_components.Component.get_template_data)
|
||||
of the component `"my_comp"` returns following data:
|
||||
|
||||
```py
|
||||
|
@ -154,11 +154,11 @@ class RootComp(Component):
|
|||
{% endwith %}
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return { "my_var": 123 }
|
||||
```
|
||||
|
||||
Then if [`get_context_data()`](../../../reference/api#django_components.Component.get_context_data)
|
||||
Then if [`get_template_data()`](../../../reference/api#django_components.Component.get_template_data)
|
||||
of the component `"my_comp"` returns following data:
|
||||
|
||||
```py
|
||||
|
@ -172,7 +172,7 @@ Then the template will be rendered as:
|
|||
# cheese
|
||||
```
|
||||
|
||||
Because variables `"my_var"` and `"cheese"` are searched only inside `RootComponent.get_context_data()`.
|
||||
Because variables `"my_var"` and `"cheese"` are searched only inside `RootComponent.get_template_data()`.
|
||||
But since `"cheese"` is not defined there, it's empty.
|
||||
|
||||
!!! info
|
||||
|
|
|
@ -12,9 +12,9 @@ class Calendar(Component):
|
|||
template_file = "template.html"
|
||||
|
||||
# This component takes one parameter, a date string to show in the template
|
||||
def get_context_data(self, date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs["date"],
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ Extensions can define methods to hook into lifecycle events, such as:
|
|||
- Un/registering a component
|
||||
- Creating or deleting a registry
|
||||
- Pre-processing data passed to a component on render
|
||||
- Post-processing data returned from [`get_context_data()`](../../../reference/api#django_components.Component.get_context_data)
|
||||
- Post-processing data returned from [`get_template_data()`](../../../reference/api#django_components.Component.get_template_data)
|
||||
and others.
|
||||
|
||||
See the full list in [Extension Hooks Reference](../../../reference/extension_hooks).
|
||||
|
@ -122,7 +122,7 @@ For example, the View extension is available as `self.view`:
|
|||
|
||||
```python
|
||||
class MyTable(Component):
|
||||
def get_context_data(self, request):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# `self.view` points to the instance of `View` extension.
|
||||
return {
|
||||
"view": self.view,
|
||||
|
@ -133,7 +133,7 @@ And the Storybook extension is available as `self.storybook`:
|
|||
|
||||
```python
|
||||
class MyTable(Component):
|
||||
def get_context_data(self, request):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# `self.storybook` points to the instance of `Storybook` extension.
|
||||
return {
|
||||
"title": self.storybook.title(),
|
||||
|
|
|
@ -78,7 +78,7 @@ In the example from previous section, we've defined two kwargs: `hello="hi" anot
|
|||
|
||||
```py
|
||||
class ChildComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
my_data = self.inject("my_data")
|
||||
print(my_data.hello) # hi
|
||||
print(my_data.another) # 123
|
||||
|
@ -94,7 +94,7 @@ To avoid the error, you can pass a second argument to [`inject()`](../../../refe
|
|||
|
||||
```py
|
||||
class ChildComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
my_data = self.inject("invalid_key", DEFAULT_DATA)
|
||||
assert my_data == DEFAULT_DATA
|
||||
return {}
|
||||
|
@ -119,7 +119,7 @@ class ChildComponent(Component):
|
|||
<div> {{ my_data.another }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
my_data = self.inject("my_data", "default")
|
||||
return {"my_data": my_data}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
When a component is being rendered, the component inputs are passed to various methods like
|
||||
[`get_context_data()`](../../../reference/api#django_components.Component.get_context_data),
|
||||
[`get_template_data()`](../../../reference/api#django_components.Component.get_template_data),
|
||||
[`get_js_data()`](../../../reference/api#django_components.Component.get_js_data),
|
||||
or [`get_css_data()`](../../../reference/api#django_components.Component.get_css_data).
|
||||
|
||||
|
@ -24,10 +24,10 @@ class MyTable(Component):
|
|||
position = "left"
|
||||
selected_items = Default(lambda: [1, 2, 3])
|
||||
|
||||
def get_context_data(self, position, selected_items):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"position": position,
|
||||
"selected_items": selected_items,
|
||||
"position": kwargs["position"],
|
||||
"selected_items": kwargs["selected_items"],
|
||||
}
|
||||
|
||||
...
|
||||
|
@ -138,10 +138,10 @@ class MyTable(Component):
|
|||
position = "left"
|
||||
selected_items = Default(lambda: [1, 2, 3])
|
||||
|
||||
def get_context_data(self, position, selected_items):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"position": position,
|
||||
"selected_items": selected_items,
|
||||
"position": kwargs["position"],
|
||||
"selected_items": kwargs["selected_items"],
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -47,10 +47,10 @@ You can use this for example to allow users of your component to add extra attri
|
|||
```djc_py
|
||||
@register("my_comp")
|
||||
class MyComp(Component):
|
||||
# Capture extra kwargs in `attrs`
|
||||
def get_context_data(self, **attrs):
|
||||
# Pass all kwargs as `attrs`
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs,
|
||||
"classes": "text-red",
|
||||
"my_id": 123,
|
||||
}
|
||||
|
@ -607,10 +607,11 @@ class MyComp(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, date: Date, attrs: dict):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
date = kwargs.pop("date")
|
||||
return {
|
||||
"date": date,
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs,
|
||||
"class_from_var": "extra-class"
|
||||
}
|
||||
|
||||
|
@ -625,7 +626,7 @@ class Parent(Component):
|
|||
/ %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, date: Date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": datetime.now(),
|
||||
"json_data": json.dumps({"value": 456})
|
||||
|
@ -669,7 +670,7 @@ So all kwargs that start with `attrs:` will be collected into an `attrs` dict.
|
|||
attrs:@click="(e) => onClick(e, 'from_parent')"
|
||||
```
|
||||
|
||||
And `get_context_data` of `MyComp` will receive `attrs` input with following keys:
|
||||
And `get_template_data` of `MyComp` will receive a kwarg named `attrs` with following keys:
|
||||
|
||||
```py
|
||||
attrs = {
|
||||
|
|
|
@ -100,6 +100,44 @@ class ProfileCard(Component):
|
|||
}
|
||||
```
|
||||
|
||||
There is a slight difference between [`get_context_data()`](../../../reference/api/#django_components.Component.get_context_data) and [`get_template_data()`](../../../reference/api/#django_components.Component.get_template_data)
|
||||
when rendering a component with the [`{% component %}`](../../../reference/template_tags/#component) tag.
|
||||
|
||||
For example if you have component that accepts kwarg `date`:
|
||||
|
||||
```py
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self, date, *args, **kwargs):
|
||||
return {
|
||||
"date": date,
|
||||
}
|
||||
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": kwargs["date"],
|
||||
}
|
||||
```
|
||||
|
||||
The difference is that:
|
||||
|
||||
- With [`get_context_data()`](../../../reference/api/#django_components.Component.get_context_data), you can pass `date` either as arg or kwarg:
|
||||
|
||||
```django
|
||||
✅
|
||||
{% component "my_component" date=some_date %}
|
||||
{% component "my_component" some_date %}
|
||||
```
|
||||
|
||||
- But with [`get_template_data()`](../../../reference/api/#django_components.Component.get_template_data), `date` MUST be passed as kwarg:
|
||||
|
||||
```django
|
||||
✅
|
||||
{% component "my_component" date=some_date %}
|
||||
|
||||
❌
|
||||
{% component "my_component" some_date %}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
|
||||
[`get_template_data()`](../../../reference/api/#django_components.Component.get_template_data)
|
||||
|
|
|
@ -48,7 +48,7 @@ When the component has access to the `request` object, the request object will b
|
|||
|
||||
```python
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
'user_id': self.request.GET['user_id'],
|
||||
}
|
||||
|
@ -77,11 +77,11 @@ class MyComponent(Component):
|
|||
MyComponent.render(request=request)
|
||||
```
|
||||
|
||||
You can also access the context processors data from within [`get_context_data()`](../../../reference/api#django_components.Component.get_context_data) and other methods under [`Component.context_processors_data`](../../../reference/api#django_components.Component.context_processors_data).
|
||||
You can also access the context processors data from within [`get_template_data()`](../../../reference/api#django_components.Component.get_template_data) and other methods under [`Component.context_processors_data`](../../../reference/api#django_components.Component.context_processors_data).
|
||||
|
||||
```python
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
csrf_token = self.context_processors_data['csrf_token']
|
||||
return {
|
||||
'csrf_token': csrf_token,
|
||||
|
|
|
@ -20,7 +20,7 @@ Example:
|
|||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access component's ID
|
||||
assert self.id == "c1A2b3c"
|
||||
|
||||
|
@ -77,7 +77,7 @@ If you need to expand this limit, please open an issue on GitHub.
|
|||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access component's ID
|
||||
assert self.id == "c1A2b3c"
|
||||
|
||||
|
@ -102,7 +102,7 @@ to access the positional and keyword arguments passed to [`Component.render()`](
|
|||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access component's inputs, slots and context
|
||||
assert self.input.args == [123, "str"]
|
||||
assert self.input.kwargs == {"variable": "test", "another": 1}
|
||||
|
@ -140,7 +140,7 @@ Read more about the request object and context processors in the [HTTP Request](
|
|||
from django.http import HttpRequest
|
||||
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access the request object and Django's context processors
|
||||
assert self.request.GET == {"query": "something"}
|
||||
assert self.context_processors_data['user'].username == "admin"
|
||||
|
@ -166,7 +166,7 @@ Read more about [Provide / Inject](../advanced/provide_inject.md).
|
|||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access provided data
|
||||
data = self.inject("some_data")
|
||||
assert data.some_data == "some_data"
|
||||
|
|
|
@ -30,9 +30,9 @@ from django_components import Component, register, types
|
|||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs["date"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -114,9 +114,9 @@ from django_components import Component, register, types
|
|||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs["date"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -155,9 +155,9 @@ from django_components import Component, register
|
|||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs["date"],
|
||||
}
|
||||
|
||||
# language=HTML
|
||||
|
|
|
@ -165,8 +165,8 @@ like so:
|
|||
|
||||
```py
|
||||
class MyTable(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
default_slot = self.input.slots["default"]
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
default_slot = slots["default"]
|
||||
return {
|
||||
"default_slot": default_slot,
|
||||
}
|
||||
|
@ -475,8 +475,8 @@ class MyComp(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, input):
|
||||
processed_input = do_something(input)
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
processed_input = do_something(kwargs["input"])
|
||||
return {"input": processed_input}
|
||||
```
|
||||
|
||||
|
@ -504,8 +504,8 @@ class MyComp(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, input):
|
||||
processed_input = do_something(input)
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
processed_input = do_something(kwargs["input"])
|
||||
return {
|
||||
"input": processed_input,
|
||||
}
|
||||
|
@ -646,9 +646,9 @@ You can dynamically pass all slots to a child component. This is similar to
|
|||
|
||||
```djc_py
|
||||
class MyTable(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"slots": self.input.slots,
|
||||
"slots": slots,
|
||||
}
|
||||
|
||||
template = """
|
||||
|
|
|
@ -100,7 +100,7 @@ class BaseForm(Component):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"form_content": self.get_form_content(),
|
||||
"submit_text": "Submit"
|
||||
|
@ -112,8 +112,8 @@ class BaseForm(Component):
|
|||
class ContactForm(BaseForm):
|
||||
# Extend parent's "context"
|
||||
# but override "submit_text"
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
context = super().get_template_data(args, kwargs, slots, context)
|
||||
context["submit_text"] = "Send Message"
|
||||
return context
|
||||
|
||||
|
|
|
@ -30,14 +30,12 @@ so are still valid:
|
|||
</body>
|
||||
```
|
||||
|
||||
These can then be accessed inside `get_context_data` so:
|
||||
These can then be accessed inside `get_template_data` so:
|
||||
|
||||
```py
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
# Since # . @ - are not valid identifiers, we have to
|
||||
# use `**kwargs` so the method can accept these args.
|
||||
def get_context_data(self, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": kwargs["my-date"],
|
||||
"id": kwargs["#some_id"],
|
||||
|
@ -92,17 +90,17 @@ _New in version 0.93_
|
|||
When passing data around, sometimes you may need to do light transformations, like negating booleans or filtering lists.
|
||||
|
||||
Normally, what you would have to do is to define ALL the variables
|
||||
inside `get_context_data()`. But this can get messy if your components contain a lot of logic.
|
||||
inside `get_template_data()`. But this can get messy if your components contain a lot of logic.
|
||||
|
||||
```py
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, id: str, editable: bool):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"editable": editable,
|
||||
"readonly": not editable,
|
||||
"input_id": f"input-{id}",
|
||||
"icon_id": f"icon-{id}",
|
||||
"editable": kwargs["editable"],
|
||||
"readonly": not kwargs["editable"],
|
||||
"input_id": f"input-{kwargs['id']}",
|
||||
"icon_id": f"icon-{kwargs['id']}",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
@ -200,10 +198,10 @@ class MyComp(Component):
|
|||
{% component "other" attrs=attrs / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, some_id: str):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
attrs = {
|
||||
"class": "pa-4 flex",
|
||||
"data-some-id": some_id,
|
||||
"data-some-id": kwargs["some_id"],
|
||||
"@click.stop": "onClickHandler",
|
||||
}
|
||||
return {"attrs": attrs}
|
||||
|
@ -231,8 +229,8 @@ class MyComp(Component):
|
|||
/ %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, some_id: str):
|
||||
return {"some_id": some_id}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"some_id": kwargs["some_id"]}
|
||||
```
|
||||
|
||||
Sweet! Now all the relevant HTML is inside the template, and we can move it to a separate file with confidence:
|
||||
|
|
|
@ -184,7 +184,7 @@ class Calendar(Component):
|
|||
js_file = "calendar.js" # <--- new
|
||||
css_file = "calendar.css" # <--- new
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": "1970-01-01",
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ class Calendar(Component):
|
|||
"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", # Tailwind
|
||||
]
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": "1970-01-01",
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ the to `2024-12-14`, which is Saturday, our template from previous step would re
|
|||
|
||||
The first instance rendered `2024-12-16`, while the rest rendered `2024-12-14`!
|
||||
|
||||
Why? Remember that in the [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
Why? Remember that in the [`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
method of our Calendar component, we pre-process the date. If the date falls on Saturday or Sunday, we shift it to next Monday:
|
||||
|
||||
```python title="[project root]/components/calendar/calendar.py"
|
||||
|
@ -174,11 +174,11 @@ def to_workweek_date(d: date):
|
|||
class Calendar(Component):
|
||||
template_file = "calendar.html"
|
||||
...
|
||||
def get_context_data(self, date: date, extra_class: str | None = None):
|
||||
workweek_date = to_workweek_date(date)
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
workweek_date = to_workweek_date(kwargs["date"])
|
||||
return {
|
||||
"date": workweek_date,
|
||||
"extra_class": extra_class,
|
||||
"extra_class": kwargs.get("extra_class", "text-blue"),
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -284,7 +284,7 @@ each time:
|
|||
Generally, slots are more flexible - you can access the slot data, even the original slot content.
|
||||
Thus, slots behave more like functions that render content based on their context.
|
||||
|
||||
On the other hand, variables are static - the variable you pass to a component is what will be used.
|
||||
On the other hand, variables are simpler - the variable you pass to a component is what will be used.
|
||||
|
||||
Moreover, slots are treated as part of the template - for example the CSS scoping (work in progress)
|
||||
is applied to the slot content too.
|
||||
|
|
|
@ -30,7 +30,7 @@ class Calendar(Component):
|
|||
js_file = "calendar.js"
|
||||
css_file = "calendar.css"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": "1970-01-01",
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ What we want is to be able to use the Calendar component within the template lik
|
|||
### 1. Understading component inputs
|
||||
|
||||
In section [Create your first component](../your_first_component), we defined
|
||||
the [`get_context_data()`](../../reference/api#django_components.Component.get_context_data) method
|
||||
the [`get_template_data()`](../../reference/api#django_components.Component.get_template_data) method
|
||||
that defines what variables will be available within the template:
|
||||
|
||||
```python title="[project root]/components/calendar/calendar.py"
|
||||
|
@ -20,13 +20,13 @@ from django_components import Component, register
|
|||
class Calendar(Component):
|
||||
template_file = "calendar.html"
|
||||
...
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": "1970-01-01",
|
||||
}
|
||||
```
|
||||
|
||||
What we didn't say is that [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
What we didn't say is that [`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
actually receives the args and kwargs that were passed to a component.
|
||||
|
||||
So if we call a component with a `date` and `extra_class` keywords:
|
||||
|
@ -38,7 +38,10 @@ So if we call a component with a `date` and `extra_class` keywords:
|
|||
This is the same as calling:
|
||||
|
||||
```py
|
||||
Calendar.get_context_data(date="2024-12-13", extra_class="text-red")
|
||||
Calendar.get_template_data(
|
||||
args=[],
|
||||
kwargs={"date": "2024-12-13", "extra_class": "text-red"},
|
||||
)
|
||||
```
|
||||
|
||||
And same applies to positional arguments, or mixing args and kwargs, where:
|
||||
|
@ -50,13 +53,16 @@ And same applies to positional arguments, or mixing args and kwargs, where:
|
|||
is same as
|
||||
|
||||
```py
|
||||
Calendar.get_context_data("2024-12-13", extra_class="text-red")
|
||||
Calendar.get_template_data(
|
||||
args=["2024-12-13"],
|
||||
kwargs={"extra_class": "text-red"},
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Define inputs for `get_context_data`
|
||||
### 2. Define inputs
|
||||
|
||||
Let's put this to test. We want to pass `date` and `extra_class` kwargs to the component.
|
||||
And so, we can write the [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
And so, we can write the [`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
method such that it expects those parameters:
|
||||
|
||||
```python title="[project root]/components/calendar/calendar.py"
|
||||
|
@ -68,46 +74,40 @@ from django_components import Component, register
|
|||
class Calendar(Component):
|
||||
template_file = "calendar.html"
|
||||
...
|
||||
def get_context_data(self, date: date, extra_class: str = "text-blue"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"extra_class": extra_class,
|
||||
"date": kwargs["date"],
|
||||
"extra_class": kwargs.get("extra_class", "text-blue"),
|
||||
}
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
||||
Since [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
is just a regular Python function, type hints annotations work the same way as anywhere else.
|
||||
|
||||
!!! warning
|
||||
|
||||
Since [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
is just a regular Python function, it will raise TypeError if it receives incorrect parameters.
|
||||
|
||||
Since `extra_class` is optional in the function signature, it's optional also in the template.
|
||||
So both following calls are valid:
|
||||
|
||||
```htmldjango
|
||||
{% component "calendar" "2024-12-13" / %}
|
||||
{% component "calendar" "2024-12-13" extra_class="text-red" / %}
|
||||
{% component "calendar" date="2024-12-13" / %}
|
||||
{% component "calendar" date="2024-12-13" extra_class="text-red" / %}
|
||||
```
|
||||
|
||||
However, `date` is required. Thus we MUST provide it. Same with regular Python functions,
|
||||
`date` can be set either as positional or keyword argument. But either way it MUST be set:
|
||||
!!! warning
|
||||
|
||||
```htmldjango
|
||||
✅
|
||||
{% component "calendar" "2024-12-13" / %}
|
||||
{% component "calendar" extra_class="text-red" date="2024-12-13" / %}
|
||||
[`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
differentiates between positional and keyword arguments,
|
||||
so you have to make sure to pass the arguments correctly.
|
||||
|
||||
❌
|
||||
{% component "calendar" extra_class="text-red" / %}
|
||||
```
|
||||
Since `date` is expected to be a keyword argument, it MUST be provided as such:
|
||||
|
||||
### 3. Process inputs in `get_context_data`
|
||||
```htmldjango
|
||||
✅ `date` is kwarg
|
||||
{% component "calendar" date="2024-12-13" / %}
|
||||
|
||||
The [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
❌ `date` is arg
|
||||
{% component "calendar" "2024-12-13" / %}
|
||||
```
|
||||
|
||||
### 3. Process inputs
|
||||
|
||||
The [`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
method is powerful, because it allows us to decouple
|
||||
component inputs from the template variables. In other words, we can pre-process
|
||||
the component inputs, and massage them into a shape that's most appropriate for
|
||||
|
@ -160,12 +160,14 @@ cities_by_pop = [
|
|||
]
|
||||
```
|
||||
|
||||
Without the `get_context_data()` method, we'd have to either:
|
||||
Without the [`get_template_data()`](../../reference/api#django_components.Component.get_template_data) method,
|
||||
we'd have to either:
|
||||
|
||||
1. Pre-process the data in Python before passing it to the components.
|
||||
2. Define a Django filter or template tag to take the data and process it on the spot.
|
||||
|
||||
Instead, with `get_context_data()`, we can keep this transformation private to this component,
|
||||
Instead, with [`get_template_data()`](../../reference/api#django_components.Component.get_template_data),
|
||||
we can keep this transformation private to this component,
|
||||
and keep the rest of the codebase clean.
|
||||
|
||||
```py
|
||||
|
@ -176,13 +178,14 @@ def group_by_pop(data):
|
|||
class PopulationTable(Component):
|
||||
template_file = "population_table.html"
|
||||
|
||||
def get_context_data(self, data):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"data": group_by_pop(data),
|
||||
"data": group_by_pop(kwargs["data"]),
|
||||
}
|
||||
```
|
||||
|
||||
Similarly we can make use of `get_context_data()` to pre-process the date that was given to the component:
|
||||
Similarly we can make use of [`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
to pre-process the date that was given to the component:
|
||||
|
||||
```python title="[project root]/components/calendar/calendar.py"
|
||||
from datetime import date
|
||||
|
@ -197,17 +200,17 @@ def to_workweek_date(d: date):
|
|||
class Calendar(Component):
|
||||
template_file = "calendar.html"
|
||||
...
|
||||
def get_context_data(self, date: date, extra_class: str = "text-blue"):
|
||||
workweek_date = to_workweek_date(date) # <--- new
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
workweek_date = to_workweek_date(kwargs["date"]) # <--- new
|
||||
return {
|
||||
"date": workweek_date, # <--- changed
|
||||
"extra_class": extra_class,
|
||||
"extra_class": kwargs.get("extra_class", "text-blue"),
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Pass inputs to components
|
||||
|
||||
Once we're happy with `Calendar.get_contex_data()`, we can update our templates to use
|
||||
Once we're happy with `Calendar.get_template_data()`, we can update our templates to use
|
||||
the parametrized version of the component:
|
||||
|
||||
```htmldjango
|
||||
|
@ -224,7 +227,7 @@ Next, you will learn [how to use slots give your components even more flexibilit
|
|||
### 5. Add defaults
|
||||
|
||||
In our example, we've set the `extra_class` to default to `"text-blue"` by setting it in the
|
||||
[`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
[`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
method.
|
||||
|
||||
However, you may want to use the same default value in multiple methods, like
|
||||
|
@ -248,10 +251,10 @@ class Calendar(Component):
|
|||
class Defaults: # <--- new
|
||||
extra_class = "text-blue"
|
||||
|
||||
def get_context_data(self, date: date, extra_class: str): # <--- changed
|
||||
workweek_date = to_workweek_date(date)
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
workweek_date = to_workweek_date(kwargs["date"])
|
||||
return {
|
||||
"date": workweek_date,
|
||||
"extra_class": extra_class,
|
||||
"extra_class": kwargs["extra_class"], # <--- changed
|
||||
}
|
||||
```
|
||||
|
|
|
@ -19,7 +19,7 @@ class Calendar(Component):
|
|||
js_file = "calendar.js"
|
||||
css_file = "calendar.css"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": "1970-01-01",
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ Inside `calendar.html`, write:
|
|||
```
|
||||
|
||||
In this example we've defined one template variable `date`. You can use any and as many variables as you like. These variables will be
|
||||
defined in the Python file in [`get_context_data()`](../../reference/api#django_components.Component.get_context_data)
|
||||
defined in the Python file in [`get_template_data()`](../../reference/api#django_components.Component.get_template_data)
|
||||
when creating an instance of this component.
|
||||
|
||||
!!! note
|
||||
|
@ -142,7 +142,7 @@ class Calendar(Component):
|
|||
|
||||
In `calendar.html`, we've used the variable `date`. So we need to define it for the template to work.
|
||||
|
||||
This is done using [`Component.get_context_data()`](../../reference/api#django_components.Component.get_context_data).
|
||||
This is done using [`Component.get_template_data()`](../../reference/api#django_components.Component.get_template_data).
|
||||
It's a function that returns a dictionary. The entries in this dictionary
|
||||
will become available within the template as variables, e.g. as `{{ date }}`.
|
||||
|
||||
|
@ -152,7 +152,7 @@ from django_components import Component
|
|||
class Calendar(Component):
|
||||
template_file = "calendar.html"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": "1970-01-01",
|
||||
}
|
||||
|
|
|
@ -246,6 +246,6 @@ Instead, our solution is closer to [how Vue handles slots](https://vuejs.org/gui
|
|||
|
||||
While we do not wrap the logic in a function, we do PREPARE IN ADVANCE:
|
||||
1. The content that should be rendered for each slot
|
||||
2. The context variables from `get_context_data()`
|
||||
2. The context variables from `get_template_data()`
|
||||
|
||||
Thus, once we reach the `{% slot %}` node, in it's `render()` method, we access the data above, and, depending on the `context_behavior` setting, include the current context or not. For more info, see `SlotNode.render()`.
|
||||
|
|
|
@ -53,8 +53,8 @@ class Calendar(Component):
|
|||
js_file = "calendar.js"
|
||||
css_file = "calendar.css"
|
||||
|
||||
def get_context_data(self, date):
|
||||
return {"date": date}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"date": kwargs["date"]}
|
||||
```
|
||||
|
||||
Use the component like this:
|
||||
|
@ -115,9 +115,9 @@ class Calendar(Component):
|
|||
css = ["bootstrap/dist/css/bootstrap.min.css"]
|
||||
|
||||
# Variables available in the template
|
||||
def get_context_data(self, date):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"date": date
|
||||
"date": kwargs["date"]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -222,7 +222,7 @@ class Table(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, var1, var2, variable, another, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access component's ID
|
||||
assert self.id == "djc1A2b3c"
|
||||
|
||||
|
@ -237,7 +237,7 @@ class Table(Component):
|
|||
assert self.context_processors_data['user'].username == "admin"
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
# Access component's HTML / JS / CSS
|
||||
|
@ -337,9 +337,9 @@ class Calendar(Component):
|
|||
},
|
||||
)
|
||||
|
||||
def get_context_data(self, page):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"page": page,
|
||||
"page": kwargs["page"],
|
||||
}
|
||||
|
||||
# Get auto-generated URL for the component
|
||||
|
@ -371,7 +371,7 @@ Read more about [Provide / Inject](https://django-components.github.io/django-co
|
|||
class Header(Component):
|
||||
template = "..."
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
theme = self.inject("theme").variant
|
||||
return {
|
||||
"theme": theme,
|
||||
|
|
|
@ -67,7 +67,7 @@ If you insert this tag multiple times, ALL JS scripts will be duplicately insert
|
|||
|
||||
|
||||
|
||||
<a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L2794" target="_blank">See source code</a>
|
||||
<a href="https://github.com/django-components/django-components/tree/master/src/django_components/templatetags/component_tags.py#L2772" target="_blank">See source code</a>
|
||||
|
||||
|
||||
|
||||
|
@ -363,9 +363,9 @@ class Parent(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, user: User):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"user": user,
|
||||
"user": kwargs["user"],
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -381,7 +381,7 @@ class Child(Component):
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
user = self.inject("user_data").user
|
||||
return {
|
||||
"user": user,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from typing import NamedTuple
|
||||
|
||||
from django_components import Component, register
|
||||
|
||||
|
||||
|
@ -13,9 +15,12 @@ class Calendar(Component):
|
|||
js_file = "calendar/calendar.js"
|
||||
|
||||
# This component takes one parameter, a date string to show in the template
|
||||
def get_context_data(self, date):
|
||||
class Kwargs(NamedTuple):
|
||||
date: str
|
||||
|
||||
def get_template_data(self, args, kwargs: Kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs.date,
|
||||
}
|
||||
|
||||
class View:
|
||||
|
@ -41,9 +46,12 @@ class CalendarRelative(Component):
|
|||
js_file = "calendar.js"
|
||||
|
||||
# This component takes one parameter, a date string to show in the template
|
||||
def get_context_data(self, date):
|
||||
class Kwargs(NamedTuple):
|
||||
date: str
|
||||
|
||||
def get_template_data(self, args, kwargs: Kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs.date,
|
||||
}
|
||||
|
||||
class View:
|
||||
|
|
|
@ -1,24 +1,8 @@
|
|||
from typing import Any, Dict
|
||||
|
||||
from django_components import Component, register, types
|
||||
|
||||
|
||||
@register("greeting")
|
||||
class Greeting(Component):
|
||||
class View:
|
||||
def get(self, request, *args, **kwargs):
|
||||
slots = {"message": "Hello, world!"}
|
||||
return Greeting.render_to_response(
|
||||
request=request,
|
||||
slots=slots,
|
||||
kwargs={
|
||||
"name": request.GET.get("name", ""),
|
||||
},
|
||||
)
|
||||
|
||||
def get_context_data(self, name, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"name": name}
|
||||
|
||||
template: types.django_html = """
|
||||
<div id="greeting">Hello, {{ name }}!</div>
|
||||
{% slot "message" %}{% endslot %}
|
||||
|
@ -37,3 +21,17 @@ class Greeting(Component):
|
|||
alert("Hello!");
|
||||
});
|
||||
"""
|
||||
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": kwargs["name"]}
|
||||
|
||||
class View:
|
||||
def get(self, request, *args, **kwargs):
|
||||
slots = {"message": "Hello, world!"}
|
||||
return Greeting.render_to_response(
|
||||
request=request,
|
||||
slots=slots,
|
||||
kwargs={
|
||||
"name": request.GET.get("name", ""),
|
||||
},
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from typing import NamedTuple
|
||||
|
||||
from django_components import Component, register
|
||||
|
||||
|
||||
|
@ -13,9 +15,12 @@ class CalendarNested(Component):
|
|||
js_file = "calendar.js"
|
||||
|
||||
# This component takes one parameter, a date string to show in the template
|
||||
def get_context_data(self, date):
|
||||
class Kwargs(NamedTuple):
|
||||
date: str
|
||||
|
||||
def get_template_data(self, args, kwargs: Kwargs, slots, context):
|
||||
return {
|
||||
"date": date,
|
||||
"date": kwargs.date,
|
||||
}
|
||||
|
||||
class View:
|
||||
|
|
|
@ -1,27 +1,11 @@
|
|||
import time
|
||||
from typing import Any, Dict
|
||||
from typing import NamedTuple
|
||||
|
||||
from django_components import Component, register, types
|
||||
|
||||
|
||||
@register("recursive")
|
||||
class Recursive(Component):
|
||||
class View:
|
||||
def get(self, request):
|
||||
time_before = time.time()
|
||||
output = Recursive.render_to_response(
|
||||
request=request,
|
||||
kwargs={
|
||||
"depth": 0,
|
||||
},
|
||||
)
|
||||
time_after = time.time()
|
||||
print("TIME: ", time_after - time_before)
|
||||
return output
|
||||
|
||||
def get_context_data(self, depth: int = 0) -> Dict[str, Any]:
|
||||
return {"depth": depth + 1}
|
||||
|
||||
template: types.django_html = """
|
||||
<div id="recursive">
|
||||
depth: {{ depth }}
|
||||
|
@ -31,3 +15,25 @@ class Recursive(Component):
|
|||
{% endif %}
|
||||
</div>
|
||||
"""
|
||||
|
||||
class Kwargs(NamedTuple):
|
||||
depth: int
|
||||
|
||||
class Defaults:
|
||||
depth = 0
|
||||
|
||||
def get_template_data(self, args, kwargs: Kwargs, slots, context):
|
||||
return {"depth": kwargs.depth + 1}
|
||||
|
||||
class View:
|
||||
def get(self, request):
|
||||
time_before = time.time()
|
||||
output = Recursive.render_to_response(
|
||||
request=request,
|
||||
kwargs=Recursive.Kwargs(
|
||||
depth=0,
|
||||
),
|
||||
)
|
||||
time_after = time.time()
|
||||
print("TIME: ", time_after - time_before)
|
||||
return output
|
||||
|
|
|
@ -56,7 +56,7 @@ class ContextBehavior(str, Enum):
|
|||
That is, they enrich the context, and pass it along.
|
||||
|
||||
1. Component fills use the context of the component they are within.
|
||||
2. Variables from [`Component.get_context_data()`](../api#django_components.Component.get_context_data)
|
||||
2. Variables from [`Component.get_template_data()`](../api#django_components.Component.get_template_data)
|
||||
are available to the component fill.
|
||||
|
||||
**Example:**
|
||||
|
@ -71,7 +71,7 @@ class ContextBehavior(str, Enum):
|
|||
{% endwith %}
|
||||
```
|
||||
|
||||
and this context returned from the `Component.get_context_data()` method
|
||||
and this context returned from the `Component.get_template_data()` method
|
||||
```python
|
||||
{ "my_var": 123 }
|
||||
```
|
||||
|
@ -98,7 +98,7 @@ class ContextBehavior(str, Enum):
|
|||
"""
|
||||
This setting makes the component fills behave similar to Vue or React, where
|
||||
the fills use EXCLUSIVELY the context variables defined in
|
||||
[`Component.get_context_data()`](../api#django_components.Component.get_context_data).
|
||||
[`Component.get_template_data()`](../api#django_components.Component.get_template_data).
|
||||
|
||||
**Example:**
|
||||
|
||||
|
@ -112,7 +112,7 @@ class ContextBehavior(str, Enum):
|
|||
{% endwith %}
|
||||
```
|
||||
|
||||
and this context returned from the `get_context_data()` method
|
||||
and this context returned from the `get_template_data()` method
|
||||
```python
|
||||
{ "my_var": 123 }
|
||||
```
|
||||
|
|
|
@ -199,16 +199,20 @@ class CreateCommand(ComponentCommand):
|
|||
|
||||
@register("{name}")
|
||||
class {name.capitalize()}(Component):
|
||||
template_file = "{name}/{template_filename}"
|
||||
template_file = "{template_filename}"
|
||||
js_file = "{js_filename}"
|
||||
css_file = "{css_filename}"
|
||||
|
||||
def get_context_data(self, value):
|
||||
class Kwargs(NamedTuple):
|
||||
param: str
|
||||
|
||||
class Defaults:
|
||||
param = "sample value"
|
||||
|
||||
def get_template_data(self, args, kwargs: Kwargs, slots, context):
|
||||
return {{
|
||||
"param": "sample value",
|
||||
"param": kwargs.param,
|
||||
}}
|
||||
|
||||
class Media:
|
||||
css = "{name}/{css_filename}"
|
||||
js = "{name}/{js_filename}"
|
||||
"""
|
||||
)
|
||||
f.write(py_content.strip())
|
||||
|
|
|
@ -231,9 +231,9 @@ class ComponentVars(NamedTuple):
|
|||
|
||||
```py
|
||||
class MyTable(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"my_slot_filled": "my_slot" in self.input.slots
|
||||
"my_slot_filled": "my_slot" in slots
|
||||
}
|
||||
```
|
||||
"""
|
||||
|
@ -508,7 +508,7 @@ class Component(metaclass=ComponentMeta):
|
|||
class MyComponent(Component):
|
||||
template_file = "path/to/template.html"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": "World"}
|
||||
```
|
||||
"""
|
||||
|
@ -556,7 +556,7 @@ class Component(metaclass=ComponentMeta):
|
|||
class MyComponent(Component):
|
||||
template = "Hello, {{ name }}!"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": "World"}
|
||||
```
|
||||
"""
|
||||
|
@ -1663,7 +1663,7 @@ class Component(metaclass=ComponentMeta):
|
|||
|
||||
```py
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
print(f"Rendering '{self.id}'")
|
||||
return {}
|
||||
|
||||
|
@ -1702,14 +1702,9 @@ class Component(metaclass=ComponentMeta):
|
|||
|
||||
**Example:**
|
||||
|
||||
Use can use [`self.input.args`](../api/#django_components.ComponentInput.args)
|
||||
and [`self.input.kwargs`](../api/#django_components.ComponentInput.kwargs)
|
||||
to access the positional and keyword arguments passed to
|
||||
[`Component.render()`](../api/#django_components.Component.render).
|
||||
|
||||
```python
|
||||
class Table(Component):
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
# Access component's inputs, slots and context
|
||||
assert self.input.args == [123, "str"]
|
||||
assert self.input.kwargs == {"variable": "test", "another": 1}
|
||||
|
@ -1778,7 +1773,7 @@ class Component(metaclass=ComponentMeta):
|
|||
|
||||
```py
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
user_id = self.request.GET['user_id']
|
||||
return {
|
||||
'user_id': user_id,
|
||||
|
@ -1801,7 +1796,7 @@ class Component(metaclass=ComponentMeta):
|
|||
|
||||
This data is also available from within the component's template, without having to
|
||||
return this data from
|
||||
[`get_context_data()`](../api#django_components.Component.get_context_data).
|
||||
[`get_template_data()`](../api#django_components.Component.get_template_data).
|
||||
|
||||
In regular Django templates, you need to use
|
||||
[`RequestContext`](https://docs.djangoproject.com/en/5.1/ref/templates/api/#django.template.RequestContext)
|
||||
|
@ -1831,7 +1826,7 @@ class Component(metaclass=ComponentMeta):
|
|||
|
||||
```py
|
||||
class MyComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
user = self.context_processors_data['user']
|
||||
return {
|
||||
'is_logged_in': user.is_authenticated,
|
||||
|
@ -2371,7 +2366,7 @@ class Component(metaclass=ComponentMeta):
|
|||
|
||||
# By adding the current input to the stack, we temporarily allow users
|
||||
# to access the provided context, slots, etc. Also required so users can
|
||||
# call `self.inject()` from within `get_context_data()`.
|
||||
# call `self.inject()` from within `get_template_data()`.
|
||||
#
|
||||
# This is handled as a stack, as users can potentially call `component.render()`
|
||||
# from within component hooks. Thus, then they do so, `component.id` will be the ID
|
||||
|
|
|
@ -539,7 +539,7 @@ def _resolve_media(comp_cls: Type["Component"], comp_media: ComponentMedia) -> N
|
|||
|
||||
class MyComponent(Component):
|
||||
media_class = MyMedia
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
assert isinstance(self.media, MyMedia)
|
||||
```
|
||||
"""
|
||||
|
|
|
@ -99,13 +99,14 @@ class DynamicComponent(Component):
|
|||
|
||||
_is_dynamic_component = True
|
||||
|
||||
def get_context_data(
|
||||
def get_template_data(
|
||||
self,
|
||||
*args: Any,
|
||||
registry: Optional[ComponentRegistry] = None,
|
||||
**kwargs: Any,
|
||||
args: Any,
|
||||
kwargs: Any,
|
||||
slots: Any,
|
||||
context: Any,
|
||||
) -> Dict:
|
||||
# NOTE: We have to access `is` via kwargs, because it's a special keyword in Python
|
||||
registry: Optional[ComponentRegistry] = kwargs.pop("registry", None)
|
||||
comp_name_or_class: Union[str, Type[Component]] = kwargs.pop("is", None)
|
||||
if not comp_name_or_class:
|
||||
raise TypeError(f"Component '{self.name}' is missing a required argument 'is'")
|
||||
|
|
|
@ -172,7 +172,7 @@ class ComponentExtension:
|
|||
class MyExtension:
|
||||
...
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"my_extension": self.my_extension.do_something(),
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ class ComponentExtension:
|
|||
class MyExtension:
|
||||
...
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"my_extension": self.my_extension.do_something(),
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ class ComponentExtension:
|
|||
Use this hook to modify or validate component inputs before they're processed.
|
||||
|
||||
This is the first hook that is called when rendering a component. As such this hook is called before
|
||||
[`Component.get_context_data()`](../api#django_components.Component.get_context_data),
|
||||
[`Component.get_template_data()`](../api#django_components.Component.get_template_data),
|
||||
[`Component.get_js_data()`](../api#django_components.Component.get_js_data),
|
||||
and [`Component.get_css_data()`](../api#django_components.Component.get_css_data) methods,
|
||||
and the
|
||||
|
@ -482,7 +482,7 @@ class ComponentExtension:
|
|||
after a component's context and data methods have been processed.
|
||||
|
||||
This hook is called after
|
||||
[`Component.get_context_data()`](../api#django_components.Component.get_context_data),
|
||||
[`Component.get_template_data()`](../api#django_components.Component.get_template_data),
|
||||
[`Component.get_js_data()`](../api#django_components.Component.get_js_data)
|
||||
and [`Component.get_css_data()`](../api#django_components.Component.get_css_data).
|
||||
|
||||
|
@ -498,7 +498,7 @@ class ComponentExtension:
|
|||
class MyExtension(ComponentExtension):
|
||||
def on_component_data(self, ctx: OnComponentDataContext) -> None:
|
||||
# Add extra template variable to all components when they are rendered
|
||||
ctx.context_data["my_template_var"] = "my_value"
|
||||
ctx.template_data["my_template_var"] = "my_value"
|
||||
```
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -100,9 +100,9 @@ class NodeMeta(type):
|
|||
#
|
||||
# ```py
|
||||
# class MyComponent(Component):
|
||||
# def get_context_data(self, name: str, **kwargs: Any) -> str:
|
||||
# def get_template_data(self, args, kwargs, slots, context) -> str:
|
||||
# return {
|
||||
# "name": name,
|
||||
# "name": kwargs.pop("name"),
|
||||
# "attrs": kwargs,
|
||||
# }
|
||||
# template = """
|
||||
|
|
|
@ -41,9 +41,9 @@ class ProvideNode(BaseNode):
|
|||
</div>
|
||||
\"\"\"
|
||||
|
||||
def get_context_data(self, user: User):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"user": user,
|
||||
"user": kwargs["user"],
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -59,7 +59,7 @@ class ProvideNode(BaseNode):
|
|||
</div>
|
||||
\"\"\"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
user = self.inject("user_data").user
|
||||
return {
|
||||
"user": user,
|
||||
|
@ -138,7 +138,7 @@ def set_provided_context_var(
|
|||
) -> str:
|
||||
"""
|
||||
'Provide' given data under given key. In other words, this data can be retrieved
|
||||
using `self.inject(key)` inside of `get_context_data()` method of components that
|
||||
using `self.inject(key)` inside of `get_template_data()` method of components that
|
||||
are nested inside the `{% provide %}` tag.
|
||||
"""
|
||||
# NOTE: We raise TemplateSyntaxError since this func should be called only from
|
||||
|
|
|
@ -1083,8 +1083,8 @@ def _nodelist_to_slot_render_func(
|
|||
#
|
||||
# And so we want to put the `extra_context` into the same layer that contains `_COMPONENT_CONTEXT_KEY`.
|
||||
#
|
||||
# HOWEVER, the layer with `_COMPONENT_CONTEXT_KEY` also contains user-defined data from `get_context_data()`.
|
||||
# Data from `get_context_data()` should take precedence over `extra_context`. So we have to insert
|
||||
# HOWEVER, the layer with `_COMPONENT_CONTEXT_KEY` also contains user-defined data from `get_template_data()`.
|
||||
# Data from `get_template_data()` should take precedence over `extra_context`. So we have to insert
|
||||
# the forloop variables BEFORE that.
|
||||
index_of_last_component_layer = get_last_index(ctx.dicts, lambda d: _COMPONENT_CONTEXT_KEY in d)
|
||||
if index_of_last_component_layer is None:
|
||||
|
@ -1096,8 +1096,8 @@ def _nodelist_to_slot_render_func(
|
|||
# the following line can be removed.
|
||||
index_of_last_component_layer -= 1
|
||||
|
||||
# Insert the `extra_context` layer BEFORE the layer that defines the variables from get_context_data.
|
||||
# Thus, get_context_data will overshadow these on conflict.
|
||||
# Insert the `extra_context` layer BEFORE the layer that defines the variables from get_template_data.
|
||||
# Thus, get_template_data will overshadow these on conflict.
|
||||
ctx.dicts.insert(index_of_last_component_layer, extra_context or {})
|
||||
|
||||
trace_component_msg("RENDER_NODELIST", component_name, component_id=None, slot_name=slot_name)
|
||||
|
|
|
@ -23,5 +23,5 @@ class MultFileComponent(Component):
|
|||
kwargs={"variable": "GET"},
|
||||
)
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context) -> Dict[str, Any]:
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -27,5 +27,5 @@ class RelativeFileComponent(Component):
|
|||
kwargs={"variable": "GET"},
|
||||
)
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context) -> Dict[str, Any]:
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -32,5 +32,5 @@ class RelativeFileWithPathObjComponent(Component):
|
|||
js = PathObj("relative_file_pathobj.js")
|
||||
css = PathObj("relative_file_pathobj.css")
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context) -> Dict[str, Any]:
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -29,5 +29,5 @@ class SingleFileComponent(Component):
|
|||
kwargs={"variable": "GET"},
|
||||
)
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context) -> Dict[str, Any]:
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -12,5 +12,5 @@ class RelativeFileWithPathObjComponent(Component):
|
|||
js = "staticfiles.js"
|
||||
css = "staticfiles.css"
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context) -> Dict[str, Any]:
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -17,10 +17,13 @@ class SimpleComponent(Component):
|
|||
globalThis.testSimpleComponent = 'kapowww!'
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
class Defaults:
|
||||
variable2 = "default"
|
||||
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs["variable2"],
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -48,8 +51,8 @@ class SimpleComponentNested(Component):
|
|||
globalThis.testSimpleComponentNested = 'bongo!'
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
||||
class Media:
|
||||
css = ["style.css", "style2.css"]
|
||||
|
@ -72,8 +75,8 @@ class OtherComponent(Component):
|
|||
globalThis.testOtherComponent = 'wowzee!'
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
||||
class Media:
|
||||
css = "style.css"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any, Dict, Optional
|
||||
from typing import Optional
|
||||
|
||||
from django_components import Component, register
|
||||
|
||||
|
@ -14,5 +14,5 @@ class AppLvlCompComponent(Component):
|
|||
js = "app_lvl_comp.js"
|
||||
css = "app_lvl_comp.css"
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from typing import Any, Dict
|
||||
|
||||
from django_components import Component, register
|
||||
|
||||
|
||||
|
@ -12,5 +10,5 @@ class AppLvlCompComponent(Component):
|
|||
js = "app_lvl_comp.js"
|
||||
css = "app_lvl_comp.css"
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from typing import Any, Dict
|
||||
|
||||
from django_components import Component, register
|
||||
|
||||
|
||||
|
@ -10,5 +8,5 @@ class AppLvlCompComponent(Component):
|
|||
{{ variable }}
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
|
|
@ -144,9 +144,9 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs["attrs"],
|
||||
"defaults": {"class": "override-me"},
|
||||
}
|
||||
|
||||
|
@ -172,9 +172,9 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs["attrs"],
|
||||
"defaults": {"class": "override-me"},
|
||||
"class": "123 457",
|
||||
}
|
||||
|
@ -197,9 +197,9 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs["attrs"],
|
||||
"defaults": {"class": "override-me"},
|
||||
}
|
||||
|
||||
|
@ -225,9 +225,9 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs["attrs"],
|
||||
"defaults": {"class": "override-me"},
|
||||
}
|
||||
|
||||
|
@ -253,10 +253,10 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"props": {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs["attrs"],
|
||||
"defaults": {"class": "override-me"},
|
||||
"class": "added_class",
|
||||
"data-id": 123,
|
||||
|
@ -285,8 +285,8 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
return {"attrs": attrs}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"attrs": kwargs["attrs"]}
|
||||
|
||||
template = Template(self.template_str)
|
||||
rendered = template.render(Context({"class_var": "padding-top-8"}))
|
||||
|
@ -318,8 +318,8 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
return {"attrs": attrs}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"attrs": kwargs["attrs"]}
|
||||
|
||||
template = Template(self.template_str)
|
||||
|
||||
|
@ -346,8 +346,8 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
return {"attrs": attrs}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"attrs": kwargs["attrs"]}
|
||||
|
||||
template = Template(self.template_str)
|
||||
|
||||
|
@ -367,8 +367,8 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
return {"attrs": attrs}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"attrs": kwargs["attrs"]}
|
||||
|
||||
template = Template(self.template_str)
|
||||
rendered = template.render(Context({"class_var": "padding-top-8"}))
|
||||
|
@ -391,8 +391,8 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
return {"attrs": attrs}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"attrs": kwargs["attrs"]}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -421,8 +421,8 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
""" # noqa: E501
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
return {"attrs": attrs}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"attrs": kwargs["attrs"]}
|
||||
|
||||
template = Template(self.template_str)
|
||||
rendered = template.render(Context({"class_var": "padding-top-8"}))
|
||||
|
@ -446,9 +446,9 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": attrs,
|
||||
"attrs": kwargs["attrs"],
|
||||
"defaults": {"class": "override-me"},
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ class TestHtmlAttrs:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": None,
|
||||
"defaults": None,
|
||||
|
|
|
@ -4,7 +4,7 @@ For tests focusing on the `component` tag, see `test_templatetags_component.py`
|
|||
"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict, no_type_check
|
||||
from typing import Dict, no_type_check
|
||||
|
||||
import pytest
|
||||
from django.conf import settings
|
||||
|
@ -48,9 +48,9 @@ class CustomClient(Client):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
# TODO_REMOVE_IN_V1 - Superseded by `self.get_template` in v1
|
||||
@djc_test
|
||||
class TestComponentOldTemplateApi:
|
||||
class TestComponentLegacyApi:
|
||||
# TODO_REMOVE_IN_V1 - Superseded by `self.get_template` in v1
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_get_template_string(self, components_settings):
|
||||
class SimpleComponent(Component):
|
||||
|
@ -60,6 +60,31 @@ class TestComponentOldTemplateApi:
|
|||
"""
|
||||
return content
|
||||
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
class Media:
|
||||
css = "style.css"
|
||||
js = "script.js"
|
||||
|
||||
rendered = SimpleComponent.render(kwargs={"variable": "test"})
|
||||
assertHTMLEqual(
|
||||
rendered,
|
||||
"""
|
||||
Variable: <strong data-djc-id-ca1bc3e>test</strong>
|
||||
""",
|
||||
)
|
||||
|
||||
# TODO_REMOVE_IN_V2 - `get_context_data()` was superseded by `self.get_template_data`
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_get_context_data(self, components_settings):
|
||||
class SimpleComponent(Component):
|
||||
template = """
|
||||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
return {
|
||||
"variable": variable,
|
||||
|
@ -95,9 +120,9 @@ class TestComponent:
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -121,9 +146,9 @@ class TestComponent:
|
|||
"""
|
||||
return content
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -143,9 +168,9 @@ class TestComponent:
|
|||
class SimpleComponent(Component):
|
||||
template_file = "simple_template.html"
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -165,9 +190,9 @@ class TestComponent:
|
|||
class SimpleComponent(Component):
|
||||
template_name = "simple_template.html"
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -214,12 +239,12 @@ class TestComponent:
|
|||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_template_file_dynamic(self, components_settings):
|
||||
class SvgComponent(Component):
|
||||
def get_context_data(self, name, css_class="", title="", **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"css_class": css_class,
|
||||
"title": title,
|
||||
**attrs,
|
||||
"name": kwargs.pop("name", None),
|
||||
"css_class": kwargs.pop("css_class", None),
|
||||
"title": kwargs.pop("title", None),
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_template_name(self, context):
|
||||
|
@ -241,9 +266,9 @@ class TestComponent:
|
|||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_allows_to_return_template(self, components_settings):
|
||||
class TestComponent(Component):
|
||||
def get_context_data(self, variable, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.pop("variable", None),
|
||||
}
|
||||
|
||||
def get_template(self, context):
|
||||
|
@ -261,7 +286,7 @@ class TestComponent:
|
|||
def test_input(self):
|
||||
class TestComponent(Component):
|
||||
@no_type_check
|
||||
def get_context_data(self, var1, var2, variable, another, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
assert self.input.args == [123, "str"]
|
||||
assert self.input.kwargs == {"variable": "test", "another": 1}
|
||||
assert isinstance(self.input.context, Context)
|
||||
|
@ -269,7 +294,7 @@ class TestComponent:
|
|||
assert self.input.slots["my_slot"](Context(), None, None) == "MY_SLOT"
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
@no_type_check
|
||||
|
@ -312,15 +337,15 @@ class TestComponent:
|
|||
</main>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
data = self.inject("my_provide")
|
||||
data["data1"] # This should raise TypeError
|
||||
return {"data": data}
|
||||
|
||||
@register("provider")
|
||||
class Provider(Component):
|
||||
def get_context_data(self, data: Any) -> Any:
|
||||
return {"data": data}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"data": kwargs["data"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -331,8 +356,8 @@ class TestComponent:
|
|||
|
||||
@register("parent")
|
||||
class Parent(Component):
|
||||
def get_context_data(self, data: Any) -> Any:
|
||||
return {"data": data}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"data": kwargs["data"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -387,7 +412,7 @@ class TestComponent:
|
|||
class SimpleComponent(Component):
|
||||
template = "Hello"
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return None
|
||||
|
||||
assert SimpleComponent.render() == "Hello"
|
||||
|
@ -412,11 +437,11 @@ class TestComponentRender:
|
|||
{% endslot %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, the_arg2=None, *args, the_kwarg=None, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"the_arg2": the_arg2,
|
||||
"the_kwarg": the_kwarg,
|
||||
"args": args,
|
||||
"the_arg2": args[0] if args else None,
|
||||
"the_kwarg": kwargs.pop("the_kwarg", None),
|
||||
"args": args[1:],
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
|
||||
|
@ -425,7 +450,7 @@ class TestComponentRender:
|
|||
rendered,
|
||||
"""
|
||||
the_arg2: None
|
||||
args: ()
|
||||
args: []
|
||||
the_kwarg: None
|
||||
kwargs: {}
|
||||
---
|
||||
|
@ -456,12 +481,12 @@ class TestComponentRender:
|
|||
{% endslot %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, the_arg, the_arg2=None, *args, the_kwarg, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"the_arg": the_arg,
|
||||
"the_arg2": the_arg2,
|
||||
"the_kwarg": the_kwarg,
|
||||
"args": args,
|
||||
"the_arg": args[0],
|
||||
"the_arg2": args[1],
|
||||
"the_kwarg": kwargs.pop("the_kwarg", None),
|
||||
"args": args[2:],
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
|
||||
|
@ -476,7 +501,7 @@ class TestComponentRender:
|
|||
"""
|
||||
the_arg: one
|
||||
the_arg2: two
|
||||
args: ('three',)
|
||||
args: ['three']
|
||||
the_kwarg: test
|
||||
kwargs: {'kw2': 'ooo'}
|
||||
---
|
||||
|
@ -509,12 +534,12 @@ class TestComponentRender:
|
|||
{% endslot %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, the_arg, the_arg2=None, *args, the_kwarg, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"the_arg": the_arg,
|
||||
"the_arg2": the_arg2,
|
||||
"the_kwarg": the_kwarg,
|
||||
"args": args,
|
||||
"the_arg": args[0],
|
||||
"the_arg2": args[1],
|
||||
"the_kwarg": kwargs.pop("the_kwarg"),
|
||||
"args": args[2:],
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
|
||||
|
@ -531,7 +556,7 @@ class TestComponentRender:
|
|||
"""
|
||||
the_arg: one
|
||||
the_arg2: two
|
||||
args: ('three',)
|
||||
args: ['three']
|
||||
the_kwarg: test
|
||||
kwargs: {'kw2': 'ooo'}
|
||||
---
|
||||
|
@ -580,10 +605,10 @@ class TestComponentRender:
|
|||
{% endslot %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, the_arg, the_kwarg=None, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"the_arg": the_arg,
|
||||
"the_kwarg": the_kwarg,
|
||||
"the_arg": args[0],
|
||||
"the_kwarg": kwargs.pop("the_kwarg", None),
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
|
||||
|
@ -592,7 +617,7 @@ class TestComponentRender:
|
|||
# NOTE: Since the slot has access to the Context object, it should behave
|
||||
# the same way as it does in templates - when in "isolated" mode, then the
|
||||
# slot fill has access only to the "root" context, but not to the data of
|
||||
# get_context_data() of SimpleComponent.
|
||||
# get_template_data() of SimpleComponent.
|
||||
if is_isolated:
|
||||
assert ctx.get("the_arg") is None
|
||||
assert ctx.get("the_kwarg") is None
|
||||
|
@ -725,8 +750,8 @@ class TestComponentRender:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, how: str, **kwargs):
|
||||
return {"how": how}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"how": kwargs.pop("how")}
|
||||
|
||||
class View(ComponentView):
|
||||
def get(self, request):
|
||||
|
@ -734,7 +759,7 @@ class TestComponentRender:
|
|||
|
||||
return self.component.render_to_response(
|
||||
context=RequestContext(self.request),
|
||||
kwargs=self.component.get_context_data(how=how),
|
||||
kwargs={"how": how},
|
||||
)
|
||||
|
||||
client = CustomClient(urlpatterns=[path("test_thing/", Thing.as_view())])
|
||||
|
@ -869,7 +894,7 @@ class TestComponentRender:
|
|||
class TestComponent(Component):
|
||||
template = "Variable: <strong>{{ id }}</strong>"
|
||||
|
||||
def get_context_data(self, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"id": self.id,
|
||||
}
|
||||
|
@ -885,7 +910,7 @@ class TestComponentRender:
|
|||
class TestComponent(Component):
|
||||
template = "Variable: <strong>{{ id }}</strong>"
|
||||
|
||||
def get_context_data(self, **attrs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"id": self.id,
|
||||
}
|
||||
|
@ -923,7 +948,7 @@ class TestComponentHook:
|
|||
{% endcomponent %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"args": args,
|
||||
"kwargs": kwargs,
|
||||
|
@ -943,7 +968,7 @@ class TestComponentHook:
|
|||
assertHTMLEqual(
|
||||
rendered,
|
||||
"""
|
||||
args: ()
|
||||
args: []
|
||||
kwargs: {}
|
||||
---
|
||||
from_on_before: :)
|
||||
|
@ -984,7 +1009,7 @@ class TestComponentHook:
|
|||
{% endcomponent %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"args": args,
|
||||
"kwargs": kwargs,
|
||||
|
@ -1006,7 +1031,7 @@ class TestComponentHook:
|
|||
assertHTMLEqual(
|
||||
captured_content,
|
||||
"""
|
||||
args: ()
|
||||
args: []
|
||||
kwargs: {}
|
||||
---
|
||||
from_on_after:
|
||||
|
@ -1020,7 +1045,7 @@ class TestComponentHook:
|
|||
assertHTMLEqual(
|
||||
rendered,
|
||||
"""
|
||||
args: ()
|
||||
args: []
|
||||
kwargs: {}
|
||||
---
|
||||
from_on_after:
|
||||
|
@ -1060,7 +1085,7 @@ class TestComponentHook:
|
|||
{% endcomponent %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"args": args,
|
||||
"kwargs": kwargs,
|
||||
|
@ -1077,7 +1102,7 @@ class TestComponentHook:
|
|||
assertHTMLEqual(
|
||||
captured_content,
|
||||
"""
|
||||
args: ()
|
||||
args: []
|
||||
kwargs: {}
|
||||
---
|
||||
from_on_before:
|
||||
|
@ -1092,7 +1117,7 @@ class TestComponentHook:
|
|||
rendered,
|
||||
"""
|
||||
Chocolate cookie recipe:
|
||||
args: ()
|
||||
args: []
|
||||
kwargs: {}
|
||||
---
|
||||
from_on_before:
|
||||
|
@ -1131,7 +1156,7 @@ class TestComponentHook:
|
|||
{% endcomponent %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"args": args,
|
||||
"kwargs": kwargs,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import time
|
||||
from typing import Any
|
||||
|
||||
from django.core.cache import caches
|
||||
from django.template import Template
|
||||
|
@ -33,7 +32,7 @@ class TestComponentCache:
|
|||
class Cache:
|
||||
enabled = True
|
||||
|
||||
def get_context_data(self, **kwargs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal did_call_get
|
||||
did_call_get = True
|
||||
return {}
|
||||
|
@ -55,7 +54,7 @@ class TestComponentCache:
|
|||
did_call_get = False
|
||||
component.render()
|
||||
|
||||
# get_context_data not called because the cache entry was returned
|
||||
# get_template_data not called because the cache entry was returned
|
||||
assert not did_call_get
|
||||
assert result == "Hello"
|
||||
|
||||
|
@ -68,7 +67,7 @@ class TestComponentCache:
|
|||
class Cache:
|
||||
enabled = False
|
||||
|
||||
def get_context_data(self, **kwargs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal did_call_get
|
||||
did_call_get = True
|
||||
return {}
|
||||
|
@ -89,7 +88,7 @@ class TestComponentCache:
|
|||
did_call_get = False
|
||||
result = component.render()
|
||||
|
||||
# get_context_data IS called because the cache is NOT used
|
||||
# get_template_data IS called because the cache is NOT used
|
||||
assert did_call_get
|
||||
assert result == "Hello"
|
||||
|
||||
|
@ -151,8 +150,8 @@ class TestComponentCache:
|
|||
class Cache:
|
||||
enabled = True
|
||||
|
||||
def get_context_data(self, input, **kwargs: Any):
|
||||
return {"input": input}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"input": kwargs["input"]}
|
||||
|
||||
component = TestComponent()
|
||||
component.render(
|
||||
|
@ -200,7 +199,7 @@ class TestComponentCache:
|
|||
# Custom hash method for args and kwargs
|
||||
return "custom-args-and-kwargs"
|
||||
|
||||
def get_context_data(self, *args, **kwargs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
component = TestComponent()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from dataclasses import field
|
||||
from typing import Any
|
||||
|
||||
from django.template import Context
|
||||
|
||||
|
@ -25,25 +24,36 @@ class TestComponentDefaults:
|
|||
extra = "extra"
|
||||
fn = lambda: "fn_as_val" # noqa: E731
|
||||
|
||||
def get_context_data(self, arg1: Any, variable: Any, another: Any, **attrs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal did_call_context
|
||||
did_call_context = True
|
||||
|
||||
# Check that args and slots are NOT affected by the defaults
|
||||
assert self.input.args == [123]
|
||||
assert [*self.input.slots.keys()] == ["my_slot"]
|
||||
assert self.input.slots["my_slot"](Context(), None, None) == "MY_SLOT" # type: ignore[arg-type]
|
||||
|
||||
assert kwargs == {
|
||||
"variable": "test", # User-given
|
||||
"another": 1, # Default because missing
|
||||
"extra": "extra", # Default because `None` was given
|
||||
"fn": self.Defaults.fn, # Default because missing
|
||||
}
|
||||
assert self.input.kwargs == {
|
||||
"variable": "test", # User-given
|
||||
"another": 1, # Default because missing
|
||||
"extra": "extra", # Default because `None` was given
|
||||
"fn": self.Defaults.fn, # Default because missing
|
||||
}
|
||||
|
||||
# Check that args and slots are NOT affected by the defaults
|
||||
assert args == [123]
|
||||
assert [*slots.keys()] == ["my_slot"]
|
||||
assert slots["my_slot"](Context(), None, None) == "MY_SLOT" # type: ignore[arg-type]
|
||||
|
||||
assert self.input.args == [123]
|
||||
assert [*self.input.slots.keys()] == ["my_slot"]
|
||||
assert self.input.slots["my_slot"](Context(), None, None) == "MY_SLOT" # type: ignore[arg-type]
|
||||
|
||||
assert isinstance(self.input.context, Context)
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
TestComponent.render(
|
||||
|
@ -64,10 +74,14 @@ class TestComponentDefaults:
|
|||
variable = "test"
|
||||
fn = Default(lambda: "fn_as_factory")
|
||||
|
||||
def get_context_data(self, variable: Any, **attrs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal did_call_context
|
||||
did_call_context = True
|
||||
|
||||
assert kwargs == {
|
||||
"variable": "test", # User-given
|
||||
"fn": "fn_as_factory", # Default because missing
|
||||
}
|
||||
assert self.input.kwargs == {
|
||||
"variable": "test", # User-given
|
||||
"fn": "fn_as_factory", # Default because missing
|
||||
|
@ -75,7 +89,7 @@ class TestComponentDefaults:
|
|||
assert isinstance(self.input.context, Context)
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
TestComponent.render(
|
||||
|
@ -94,10 +108,15 @@ class TestComponentDefaults:
|
|||
variable = "test"
|
||||
fn = field(default=lambda: "fn_as_factory")
|
||||
|
||||
def get_context_data(self, variable: Any, **attrs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal did_call_context
|
||||
did_call_context = True
|
||||
|
||||
assert kwargs == {
|
||||
"variable": "test", # User-given
|
||||
# NOTE: NOT a factory, because it was set as `field(default=...)`
|
||||
"fn": self.Defaults.fn.default, # type: ignore[attr-defined]
|
||||
}
|
||||
assert self.input.kwargs == {
|
||||
"variable": "test", # User-given
|
||||
# NOTE: NOT a factory, because it was set as `field(default=...)`
|
||||
|
@ -106,7 +125,7 @@ class TestComponentDefaults:
|
|||
assert isinstance(self.input.context, Context)
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
TestComponent.render(
|
||||
|
@ -125,10 +144,15 @@ class TestComponentDefaults:
|
|||
variable = "test"
|
||||
fn = field(default_factory=lambda: "fn_as_factory")
|
||||
|
||||
def get_context_data(self, variable: Any, **attrs: Any):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal did_call_context
|
||||
did_call_context = True
|
||||
|
||||
assert kwargs == {
|
||||
"variable": "test", # User-given
|
||||
# NOTE: IS a factory, because it was set as `field(default_factory=...)`
|
||||
"fn": "fn_as_factory", # Default because missing
|
||||
}
|
||||
assert self.input.kwargs == {
|
||||
"variable": "test", # User-given
|
||||
# NOTE: IS a factory, because it was set as `field(default_factory=...)`
|
||||
|
@ -137,7 +161,7 @@ class TestComponentDefaults:
|
|||
assert isinstance(self.input.context, Context)
|
||||
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
TestComponent.render(
|
||||
|
|
|
@ -132,9 +132,9 @@ class TestMainMedia:
|
|||
css_file = "style.css"
|
||||
js_file = "script.js"
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs["variable"],
|
||||
}
|
||||
|
||||
registry.register("test", TestComponent)
|
||||
|
@ -231,10 +231,10 @@ class TestMainMedia:
|
|||
Var2 (uppercased): <strong>{{ var2|upper }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, var1=None, var2=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"var1": var1,
|
||||
"var2": var2,
|
||||
"var1": kwargs["var1"],
|
||||
"var2": kwargs["var2"],
|
||||
}
|
||||
|
||||
rendered = FilteredComponent.render(kwargs={"var1": "test1", "var2": "test2"})
|
||||
|
@ -871,7 +871,7 @@ class TestMediaRelativePath:
|
|||
</div>
|
||||
""" # noqa
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"shadowing_variable": "NOT SHADOWED"}
|
||||
|
||||
class VariableDisplay(Component):
|
||||
|
@ -881,12 +881,12 @@ class TestMediaRelativePath:
|
|||
<h1>Uniquely named variable = {{ unique_variable }}</h1>
|
||||
"""
|
||||
|
||||
def get_context_data(self, shadowing_variable=None, new_variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
context = {}
|
||||
if shadowing_variable is not None:
|
||||
context["shadowing_variable"] = shadowing_variable
|
||||
if new_variable is not None:
|
||||
context["unique_variable"] = new_variable
|
||||
if kwargs["shadowing_variable"] is not None:
|
||||
context["shadowing_variable"] = kwargs["shadowing_variable"]
|
||||
if kwargs["new_variable"] is not None:
|
||||
context["unique_variable"] = kwargs["new_variable"]
|
||||
return context
|
||||
|
||||
# Settings required for autodiscover to work
|
||||
|
|
|
@ -142,7 +142,7 @@ class TestComponentTyping:
|
|||
css_data_instance = None
|
||||
|
||||
class Button(Component):
|
||||
# Data returned from `get_context_data`
|
||||
# Data returned from `get_template_data`
|
||||
@dataclass
|
||||
class TemplateData:
|
||||
data1: str
|
||||
|
@ -232,7 +232,7 @@ class TestComponentTyping:
|
|||
css_data_instance = None
|
||||
|
||||
class Button(Component):
|
||||
# Data returned from `get_context_data`
|
||||
# Data returned from `get_template_data`
|
||||
@dataclass
|
||||
class TemplateData:
|
||||
data1: str
|
||||
|
@ -348,7 +348,7 @@ class TestComponentTyping:
|
|||
# The generic specifies the data available to the slot function
|
||||
footer: NotRequired[Slot[ButtonFooterSlotData]]
|
||||
|
||||
# Data returned from `get_context_data`
|
||||
# Data returned from `get_template_data`
|
||||
class TemplateData(NamedTuple):
|
||||
data1: str
|
||||
data2: int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any, Dict
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from django.conf import settings
|
||||
|
@ -60,8 +60,8 @@ class TestComponentAsView(SimpleTestCase):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
||||
def render_template_view(request):
|
||||
template = Template(
|
||||
|
@ -90,8 +90,8 @@ class TestComponentAsView(SimpleTestCase):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"inner_var": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"inner_var": kwargs["variable"]}
|
||||
|
||||
class View(ComponentView):
|
||||
def get(self, request, *args, **kwargs) -> HttpResponse:
|
||||
|
@ -115,8 +115,8 @@ class TestComponentAsView(SimpleTestCase):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"inner_var": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"inner_var": kwargs["variable"]}
|
||||
|
||||
def get(self, request, *args, **kwargs) -> HttpResponse:
|
||||
return self.render_to_response(kwargs={"variable": "GET"})
|
||||
|
@ -139,8 +139,8 @@ class TestComponentAsView(SimpleTestCase):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"inner_var": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"inner_var": kwargs["variable"]}
|
||||
|
||||
class View(ComponentView):
|
||||
def post(self, request, *args, **kwargs) -> HttpResponse:
|
||||
|
@ -165,8 +165,8 @@ class TestComponentAsView(SimpleTestCase):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"inner_var": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"inner_var": kwargs["variable"]}
|
||||
|
||||
def post(self, request, *args, **kwargs) -> HttpResponse:
|
||||
variable = request.POST.get("variable")
|
||||
|
@ -188,8 +188,8 @@ class TestComponentAsView(SimpleTestCase):
|
|||
</form>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"inner_var": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"inner_var": kwargs["variable"]}
|
||||
|
||||
def get(self, request, *args, **kwargs) -> HttpResponse:
|
||||
return self.render_to_response(kwargs={"variable": self.name})
|
||||
|
|
|
@ -24,8 +24,8 @@ class SimpleComponent(Component):
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
return {"variable": variable} if variable is not None else {}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs.get("variable", None)} if "variable" in kwargs else {}
|
||||
|
||||
|
||||
class VariableDisplay(Component):
|
||||
|
@ -35,12 +35,12 @@ class VariableDisplay(Component):
|
|||
<h1>Uniquely named variable = {{ unique_variable }}</h1>
|
||||
"""
|
||||
|
||||
def get_context_data(self, shadowing_variable=None, new_variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
context = {}
|
||||
if shadowing_variable is not None:
|
||||
context["shadowing_variable"] = shadowing_variable
|
||||
if new_variable is not None:
|
||||
context["unique_variable"] = new_variable
|
||||
if kwargs["shadowing_variable"] is not None:
|
||||
context["shadowing_variable"] = kwargs["shadowing_variable"]
|
||||
if kwargs["new_variable"] is not None:
|
||||
context["unique_variable"] = kwargs["new_variable"]
|
||||
return context
|
||||
|
||||
|
||||
|
@ -55,8 +55,8 @@ class IncrementerComponent(Component):
|
|||
super().__init__(*args, **kwargs)
|
||||
self.call_count = 0
|
||||
|
||||
def get_context_data(self, value=0):
|
||||
value = int(value)
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
value = int(kwargs.get("value", 0))
|
||||
if hasattr(self, "call_count"):
|
||||
self.call_count += 1
|
||||
else:
|
||||
|
@ -88,7 +88,7 @@ class TestContext:
|
|||
</div>
|
||||
""" # noqa
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"shadowing_variable": "NOT SHADOWED"}
|
||||
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
|
@ -231,8 +231,8 @@ class TestParentArgs:
|
|||
</div>
|
||||
""" # noqa
|
||||
|
||||
def get_context_data(self, parent_value):
|
||||
return {"inner_parent_value": parent_value}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"inner_parent_value": kwargs["parent_value"]}
|
||||
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_parent_args_can_be_drawn_from_context(self, components_settings):
|
||||
|
@ -463,7 +463,7 @@ class TestIsolatedContext:
|
|||
registry.register(name="simple_component", component=SimpleComponent)
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
{% component 'simple_component' variable only %}{% endcomponent %}
|
||||
{% component 'simple_component' variable=variable only %}{% endcomponent %}
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered = template.render(Context({"variable": "outer_value"})).strip()
|
||||
|
@ -490,7 +490,7 @@ class TestIsolatedContextSetting:
|
|||
registry.register(name="simple_component", component=SimpleComponent)
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
{% component 'simple_component' variable %}{% endcomponent %}
|
||||
{% component 'simple_component' variable=variable %}{% endcomponent %}
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered = template.render(Context({"variable": "outer_value"}))
|
||||
|
@ -516,7 +516,7 @@ class TestIsolatedContextSetting:
|
|||
registry.register(name="simple_component", component=SimpleComponent)
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
{% component 'simple_component' variable %}
|
||||
{% component 'simple_component' variable=variable %}
|
||||
{% endcomponent %}
|
||||
"""
|
||||
template = Template(template_str)
|
||||
|
@ -549,7 +549,7 @@ class TestContextProcessors:
|
|||
class TestComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal inner_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -585,7 +585,7 @@ class TestContextProcessors:
|
|||
{% component "test_child" / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal parent_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -596,7 +596,7 @@ class TestContextProcessors:
|
|||
class TestChildComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data_child
|
||||
nonlocal child_request
|
||||
context_processors_data_child = self.context_processors_data
|
||||
|
@ -635,7 +635,7 @@ class TestContextProcessors:
|
|||
{% endcomponent %}
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal parent_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -646,7 +646,7 @@ class TestContextProcessors:
|
|||
class TestChildComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data_child
|
||||
nonlocal child_request
|
||||
context_processors_data_child = self.context_processors_data
|
||||
|
@ -680,7 +680,7 @@ class TestContextProcessors:
|
|||
class TestComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal inner_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -709,7 +709,7 @@ class TestContextProcessors:
|
|||
{% component "test_child" / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal parent_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -720,7 +720,7 @@ class TestContextProcessors:
|
|||
class TestChildComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data_child
|
||||
nonlocal child_request
|
||||
context_processors_data_child = self.context_processors_data
|
||||
|
@ -746,7 +746,7 @@ class TestContextProcessors:
|
|||
class TestComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal inner_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -774,7 +774,7 @@ class TestContextProcessors:
|
|||
{% component "test_child" / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal parent_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -785,7 +785,7 @@ class TestContextProcessors:
|
|||
class TestChildComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data_child
|
||||
nonlocal child_request
|
||||
context_processors_data_child = self.context_processors_data
|
||||
|
@ -811,7 +811,7 @@ class TestContextProcessors:
|
|||
class TestComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal inner_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -834,7 +834,7 @@ class TestContextProcessors:
|
|||
class TestComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal inner_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -857,7 +857,7 @@ class TestContextProcessors:
|
|||
class TestComponent(Component):
|
||||
template: types.django_html = """{% csrf_token %}"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal context_processors_data
|
||||
nonlocal inner_request
|
||||
context_processors_data = self.context_processors_data
|
||||
|
@ -902,7 +902,7 @@ class TestOuterContextProperty:
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return self.outer_context.flatten() # type: ignore[union-attr]
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
|
|
@ -38,10 +38,10 @@ class SimpleComponent(Component):
|
|||
console.log("xyz");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -551,7 +551,7 @@ class TestDependenciesStrategySimple:
|
|||
console.log("Hello");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -573,7 +573,7 @@ class TestDependenciesStrategySimple:
|
|||
console.log("xyz");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -711,7 +711,7 @@ class TestDependenciesStrategyPrepend:
|
|||
console.log("Hello");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -733,7 +733,7 @@ class TestDependenciesStrategyPrepend:
|
|||
console.log("xyz");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -868,7 +868,7 @@ class TestDependenciesStrategyAppend:
|
|||
console.log("Hello");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -890,7 +890,7 @@ class TestDependenciesStrategyAppend:
|
|||
console.log("xyz");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
|
|
@ -25,10 +25,10 @@ class SimpleComponent(Component):
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -55,7 +55,7 @@ class SimpleComponentNested(Component):
|
|||
console.log("Hello");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -78,7 +78,7 @@ class OtherComponent(Component):
|
|||
console.log("xyz");
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
@ -91,7 +91,7 @@ class SimpleComponentWithSharedDependency(Component):
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
class Media:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Catch-all for tests that use template tags and don't fit other files"""
|
||||
|
||||
import re
|
||||
from typing import Any, Dict
|
||||
from typing import Dict
|
||||
|
||||
import pytest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
|
@ -68,21 +68,15 @@ class TestDynamicExpr:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
*args: Any,
|
||||
bool_var: bool,
|
||||
list_var: Dict,
|
||||
):
|
||||
captured["pos_var1"] = pos_var1
|
||||
captured["bool_var"] = bool_var
|
||||
captured["list_var"] = list_var
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
captured["pos_var1"] = args[0]
|
||||
captured["bool_var"] = kwargs["bool_var"]
|
||||
captured["list_var"] = kwargs["list_var"]
|
||||
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"bool_var": bool_var,
|
||||
"list_var": list_var,
|
||||
"pos_var1": args[0],
|
||||
"bool_var": kwargs["bool_var"],
|
||||
"list_var": kwargs["list_var"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -135,24 +129,17 @@ class TestDynamicExpr:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
*args: Any,
|
||||
bool_var: bool,
|
||||
list_var: Dict,
|
||||
dict_var: Dict,
|
||||
):
|
||||
captured["pos_var1"] = pos_var1
|
||||
captured["bool_var"] = bool_var
|
||||
captured["list_var"] = list_var
|
||||
captured["dict_var"] = dict_var
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
captured["pos_var1"] = args[0]
|
||||
captured["bool_var"] = kwargs["bool_var"]
|
||||
captured["list_var"] = kwargs["list_var"]
|
||||
captured["dict_var"] = kwargs["dict_var"]
|
||||
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"bool_var": bool_var,
|
||||
"list_var": list_var,
|
||||
"dict_var": dict_var,
|
||||
"pos_var1": args[0],
|
||||
"bool_var": kwargs["bool_var"],
|
||||
"list_var": kwargs["list_var"],
|
||||
"dict_var": kwargs["dict_var"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -209,24 +196,17 @@ class TestDynamicExpr:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
pos_var2: Any,
|
||||
*args: Any,
|
||||
bool_var: bool,
|
||||
list_var: Dict,
|
||||
):
|
||||
captured["pos_var1"] = pos_var1
|
||||
captured["pos_var2"] = pos_var2
|
||||
captured["bool_var"] = bool_var
|
||||
captured["list_var"] = list_var
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
captured["pos_var1"] = args[0]
|
||||
captured["pos_var2"] = args[1]
|
||||
captured["bool_var"] = kwargs["bool_var"]
|
||||
captured["list_var"] = kwargs["list_var"]
|
||||
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"pos_var2": pos_var2,
|
||||
"bool_var": bool_var,
|
||||
"list_var": list_var,
|
||||
"pos_var1": args[0],
|
||||
"pos_var2": args[1],
|
||||
"bool_var": kwargs["bool_var"],
|
||||
"list_var": kwargs["list_var"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -281,26 +261,18 @@ class TestDynamicExpr:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
pos_var2: Any,
|
||||
*args: Any,
|
||||
bool_var: bool,
|
||||
list_var: Dict,
|
||||
dict_var: Dict,
|
||||
):
|
||||
captured["pos_var1"] = pos_var1
|
||||
captured["bool_var"] = bool_var
|
||||
captured["list_var"] = list_var
|
||||
captured["dict_var"] = dict_var
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
captured["pos_var1"] = args[0]
|
||||
captured["bool_var"] = kwargs["bool_var"]
|
||||
captured["list_var"] = kwargs["list_var"]
|
||||
captured["dict_var"] = kwargs["dict_var"]
|
||||
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"pos_var2": pos_var2,
|
||||
"bool_var": bool_var,
|
||||
"list_var": list_var,
|
||||
"dict_var": dict_var,
|
||||
"pos_var1": args[0],
|
||||
"pos_var2": args[1],
|
||||
"bool_var": kwargs["bool_var"],
|
||||
"list_var": kwargs["list_var"],
|
||||
"dict_var": kwargs["dict_var"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -357,17 +329,11 @@ class TestDynamicExpr:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
pos_var2: Any,
|
||||
*args: Any,
|
||||
bool_var: bool,
|
||||
):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"pos_var2": pos_var2,
|
||||
"bool_var": bool_var,
|
||||
"pos_var1": args[0],
|
||||
"pos_var2": args[1],
|
||||
"bool_var": kwargs["bool_var"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -404,15 +370,10 @@ class TestDynamicExpr:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
*args: Any,
|
||||
bool_var: bool,
|
||||
):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"bool_var": bool_var,
|
||||
"pos_var1": args[0],
|
||||
"bool_var": kwargs["bool_var"],
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
|
@ -461,17 +422,12 @@ class TestSpreadOperator:
|
|||
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
pos_var1: Any,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal captured
|
||||
captured = kwargs
|
||||
|
||||
return {
|
||||
"pos_var1": pos_var1,
|
||||
"pos_var1": args[0],
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
|
@ -531,7 +487,7 @@ class TestSpreadOperator:
|
|||
def test_slot(self, components_settings):
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"my_dict": {
|
||||
"attrs:@click": "() => {}",
|
||||
|
@ -568,7 +524,7 @@ class TestSpreadOperator:
|
|||
def test_fill(self, components_settings):
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"my_dict": {
|
||||
"attrs:@click": "() => {}",
|
||||
|
@ -618,7 +574,7 @@ class TestSpreadOperator:
|
|||
def test_provide(self, components_settings):
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
data = self.inject("test")
|
||||
return {
|
||||
"attrs": data.attrs,
|
||||
|
@ -692,11 +648,7 @@ class TestSpreadOperator:
|
|||
def test_later_spreads_do_not_overwrite_earlier(self, components_settings):
|
||||
@register("test")
|
||||
class SimpleComponent(Component):
|
||||
def get_context_data(
|
||||
self,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
**kwargs,
|
||||
}
|
||||
|
@ -794,7 +746,7 @@ class TestSpreadOperator:
|
|||
class SimpleComponent(Component):
|
||||
template = ""
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal captured
|
||||
captured = args, kwargs
|
||||
return {}
|
||||
|
@ -820,7 +772,7 @@ class TestSpreadOperator:
|
|||
template.render(context)
|
||||
|
||||
assert captured == (
|
||||
("a", "b", "c", 1, 2, 3),
|
||||
["a", "b", "c", 1, 2, 3],
|
||||
{},
|
||||
)
|
||||
|
||||
|
@ -858,7 +810,7 @@ class TestAggregateKwargs:
|
|||
class Test(Component):
|
||||
template = ""
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal captured
|
||||
captured = args, kwargs
|
||||
return {}
|
||||
|
@ -879,7 +831,7 @@ class TestAggregateKwargs:
|
|||
template.render(Context({"class_var": "padding-top-8", "four": 4}))
|
||||
|
||||
assert captured == (
|
||||
(),
|
||||
[],
|
||||
{
|
||||
"attrs": {
|
||||
"@click.stop": "dispatch('click_event')",
|
||||
|
|
|
@ -116,8 +116,8 @@ def with_component_cls(on_created: Callable):
|
|||
class TempComponent(Component):
|
||||
template = "Hello {{ name }}!"
|
||||
|
||||
def get_context_data(self, name="World"):
|
||||
return {"name": name}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": kwargs.get("name", "World")}
|
||||
|
||||
on_created()
|
||||
|
||||
|
@ -143,8 +143,8 @@ class TestExtension:
|
|||
class TestAccessComp(Component):
|
||||
template = "Hello {{ name }}!"
|
||||
|
||||
def get_context_data(self, arg1, arg2, name="World"):
|
||||
return {"name": name}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": kwargs.get("name", "World")}
|
||||
|
||||
ext_class = TestAccessComp.TestExtension # type: ignore[attr-defined]
|
||||
assert issubclass(ext_class, ComponentExtension.ExtensionClass)
|
||||
|
@ -240,8 +240,8 @@ class TestExtensionHooks:
|
|||
class TestComponent(Component):
|
||||
template = "Hello {{ name }}!"
|
||||
|
||||
def get_context_data(self, name="World"):
|
||||
return {"name": name}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": kwargs.get("name", "World")}
|
||||
|
||||
registry.register("test_comp", TestComponent)
|
||||
extension = cast(DummyExtension, app_settings.EXTENSIONS[3])
|
||||
|
@ -268,13 +268,13 @@ class TestExtensionHooks:
|
|||
class TestComponent(Component):
|
||||
template = "Hello {{ name }}!"
|
||||
|
||||
def get_context_data(self, arg1, arg2, name="World"):
|
||||
return {"name": name}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"name": kwargs.get("name", "World")}
|
||||
|
||||
def get_js_data(self, *args, **kwargs):
|
||||
def get_js_data(self, args, kwargs, slots, context):
|
||||
return {"script": "console.log('Hello!')"}
|
||||
|
||||
def get_css_data(self, *args, **kwargs):
|
||||
def get_css_data(self, args, kwargs, slots, context):
|
||||
return {"style": "body { color: blue; }"}
|
||||
|
||||
# Render the component with some args and kwargs
|
||||
|
|
|
@ -182,9 +182,9 @@ class TestMultipleComponentRegistries:
|
|||
Slot: {% slot "default" default / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
registry_a.register("simple_a", SimpleComponent)
|
||||
|
|
|
@ -51,10 +51,10 @@ class TestTemplateSignal:
|
|||
class InnerComponent(Component):
|
||||
template_file = "simple_template.html"
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
|
|
@ -2706,7 +2706,7 @@ class TestResolver:
|
|||
|
||||
@register("test")
|
||||
class Test(Component):
|
||||
def get_context_data(self, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal captured
|
||||
captured = kwargs
|
||||
return {}
|
||||
|
@ -2771,7 +2771,7 @@ class TestResolver:
|
|||
class Test(Component):
|
||||
template = "var"
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal captured
|
||||
captured = args, kwargs
|
||||
return {}
|
||||
|
@ -2783,7 +2783,7 @@ class TestResolver:
|
|||
"""
|
||||
Template(template_str).render(Context({"myvar": "myval", "val2": [1, 2, 3]}))
|
||||
|
||||
assert captured == ((42, "myval"), {"key": "val", "key2": [1, 2, 3]})
|
||||
assert captured == ([42, "myval"], {"key": "val", "key2": [1, 2, 3]})
|
||||
|
||||
def test_component_special_kwargs(self):
|
||||
captured = None
|
||||
|
@ -2792,7 +2792,7 @@ class TestResolver:
|
|||
class Test(Component):
|
||||
template = "var"
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal captured
|
||||
captured = args, kwargs
|
||||
return {}
|
||||
|
@ -2805,7 +2805,7 @@ class TestResolver:
|
|||
Template(template_str).render(Context({"date": 2024, "bzz": "fzz"}))
|
||||
|
||||
assert captured == (
|
||||
tuple([]),
|
||||
[],
|
||||
{
|
||||
"date": 2024,
|
||||
"@lol": 2,
|
||||
|
|
|
@ -33,9 +33,9 @@ class TestTemplateCache:
|
|||
"""
|
||||
return content
|
||||
|
||||
def get_context_data(self, variable=None):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable": kwargs.get("variable", None),
|
||||
}
|
||||
|
||||
comp = SimpleComponent()
|
||||
|
|
|
@ -215,8 +215,8 @@ class TestTemplateParser:
|
|||
Slot: {% slot "content" default / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, var: str) -> dict:
|
||||
return {"var": var}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"var": kwargs["var"]}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
|
|
@ -29,17 +29,17 @@ class TestMultilineTags:
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
{% component
|
||||
"test_component"
|
||||
123
|
||||
variable=123
|
||||
variable2="abc"
|
||||
%}
|
||||
{% endcomponent %}
|
||||
|
@ -58,9 +58,9 @@ class TestNestedTags:
|
|||
Variable: <strong>{{ var }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, var):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"var": var,
|
||||
"var": kwargs["var"],
|
||||
}
|
||||
|
||||
# See https://github.com/django-components/django-components/discussions/671
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import re
|
||||
from typing import NamedTuple
|
||||
|
||||
import pytest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
|
@ -25,8 +26,8 @@ class SlottedComponentWithContext(Component):
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
||||
|
||||
#######################
|
||||
|
@ -41,10 +42,10 @@ class TestComponentTemplateTag:
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -114,10 +115,10 @@ class TestComponentTemplateTag:
|
|||
{% endif %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -178,8 +179,11 @@ class TestComponentTemplateTag:
|
|||
Default: <p>{{ default_param }}</p>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, default_param="default text"):
|
||||
return {"variable": variable, "default_param": default_param}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": kwargs["variable"],
|
||||
"default_param": kwargs.get("default_param", "default text"),
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -204,10 +208,17 @@ class TestDynamicComponentTemplateTag:
|
|||
Variable: <strong>{{ variable }}</strong>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
class Kwargs(NamedTuple):
|
||||
variable: str
|
||||
variable2: str
|
||||
|
||||
class Defaults:
|
||||
variable2 = "default"
|
||||
|
||||
def get_template_data(self, args, kwargs: Kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs.variable,
|
||||
"variable2": kwargs.variable2,
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -375,10 +386,10 @@ class TestDynamicComponentTemplateTag:
|
|||
Slot: {% slot "default" default / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
registry.register(name="test", component=SimpleSlottedComponent)
|
||||
|
@ -412,10 +423,10 @@ class TestDynamicComponentTemplateTag:
|
|||
Slot 2: {% slot "two" / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
registry.register(name="test", component=SimpleSlottedComponent)
|
||||
|
@ -455,10 +466,10 @@ class TestDynamicComponentTemplateTag:
|
|||
Slot 2: {% slot "two" / %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
registry.register(name="test", component=SimpleSlottedComponent)
|
||||
|
@ -722,8 +733,11 @@ class TestAggregateInput:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, *args, attrs, my_dict):
|
||||
return {"attrs": attrs, "my_dict": my_dict}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"attrs": kwargs["attrs"],
|
||||
"my_dict": kwargs["my_dict"],
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -751,9 +765,12 @@ class TestRecursiveComponent:
|
|||
|
||||
@register("recursive")
|
||||
class Recursive(Component):
|
||||
def get_context_data(self, depth: int = 0):
|
||||
print("depth:", depth)
|
||||
return {"depth": depth + 1, "DEPTH": DEPTH}
|
||||
class Defaults:
|
||||
depth = 0
|
||||
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
print("depth:", kwargs["depth"])
|
||||
return {"depth": kwargs["depth"] + 1, "DEPTH": DEPTH}
|
||||
|
||||
template: types.django_html = """
|
||||
<div>
|
||||
|
|
|
@ -820,7 +820,7 @@ class TestExtendsCompat:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("block_provide")
|
||||
return {"var": var}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import re
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
|
@ -29,7 +28,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -79,7 +78,7 @@ class TestProvideTemplateTag:
|
|||
<div> another: {{ another }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
my_provide = self.inject("my_provide")
|
||||
return {
|
||||
"key": my_provide.key,
|
||||
|
@ -114,7 +113,7 @@ class TestProvideTemplateTag:
|
|||
<div> another: {{ my_provide.another }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
my_provide = self.inject("my_provide")
|
||||
return {
|
||||
"my_provide": my_provide,
|
||||
|
@ -147,7 +146,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -179,7 +178,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -214,7 +213,7 @@ class TestProvideTemplateTag:
|
|||
<div></div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {}
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
@ -246,7 +245,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -279,7 +278,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -318,7 +317,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -361,7 +360,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -390,7 +389,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -419,7 +418,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -446,7 +445,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -478,7 +477,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -515,7 +514,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -558,7 +557,7 @@ class TestProvideTemplateTag:
|
|||
<div> second_provide: {{ second_provide|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
first_provide = self.inject("first_provide", "default")
|
||||
second_provide = self.inject("second_provide", "default")
|
||||
return {
|
||||
|
@ -595,7 +594,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -626,7 +625,7 @@ class TestProvideTemplateTag:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -674,7 +673,7 @@ class TestInject:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("my_provide")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -704,7 +703,7 @@ class TestInject:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("abc")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -728,7 +727,7 @@ class TestInject:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("abc", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -755,7 +754,7 @@ class TestInject:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -783,7 +782,7 @@ class TestInject:
|
|||
<div> injected: {{ var|safe }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
var = self.inject("abc", "default")
|
||||
return {"var": var}
|
||||
|
||||
|
@ -806,14 +805,14 @@ class TestInject:
|
|||
</main>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
data = self.inject("my_provide")
|
||||
return {"data": data}
|
||||
|
||||
@register("provider")
|
||||
class Provider(Component):
|
||||
def get_context_data(self, data: Any) -> Any:
|
||||
return {"data": data}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"data": kwargs["data"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -824,8 +823,8 @@ class TestInject:
|
|||
|
||||
@register("parent")
|
||||
class Parent(Component):
|
||||
def get_context_data(self, data: Any) -> Any:
|
||||
return {"data": data}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"data": kwargs["data"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -875,14 +874,14 @@ class TestInject:
|
|||
</main>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
data = self.inject("my_provide")
|
||||
return {"data": data}
|
||||
|
||||
@register("provider")
|
||||
class Provider(Component):
|
||||
def get_context_data(self, data: Any) -> Any:
|
||||
return {"data": data}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"data": kwargs["data"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -893,8 +892,8 @@ class TestInject:
|
|||
|
||||
@register("parent")
|
||||
class Parent(Component):
|
||||
def get_context_data(self, data: Any) -> Any:
|
||||
return {"data": data}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"data": kwargs["data"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -949,7 +948,7 @@ class TestProvideCache:
|
|||
<div> Ran: {{ ran }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
assert len(provide_cache) == 1
|
||||
|
||||
data = self.inject("my_provide")
|
||||
|
@ -989,7 +988,7 @@ class TestProvideCache:
|
|||
class Injectee(Component):
|
||||
template = ""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
assert len(provide_cache) == 1
|
||||
data = self.inject("my_provide")
|
||||
|
||||
|
@ -1022,7 +1021,7 @@ class TestProvideCache:
|
|||
<div> Ran: {{ ran }} </div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
assert len(provide_cache) == 1
|
||||
|
||||
data = self.inject("my_provide")
|
||||
|
@ -1059,7 +1058,7 @@ class TestProvideCache:
|
|||
class Injectee(Component):
|
||||
template = ""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
assert len(provide_cache) == 1
|
||||
|
||||
data = self.inject("my_provide")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import re
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Dict
|
||||
|
||||
import pytest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
|
@ -40,10 +40,10 @@ class TestComponentSlot:
|
|||
class SimpleComponent(Component):
|
||||
template = """Variable: <strong>{{ variable }}</strong>"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
class Media:
|
||||
|
@ -96,10 +96,10 @@ class TestComponentSlot:
|
|||
class SimpleComponent(Component):
|
||||
template = """Variable: <strong>{{ variable }}</strong>"""
|
||||
|
||||
def get_context_data(self, variable, variable2="default"):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"variable": variable,
|
||||
"variable2": variable2,
|
||||
"variable": kwargs["variable"],
|
||||
"variable2": kwargs.get("variable2", "default"),
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
@ -152,8 +152,8 @@ class TestComponentSlot:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, variable):
|
||||
return {"variable": variable}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"variable": kwargs["variable"]}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -294,9 +294,9 @@ class TestComponentSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
registry.register("test", SlottedComponent)
|
||||
|
@ -451,8 +451,8 @@ class TestComponentSlot:
|
|||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_multiple_slots_with_same_name_different_flags(self, components_settings):
|
||||
class TestComp(Component):
|
||||
def get_context_data(self, required: bool) -> Any:
|
||||
return {"required": required}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"required": kwargs["required"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -824,8 +824,8 @@ class TestComponentSlotDefault:
|
|||
def test_implicit_fill_when_slot_marked_default_not_rendered(self, components_settings):
|
||||
@register("test_comp")
|
||||
class ConditionalSlotted(Component):
|
||||
def get_context_data(self, var: bool) -> Any:
|
||||
return {"var": var}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"var": kwargs["var"]}
|
||||
|
||||
template: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -885,9 +885,9 @@ class TestPassthroughSlots:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
@ -941,9 +941,9 @@ class TestPassthroughSlots:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
@ -985,9 +985,9 @@ class TestPassthroughSlots:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
@ -1021,7 +1021,7 @@ class TestPassthroughSlots:
|
|||
def test_slots_inside_loops(self, components_settings):
|
||||
@register("test_comp")
|
||||
class OuterComp(Component):
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"slots": ["header", "main", "footer"],
|
||||
}
|
||||
|
@ -1064,7 +1064,7 @@ class TestPassthroughSlots:
|
|||
|
||||
@register("test_comp")
|
||||
class OuterComp(Component):
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"slots": self.input.slots,
|
||||
}
|
||||
|
@ -1115,7 +1115,7 @@ class TestPassthroughSlots:
|
|||
|
||||
@register("test_comp")
|
||||
class OuterComp(Component):
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"slots": self.input.slots,
|
||||
}
|
||||
|
@ -1510,7 +1510,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1545,7 +1545,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1580,7 +1580,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1617,7 +1617,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"slot_name": "my_slot",
|
||||
"abc": "def",
|
||||
|
@ -1653,7 +1653,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"slot_props": {
|
||||
"name": "my_slot",
|
||||
|
@ -1692,7 +1692,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "xyz",
|
||||
"var123": 456,
|
||||
|
@ -1728,7 +1728,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1759,7 +1759,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1811,7 +1811,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1837,7 +1837,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1880,7 +1880,7 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"var123": 456,
|
||||
|
@ -1925,10 +1925,10 @@ class TestScopedSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, input):
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"abc": "def",
|
||||
"input": input,
|
||||
"input": kwargs["input"],
|
||||
}
|
||||
|
||||
template_str: types.django_html = """
|
||||
|
@ -1974,9 +1974,9 @@ class TestDuplicateSlot:
|
|||
<footer>{% slot "footer" %}Default footer{% endslot %}</footer>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
return DuplicateSlotComponent
|
||||
|
||||
|
@ -2001,9 +2001,9 @@ class TestDuplicateSlot:
|
|||
</div>
|
||||
"""
|
||||
|
||||
def get_context_data(self, items: List) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"items": items,
|
||||
"items": kwargs["items"],
|
||||
}
|
||||
return DuplicateSlotNestedComponent
|
||||
|
||||
|
@ -2243,9 +2243,9 @@ class TestSlotBehavior:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
registry.register("test", SlottedComponent)
|
||||
|
@ -2360,7 +2360,7 @@ class TestSlotBehavior:
|
|||
class TestSlotInput:
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_slots_accessible_when_python_render(self, components_settings):
|
||||
slots: Dict = {}
|
||||
seen_slots: Dict = {}
|
||||
|
||||
@register("test")
|
||||
class SlottedComponent(Component):
|
||||
|
@ -2371,12 +2371,12 @@ class TestSlotInput:
|
|||
<footer>{% slot "footer" %}Default footer{% endslot %}</footer>
|
||||
"""
|
||||
|
||||
def get_context_data(self, input: Optional[int] = None) -> Dict[str, Any]:
|
||||
nonlocal slots
|
||||
slots = self.input.slots
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal seen_slots
|
||||
seen_slots = slots
|
||||
return {}
|
||||
|
||||
assert slots == {}
|
||||
assert seen_slots == {}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
@ -2390,14 +2390,14 @@ class TestSlotInput:
|
|||
template = Template(template_str)
|
||||
template.render(Context())
|
||||
|
||||
assert list(slots.keys()) == ["header", "main"]
|
||||
assert callable(slots["header"])
|
||||
assert callable(slots["main"])
|
||||
assert "footer" not in slots
|
||||
assert list(seen_slots.keys()) == ["header", "main"]
|
||||
assert callable(seen_slots["header"])
|
||||
assert callable(seen_slots["main"])
|
||||
assert "footer" not in seen_slots
|
||||
|
||||
@djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR)
|
||||
def test_slots_normalized_as_slot_instances(self, components_settings):
|
||||
slots: Dict[str, Slot] = {}
|
||||
seen_slots: Dict[str, Slot] = {}
|
||||
|
||||
@register("test")
|
||||
class SlottedComponent(Component):
|
||||
|
@ -2408,12 +2408,12 @@ class TestSlotInput:
|
|||
<footer>{% slot "footer" %}Default footer{% endslot %}</footer>
|
||||
"""
|
||||
|
||||
def get_context_data(self, input: Optional[int] = None) -> Dict[str, Any]:
|
||||
nonlocal slots
|
||||
slots = self.input.slots
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
nonlocal seen_slots
|
||||
seen_slots = slots
|
||||
return {}
|
||||
|
||||
assert slots == {}
|
||||
assert seen_slots == {}
|
||||
|
||||
header_slot = Slot(lambda *a, **kw: "HEADER_SLOT")
|
||||
main_slot_str = "MAIN_SLOT"
|
||||
|
@ -2427,11 +2427,11 @@ class TestSlotInput:
|
|||
}
|
||||
)
|
||||
|
||||
assert isinstance(slots["header"], Slot)
|
||||
assert slots["header"](Context(), None, None) == "HEADER_SLOT" # type: ignore[arg-type]
|
||||
assert isinstance(seen_slots["header"], Slot)
|
||||
assert seen_slots["header"](Context(), None, None) == "HEADER_SLOT" # type: ignore[arg-type]
|
||||
|
||||
assert isinstance(slots["main"], Slot)
|
||||
assert slots["main"](Context(), None, None) == "MAIN_SLOT" # type: ignore[arg-type]
|
||||
assert isinstance(seen_slots["main"], Slot)
|
||||
assert seen_slots["main"](Context(), None, None) == "MAIN_SLOT" # type: ignore[arg-type]
|
||||
|
||||
assert isinstance(slots["footer"], Slot)
|
||||
assert slots["footer"](Context(), None, None) == "FOOTER_SLOT" # type: ignore[arg-type]
|
||||
assert isinstance(seen_slots["footer"], Slot)
|
||||
assert seen_slots["footer"](Context(), None, None) == "FOOTER_SLOT" # type: ignore[arg-type]
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""This file tests various ways how the individual tags can be combined inside the templates"""
|
||||
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from django.template import Context, Template
|
||||
from pytest_django.asserts import assertHTMLEqual
|
||||
|
||||
|
@ -103,9 +101,9 @@ class TestNestedSlot:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
registry.clear()
|
||||
|
@ -168,8 +166,8 @@ class TestConditionalSlot:
|
|||
{% endif %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, branch=None):
|
||||
return {"branch": branch}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"branch": kwargs.get("branch", None)}
|
||||
|
||||
return ConditionalComponent
|
||||
|
||||
|
@ -267,9 +265,9 @@ class TestSlotIteration:
|
|||
{% endfor %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, objects, *args, **kwargs) -> dict:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"objects": objects,
|
||||
"objects": kwargs["objects"],
|
||||
}
|
||||
|
||||
return ComponentSimpleSlotInALoop
|
||||
|
@ -303,7 +301,7 @@ class TestSlotIteration:
|
|||
assertHTMLEqual(rendered, expected)
|
||||
|
||||
# NOTE: Second arg in tuple is expected result. In isolated mode, while loops should NOT leak,
|
||||
# we should still have access to root context (returned from get_context_data)
|
||||
# we should still have access to root context (returned from get_template_data)
|
||||
@djc_test(
|
||||
parametrize=(
|
||||
["components_settings", "expected"],
|
||||
|
@ -376,7 +374,7 @@ class TestSlotIteration:
|
|||
assertHTMLEqual(rendered, expected)
|
||||
|
||||
# NOTE: Second arg in tuple is expected result. In isolated mode, while loops should NOT leak,
|
||||
# we should still have access to root context (returned from get_context_data)
|
||||
# we should still have access to root context (returned from get_template_data)
|
||||
@djc_test(
|
||||
parametrize=(
|
||||
["components_settings", "expected"],
|
||||
|
@ -662,9 +660,9 @@ class TestComponentNesting:
|
|||
</custom-template>
|
||||
"""
|
||||
|
||||
def get_context_data(self, name: Optional[str] = None) -> Dict[str, Any]:
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {
|
||||
"name": name,
|
||||
"name": kwargs.get("name", None),
|
||||
}
|
||||
|
||||
registry.register("test", SlottedComponent)
|
||||
|
@ -817,8 +815,8 @@ class TestComponentNesting:
|
|||
{% endfor %}
|
||||
"""
|
||||
|
||||
def get_context_data(self, items, *args, **kwargs) -> Dict[str, Any]:
|
||||
return {"items": items}
|
||||
def get_template_data(self, args, kwargs, slots, context):
|
||||
return {"items": kwargs["items"]}
|
||||
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue