diff --git a/README.md b/README.md
index c9c56bf8..bedfc0cc 100644
--- a/README.md
+++ b/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):
"""
- 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,
diff --git a/docs/concepts/advanced/component_caching.md b/docs/concepts/advanced/component_caching.md
index 4d427fa5..5ee84072 100644
--- a/docs/concepts/advanced/component_caching.md
+++ b/docs/concepts/advanced/component_caching.md
@@ -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.
diff --git a/docs/concepts/advanced/component_context_scope.md b/docs/concepts/advanced/component_context_scope.md
index 119b5c43..418a1d69 100644
--- a/docs/concepts/advanced/component_context_scope.md
+++ b/docs/concepts/advanced/component_context_scope.md
@@ -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_
```
-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
diff --git a/docs/concepts/advanced/component_registry.md b/docs/concepts/advanced/component_registry.md
index 57e2e328..f5865420 100644
--- a/docs/concepts/advanced/component_registry.md
+++ b/docs/concepts/advanced/component_registry.md
@@ -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"],
}
```
diff --git a/docs/concepts/advanced/extensions.md b/docs/concepts/advanced/extensions.md
index 97a9a196..dad769e6 100644
--- a/docs/concepts/advanced/extensions.md
+++ b/docs/concepts/advanced/extensions.md
@@ -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(),
diff --git a/docs/concepts/advanced/provide_inject.md b/docs/concepts/advanced/provide_inject.md
index a2013fdf..3c843f5e 100644
--- a/docs/concepts/advanced/provide_inject.md
+++ b/docs/concepts/advanced/provide_inject.md
@@ -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):
{{ my_data.another }}
"""
- 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}
diff --git a/docs/concepts/fundamentals/component_defaults.md b/docs/concepts/fundamentals/component_defaults.md
index 804226c5..23b6ec9d 100644
--- a/docs/concepts/fundamentals/component_defaults.md
+++ b/docs/concepts/fundamentals/component_defaults.md
@@ -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"],
}
```
diff --git a/docs/concepts/fundamentals/html_attributes.md b/docs/concepts/fundamentals/html_attributes.md
index b990133b..22b111d3 100644
--- a/docs/concepts/fundamentals/html_attributes.md
+++ b/docs/concepts/fundamentals/html_attributes.md
@@ -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):
"""
- 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 = {
diff --git a/docs/concepts/fundamentals/html_js_css_variables.md b/docs/concepts/fundamentals/html_js_css_variables.md
index af30fbc0..6b0da6fe 100644
--- a/docs/concepts/fundamentals/html_js_css_variables.md
+++ b/docs/concepts/fundamentals/html_js_css_variables.md
@@ -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)
diff --git a/docs/concepts/fundamentals/http_request.md b/docs/concepts/fundamentals/http_request.md
index 39fc7dc0..c6d3847d 100644
--- a/docs/concepts/fundamentals/http_request.md
+++ b/docs/concepts/fundamentals/http_request.md
@@ -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,
diff --git a/docs/concepts/fundamentals/render_api.md b/docs/concepts/fundamentals/render_api.md
index a8adc728..09dfcff1 100644
--- a/docs/concepts/fundamentals/render_api.md
+++ b/docs/concepts/fundamentals/render_api.md
@@ -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"
diff --git a/docs/concepts/fundamentals/single_file_components.md b/docs/concepts/fundamentals/single_file_components.md
index 456bc49f..6f9b0765 100644
--- a/docs/concepts/fundamentals/single_file_components.md
+++ b/docs/concepts/fundamentals/single_file_components.md
@@ -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
diff --git a/docs/concepts/fundamentals/slots.md b/docs/concepts/fundamentals/slots.md
index 9e7b7025..b1f7453c 100644
--- a/docs/concepts/fundamentals/slots.md
+++ b/docs/concepts/fundamentals/slots.md
@@ -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):
"""
- 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):
"""
- 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 = """
diff --git a/docs/concepts/fundamentals/subclassing_components.md b/docs/concepts/fundamentals/subclassing_components.md
index c1207577..4f8c1284 100644
--- a/docs/concepts/fundamentals/subclassing_components.md
+++ b/docs/concepts/fundamentals/subclassing_components.md
@@ -100,7 +100,7 @@ class BaseForm(Component):
"""
- 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
diff --git a/docs/concepts/fundamentals/template_tag_syntax.md b/docs/concepts/fundamentals/template_tag_syntax.md
index 96b99f58..54f59697 100644
--- a/docs/concepts/fundamentals/template_tag_syntax.md
+++ b/docs/concepts/fundamentals/template_tag_syntax.md
@@ -30,14 +30,12 @@ so are still valid: