|
1 |
| -# Django IDOM · [](https://github.com/idom-team/django-idom/actions?query=workflow%3ATest) [](https://pypi.python.org/pypi/django-idom) [](https://github.com/idom-team/django-idom/blob/main/LICENSE) |
2 |
| - |
3 |
| -`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**. |
4 |
| - |
5 |
| -**You can try IDOM now in a Jupyter Notebook:** |
6 |
| -<a |
7 |
| - target="_blank" |
8 |
| - href="https://mybinder.org/v2/gh/idom-team/idom-jupyter/main?filepath=notebooks%2Fintroduction.ipynb"> |
9 |
| -<img |
10 |
| - alt="Binder" |
11 |
| - valign="bottom" |
12 |
| - height="21px" |
13 |
| - src="https://mybinder.org/badge_logo.svg"/> |
14 |
| -</a> |
15 |
| - |
16 |
| -# Quick Example |
17 |
| - |
18 |
| -## `example_app/components.py` |
19 |
| - |
20 |
| -This is where you'll define your [IDOM](https://github.com/idom-team/idom) components. Ultimately though, you should |
21 |
| -feel free to organize your component modules as you wish. Any components created will ultimately be referenced |
22 |
| -by Python dotted path in `your-template.html`. |
23 |
| - |
24 |
| -```python |
25 |
| -from idom import component, html |
26 |
| -from django_idom import IdomWebsocket |
27 |
| - |
28 |
| -# Components are CamelCase by ReactJS convention |
29 |
| -@component |
30 |
| -def Hello(websocket: IdomWebsocket, greeting_recipient: str): |
31 |
| - return html.h1(f"Hello {greeting_recipient}!") |
32 |
| -``` |
33 |
| - |
34 |
| -## [`example_app/templates/your-template.html`](https://docs.djangoproject.com/en/dev/topics/templates/) |
35 |
| - |
36 |
| -In your templates, you may add IDOM components into your HTML by using the `idom_component` |
37 |
| -template tag. This tag requires the dotted path to the component function. |
38 |
| - |
39 |
| -Additonally, you can pass in keyworded arguments into your component function. |
40 |
| - |
41 |
| -In context this will look a bit like the following... |
42 |
| - |
43 |
| -```jinja |
44 |
| -{% load idom %} |
45 |
| -
|
46 |
| -<!DOCTYPE html> |
47 |
| -<html> |
48 |
| - <head> |
49 |
| - <title>Example Project</title> |
50 |
| - </head> |
51 |
| -
|
52 |
| - <body> |
53 |
| - {% idom_component "my_django_project.example_app.components.Hello" greeting_recipient="World" %} |
54 |
| - </body> |
55 |
| -</html> |
56 |
| -``` |
57 |
| - |
58 |
| -# Installation |
59 |
| - |
60 |
| -Install `django-idom` via pip. |
| 1 | +<!--header-start--> |
61 | 2 |
|
62 |
| -```bash |
63 |
| -pip install django-idom |
64 |
| -``` |
65 |
| - |
66 |
| -You'll also need to modify a few files in your Django project. |
67 |
| - |
68 |
| -## [`settings.py`](https://docs.djangoproject.com/en/dev/topics/settings/) |
69 |
| - |
70 |
| -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). |
71 |
| - |
72 |
| -```python |
73 |
| -INSTALLED_APPS = [ |
74 |
| - ..., |
75 |
| - "channels", |
76 |
| - "django_idom", |
77 |
| -] |
78 |
| - |
79 |
| -# Ensure ASGI_APPLICATION is set properly based on your project name! |
80 |
| -ASGI_APPLICATION = "my_django_project.asgi.application" |
81 |
| -``` |
82 |
| - |
83 |
| -**Optional:** You can also configure IDOM settings. |
| 3 | +# Django IDOM · [](https://github.com/idom-team/django-idom/actions?query=workflow%3ATest) [](https://pypi.python.org/pypi/django-idom) [](https://github.com/idom-team/django-idom/blob/main/LICENSE) |
84 | 4 |
|
85 |
| -```python |
86 |
| -# If "idom" cache is not configured, then we'll use "default" instead |
87 |
| -CACHES = { |
88 |
| - "idom": {"BACKEND": ...}, |
89 |
| -} |
| 5 | +<!--header-end--> |
| 6 | +<!--intro-start--> |
90 | 7 |
|
91 |
| -# Maximum seconds between two reconnection attempts that would cause the client give up. |
92 |
| -# 0 will disable reconnection. |
93 |
| -IDOM_WS_MAX_RECONNECT_TIMEOUT: int = 604800 |
| 8 | +Django-IDOM connects your project to a ReactJS frontend, allowing you to create **interactive websites without needing JavaScript!** |
94 | 9 |
|
95 |
| -# The URL for IDOM to serve websockets |
96 |
| -IDOM_WEBSOCKET_URL: str = "idom/" |
97 |
| -``` |
| 10 | +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. |
98 | 11 |
|
99 |
| -## [`urls.py`](https://docs.djangoproject.com/en/dev/topics/http/urls/) |
| 12 | +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). |
100 | 13 |
|
101 |
| -Add IDOM HTTP paths to your `urlpatterns`. |
| 14 | +Any Python web framework with Websockets can support IDOM. See below for what frameworks are supported out of the box. |
102 | 15 |
|
103 |
| -```python |
104 |
| -from django.urls import include, path |
| 16 | +| Supported Frameworks | Supported Frameworks (External) | |
| 17 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 18 | +| [`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) | |
105 | 19 |
|
106 |
| -urlpatterns = [ |
107 |
| - path("idom/", include("django_idom.http.urls")), |
108 |
| - ... |
109 |
| -] |
110 |
| -``` |
| 20 | +<!--intro-end--> |
111 | 21 |
|
112 |
| -## [`asgi.py`](https://docs.djangoproject.com/en/dev/howto/deployment/asgi/) |
| 22 | +--- |
113 | 23 |
|
114 |
| -Register IDOM's websocket using `IDOM_WEBSOCKET_PATH`. |
| 24 | +# At a Glance |
115 | 25 |
|
116 |
| -_Note: If you do not have an `asgi.py`, follow the [`channels` installation guide](https://channels.readthedocs.io/en/stable/installation.html)._ |
| 26 | +## `my_app/components.py` |
117 | 27 |
|
118 |
| -```python |
| 28 | +<!--py-header-start--> |
119 | 29 |
|
120 |
| -import os |
121 |
| -from django.core.asgi import get_asgi_application |
| 30 | +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. |
122 | 31 |
|
123 |
| -# Ensure DJANGO_SETTINGS_MODULE is set properly based on your project name! |
124 |
| -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_django_project.settings") |
125 |
| -django_asgi_app = get_asgi_application() |
| 32 | +<!--py-header-end--> |
| 33 | +<!--py-code-start--> |
126 | 34 |
|
127 |
| -from channels.auth import AuthMiddlewareStack |
128 |
| -from channels.routing import ProtocolTypeRouter, URLRouter |
129 |
| -from channels.sessions import SessionMiddlewareStack |
130 |
| -from django_idom import IDOM_WEBSOCKET_PATH |
| 35 | +```python title="components.py" |
| 36 | +from idom import component, html |
131 | 37 |
|
132 |
| -application = ProtocolTypeRouter( |
133 |
| - { |
134 |
| - "http": django_asgi_app, |
135 |
| - "websocket": SessionMiddlewareStack( |
136 |
| - AuthMiddlewareStack(URLRouter([IDOM_WEBSOCKET_PATH])) |
137 |
| - ), |
138 |
| - } |
139 |
| -) |
| 38 | +@component |
| 39 | +def HelloWorld(recipient: str): |
| 40 | + return html.h1(f"Hello {recipient}!") |
140 | 41 | ```
|
141 | 42 |
|
142 |
| -# Developer Guide |
| 43 | +<!--py-code-end--> |
143 | 44 |
|
144 |
| -If you plan to make code changes to this repository, you'll need to install the |
145 |
| -following dependencies first: |
| 45 | +## [`my_app/templates/my-template.html`](https://docs.djangoproject.com/en/dev/topics/templates/) |
146 | 46 |
|
147 |
| -- [NPM](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) for |
148 |
| - installing and managing Javascript |
149 |
| -- [ChromeDriver](https://chromedriver.chromium.org/downloads) for testing with |
150 |
| - [Selenium](https://www.seleniumhq.org/) |
| 47 | +<!--html-header-start--> |
151 | 48 |
|
152 |
| -Once done, you should clone this repository: |
| 49 | +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. |
153 | 50 |
|
154 |
| -```bash |
155 |
| -git clone https://github.com/idom-team/django-idom.git |
156 |
| -cd django-idom |
157 |
| -``` |
158 |
| - |
159 |
| -Then, by running the command below you can: |
| 51 | +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. |
160 | 52 |
|
161 |
| -- Install an editable version of the Python code |
| 53 | +<!--html-header-end--> |
| 54 | +<!--html-code-start--> |
162 | 55 |
|
163 |
| -- Download, build, and install Javascript dependencies |
164 |
| - |
165 |
| -```bash |
166 |
| -pip install -e . -r requirements.txt |
| 56 | +```jinja title="my-template.html" |
| 57 | +{% load idom %} |
| 58 | +<!DOCTYPE html> |
| 59 | +<html> |
| 60 | + <body> |
| 61 | + {% component "example_project.my_app.components.HelloWorld" recipient="World" %} |
| 62 | + </body> |
| 63 | +</html> |
167 | 64 | ```
|
168 | 65 |
|
169 |
| -Finally, to verify that everything is working properly, you'll want to run the test suite. |
| 66 | +<!--html-code-end--> |
170 | 67 |
|
171 |
| -## Running The Tests |
| 68 | +--- |
172 | 69 |
|
173 |
| -This repo uses [Nox](https://nox.thea.codes/en/stable/) to run scripts which can |
174 |
| -be found in `noxfile.py`. For a full test of available scripts run `nox -l`. To run the full test suite simple execute: |
| 70 | +# Resources |
175 | 71 |
|
176 |
| -``` |
177 |
| -nox -s test |
178 |
| -``` |
| 72 | +<!--resources-start--> |
179 | 73 |
|
180 |
| -To run the tests using a headless browser: |
| 74 | +Follow the links below to find out more about this project. |
181 | 75 |
|
182 |
| -``` |
183 |
| -nox -s test -- --headless |
184 |
| -``` |
| 76 | +- [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. |
| 77 | +- [Documentation](https://idom-team.github.io/django-idom) - Learn how to install, run, and use IDOM. |
| 78 | +- [Community Forum](https://github.com/idom-team/idom/discussions) - Ask questions, share ideas, and show off projects. |
| 79 | +<!--resources-end--> |
0 commit comments