mirror of
https://github.com/django-components/django-components.git
synced 2025-08-31 03:07:19 +00:00
docs: update testing, single file comp, and syntax highlight (#1109)
This commit is contained in:
parent
b6994e9ad3
commit
9ede779fa3
5 changed files with 232 additions and 146 deletions
|
@ -4,7 +4,10 @@ The [`@djc_test`](../../../reference/testing_api#djc_test) decorator is a powerf
|
|||
|
||||
## Usage
|
||||
|
||||
The [`@djc_test`](../../../reference/testing_api#djc_test) decorator can be applied to functions, methods, or classes. When applied to a class, it recursively decorates all methods starting with `test_`, including those in nested classes. This allows for comprehensive testing of component behavior.
|
||||
The [`@djc_test`](../../../reference/testing_api#djc_test) decorator can be applied to functions, methods, or classes.
|
||||
|
||||
When applied to a class, it decorates all methods starting with `test_`, and all nested classes starting with `Test`,
|
||||
recursively.
|
||||
|
||||
### Applying to a Function
|
||||
|
||||
|
@ -15,8 +18,6 @@ simply decorate the function as shown below:
|
|||
import django
|
||||
from django_components.testing import djc_test
|
||||
|
||||
django.setup()
|
||||
|
||||
@djc_test
|
||||
def test_my_component():
|
||||
@register("my_component")
|
||||
|
@ -27,38 +28,34 @@ def test_my_component():
|
|||
|
||||
### Applying to a Class
|
||||
|
||||
When applied to a class, `djc_test` decorates each `test_` method individually:
|
||||
When applied to a class, `djc_test` decorates each `test_` method, as well as all nested classes starting with `Test`.
|
||||
|
||||
```python
|
||||
import django
|
||||
from django_components.testing import djc_test
|
||||
|
||||
django.setup()
|
||||
|
||||
@djc_test
|
||||
class TestMyComponent:
|
||||
def test_something(self):
|
||||
...
|
||||
|
||||
class Nested:
|
||||
class TestNested:
|
||||
def test_something_else(self):
|
||||
...
|
||||
```
|
||||
|
||||
This is equivalent to applying the decorator to each method individually:
|
||||
This is equivalent to applying the decorator to both of the methods individually:
|
||||
|
||||
```python
|
||||
import django
|
||||
from django_components.testing import djc_test
|
||||
|
||||
django.setup()
|
||||
|
||||
class TestMyComponent:
|
||||
@djc_test
|
||||
def test_something(self):
|
||||
...
|
||||
|
||||
class Nested:
|
||||
class TestNested:
|
||||
@djc_test
|
||||
def test_something_else(self):
|
||||
...
|
||||
|
@ -70,19 +67,26 @@ See the API reference for [`@djc_test`](../../../reference/testing_api#djc_test)
|
|||
|
||||
### Setting Up Django
|
||||
|
||||
Before using [`djc_test`](../../../reference/testing_api#djc_test), ensure Django is set up:
|
||||
If you want to define a common Django settings that would be the baseline for all tests,
|
||||
you can call [`django.setup()`](https://docs.djangoproject.com/en/5.2/ref/applications/#django.setup)
|
||||
before the `@djc_test` decorator:
|
||||
|
||||
```python
|
||||
import django
|
||||
from django_components.testing import djc_test
|
||||
|
||||
django.setup()
|
||||
django.setup(...)
|
||||
|
||||
@djc_test
|
||||
def test_my_component():
|
||||
...
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
||||
If you omit [`django.setup()`](https://docs.djangoproject.com/en/5.2/ref/applications/#django.setup)
|
||||
in the example above, `@djc_test` will call it for you, so you don't need to do it manually.
|
||||
|
||||
## Example: Parametrizing Context Behavior
|
||||
|
||||
You can parametrize the [context behavior](../../../reference/settings#django_components.app_settings.ComponentsSettings.context_behavior) using [`djc_test`](../../../reference/testing_api#djc_test):
|
||||
|
|
|
@ -1,8 +1,29 @@
|
|||
Components can be defined in a single file, which is useful for small components. To do this, you can use the `template`, `js`, and `css` class attributes instead of the `template_file`, `js_file`, and `css_file`.
|
||||
Components can be defined in a single file, inlining the HTML, JS and CSS within the Python code.
|
||||
|
||||
## Writing single file components
|
||||
|
||||
To do this, you can use the
|
||||
[`template`](../../../reference/api#django_components.Component.template),
|
||||
[`js`](../../../reference/api#django_components.Component.js),
|
||||
and [`css`](../../../reference/api#django_components.Component.css)
|
||||
class attributes instead of the
|
||||
[`template_file`](../../../reference/api#django_components.Component.template_file),
|
||||
[`js_file`](../../../reference/api#django_components.Component.js_file),
|
||||
and [`css_file`](../../../reference/api#django_components.Component.css_file).
|
||||
|
||||
For example, here's the calendar component from
|
||||
the [Getting started](../../getting_started/your_first_component.md) tutorial,
|
||||
defined in a single file:
|
||||
the [Getting started](../../getting_started/your_first_component.md) tutorial:
|
||||
|
||||
```py title="calendar.py"
|
||||
from django_components import Component
|
||||
|
||||
class Calendar(Component):
|
||||
template_file = "calendar.html"
|
||||
js_file = "calendar.js"
|
||||
css_file = "calendar.css"
|
||||
```
|
||||
|
||||
And here is the same component, rewritten in a single file:
|
||||
|
||||
```djc_py title="[project root]/components/calendar.py"
|
||||
from django_components import Component, register, types
|
||||
|
@ -41,6 +62,194 @@ class Calendar(Component):
|
|||
"""
|
||||
```
|
||||
|
||||
This makes it easy to create small components without having to create a separate template, CSS, and JS file.
|
||||
You can mix and match, so you can have a component with inlined HTML,
|
||||
while the JS and CSS are in separate files:
|
||||
|
||||
To add syntax highlighting to these snippets, head over to [Syntax highlighting](../../guides/setup/syntax_highlight.md).
|
||||
```djc_py title="[project root]/components/calendar.py"
|
||||
from django_components import Component, register, types
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
js_file = "calendar.js"
|
||||
css_file = "calendar.css"
|
||||
|
||||
template: types.django_html = """
|
||||
<div class="calendar">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
```
|
||||
|
||||
## Syntax highlighting
|
||||
|
||||
If you "inline" the HTML, JS and CSS code into the Python class, you should set up
|
||||
syntax highlighting to let your code editor know that the inlined code is HTML, JS and CSS.
|
||||
|
||||
In the examples above, we've annotated the
|
||||
[`template`](../../../reference/api#django_components.Component.template),
|
||||
[`js`](../../../reference/api#django_components.Component.js),
|
||||
and [`css`](../../../reference/api#django_components.Component.css)
|
||||
attributes with
|
||||
the `types.django_html`, `types.js` and `types.css` types. These are used for syntax highlighting in VSCode.
|
||||
|
||||
!!! warning
|
||||
|
||||
Autocompletion / intellisense does not work in the inlined code.
|
||||
|
||||
Help us add support for intellisense in the inlined code! Start a conversation in the
|
||||
[GitHub Discussions](https://github.com/django-components/django-components/discussions).
|
||||
|
||||
### VSCode
|
||||
|
||||
1. First install [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.
|
||||
|
||||
2. Next, in your component, set typings of
|
||||
[`Component.template`](../../../reference/api#django_components.Component.template),
|
||||
[`Component.js`](../../../reference/api#django_components.Component.js),
|
||||
[`Component.css`](../../../reference/api#django_components.Component.css)
|
||||
to `types.django_html`, `types.css`, and `types.js` respectively. The extension will recognize these and will activate syntax highlighting.
|
||||
|
||||
```djc_py title="[project root]/components/calendar.py"
|
||||
from django_components import Component, register, types
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
return {
|
||||
"date": date,
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
css: types.css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
|
||||
js: types.js = """
|
||||
(function(){
|
||||
if (document.querySelector(".calendar-component")) {
|
||||
document.querySelector(".calendar-component").onclick = function(){ alert("Clicked calendar!"); };
|
||||
}
|
||||
})()
|
||||
"""
|
||||
```
|
||||
|
||||
### Pycharm (or other Jetbrains IDEs)
|
||||
|
||||
With PyCharm (or any other editor from Jetbrains), you don't need to use `types.django_html`, `types.css`, `types.js` since Pycharm uses [language injections](https://www.jetbrains.com/help/pycharm/using-language-injections.html).
|
||||
|
||||
You only need to write the comments `# language=<lang>` above the variables.
|
||||
|
||||
```djc_py
|
||||
from django_components import Component, register
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
return {
|
||||
"date": date,
|
||||
}
|
||||
|
||||
# language=HTML
|
||||
template= """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
# language=CSS
|
||||
css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
|
||||
# language=JS
|
||||
js = """
|
||||
(function(){
|
||||
if (document.querySelector(".calendar-component")) {
|
||||
document.querySelector(".calendar-component").onclick = function(){ alert("Clicked calendar!"); };
|
||||
}
|
||||
})()
|
||||
"""
|
||||
```
|
||||
|
||||
### Markdown code blocks with Pygments
|
||||
|
||||
[Pygments](https://pygments.org/) is a syntax highlighting library written in Python. It's also what's used by this documentation site ([mkdocs-material](https://squidfunk.github.io/mkdocs-material/)) to highlight code blocks.
|
||||
|
||||
To write code blocks with syntax highlighting, you need to install the [`pygments-djc`](https://pypi.org/project/pygments-djc/) package.
|
||||
|
||||
```bash
|
||||
pip install pygments-djc
|
||||
```
|
||||
|
||||
And then initialize it by importing `pygments_djc` somewhere in your project:
|
||||
|
||||
```python
|
||||
import pygments_djc
|
||||
```
|
||||
|
||||
Now you can use the `djc_py` code block to write code blocks with syntax highlighting for components.
|
||||
|
||||
```txt
|
||||
\```djc_py
|
||||
from django_components import Component, register
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
template = """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
\```
|
||||
```
|
||||
|
||||
Will be rendered as below. Notice that the CSS and HTML are highlighted correctly:
|
||||
|
||||
```djc_py
|
||||
from django_components import Component, register
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
template= """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
```
|
||||
|
|
|
@ -72,7 +72,7 @@ class Calendar(Component):
|
|||
!!! note
|
||||
|
||||
If you "inline" the HTML, JS and CSS code into the Python class, you can set up
|
||||
[syntax highlighting](../../guides/setup/syntax_highlight) for better experience.
|
||||
[syntax highlighting](../../concepts/fundamentals/single_file_components#syntax-highlighting) for better experience.
|
||||
However, autocompletion / intellisense does not work with syntax highlighting.
|
||||
|
||||
We'll start by creating a component that defines only a Django template:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav
|
||||
nav:
|
||||
- Syntax highlighting: syntax_highlight.md
|
||||
- Caching: caching.md
|
||||
- Development server: development_server.md
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
## VSCode
|
||||
|
||||
1. First install [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.
|
||||
|
||||
2. Next, in your component, set typings of `Component.template/css/js` to `types.django_html`, `types.css`, and `types.js` respectively. The extension will recognize these and will activate syntax highlighting.
|
||||
|
||||
```djc_py title="[project root]/components/calendar.py"
|
||||
# In a file called [project root]/components/calendar.py
|
||||
from django_components import Component, register, types
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
return {
|
||||
"date": date,
|
||||
}
|
||||
|
||||
template: types.django_html = """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
css: types.css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
|
||||
js: types.js = """
|
||||
(function(){
|
||||
if (document.querySelector(".calendar-component")) {
|
||||
document.querySelector(".calendar-component").onclick = function(){ alert("Clicked calendar!"); };
|
||||
}
|
||||
})()
|
||||
"""
|
||||
```
|
||||
|
||||
## Pycharm (or other Jetbrains IDEs)
|
||||
|
||||
With PyCharm (or any other editor from Jetbrains), you don't need to use `types.django_html`, `types.css`, `types.js` since Pycharm uses [language injections](https://www.jetbrains.com/help/pycharm/using-language-injections.html).
|
||||
You only need to write the comments `# language=<lang>` above the variables.
|
||||
|
||||
```djc_py
|
||||
from django_components import Component, register
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
def get_context_data(self, date):
|
||||
return {
|
||||
"date": date,
|
||||
}
|
||||
|
||||
# language=HTML
|
||||
template= """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
# language=CSS
|
||||
css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
|
||||
# language=JS
|
||||
js = """
|
||||
(function(){
|
||||
if (document.querySelector(".calendar-component")) {
|
||||
document.querySelector(".calendar-component").onclick = function(){ alert("Clicked calendar!"); };
|
||||
}
|
||||
})()
|
||||
"""
|
||||
```
|
||||
|
||||
## Pygments
|
||||
|
||||
[Pygments](https://pygments.org/) is a syntax highlighting library written in Python. It's also what's used by this documentation site ([mkdocs-material](https://squidfunk.github.io/mkdocs-material/)) to highlight code blocks.
|
||||
|
||||
To write code blocks with syntax highlighting, you need to install the [`pygments-djc`](https://pypi.org/project/pygments-djc/) package.
|
||||
|
||||
```bash
|
||||
pip install pygments-djc
|
||||
```
|
||||
|
||||
And then initialize it by importing `pygments_djc`:
|
||||
|
||||
```python
|
||||
import pygments_djc
|
||||
```
|
||||
|
||||
Now you can write code blocks with syntax highlighting.
|
||||
|
||||
```txt
|
||||
\```djc_py
|
||||
from django_components import Component, register
|
||||
|
||||
@register("calendar")
|
||||
class Calendar(Component):
|
||||
template= """
|
||||
<div class="calendar-component">
|
||||
Today's date is <span>{{ date }}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
css = """
|
||||
.calendar-component {
|
||||
width: 200px;
|
||||
background: pink;
|
||||
}
|
||||
.calendar-component span {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
\```
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue