Skip to content

Commit 9fd30aa

Browse files
authored
v3.0.0a1: Bump IDOM to 1.0.0 pre-release (#125)
- Modify docs to use the upcoming IDOM-Core docs styling - Move docs python examples to individual files so we can run tests on them - CI for type checking + linting docs examples - Minor wording and section naming changes to feel more React-like - Bump IDOM to 1.0.0 pre-release - Use the new `idom.html` API - Update package.json to be compatible with `idom>=1.0.0` - Make the main `requirements.txt` be fully inclusive of all dev/user/docs dependencies to simplify development workflow - Update `setup.py` to automatically install the latest NPM, and be easier to debug when things fail
1 parent da083ac commit 9fd30aa

File tree

86 files changed

+1896
-1067
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1896
-1067
lines changed

.github/workflows/test-docs.yml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ jobs:
2020
- uses: actions/setup-python@v4
2121
with:
2222
python-version: 3.x
23-
- run: pip install -r requirements/build-docs.txt
24-
- run: linkcheckMarkdown docs/ -v -r
25-
- run: mkdocs build --strict
23+
- name: Check docs build
24+
run: |
25+
pip install -r requirements/build-docs.txt
26+
linkcheckMarkdown docs/ -v -r
27+
mkdocs build --strict
28+
- name: Check docs examples
29+
run: |
30+
pip install -r requirements/check-types.txt
31+
pip install -r requirements/check-style.txt
32+
mypy --show-error-codes docs/python/
33+
black docs/python/ --check
34+
isort docs/python/ --check-only
35+
flake8 docs/python/

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ settings.json
3838
*$py.class
3939

4040
# Distribution / packaging
41+
build/
4142
.Python build/
4243
develop-eggs/
4344
dist/

CHANGELOG.md

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,58 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1010

1111
<!--
1212
Using the following categories, list your changes in this order:
13-
- "Added" for new features.
14-
- "Changed" for changes in existing functionality.
15-
- "Deprecated" for soon-to-be removed features.
16-
- "Removed" for now removed features.
17-
- "Fixed" for any bug fixes.
18-
- "Security" in case of vulnerabilities.
13+
14+
### Added
15+
- for new features.
16+
17+
### Changed
18+
- for changes in existing functionality.
19+
20+
### Deprecated
21+
- for soon-to-be removed features.
22+
23+
### Removed
24+
- for removed features.
25+
26+
### Fixed
27+
- for bug fixes.
28+
29+
### Security
30+
- for vulnerability fixes.
1931
-->
2032

2133
<!--changelog-start-->
2234

2335
## [Unreleased]
2436

37+
- Nothing (yet)
38+
39+
## [3.0.0a1] - 2023-02-02
40+
41+
???+ note
42+
43+
This is Django-IDOM's biggest update yet!
44+
45+
To upgrade from previous version you will need to...
46+
47+
1. Install `django-idom >= 3.0.0`
48+
2. Run `idom update-html-usages <DIR>` to update your `idom.html.*` calls to the new syntax
49+
3. Run `python manage.py migrate` to create the new Django-IDOM database entries
50+
2551
### Added
2652

2753
- The `idom` client will automatically configure itself to debug mode depending on `settings.py:DEBUG`.
2854
- `use_connection` hook for returning the browser's active `Connection`
2955

3056
### Changed
3157

58+
- It is now mandatory to run `manage.py migrate` after installing IDOM.
59+
- Bumped the minimum IDOM version to 1.0.0
60+
- Due to IDOM 1.0.0, `idom.html.*`, HTML properties are now `snake_case` `**kwargs` rather than a `dict` of values.
61+
- You can auto-convert to the new style using `idom update-html-usages <DIR>`.
3262
- The `component` template tag now supports both positional and keyword arguments.
3363
- The `component` template tag now supports non-serializable arguments.
3464
- `IDOM_WS_MAX_RECONNECT_TIMEOUT` setting has been renamed to `IDOM_RECONNECT_MAX`.
35-
- It is now mandatory to run `manage.py migrate` after installing IDOM.
36-
- Bumped the minimum IDOM version to 0.43.0
3765

3866
### Removed
3967

@@ -51,7 +79,7 @@ Using the following categories, list your changes in this order:
5179
- Fixed a potential method of component template tag argument spoofing.
5280
- Exception information will no longer be displayed on the page, based on the value of `settings.py:DEBUG`.
5381

54-
## [2.2.1] - 2022-01-09
82+
## [2.2.1] - 2023-01-09
5583

5684
### Fixed
5785

@@ -218,7 +246,8 @@ Using the following categories, list your changes in this order:
218246

219247
- Support for IDOM within the Django
220248

221-
[unreleased]: https://github.com/idom-team/django-idom/compare/2.2.1...HEAD
249+
[unreleased]: https://github.com/idom-team/django-idom/compare/3.0.0a1...HEAD
250+
[3.0.0a1]: https://github.com/idom-team/django-idom/compare/2.2.1...3.0.0a1
222251
[2.2.1]: https://github.com/idom-team/django-idom/compare/2.2.0...2.2.1
223252
[2.2.0]: https://github.com/idom-team/django-idom/compare/2.1.0...2.2.0
224253
[2.1.0]: https://github.com/idom-team/django-idom/compare/2.0.1...2.1.0

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--header-start-->
22

3-
# Django IDOM &middot; [![Tests](https://github.com/idom-team/django-idom/workflows/Test/badge.svg?event=push)](https://github.com/idom-team/django-idom/actions?query=workflow%3ATest) [![PyPI Version](https://img.shields.io/pypi/v/django-idom.svg?label=PyPI)](https://pypi.python.org/pypi/django-idom) [![License](https://img.shields.io/badge/License-MIT-purple.svg)](https://github.com/idom-team/django-idom/blob/main/LICENSE) [![Docs](https://img.shields.io/website?down_message=offline&label=Docs&logo=read%20the%20docs&logoColor=white&up_message=online&url=https%3A%2F%2Fidom-team.github.io%2Fdjango-idom%2F)](https://idom-team.github.io/django-idom/)
3+
# Django-IDOM &middot; [![Tests](https://github.com/idom-team/django-idom/workflows/Test/badge.svg?event=push)](https://github.com/idom-team/django-idom/actions?query=workflow%3ATest) [![PyPI Version](https://img.shields.io/pypi/v/django-idom.svg?label=PyPI)](https://pypi.python.org/pypi/django-idom) [![License](https://img.shields.io/badge/License-MIT-purple.svg)](https://github.com/idom-team/django-idom/blob/main/LICENSE) [![Docs](https://img.shields.io/website?down_message=offline&label=Docs&logo=read%20the%20docs&logoColor=white&up_message=online&url=https%3A%2F%2Fidom-team.github.io%2Fdjango-idom%2F)](https://idom-team.github.io/django-idom/)
44

55
<!--header-end-->
66
<!--intro-start-->

docs/includes/examples.md

Lines changed: 0 additions & 10 deletions
This file was deleted.

docs/includes/pr.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Now, you can create/modify the Django-IDOM source code, and Pull Request (PR) your changes to our GitHub repository.
2+
3+
To learn how to create GitHub PRs, [click here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).

docs/overrides/main.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
{{ super() }}
5+
6+
{% if git_page_authors %}
7+
<div class="md-source-date">
8+
<small>
9+
Authors: {{ git_page_authors | default('enable mkdocs-git-authors-plugin') }}
10+
</small>
11+
</div>
12+
{% endif %}
13+
{% endblock %}

docs/python/__init__.py

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from idom import component, html
2+
3+
from django_idom.decorators import auth_required
4+
5+
6+
@component
7+
@auth_required(auth_attribute="is_staff")
8+
def my_component():
9+
return html.div("I am logged in!")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from idom import component, html
2+
3+
from django_idom.decorators import auth_required
4+
5+
6+
@component
7+
def my_component_fallback():
8+
return html.div("I am NOT logged in!")
9+
10+
11+
@component
12+
@auth_required(fallback=my_component_fallback)
13+
def my_component():
14+
return html.div("I am logged in!")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.contrib.auth.models import AbstractBaseUser
2+
3+
4+
class CustomUserModel(AbstractBaseUser):
5+
@property
6+
def is_really_cool(self):
7+
return True
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from idom import component, html
2+
3+
from django_idom.decorators import auth_required
4+
5+
6+
@component
7+
@auth_required(auth_attribute="is_really_cool")
8+
def my_component():
9+
return html.div("I am logged in!")
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from idom import component, html
2+
3+
from django_idom.decorators import auth_required
4+
5+
6+
@component
7+
@auth_required(fallback=html.div("I am NOT logged in!"))
8+
def my_component():
9+
return html.div("I am logged in!")

docs/python/auth-required.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from idom import component, html
2+
3+
from django_idom.decorators import auth_required
4+
5+
6+
@component
7+
@auth_required
8+
def my_component():
9+
return html.div("I am logged in!")

docs/python/configure-asgi.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
3+
from django.core.asgi import get_asgi_application
4+
5+
6+
# Ensure DJANGO_SETTINGS_MODULE is set properly based on your project name!
7+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")
8+
9+
# Fetch ASGI application before importing dependencies that require ORM models.
10+
django_asgi_app = get_asgi_application()
11+
12+
13+
from channels.auth import AuthMiddlewareStack # noqa: E402
14+
from channels.routing import ProtocolTypeRouter, URLRouter # noqa: E402
15+
from channels.sessions import SessionMiddlewareStack # noqa: E402
16+
17+
from django_idom import IDOM_WEBSOCKET_PATH # noqa: E402
18+
19+
20+
application = ProtocolTypeRouter(
21+
{
22+
"http": django_asgi_app,
23+
"websocket": SessionMiddlewareStack(
24+
AuthMiddlewareStack(URLRouter([IDOM_WEBSOCKET_PATH]))
25+
),
26+
}
27+
)

docs/python/configure-channels.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
INSTALLED_APPS = [
2+
"daphne",
3+
...,
4+
]
5+
ASGI_APPLICATION = "example_project.asgi.application"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
INSTALLED_APPS = [
2+
"django_idom",
3+
...,
4+
]

docs/python/configure-urls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.urls import include, path
2+
3+
4+
urlpatterns = [
5+
path("idom/", include("django_idom.http.urls")),
6+
...,
7+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from idom import component, html
2+
3+
4+
@component
5+
def my_component():
6+
return html.div(
7+
html.link(
8+
{"rel": "stylesheet", "href": "https://example.com/external-styles.css"}
9+
),
10+
html.button("My Button!"),
11+
)

docs/python/django-css-local-link.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.templatetags.static import static
2+
from idom import component, html
3+
4+
5+
@component
6+
def my_component():
7+
return html.div(
8+
html.link({"rel": "stylesheet", "href": static("css/buttons.css")}),
9+
html.button("My Button!"),
10+
)

docs/python/django-css.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from idom import component, html
2+
3+
from django_idom.components import django_css
4+
5+
6+
@component
7+
def my_component():
8+
return html.div(
9+
django_css("css/buttons.css"),
10+
html.button("My Button!"),
11+
)

docs/python/django-js-local-script.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.templatetags.static import static
2+
from idom import component, html
3+
4+
5+
@component
6+
def my_component():
7+
return html.div(
8+
html.script({"src": static("js/scripts.js")}),
9+
html.button("My Button!"),
10+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from idom import component, html
2+
3+
4+
@component
5+
def my_component():
6+
return html.div(
7+
html.script({"src": "https://example.com/external-scripts.js"}),
8+
html.button("My Button!"),
9+
)

docs/python/django-js.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from idom import component, html
2+
3+
from django_idom.components import django_js
4+
5+
6+
@component
7+
def my_component():
8+
return html.div(
9+
html.button("My Button!"),
10+
django_js("js/scripts.js"),
11+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from example.models import TodoItem
2+
from idom import component
3+
4+
from django_idom.hooks import use_query
5+
from django_idom.types import QueryOptions
6+
from django_idom.utils import django_query_postprocessor
7+
8+
9+
def get_items():
10+
return TodoItem.objects.all()
11+
12+
13+
@component
14+
def todo_list():
15+
# These `QueryOptions` are functionally equivalent to Django-IDOM's default values
16+
item_query = use_query(
17+
QueryOptions(
18+
postprocessor=django_query_postprocessor,
19+
postprocessor_kwargs={"many_to_many": True, "many_to_one": True},
20+
),
21+
get_items,
22+
)
23+
24+
return item_query.data

docs/python/example/__init__.py

Whitespace-only changes.

docs/python/example/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.db.models import CharField, Model
2+
3+
4+
class TodoItem(Model):
5+
text: CharField = CharField(max_length=255)

docs/python/example/urls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.urls import path
2+
from example import views
3+
4+
5+
urlpatterns = [
6+
path("example/", views.index),
7+
]

docs/python/example/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.shortcuts import render
2+
3+
4+
def index(request):
5+
return render(request, "my-template.html")

docs/python/settings.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# If "idom" cache is not configured, then "default" will be used
2+
# IDOM works best with a multiprocessing-safe and thread-safe cache backend.
3+
CACHES = {
4+
"idom": {"BACKEND": ...},
5+
}
6+
7+
# Maximum seconds between reconnection attempts before giving up.
8+
# Use `0` to prevent component reconnection.
9+
IDOM_RECONNECT_MAX = 259200
10+
11+
# The URL for IDOM to serve the component rendering websocket
12+
IDOM_WEBSOCKET_URL = "idom/"
13+
14+
# Dotted path to the default postprocessor function, or `None`
15+
IDOM_DEFAULT_QUERY_POSTPROCESSOR = "example_project.utils.my_postprocessor"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from idom import component
2+
3+
4+
@component
5+
def frog_greeter(number, name, species=""):
6+
return f"Hello #{number}, {name} the {species}!"

0 commit comments

Comments
 (0)