Skip to content

Make django_idom an installable app #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
30a481f
create barebones templatetags
Archmonger Jul 22, 2021
8b0b363
styling fix
Archmonger Jul 22, 2021
4bcd9bf
idom_view
Archmonger Jul 26, 2021
f8f094e
skeleton of django installable app
rmorshea Jul 26, 2021
937da20
get test_app runserver to work
rmorshea Jul 26, 2021
e76408b
fix MANIFEST.in to include static/templates
rmorshea Jul 28, 2021
f008f6b
fix style
rmorshea Jul 28, 2021
b4f256b
require a my_app.idom.components attribute
rmorshea Jul 28, 2021
a0b75e0
parametrized components + serve web modules
rmorshea Jul 28, 2021
cd12a7c
add IDOM_IGNORED_DJANGO_APPS option
rmorshea Jul 29, 2021
9f4412d
add basic docs to README
rmorshea Jul 29, 2021
34452e4
minor doc improvements
rmorshea Jul 29, 2021
3e07d5a
more doc updates
rmorshea Jul 29, 2021
0ff84ec
make logger private
rmorshea Aug 5, 2021
fbb0037
use string path to template
rmorshea Aug 5, 2021
407b506
rename URL resolver functions
rmorshea Aug 5, 2021
fa95bb1
fix flake8
rmorshea Aug 5, 2021
9da3de8
correct template tag description
rmorshea Aug 5, 2021
a05d0ef
update app organization in README
rmorshea Aug 5, 2021
937244c
switch to decorator collection method
rmorshea Aug 11, 2021
af6601d
load components using template names
rmorshea Aug 12, 2021
60384af
minor README tweaks
rmorshea Aug 12, 2021
f72b2d6
remove unused config option
rmorshea Aug 12, 2021
4bcdeb5
use different param name in README ex
rmorshea Aug 12, 2021
536968a
cache and asyncify web module loading
rmorshea Aug 19, 2021
aee70a7
rename idom_view to idom_component
rmorshea Aug 19, 2021
7093252
README rename your_template to your_view
rmorshea Aug 19, 2021
66b7cb3
fix README typo
rmorshea Aug 19, 2021
4a4fa74
make websocket and web module paths consts
rmorshea Aug 19, 2021
b209995
correct terminology
rmorshea Aug 19, 2021
b9934de
slim down README asgi.py description
rmorshea Aug 19, 2021
fa70766
better summarize what IDOM is
rmorshea Aug 19, 2021
a15c334
bump copyright year
rmorshea Aug 19, 2021
aed7fc7
fix template formatting
rmorshea Aug 19, 2021
68aa643
rename your_app to your_project
rmorshea Aug 19, 2021
83e3f7c
add CODEOWNERS
rmorshea Aug 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Django IDOM Build Artifacts
src/django_idom/static/js

# Django #
logs
*.log
Expand Down
76 changes: 76 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [email protected]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2021 Ryan S. Morshead

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
recursive-include src/django_idom/static/ *
recursive-include src/django_idom/templates/ *.html
252 changes: 226 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,243 @@
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-purple.svg">
</a>

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

**Be sure to [read the IDOM Documentation](https://idom-docs.herokuapp.com)!**

If you have ideas or find a bug, be sure to post an
[issue](https://github.com/idom-team/django-idom/issues)
or create a
[pull request](https://github.com/idom-team/django-idom/pulls). Thanks in advance!

<h3>
<a
target="_blank"
href="https://mybinder.org/v2/gh/idom-team/idom-jupyter/main?filepath=notebooks%2Fintroduction.ipynb"
>
Try it Now
<img alt="Binder" valign="bottom" height="25px"
src="https://mybinder.org/badge_logo.svg"
/>
</a>
</h3>
**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>

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

### Or Install it Now
# Install Django IDOM

```bash
pip install django-idom
```

# Django Integration

This version of IDOM can be directly integrated into Django. For example
To integrate IDOM into your application you'll need to modify or add the following files to `your_project`:

```
your_project/
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── example_app/
├── __init__.py
├── idom.py
├── templates/
│ └── your-template.html
└── urls.py
```

## `asgi.py`

Follow the [`channels`](https://channels.readthedocs.io/en/stable/)
[installation guide](https://channels.readthedocs.io/en/stable/installation.html) in
order to create ASGI websockets within Django. Then, we will add a path for IDOM's
websocket consumer using `IDOM_WEBSOCKET_PATH`.

_Note: If you wish to change the route where this websocket is served from, see the
available [settings](#settings.py)._

```python

import os

from django.core.asgi import get_asgi_application

from django_idom import IDOM_WEB_MODULES_PATH

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_app.settings")

# Fetch ASGI application before importing dependencies that require ORM models.
http_asgi_app = get_asgi_application()

from channels.routing import ProtocolTypeRouter, URLRouter

application = ProtocolTypeRouter(
{
"http": http_asgi_app,
"websocket": URLRouter(
# add a path for IDOM's websocket
[IDOM_WEB_MODULES_PATH]
),
}
)
```

## `settings.py`

In your settings you'll need to add `django_idom` to the
[`INSTALLED_APPS`](https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-INSTALLED_APPS)
list:

```python
# Example code goes here
INSTALLED_APPS = [
...,
"django_idom",
]
```

For examples on how to use IDOM, [read the IDOM Documentation](https://idom-docs.herokuapp.com).
You may configure additional options as well:

```python
# the base URL for all IDOM-releated resources
IDOM_BASE_URL: str = "_idom/"

# Set cache size limit for loading JS files for IDOM.
# Only applies when not using Django's caching framework (see below).
IDOM_WEB_MODULE_LRU_CACHE_SIZE: int | None = None

# Configure a cache for loading JS files
CACHES = {
# Configure a cache for loading JS files for IDOM
"idom_web_modules": {"BACKEND": ...},
# If the above cache is not configured, then we'll use the "default" instead
"default": {"BACKEND": ...},
}
```

## `urls.py`

You'll need to include IDOM's static web modules path using `IDOM_WEB_MODULES_PATH`.
Similarly to the `IDOM_WEBSOCKET_PATH`. If you wish to change the route where this
websocket is served from, see the available [settings](#settings.py).

```python
from django_idom import IDOM_WEB_MODULES_PATH

urlpatterns = [
IDOM_WEB_MODULES_PATH,
...
]
```

## `example_app/components.py`

This is where, by a convention similar to that of
[`views.py`](https://docs.djangoproject.com/en/3.2/topics/http/views/), you'll define
your [IDOM](https://github.com/idom-team/idom) components. Ultimately though, you should
feel free to organize your component modules you wish. The components created here will
ultimately be referenced by name in `your-template.html`. `your-template.html`.

```python
import idom

@idom.component
def Hello(greeting_recipient): # component names are camelcase by convention
return Header(f"Hello {greeting_recipient}!")
```

## `example_app/templates/your-template.html`

In your templates, you may inject a view of an IDOM component into your templated HTML
by using the `idom_component` template tag. This tag which requires the name of a component
to render (of the form `module_name.ComponentName`) and keyword arguments you'd like to
pass it from the template.

```python
idom_component module_name.ComponentName param_1="something" param_2="something-else"
```

In context this will look a bit like the following...

```jinja
<!-- don't forget your load statements -->
{% load static %}
{% load idom %}

<!DOCTYPE html>
<html>
<body>
...
{% idom_component "your_project.example_app.components.Hello" greeting_recipient="World" %}
</body>
</html>
```

## `example_app/views.py`

You can then serve `your-template.html` from a view just
[like any other](https://docs.djangoproject.com/en/3.2/intro/tutorial03/#write-views-that-actually-do-something).

```python
from django.http import HttpResponse
from django.template import loader


def your_view(request):
context = {}
return HttpResponse(
loader.get_template("your-template.html").render(context, request)
)
```

## `example_app/urls.py`

Include your view in the list of urlpatterns

```python
from django.urls import path
from .views import your_view # define this view like any other HTML template view

urlpatterns = [
path("", your_view),
...
]
```

# Developer Guide

If you plan to make code changes to this repository, you'll need to install the
following dependencies first:

- [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/)

Once done, you should clone this repository:

```bash
git clone https://github.com/idom-team/django-idom.git
cd django-idom
```

Then, by running the command below you can:

- Install an editable version of the Python code

- Download, build, and install Javascript dependencies

```bash
pip install -e . -r requirements.txt
```

Finally, to verify that everything is working properly, you'll want to run the test suite.

## 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:

```
nox -s test
```

To run the tests using a headless browser:

```
nox -s test -- --headless
```
Loading