-
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Change Django IDOM version to 1.0.0 - Unpins top boundary on `channels` and `aiofile` - Bumps IDOM's minimum version - Use f-strings when possible - Use `contexlib.suppress` when possible - Implement `use_websocket`, `use_scope`, and `use_location` - Remove `websocket` parameter from components (replaced by `use_websocket` hook) - Create formal docs - Rename `idom_component` template tag to `component` in preparation for repo rename - Logging for when a component fails to import, or if no components were found within Django.
- Loading branch information
1 parent
83fcb8d
commit a0a6555
Showing
30 changed files
with
803 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
name: Publish Docs | ||
on: | ||
push: | ||
branches: | ||
- main | ||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
with: | ||
python-version: 3.x | ||
- run: pip install requirements/build-docs.txt | ||
- run: mkdocs gh-deploy --force |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,184 +1,79 @@ | ||
# Django IDOM · [![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)](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) | ||
|
||
`django-idom` allows Django to integrate with [IDOM](https://github.com/idom-team/idom), a reactive Python web framework for building **interactive websites without needing a single line of Javascript**. | ||
|
||
**You can try IDOM now in a Jupyter Notebook:** | ||
<a | ||
target="_blank" | ||
href="https://mybinder.org/v2/gh/idom-team/idom-jupyter/main?filepath=notebooks%2Fintroduction.ipynb"> | ||
<img | ||
alt="Binder" | ||
valign="bottom" | ||
height="21px" | ||
src="https://mybinder.org/badge_logo.svg"/> | ||
</a> | ||
|
||
# Quick Example | ||
|
||
## `example_app/components.py` | ||
|
||
This is where you'll define your [IDOM](https://github.com/idom-team/idom) components. Ultimately though, you should | ||
feel free to organize your component modules as you wish. Any components created will ultimately be referenced | ||
by Python dotted path in `your-template.html`. | ||
|
||
```python | ||
from idom import component, html | ||
from django_idom import IdomWebsocket | ||
|
||
# Components are CamelCase by ReactJS convention | ||
@component | ||
def Hello(websocket: IdomWebsocket, greeting_recipient: str): | ||
return html.h1(f"Hello {greeting_recipient}!") | ||
``` | ||
|
||
## [`example_app/templates/your-template.html`](https://docs.djangoproject.com/en/dev/topics/templates/) | ||
|
||
In your templates, you may add IDOM components into your HTML by using the `idom_component` | ||
template tag. This tag requires the dotted path to the component function. | ||
|
||
Additonally, you can pass in keyworded arguments into your component function. | ||
|
||
In context this will look a bit like the following... | ||
|
||
```jinja | ||
{% load idom %} | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Example Project</title> | ||
</head> | ||
<body> | ||
{% idom_component "my_django_project.example_app.components.Hello" greeting_recipient="World" %} | ||
</body> | ||
</html> | ||
``` | ||
|
||
# Installation | ||
|
||
Install `django-idom` via pip. | ||
<!--header-start--> | ||
|
||
```bash | ||
pip install django-idom | ||
``` | ||
|
||
You'll also need to modify a few files in your Django project. | ||
|
||
## [`settings.py`](https://docs.djangoproject.com/en/dev/topics/settings/) | ||
|
||
In your settings you'll need to add `channels` and `django_idom` to [`INSTALLED_APPS`](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-INSTALLED_APPS). | ||
|
||
```python | ||
INSTALLED_APPS = [ | ||
..., | ||
"channels", | ||
"django_idom", | ||
] | ||
|
||
# Ensure ASGI_APPLICATION is set properly based on your project name! | ||
ASGI_APPLICATION = "my_django_project.asgi.application" | ||
``` | ||
|
||
**Optional:** You can also configure IDOM settings. | ||
# Django IDOM · [![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)](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) | ||
|
||
```python | ||
# If "idom" cache is not configured, then we'll use "default" instead | ||
CACHES = { | ||
"idom": {"BACKEND": ...}, | ||
} | ||
<!--header-end--> | ||
<!--intro-start--> | ||
|
||
# Maximum seconds between two reconnection attempts that would cause the client give up. | ||
# 0 will disable reconnection. | ||
IDOM_WS_MAX_RECONNECT_TIMEOUT: int = 604800 | ||
Django-IDOM connects your project to a ReactJS frontend, allowing you to create **interactive websites without needing JavaScript!** | ||
|
||
# The URL for IDOM to serve websockets | ||
IDOM_WEBSOCKET_URL: str = "idom/" | ||
``` | ||
Following ReactJS styling, web elements are combined into [reusable "components"](https://idom-docs.herokuapp.com/docs/guides/creating-interfaces/your-first-components/index.html#parametrizing-components). These components can utilize [hooks](https://idom-docs.herokuapp.com/docs/reference/hooks-api.html) and [events](https://idom-docs.herokuapp.com/docs/guides/adding-interactivity/responding-to-events/index.html#async-event-handlers) to create infinitely complex web pages. | ||
|
||
## [`urls.py`](https://docs.djangoproject.com/en/dev/topics/http/urls/) | ||
When needed, IDOM can [use components directly from NPM](https://idom-docs.herokuapp.com/docs/guides/escape-hatches/javascript-components.html#dynamically-loaded-components). For additional flexibility, components can also be [fully developed in JavaScript](https://idom-docs.herokuapp.com/docs/guides/escape-hatches/javascript-components.html#custom-javascript-components). | ||
|
||
Add IDOM HTTP paths to your `urlpatterns`. | ||
Any Python web framework with Websockets can support IDOM. See below for what frameworks are supported out of the box. | ||
|
||
```python | ||
from django.urls import include, path | ||
| Supported Frameworks | Supported Frameworks (External) | | ||
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| [`Flask`, `FastAPI`, `Sanic`, `Tornado`](https://idom-docs.herokuapp.com/docs/guides/getting-started/installing-idom.html#officially-supported-servers) | [`Django`](https://github.com/idom-team/django-idom), [`Plotly-Dash`](https://github.com/idom-team/idom-dash), [`Jupyter`](https://github.com/idom-team/idom-jupyter) | | ||
|
||
urlpatterns = [ | ||
path("idom/", include("django_idom.http.urls")), | ||
... | ||
] | ||
``` | ||
<!--intro-end--> | ||
|
||
## [`asgi.py`](https://docs.djangoproject.com/en/dev/howto/deployment/asgi/) | ||
--- | ||
|
||
Register IDOM's websocket using `IDOM_WEBSOCKET_PATH`. | ||
# At a Glance | ||
|
||
_Note: If you do not have an `asgi.py`, follow the [`channels` installation guide](https://channels.readthedocs.io/en/stable/installation.html)._ | ||
## `my_app/components.py` | ||
|
||
```python | ||
<!--py-header-start--> | ||
|
||
import os | ||
from django.core.asgi import get_asgi_application | ||
You'll need a file to define your [IDOM](https://github.com/idom-team/idom) components. We recommend creating a `components.py` file within your chosen **Django app** to start out. | ||
|
||
# Ensure DJANGO_SETTINGS_MODULE is set properly based on your project name! | ||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_django_project.settings") | ||
django_asgi_app = get_asgi_application() | ||
<!--py-header-end--> | ||
<!--py-code-start--> | ||
|
||
from channels.auth import AuthMiddlewareStack | ||
from channels.routing import ProtocolTypeRouter, URLRouter | ||
from channels.sessions import SessionMiddlewareStack | ||
from django_idom import IDOM_WEBSOCKET_PATH | ||
```python title="components.py" | ||
from idom import component, html | ||
|
||
application = ProtocolTypeRouter( | ||
{ | ||
"http": django_asgi_app, | ||
"websocket": SessionMiddlewareStack( | ||
AuthMiddlewareStack(URLRouter([IDOM_WEBSOCKET_PATH])) | ||
), | ||
} | ||
) | ||
@component | ||
def HelloWorld(recipient: str): | ||
return html.h1(f"Hello {recipient}!") | ||
``` | ||
|
||
# Developer Guide | ||
<!--py-code-end--> | ||
|
||
If you plan to make code changes to this repository, you'll need to install the | ||
following dependencies first: | ||
## [`my_app/templates/my-template.html`](https://docs.djangoproject.com/en/dev/topics/templates/) | ||
|
||
- [NPM](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) for | ||
installing and managing Javascript | ||
- [ChromeDriver](https://chromedriver.chromium.org/downloads) for testing with | ||
[Selenium](https://www.seleniumhq.org/) | ||
<!--html-header-start--> | ||
|
||
Once done, you should clone this repository: | ||
In your **Django app**'s HTML located within your `templates` folder, you can now embed your IDOM component using the `component` template tag. Within this tag, you will need to type in your dotted path to the component function as the first argument. | ||
|
||
```bash | ||
git clone https://github.com/idom-team/django-idom.git | ||
cd django-idom | ||
``` | ||
|
||
Then, by running the command below you can: | ||
Additonally, you can pass in keyword arguments into your component function. For example, after reading the code below, pay attention to how the function definition for `HelloWorld` (_in the previous example_) accepts a `recipient` argument. | ||
|
||
- Install an editable version of the Python code | ||
<!--html-header-end--> | ||
<!--html-code-start--> | ||
|
||
- Download, build, and install Javascript dependencies | ||
|
||
```bash | ||
pip install -e . -r requirements.txt | ||
```jinja title="my-template.html" | ||
{% load idom %} | ||
<!DOCTYPE html> | ||
<html> | ||
<body> | ||
{% component "example_project.my_app.components.HelloWorld" recipient="World" %} | ||
</body> | ||
</html> | ||
``` | ||
|
||
Finally, to verify that everything is working properly, you'll want to run the test suite. | ||
<!--html-code-end--> | ||
|
||
## Running The Tests | ||
--- | ||
|
||
This repo uses [Nox](https://nox.thea.codes/en/stable/) to run scripts which can | ||
be found in `noxfile.py`. For a full test of available scripts run `nox -l`. To run the full test suite simple execute: | ||
# Resources | ||
|
||
``` | ||
nox -s test | ||
``` | ||
<!--resources-start--> | ||
|
||
To run the tests using a headless browser: | ||
Follow the links below to find out more about this project. | ||
|
||
``` | ||
nox -s test -- --headless | ||
``` | ||
- [Try it Now](https://mybinder.org/v2/gh/idom-team/idom-jupyter/main?urlpath=lab/tree/notebooks/introduction.ipynb) - Check out IDOM in a Jupyter Notebook. | ||
- [Documentation](https://idom-team.github.io/django-idom) - Learn how to install, run, and use IDOM. | ||
- [Community Forum](https://github.com/idom-team/idom/discussions) - Ask questions, share ideas, and show off projects. | ||
<!--resources-end--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
hide: | ||
- navigation | ||
- toc | ||
--- | ||
|
||
!!! note "Attribution" | ||
|
||
{% include-markdown "../../CHANGELOG.md" start="<!--attr-start-->" end="<!--attr-end-->" %} | ||
|
||
{% include-markdown "../../CHANGELOG.md" start="<!--changelog-start-->" %} |
Oops, something went wrong.