mirror of
https://github.com/django-components/django-components.git
synced 2025-09-26 15:39:08 +00:00
docs: update README
This commit is contained in:
parent
36cd6e3f06
commit
bca26c46f3
1 changed files with 137 additions and 3 deletions
140
README.md
140
README.md
|
@ -45,6 +45,10 @@ Read on to learn about the details!
|
||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
|
||||||
|
🚨📢 **Version 0.81** Aligned the `render_to_response` method with the (now public) `render` method of `Component` class. Moreover, slots passed to these can now be rendered also as functions.
|
||||||
|
|
||||||
|
- BREAKING CHANGE: The order of arguments to `render_to_response` has changed.
|
||||||
|
|
||||||
**Version 0.80** introduces dependency injection with the `{% provide %}` tag and `inject()` method.
|
**Version 0.80** introduces dependency injection with the `{% provide %}` tag and `inject()` method.
|
||||||
|
|
||||||
🚨📢 **Version 0.79**
|
🚨📢 **Version 0.79**
|
||||||
|
@ -313,7 +317,7 @@ This makes it easy to create small components without having to create a separat
|
||||||
|
|
||||||
Note that the `t.django_html`, `t.css`, and `t.js` types are used to specify the type of the template, CSS, and JS files, respectively. This is not necessary, but if you're using VSCode with the [Python Inline Source Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=samwillis.python-inline-source) extension, it will give you syntax highlighting for the template, CSS, and JS.
|
Note that the `t.django_html`, `t.css`, and `t.js` types are used to specify the type of the template, CSS, and JS files, respectively. This is not necessary, but if you're using VSCode with the [Python Inline Source Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=samwillis.python-inline-source) extension, it will give you syntax highlighting for the template, CSS, and JS.
|
||||||
|
|
||||||
## Use the component in a template
|
## Use components in templates
|
||||||
|
|
||||||
First load the `component_tags` tag library, then use the `component_[js/css]_dependencies` and `component` tags to render the component to the page.
|
First load the `component_tags` tag library, then use the `component_[js/css]_dependencies` and `component` tags to render the component to the page.
|
||||||
|
|
||||||
|
@ -358,13 +362,143 @@ The output from the above template will be:
|
||||||
|
|
||||||
This makes it possible to organize your front-end around reusable components. Instead of relying on template tags and keeping your CSS and Javascript in the static directory.
|
This makes it possible to organize your front-end around reusable components. Instead of relying on template tags and keeping your CSS and Javascript in the static directory.
|
||||||
|
|
||||||
|
## Use components outside of templates
|
||||||
|
|
||||||
|
_New in version 0.81_
|
||||||
|
|
||||||
|
Components can be rendered outside of Django templates, calling them as regular functions ("React-style").
|
||||||
|
|
||||||
|
The component class defines `render` and `render_to_response` class methods. These methods accept positional args, kwargs, and slots, offering the same flexibility as the `{% component %}` tag:
|
||||||
|
|
||||||
|
```py
|
||||||
|
class SimpleComponent(component.Component):
|
||||||
|
template = """
|
||||||
|
{% load component_tags %}
|
||||||
|
hello: {{ hello }}
|
||||||
|
foo: {{ foo }}
|
||||||
|
kwargs: {{ kwargs|safe }}
|
||||||
|
slot_first: {% slot "first" required %}{% endslot %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_context_data(self, arg1, arg2, **kwargs):
|
||||||
|
return {
|
||||||
|
"hello": arg1,
|
||||||
|
"foo": arg2,
|
||||||
|
"kwargs": kwargs,
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered = SimpleComponent.render(
|
||||||
|
args=["world", "bar"],
|
||||||
|
kwargs={"kw1": "test", "kw2": "ooo"},
|
||||||
|
slots={"first": "FIRST_SLOT"},
|
||||||
|
context={"from_context": 98},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Renders:
|
||||||
|
|
||||||
|
```
|
||||||
|
hello: world
|
||||||
|
foo: bar
|
||||||
|
kwargs: {'kw1': 'test', 'kw2': 'ooo'}
|
||||||
|
slot_first: FIRST_SLOT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inputs of `render` and `render_to_response`
|
||||||
|
|
||||||
|
Both `render` and `render_to_response` accept the same input:
|
||||||
|
|
||||||
|
```py
|
||||||
|
Component.render(
|
||||||
|
context: Mapping | django.template.Context | None = None,
|
||||||
|
args: List[Any] | None = None,
|
||||||
|
kwargs: Dict[str, Any] | None = None,
|
||||||
|
slots: Dict[str, str | SafeString | SlotRenderFunc] | None = None,
|
||||||
|
escape_slots_content: bool = True
|
||||||
|
) -> str:
|
||||||
|
```
|
||||||
|
|
||||||
|
- _`args`_ - Positional args for the component. This is the same as calling the component
|
||||||
|
as `{% component "my_comp" arg1 arg2 ... %}`
|
||||||
|
|
||||||
|
- _`kwargs`_ - Keyword args for the component. This is the same as calling the component
|
||||||
|
as `{% component "my_comp" key1=val1 key2=val2 ... %}`
|
||||||
|
|
||||||
|
- _`slots`_ - Component slot fills. This is the same as pasing `{% fill %}` tags to the component.
|
||||||
|
Accepts a dictionary of `{ slot_name: slot_content }` where `slot_content` can be a string
|
||||||
|
or [`SlotRenderFunc`](#slotrenderfunc).
|
||||||
|
|
||||||
|
- _`escape_slots_content`_ - Whether the content from `slots` should be escaped. `True` by default to prevent XSS attacks. If you disable escaping, you should make sure that any content you pass to the slots is safe, especially if it comes from user input.
|
||||||
|
|
||||||
|
- _`context`_ - A context (dictionary or Django's Context) within which the component
|
||||||
|
is rendered. The keys on the context can be accessed from within the template.
|
||||||
|
- NOTE: In "isolated" mode, context is NOT accessible, and data MUST be passed via
|
||||||
|
component's args and kwargs.
|
||||||
|
|
||||||
|
#### `SlotRenderFunc`
|
||||||
|
|
||||||
|
When rendering components with slots in `render` or `render_to_response`, you can pass either a string or a function.
|
||||||
|
|
||||||
|
The function has following signature:
|
||||||
|
|
||||||
|
```py
|
||||||
|
def render_func(
|
||||||
|
context: Context,
|
||||||
|
data: Dict[str, Any],
|
||||||
|
slot_ref: SlotRef,
|
||||||
|
) -> str | SafeString:
|
||||||
|
return nodelist.render(ctx)
|
||||||
|
```
|
||||||
|
|
||||||
|
- _`context`_ - Django's Context available to the Slot Node.
|
||||||
|
- _`data`_ - Data passed to the `{% slot %}` tag. See [Scoped Slots](#scoped-slots).
|
||||||
|
- _`slot_ref`_ - The default slot content. See [Accessing original content of slots](#accessing-original-content-of-slots).
|
||||||
|
- NOTE: The slot is lazily evaluated. To render the slot, convert it to string with `str(slot_ref)`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```py
|
||||||
|
def footer_slot(ctx, data, slot_ref):
|
||||||
|
return f"""
|
||||||
|
SLOT_DATA: {data['abc']}
|
||||||
|
ORIGINAL: {slot_ref}
|
||||||
|
"""
|
||||||
|
|
||||||
|
MyComponent.render_to_response(
|
||||||
|
slots={
|
||||||
|
"footer": footer_slot,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Response class of `render_to_response`
|
||||||
|
|
||||||
|
While `render` method returns a plain string, `render_to_response` wraps the rendered content in a "Response" class. By default, this is `django.http.HttpResponse`.
|
||||||
|
|
||||||
|
If you want to use a different Response class in `render_to_response`, set the `Component.response_class` attribute:
|
||||||
|
|
||||||
|
```py
|
||||||
|
class MyResponse(HttpResponse):
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
# Configure response
|
||||||
|
self.headers = ...
|
||||||
|
self.status = ...
|
||||||
|
|
||||||
|
class SimpleComponent(component.Component):
|
||||||
|
response_class = MyResponse
|
||||||
|
template: types.django_html = "HELLO"
|
||||||
|
|
||||||
|
response = SimpleComponent.render_to_response()
|
||||||
|
assert isinstance(response, MyResponse)
|
||||||
|
```
|
||||||
|
|
||||||
## Use components as views
|
## Use components as views
|
||||||
|
|
||||||
_New in version 0.34_
|
_New in version 0.34_
|
||||||
|
|
||||||
Components can now be used as views. To do this, `Component` subclasses Django's `View` class. This means that you can use all of the [methods](https://docs.djangoproject.com/en/5.0/ref/class-based-views/base/#view) of `View` in your component. For example, you can override `get` and `post` to handle GET and POST requests, respectively.
|
Components can now be used as views. To do this, `Component` subclasses Django's `View` class. This means that you can use all of the [methods](https://docs.djangoproject.com/en/5.0/ref/class-based-views/base/#view) of `View` in your component. For example, you can override `get` and `post` to handle GET and POST requests, respectively.
|
||||||
|
|
||||||
In addition, `Component` now has a `render_to_response` method that renders the component template based on the provided context and slots' data and returns an `HttpResponse` object.
|
In addition, `Component` now has a [`render_to_response`](#inputs-of-render-and-render_to_response) method that renders the component template based on the provided context and slots' data and returns an `HttpResponse` object.
|
||||||
|
|
||||||
Here's an example of a calendar component defined as a view:
|
Here's an example of a calendar component defined as a view:
|
||||||
|
|
||||||
|
@ -393,7 +527,7 @@ class Calendar(component.Component):
|
||||||
slots = {
|
slots = {
|
||||||
"header": "Calendar header",
|
"header": "Calendar header",
|
||||||
}
|
}
|
||||||
return self.render_to_response(context, slots)
|
return self.render_to_response(context=context, slots=slots)
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, to use this component as a view, you should create a `urls.py` file in your components directory, and add a path to the component's view:
|
Then, to use this component as a view, you should create a `urls.py` file in your components directory, and add a path to the component's view:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue