diff --git a/docs/concepts/advanced/authoring_component_libraries.md b/docs/concepts/advanced/authoring_component_libraries.md index 242bbbb5..9d7f8b03 100644 --- a/docs/concepts/advanced/authoring_component_libraries.md +++ b/docs/concepts/advanced/authoring_component_libraries.md @@ -105,7 +105,7 @@ For live examples, see the [Community examples](../../overview/community.md#comm It's also a good idea to have a common prefix for your components, so they can be easily distinguished from users' components. In the example below, we use the prefix `my_` / `My`. - ```py + ```djc_py from typing import Dict, NotRequired, Optional, Tuple, TypedDict from django_components import Component, SlotFunc, register, types diff --git a/docs/concepts/advanced/html_tragments.md b/docs/concepts/advanced/html_tragments.md index 1b93c167..42f6d04c 100644 --- a/docs/concepts/advanced/html_tragments.md +++ b/docs/concepts/advanced/html_tragments.md @@ -106,7 +106,7 @@ Then navigate to these URLs: ### 1. Define document HTML -```py title="[root]/components/demo.py" +```djc_py title="[root]/components/demo.py" from django_components import Component, types # HTML into which a fragment will be loaded using HTMX @@ -141,7 +141,7 @@ class MyPage(Component): ### 2. Define fragment HTML -```py title="[root]/components/demo.py" +```djc_py title="[root]/components/demo.py" class Frag(Component): def get(self, request): return self.render_to_response( @@ -184,7 +184,7 @@ urlpatterns = [ ### 1. Define document HTML -```py title="[root]/components/demo.py" +```djc_py title="[root]/components/demo.py" from django_components import Component, types # HTML into which a fragment will be loaded using AlpineJS @@ -225,7 +225,7 @@ class MyPage(Component): ### 2. Define fragment HTML -```py title="[root]/components/demo.py" +```djc_py title="[root]/components/demo.py" class Frag(Component): def get(self, request): # IMPORTANT: Don't forget `type="fragment"` @@ -281,7 +281,7 @@ urlpatterns = [ ### 1. Define document HTML -```py title="[root]/components/demo.py" +```djc_py title="[root]/components/demo.py" from django_components import Component, types # HTML into which a fragment will be loaded using JS @@ -321,7 +321,7 @@ class MyPage(Component): ### 2. Define fragment HTML -```py title="[root]/components/demo.py" +```djc_py title="[root]/components/demo.py" class Frag(Component): def get(self, request): return self.render_to_response( diff --git a/docs/concepts/advanced/provide_inject.md b/docs/concepts/advanced/provide_inject.md index ac73688d..68954d0e 100644 --- a/docs/concepts/advanced/provide_inject.md +++ b/docs/concepts/advanced/provide_inject.md @@ -107,7 +107,7 @@ have all the keys that were passed to the `provide` tag. ## Full example -```py +```djc_py @register("child") class ChildComponent(Component): template = """ diff --git a/docs/concepts/advanced/rendering_js_css.md b/docs/concepts/advanced/rendering_js_css.md index 364232dc..3772d2d5 100644 --- a/docs/concepts/advanced/rendering_js_css.md +++ b/docs/concepts/advanced/rendering_js_css.md @@ -27,7 +27,7 @@ the locations by inserting following Django template tags: So if you have a component with JS and CSS: -```python +```djc_py from django_components import Component, types class MyButton(Component): diff --git a/docs/concepts/fundamentals/component_context_scope.md b/docs/concepts/fundamentals/component_context_scope.md index adc5f33d..fca79315 100644 --- a/docs/concepts/fundamentals/component_context_scope.md +++ b/docs/concepts/fundamentals/component_context_scope.md @@ -85,9 +85,9 @@ This has two modes: Consider this example: - ```python + ```djc_py class Outer(Component): - template = \"\"\" + template = """
{% component "inner" %} {% fill "content" %} @@ -95,7 +95,7 @@ This has two modes: {% endfill %} {% endcomponent %}
- \"\"\" + """ ``` - `"django"` - `my_var` has access to data from `get_context_data()` of both `Inner` and `Outer`. @@ -108,7 +108,7 @@ This has two modes: Given this template: -```python +```djc_py @register("root_comp") class RootComp(Component): template = """ @@ -148,7 +148,7 @@ all the data defined in the outer layers, like the `{% with %}` tag. Given this template: -```python +```djc_py class RootComp(Component): template = """ {% with cheese="feta" %} diff --git a/docs/concepts/fundamentals/components_as_views.md b/docs/concepts/fundamentals/components_as_views.md index c950b1db..21b181e2 100644 --- a/docs/concepts/fundamentals/components_as_views.md +++ b/docs/concepts/fundamentals/components_as_views.md @@ -19,7 +19,7 @@ Components can now be used as views: Here's an example of a calendar component defined as a view: -```python +```djc_py # In a file called [project root]/components/calendar.py from django_components import Component, ComponentView, register diff --git a/docs/concepts/fundamentals/components_in_python.md b/docs/concepts/fundamentals/components_in_python.md index 5afd54d5..475add38 100644 --- a/docs/concepts/fundamentals/components_in_python.md +++ b/docs/concepts/fundamentals/components_in_python.md @@ -9,7 +9,7 @@ Components can be rendered outside of Django templates, calling them as regular 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 +```djc_py class SimpleComponent(Component): template = """ {% load component_tags %} diff --git a/docs/concepts/fundamentals/defining_js_css_html_files.md b/docs/concepts/fundamentals/defining_js_css_html_files.md index c55145b6..a34d9242 100644 --- a/docs/concepts/fundamentals/defining_js_css_html_files.md +++ b/docs/concepts/fundamentals/defining_js_css_html_files.md @@ -28,7 +28,7 @@ HTML / JS / CSS with a component: However, you can freely mix these for different languages: - ```py + ```djc_py class MyTable(Component): template: types.django_html = """
diff --git a/docs/concepts/fundamentals/html_attributes.md b/docs/concepts/fundamentals/html_attributes.md index 64e04b23..eeeea8ac 100644 --- a/docs/concepts/fundamentals/html_attributes.md +++ b/docs/concepts/fundamentals/html_attributes.md @@ -256,7 +256,7 @@ Then: ## Full example for `html_attrs` -```py +```djc_py @register("my_comp") class MyComp(Component): template: t.django_html = """ diff --git a/docs/concepts/fundamentals/http_request.md b/docs/concepts/fundamentals/http_request.md index 91f95a53..57947de0 100644 --- a/docs/concepts/fundamentals/http_request.md +++ b/docs/concepts/fundamentals/http_request.md @@ -78,7 +78,7 @@ rendered = template.render(RequestContext(request, {})) The data from context processors is automatically available within the component's template. -```python +```djc_py class MyComponent(Component): template = """
diff --git a/docs/concepts/fundamentals/single_file_components.md b/docs/concepts/fundamentals/single_file_components.md index 73f9e870..708d2925 100644 --- a/docs/concepts/fundamentals/single_file_components.md +++ b/docs/concepts/fundamentals/single_file_components.md @@ -9,7 +9,7 @@ For example, here's the calendar component from the [Getting started](../../getting_started/your_first_component.md) tutorial, defined in a single file: -```python title="[project root]/components/calendar.py" +```djc_py title="[project root]/components/calendar.py" from django_components import Component, register, types @register("calendar") diff --git a/docs/concepts/fundamentals/slots.md b/docs/concepts/fundamentals/slots.md index f1ba610a..f9ea4f68 100644 --- a/docs/concepts/fundamentals/slots.md +++ b/docs/concepts/fundamentals/slots.md @@ -469,7 +469,7 @@ _Added in version 0.76_: Consider a component with slot(s). This component may do some processing on the inputs, and then use the processed variable in the slot's default template: -```py +```djc_py @register("my_comp") class MyComp(Component): template = """ @@ -498,7 +498,7 @@ Using scoped slots consists of two steps: To pass the data to the `slot` tag, simply pass them as keyword attributes (`key=value`): -```py +```djc_py @register("my_comp") class MyComp(Component): template = """ @@ -649,14 +649,14 @@ So it's possible to define a `name` key on a dictionary, and then spread that on You can dynamically pass all slots to a child component. This is similar to [passing all slots in Vue](https://vue-land.github.io/faq/forwarding-slots#passing-all-slots): -```py +```djc_py class MyTable(Component): def get_context_data(self, *args, **kwargs): return { "slots": self.input.slots, } - template: """ + template = """
{% component "child" %} {% for slot_name in slots %} diff --git a/docs/concepts/fundamentals/subclassing_components.md b/docs/concepts/fundamentals/subclassing_components.md index dc376273..e946b74c 100644 --- a/docs/concepts/fundamentals/subclassing_components.md +++ b/docs/concepts/fundamentals/subclassing_components.md @@ -25,7 +25,7 @@ inheritance follows these rules: For example: -```python +```djc_py class BaseCard(Component): template = """
@@ -37,7 +37,7 @@ class BaseCard(Component): border: 1px solid gray; } """ - js = "console.log('Base card loaded');" + js = """console.log('Base card loaded');""" # This class overrides parent's template, but inherits CSS and JS class SpecialCard(BaseCard): @@ -94,7 +94,7 @@ All other attributes and methods (including the [`Component.View`](../../referen For example: -```python +```djc_py class BaseForm(Component): template = """
diff --git a/docs/concepts/fundamentals/template_tag_syntax.md b/docs/concepts/fundamentals/template_tag_syntax.md index 6d4b1949..713895e5 100644 --- a/docs/concepts/fundamentals/template_tag_syntax.md +++ b/docs/concepts/fundamentals/template_tag_syntax.md @@ -202,7 +202,7 @@ of HTML attributes (usually called `attrs`) to pass to the underlying template. In such cases, we may want to define some HTML attributes statically, and other dynamically. But for that, we need to define this dictionary on Python side: -```py +```djc_py @register("my_comp") class MyComp(Component): template = """ @@ -229,7 +229,7 @@ as component kwargs, so we can keep all the relevant information in the template we prefix the key with the name of the dict and `:`. So key `class` of input `attrs` becomes `attrs:class`. And our example becomes: -```py +```djc_py @register("my_comp") class MyComp(Component): template = """ diff --git a/docs/getting_started/your_first_component.md b/docs/getting_started/your_first_component.md index c8ab581a..a68a68c5 100644 --- a/docs/getting_started/your_first_component.md +++ b/docs/getting_started/your_first_component.md @@ -50,7 +50,7 @@ class Calendar(Component): Alternatively, you can "inline" HTML, JS, and CSS right into the component class: -```py +```djc_py from django_components import Component class Calendar(Component): diff --git a/docs/guides/devguides/dependency_mgmt.md b/docs/guides/devguides/dependency_mgmt.md index 8ffbb014..a165680b 100644 --- a/docs/guides/devguides/dependency_mgmt.md +++ b/docs/guides/devguides/dependency_mgmt.md @@ -7,7 +7,7 @@ associated with components, and how we render them. 1. First of all, when we consider a component, it has two kind of dependencies - the "inlined" JS and CSS, and additional linked JS and CSS via `Media.js/css`: - ```py + ```djc_py from django_components import Component, types class MyTable(Component): diff --git a/docs/guides/devguides/slots_and_blocks.md b/docs/guides/devguides/slots_and_blocks.md index 37f538d9..b2d46678 100644 --- a/docs/guides/devguides/slots_and_blocks.md +++ b/docs/guides/devguides/slots_and_blocks.md @@ -15,7 +15,7 @@ ``` And components that make use of `abc.html` via `include` or `extends`: - ```py + ```djc_py from django_components import Component, register @register("my_comp_extends") @@ -66,7 +66,7 @@ ```py @register("my_comp") class MyComp(Component): - template_file = "abc.html" + template_file = "abc.html" ``` Then: @@ -110,37 +110,34 @@ uses `extends`. In that case, just as you would expect, the `block inner` inside `abc.html` will render `OVERRIDEN`: - ````py + ```djc_py @register("my_comp") class MyComp(Component): - template_file = """ - {% extends "abc.html" %} - - {% block inner %} - OVERRIDEN - {% endblock %} - """ - ``` - - ```` + template = """ + {% extends "abc.html" %} + {% block inner %} + OVERRIDEN + {% endblock %} + """ + ``` 4. This is where it gets interesting (but still intuitive). You can insert even new `slots` inside these "overriding" blocks: - ```py + ```djc_py @register("my_comp") class MyComp(Component): - template_file = """ - {% extends "abc.html" %} + template = """ + {% extends "abc.html" %} - {% load component_tags %} - {% block "inner" %} - OVERRIDEN - {% slot "new_slot" %} - hello - {% endslot %} - {% endblock %} - """ + {% load component_tags %} + {% block "inner" %} + OVERRIDEN + {% slot "new_slot" %} + hello + {% endslot %} + {% endblock %} + """ ``` And you can then pass fill for this `new_slot` when rendering the component: diff --git a/docs/guides/setup/syntax_highlight.md b/docs/guides/setup/syntax_highlight.md index 0cc68ca3..47f9daf9 100644 --- a/docs/guides/setup/syntax_highlight.md +++ b/docs/guides/setup/syntax_highlight.md @@ -9,7 +9,7 @@ weight: 1 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. -```python title="[project root]/components/calendar.py" +```djc_py title="[project root]/components/calendar.py" # In a file called [project root]/components/calendar.py from django_components import Component, register, types @@ -21,12 +21,19 @@ class Calendar(Component): } template: types.django_html = """ -
Today's date is {{ date }}
+
+ Today's date is {{ date }} +
""" css: types.css = """ - .calendar-component { width: 200px; background: pink; } - .calendar-component span { font-weight: bold; } + .calendar-component { + width: 200px; + background: pink; + } + .calendar-component span { + font-weight: bold; + } """ js: types.js = """ @@ -43,7 +50,7 @@ class Calendar(Component): 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=` above the variables. -```python +```djc_py from django_components import Component, register @register("calendar") @@ -55,13 +62,20 @@ class Calendar(Component): # language=HTML template= """ -
Today's date is {{ date }}
+
+ Today's date is {{ date }} +
""" # language=CSS css = """ - .calendar-component { width: 200px; background: pink; } - .calendar-component span { font-weight: bold; } + .calendar-component { + width: 200px; + background: pink; + } + .calendar-component span { + font-weight: bold; + } """ # language=JS @@ -73,3 +87,45 @@ class Calendar(Component): })() """ ``` + +## 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= """ +
+ Today's date is {{ date }} +
+ """ + + css = """ + .calendar-component { + width: 200px; + background: pink; + } + .calendar-component span { + font-weight: bold; + } + """ +\``` +``` diff --git a/docs/overview/welcome.md b/docs/overview/welcome.md index 8e1b17a9..7f76ce01 100644 --- a/docs/overview/welcome.md +++ b/docs/overview/welcome.md @@ -88,7 +88,7 @@ Read on to learn about all the exciting details and configuration possibilities! - Each component can include its own HTML, CSS, and JS, or additional third-party JS and CSS. - HTML, CSS, and JS can be defined on the component class, or loaded from files. -```python +```djc_py from django_components import Component @register("calendar") diff --git a/docs/reference/signals.md b/docs/reference/signals.md index ed2bb28d..eab706c6 100644 --- a/docs/reference/signals.md +++ b/docs/reference/signals.md @@ -14,7 +14,7 @@ the signal is triggered for each component. Import from django as `django.test.signals.template_rendered`. -```python +```djc_py from django.test.signals import template_rendered # Setup a callback function diff --git a/docs/scripts/setup.py b/docs/scripts/setup.py new file mode 100644 index 00000000..d419fdee --- /dev/null +++ b/docs/scripts/setup.py @@ -0,0 +1,3 @@ +# Allow us to use `djc_py` / `djc_python` code blocks. +# Importing this package automatically registers the `djc_py` lexer onto Pygments. +import pygments_djc # noqa: F401 diff --git a/docs/templates/reference_signals.md b/docs/templates/reference_signals.md index 941efe51..56cae6e9 100644 --- a/docs/templates/reference_signals.md +++ b/docs/templates/reference_signals.md @@ -12,7 +12,7 @@ the signal is triggered for each component. Import from django as `django.test.signals.template_rendered`. -```python +```djc_py from django.test.signals import template_rendered # Setup a callback function diff --git a/mkdocs.yml b/mkdocs.yml index a6314ad6..5d90d37a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -123,6 +123,7 @@ plugins: closing_tag: "!}" - gen-files: scripts: + - docs/scripts/setup.py - docs/scripts/reference.py - literate-nav: nav_file: SUMMARY.md diff --git a/requirements-dev.in b/requirements-dev.in index 7d4edafb..a982f1e2 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -11,4 +11,5 @@ mypy playwright requests types-requests -whitenoise \ No newline at end of file +whitenoise +pygments-djc \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index d1472f3a..f06decbd 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ asgiref==3.8.1 # via django black==24.10.0 # via -r requirements-dev.in -cachetools==5.5.0 +cachetools==5.5.1 # via tox certifi==2024.8.30 # via requests @@ -16,15 +16,15 @@ cfgv==3.4.0 # via pre-commit chardet==5.2.0 # via tox -charset-normalizer==3.4.0 +charset-normalizer==3.4.1 # via requests -click==8.1.7 +click==8.1.8 # via black colorama==0.4.6 # via tox distlib==0.3.9 # via virtualenv -django==5.1.5 +django==5.1.6 # via -r requirements-dev.in djc-core-html-parser==1.0.1 # via -r requirements-dev.in @@ -32,7 +32,7 @@ filelock==3.16.1 # via # tox # virtualenv -flake8==7.1.1 +flake8==7.1.2 # via # -r requirements-dev.in # flake8-pyproject @@ -40,7 +40,7 @@ flake8-pyproject==1.2.3 # via -r requirements-dev.in greenlet==3.1.1 # via playwright -identify==2.6.3 +identify==2.6.7 # via pre-commit idna==3.10 # via requests @@ -85,6 +85,10 @@ pyee==12.0.0 # via playwright pyflakes==3.2.0 # via flake8 +pygments==2.19.1 + # via pygments-djc +pygments-djc==1.0.1 + # via -r requirements-dev.in pyproject-api==1.8.0 # via tox pytest==8.3.4 @@ -93,7 +97,7 @@ pyyaml==6.0.2 # via pre-commit requests==2.32.3 # via -r requirements-dev.in -sqlparse==0.5.2 +sqlparse==0.5.3 # via django tox==4.24.1 # via -r requirements-dev.in diff --git a/requirements-docs.txt b/requirements-docs.txt index b493e6f3..e54c8d79 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -59,7 +59,7 @@ cssselect2==0.7.0 # via cairosvg defusedxml==0.7.1 # via cairosvg -django==5.1.5 +django==5.1.6 # via hatch.envs.docs ghp-import==2.1.0 # via mkdocs @@ -178,7 +178,11 @@ platformdirs==4.3.6 pycparser==2.22 # via cffi pygments==2.19.1 - # via mkdocs-material + # via + # mkdocs-material + # pygments-djc +pygments-djc==1.0.1 + # via -r requirements-dev.in pymdown-extensions==10.14.3 # via # hatch.envs.docs