Skip to content

Commit 90db8d9

Browse files
authored
Merge pull request #3 from idom-team/installable-app
Make django_idom an installable app
2 parents ff7ec1c + 83e3f7c commit 90db8d9

32 files changed

+718
-141
lines changed

Diff for: .github/CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @idom-team/django

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Django IDOM Build Artifacts
2+
src/django_idom/static/js
3+
14
# Django #
25
logs
36
*.log

Diff for: CODE_OF_CONDUCT.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as
6+
contributors and maintainers pledge to making participation in our project and
7+
our community a harassment-free experience for everyone, regardless of age, body
8+
size, disability, ethnicity, sex characteristics, gender identity and expression,
9+
level of experience, education, socio-economic status, nationality, personal
10+
appearance, race, religion, or sexual identity and orientation.
11+
12+
## Our Standards
13+
14+
Examples of behavior that contributes to creating a positive environment
15+
include:
16+
17+
* Using welcoming and inclusive language
18+
* Being respectful of differing viewpoints and experiences
19+
* Gracefully accepting constructive criticism
20+
* Focusing on what is best for the community
21+
* Showing empathy towards other community members
22+
23+
Examples of unacceptable behavior by participants include:
24+
25+
* The use of sexualized language or imagery and unwelcome sexual attention or
26+
advances
27+
* Trolling, insulting/derogatory comments, and personal or political attacks
28+
* Public or private harassment
29+
* Publishing others' private information, such as a physical or electronic
30+
address, without explicit permission
31+
* Other conduct which could reasonably be considered inappropriate in a
32+
professional setting
33+
34+
## Our Responsibilities
35+
36+
Project maintainers are responsible for clarifying the standards of acceptable
37+
behavior and are expected to take appropriate and fair corrective action in
38+
response to any instances of unacceptable behavior.
39+
40+
Project maintainers have the right and responsibility to remove, edit, or
41+
reject comments, commits, code, wiki edits, issues, and other contributions
42+
that are not aligned to this Code of Conduct, or to ban temporarily or
43+
permanently any contributor for other behaviors that they deem inappropriate,
44+
threatening, offensive, or harmful.
45+
46+
## Scope
47+
48+
This Code of Conduct applies both within project spaces and in public spaces
49+
when an individual is representing the project or its community. Examples of
50+
representing a project or community include using an official project e-mail
51+
address, posting via an official social media account, or acting as an appointed
52+
representative at an online or offline event. Representation of a project may be
53+
further defined and clarified by project maintainers.
54+
55+
## Enforcement
56+
57+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
58+
reported by contacting the project team at [email protected]. All
59+
complaints will be reviewed and investigated and will result in a response that
60+
is deemed necessary and appropriate to the circumstances. The project team is
61+
obligated to maintain confidentiality with regard to the reporter of an incident.
62+
Further details of specific enforcement policies may be posted separately.
63+
64+
Project maintainers who do not follow or enforce the Code of Conduct in good
65+
faith may face temporary or permanent repercussions as determined by other
66+
members of the project's leadership.
67+
68+
## Attribution
69+
70+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72+
73+
[homepage]: https://www.contributor-covenant.org
74+
75+
For answers to common questions about this code of conduct, see
76+
https://www.contributor-covenant.org/faq

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2021 Ryan S. Morshead
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: MANIFEST.in

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
recursive-include src/django_idom/static/ *
2+
recursive-include src/django_idom/templates/ *.html

Diff for: README.md

+226-26
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,243 @@
1010
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-purple.svg">
1111
</a>
1212

13-
A package for building highly interactive user interfaces in pure Python inspired by
14-
[ReactJS](https://reactjs.org/).
13+
`django-idom` allows you to integrate [IDOM](https://github.com/idom-team/idom) into
14+
Django applications. IDOM is a pure Python library inspired by
15+
[ReactJS](https://reactjs.org/) for creating responsive web interfaces.
1516

16-
**Be sure to [read the IDOM Documentation](https://idom-docs.herokuapp.com)!**
17-
18-
If you have ideas or find a bug, be sure to post an
19-
[issue](https://github.com/idom-team/django-idom/issues)
20-
or create a
21-
[pull request](https://github.com/idom-team/django-idom/pulls). Thanks in advance!
22-
23-
<h3>
24-
<a
25-
target="_blank"
26-
href="https://mybinder.org/v2/gh/idom-team/idom-jupyter/main?filepath=notebooks%2Fintroduction.ipynb"
27-
>
28-
Try it Now
29-
<img alt="Binder" valign="bottom" height="25px"
30-
src="https://mybinder.org/badge_logo.svg"
31-
/>
32-
</a>
33-
</h3>
17+
**You can try IDOM now in a Jupyter Notebook:**
18+
<a
19+
target="_blank"
20+
href="https://mybinder.org/v2/gh/idom-team/idom-jupyter/main?filepath=notebooks%2Fintroduction.ipynb">
21+
<img
22+
alt="Binder"
23+
valign="bottom"
24+
height="21px"
25+
src="https://mybinder.org/badge_logo.svg"/>
26+
</a>
3427

35-
Click the badge above to get started! It will take you to a [Jupyter Notebooks](https://jupyter.org/)
36-
hosted by [Binder](https://mybinder.org/) with some great examples.
3728

38-
### Or Install it Now
29+
# Install Django IDOM
3930

4031
```bash
4132
pip install django-idom
4233
```
4334

4435
# Django Integration
4536

46-
This version of IDOM can be directly integrated into Django. For example
37+
To integrate IDOM into your application you'll need to modify or add the following files to `your_project`:
38+
39+
```
40+
your_project/
41+
├── __init__.py
42+
├── asgi.py
43+
├── settings.py
44+
├── urls.py
45+
└── example_app/
46+
├── __init__.py
47+
├── idom.py
48+
├── templates/
49+
│ └── your-template.html
50+
└── urls.py
51+
```
52+
53+
## `asgi.py`
54+
55+
Follow the [`channels`](https://channels.readthedocs.io/en/stable/)
56+
[installation guide](https://channels.readthedocs.io/en/stable/installation.html) in
57+
order to create ASGI websockets within Django. Then, we will add a path for IDOM's
58+
websocket consumer using `IDOM_WEBSOCKET_PATH`.
59+
60+
_Note: If you wish to change the route where this websocket is served from, see the
61+
available [settings](#settings.py)._
62+
63+
```python
64+
65+
import os
66+
67+
from django.core.asgi import get_asgi_application
68+
69+
from django_idom import IDOM_WEB_MODULES_PATH
70+
71+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_app.settings")
72+
73+
# Fetch ASGI application before importing dependencies that require ORM models.
74+
http_asgi_app = get_asgi_application()
75+
76+
from channels.routing import ProtocolTypeRouter, URLRouter
77+
78+
application = ProtocolTypeRouter(
79+
{
80+
"http": http_asgi_app,
81+
"websocket": URLRouter(
82+
# add a path for IDOM's websocket
83+
[IDOM_WEB_MODULES_PATH]
84+
),
85+
}
86+
)
87+
```
88+
89+
## `settings.py`
90+
91+
In your settings you'll need to add `django_idom` to the
92+
[`INSTALLED_APPS`](https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-INSTALLED_APPS)
93+
list:
4794

4895
```python
49-
# Example code goes here
96+
INSTALLED_APPS = [
97+
...,
98+
"django_idom",
99+
]
50100
```
51101

52-
For examples on how to use IDOM, [read the IDOM Documentation](https://idom-docs.herokuapp.com).
102+
You may configure additional options as well:
103+
104+
```python
105+
# the base URL for all IDOM-releated resources
106+
IDOM_BASE_URL: str = "_idom/"
107+
108+
# Set cache size limit for loading JS files for IDOM.
109+
# Only applies when not using Django's caching framework (see below).
110+
IDOM_WEB_MODULE_LRU_CACHE_SIZE: int | None = None
111+
112+
# Configure a cache for loading JS files
113+
CACHES = {
114+
# Configure a cache for loading JS files for IDOM
115+
"idom_web_modules": {"BACKEND": ...},
116+
# If the above cache is not configured, then we'll use the "default" instead
117+
"default": {"BACKEND": ...},
118+
}
119+
```
120+
121+
## `urls.py`
122+
123+
You'll need to include IDOM's static web modules path using `IDOM_WEB_MODULES_PATH`.
124+
Similarly to the `IDOM_WEBSOCKET_PATH`. If you wish to change the route where this
125+
websocket is served from, see the available [settings](#settings.py).
126+
127+
```python
128+
from django_idom import IDOM_WEB_MODULES_PATH
129+
130+
urlpatterns = [
131+
IDOM_WEB_MODULES_PATH,
132+
...
133+
]
134+
```
135+
136+
## `example_app/components.py`
137+
138+
This is where, by a convention similar to that of
139+
[`views.py`](https://docs.djangoproject.com/en/3.2/topics/http/views/), you'll define
140+
your [IDOM](https://github.com/idom-team/idom) components. Ultimately though, you should
141+
feel free to organize your component modules you wish. The components created here will
142+
ultimately be referenced by name in `your-template.html`. `your-template.html`.
143+
144+
```python
145+
import idom
146+
147+
@idom.component
148+
def Hello(greeting_recipient): # component names are camelcase by convention
149+
return Header(f"Hello {greeting_recipient}!")
150+
```
151+
152+
## `example_app/templates/your-template.html`
153+
154+
In your templates, you may inject a view of an IDOM component into your templated HTML
155+
by using the `idom_component` template tag. This tag which requires the name of a component
156+
to render (of the form `module_name.ComponentName`) and keyword arguments you'd like to
157+
pass it from the template.
158+
159+
```python
160+
idom_component module_name.ComponentName param_1="something" param_2="something-else"
161+
```
162+
163+
In context this will look a bit like the following...
164+
165+
```jinja
166+
<!-- don't forget your load statements -->
167+
{% load static %}
168+
{% load idom %}
169+
170+
<!DOCTYPE html>
171+
<html>
172+
<body>
173+
...
174+
{% idom_component "your_project.example_app.components.Hello" greeting_recipient="World" %}
175+
</body>
176+
</html>
177+
```
178+
179+
## `example_app/views.py`
180+
181+
You can then serve `your-template.html` from a view just
182+
[like any other](https://docs.djangoproject.com/en/3.2/intro/tutorial03/#write-views-that-actually-do-something).
183+
184+
```python
185+
from django.http import HttpResponse
186+
from django.template import loader
187+
188+
189+
def your_view(request):
190+
context = {}
191+
return HttpResponse(
192+
loader.get_template("your-template.html").render(context, request)
193+
)
194+
```
195+
196+
## `example_app/urls.py`
197+
198+
Include your view in the list of urlpatterns
199+
200+
```python
201+
from django.urls import path
202+
from .views import your_view # define this view like any other HTML template view
203+
204+
urlpatterns = [
205+
path("", your_view),
206+
...
207+
]
208+
```
209+
210+
# Developer Guide
211+
212+
If you plan to make code changes to this repository, you'll need to install the
213+
following dependencies first:
214+
215+
- [NPM](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) for
216+
installing and managing Javascript
217+
- [ChromeDriver](https://chromedriver.chromium.org/downloads) for testing with
218+
[Selenium](https://www.seleniumhq.org/)
219+
220+
Once done, you should clone this repository:
221+
222+
```bash
223+
git clone https://github.com/idom-team/django-idom.git
224+
cd django-idom
225+
```
226+
227+
Then, by running the command below you can:
228+
229+
- Install an editable version of the Python code
230+
231+
- Download, build, and install Javascript dependencies
232+
233+
```bash
234+
pip install -e . -r requirements.txt
235+
```
236+
237+
Finally, to verify that everything is working properly, you'll want to run the test suite.
238+
239+
## Running The Tests
240+
241+
This repo uses [Nox](https://nox.thea.codes/en/stable/) to run scripts which can
242+
be found in `noxfile.py`. For a full test of available scripts run `nox -l`. To run the full test suite simple execute:
243+
244+
```
245+
nox -s test
246+
```
247+
248+
To run the tests using a headless browser:
249+
250+
```
251+
nox -s test -- --headless
252+
```

0 commit comments

Comments
 (0)