Skip to content

v1.0.0 #73

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 53 commits into from
May 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
4d272fc
change required versions
Archmonger Apr 17, 2022
2f4bc41
bump version number
Archmonger Apr 17, 2022
fcb1f8c
add changelog entry
Archmonger Apr 17, 2022
98b795a
use contextlib suppress
Archmonger Apr 17, 2022
f03b0cb
use f-strings
Archmonger Apr 17, 2022
0d1acba
dispatch_single_view -> serve_json_patch
Archmonger Apr 17, 2022
9b13b6a
sort imports
Archmonger Apr 17, 2022
036c4ad
new hooks
Archmonger Apr 17, 2022
2db9b1d
formatting
Archmonger Apr 17, 2022
c4e8b4a
update changelog to add hooks
Archmonger Apr 17, 2022
9de275a
Python 3.8 fixes
Archmonger Apr 17, 2022
2fe1208
more python 3.8 fixes
Archmonger Apr 17, 2022
eda71b9
new docs source
Archmonger Apr 24, 2022
2965ceb
publish docs workflow
Archmonger Apr 24, 2022
dedaf7e
rename idom_component to component
Archmonger Apr 24, 2022
465092d
better docs statement in changelog
Archmonger Apr 24, 2022
d1c4637
formatting and cleanup
Archmonger Apr 24, 2022
d31cad0
more everything
Archmonger Apr 24, 2022
96a1605
cleanup
Archmonger Apr 25, 2022
c937fcf
cleanup gen2
Archmonger Apr 25, 2022
9d83b00
templatetags -> templatetag
Archmonger Apr 25, 2022
9fcc082
quick start -> at a glance
Archmonger Apr 25, 2022
87a900a
collapsible everything!
Archmonger Apr 25, 2022
30b8f5c
0.0.6 -> 1.0.0
Archmonger Apr 25, 2022
ad9b672
note cleanup
Archmonger Apr 25, 2022
f931f9b
better component regex
Archmonger Apr 25, 2022
a4abe01
add logging to test app
Archmonger Apr 25, 2022
ddbf68c
fix spacing
Archmonger Apr 25, 2022
5d924d3
more smithing
Archmonger Apr 25, 2022
a772359
ELI5
Archmonger Apr 26, 2022
45159b6
better examples
Archmonger Apr 26, 2022
1f1a2b1
fix example
Archmonger Apr 26, 2022
f1d6afe
highlight body tag
Archmonger Apr 26, 2022
9d98425
add more guidance
Archmonger Apr 26, 2022
a142bfb
smithy
Archmonger Apr 26, 2022
c2104ca
english tweaks
Archmonger Apr 26, 2022
1d072dc
minor rework
Archmonger Apr 27, 2022
bb35d0d
rename component to HelloWorld
Archmonger May 1, 2022
c9646f0
warning if no components are found
Archmonger May 5, 2022
059ae0e
fix spacing in templatetag.md
Archmonger May 5, 2022
1ea9e80
fix multiline strings
Archmonger May 5, 2022
34ae18c
clean changelong
Archmonger May 5, 2022
9e3c035
fix unreleased link
Archmonger May 6, 2022
f22d60e
Add link to django only features
Archmonger May 9, 2022
5095588
disable prose wrap formatting
Archmonger May 9, 2022
dbc2ace
how to use -> getting started
Archmonger May 10, 2022
12cfc99
django-only -> exclusive
Archmonger May 10, 2022
b1c41f8
color error/warning log messages
Archmonger May 13, 2022
7e8ace8
remove duplicate log message
Archmonger May 13, 2022
4a4e51d
add newline
Archmonger May 27, 2022
52f335a
minor readme revision
Archmonger May 31, 2022
8f64511
change contribute section names
Archmonger May 31, 2022
d758ec8
IDOM Core tip
Archmonger May 31, 2022
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
15 changes: 15 additions & 0 deletions .github/workflows/publish-docs.yml
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
73 changes: 48 additions & 25 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
<!--attr-start-->

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

<!--attr-end-->

<!--
Types of changes are to be listed in this order
Expand All @@ -15,72 +18,92 @@ Types of changes are to be listed in this order
- "Security" in case of vulnerabilities.
-->

<!--changelog-start-->

## [Unreleased]

- Nothing (yet)
- Nothing (yet)

## [1.0.0] - 2022-05-22

### Added

- Django-specific hooks! `use_websocket`, `use_scope`, and `use_location` are now available within the `django_idom.hooks` module.
- Documentation has been placed into a formal docs webpage.
- Logging for when a component fails to import, or if no components were found within Django.

### Changed

- `idom_component` template tag has been renamed to `component`
- Bumped the minimum IDOM version to 0.38.0

### Removed

- `websocket` parameter for components has been removed. Functionally, it is replaced with `django_idom.hooks.use_websocket`.

## [0.0.5] - 2022-04-04

### Changed

- Bumped the minimum IDOM version to 0.37.2
- Bumped the minimum IDOM version to 0.37.2

### Fixed

- ModuleNotFoundError: No module named `idom.core.proto` caused by IDOM 0.37.2
- ModuleNotFoundError: No module named `idom.core.proto` caused by IDOM 0.37.2

## [0.0.4] - 2022-03-05

### Changed

- Bumped the minimum IDOM version to 0.37.1
- Bumped the minimum IDOM version to 0.37.1

## [0.0.3] - 2022-02-19

### Changed

- Bumped the minimum IDOM version to 0.36.3
- Bumped the minimum IDOM version to 0.36.3

## [0.0.2] - 2022-01-30

### Added

- Ability to declare the HTML class of the top-level component `div`
- `name = ...` parameter to IDOM HTTP paths for use with `django.urls.reverse()`
- Cache versioning to automatically invalidate old web module files from the cache backend
- Automatic pre-population of the IDOM component registry
- Type hinting for `IdomWebsocket`
- Ability to declare the HTML class of the top-level component `div`
- `name = ...` parameter to IDOM HTTP paths for use with `django.urls.reverse()`
- Cache versioning to automatically invalidate old web module files from the cache backend
- Automatic pre-population of the IDOM component registry
- Type hinting for `IdomWebsocket`

### Changed

- Fetching web modules from disk and/or cache is now fully async
- Static files are now contained within a `django_idom/` parent folder
- Upgraded IDOM to version `0.36.0`
- Minimum Django version required is now `4.0`
- Minimum Python version required is now `3.8`
- Fetching web modules from disk and/or cache is now fully async
- Static files are now contained within a `django_idom/` parent folder
- Upgraded IDOM to version `0.36.0`
- Minimum Django version required is now `4.0`
- Minimum Python version required is now `3.8`

### Removed

- `IDOM_WEB_MODULES_PATH` has been replaced with Django `include(...)`
- `IDOM_WS_MAX_RECONNECT_DELAY` has been renamed to `IDOM_WS_MAX_RECONNECT_TIMEOUT`
- `idom_web_modules` cache backend has been renamed to `idom`
- `IDOM_WEB_MODULES_PATH` has been replaced with Django `include(...)`
- `IDOM_WS_MAX_RECONNECT_DELAY` has been renamed to `IDOM_WS_MAX_RECONNECT_TIMEOUT`
- `idom_web_modules` cache backend has been renamed to `idom`

### Fixed

- Increase test timeout values to prevent false positives
- Windows compatibility for building Django-IDOM
- Increase test timeout values to prevent false positives
- Windows compatibility for building Django-IDOM

### Security

- Fixed potential directory travesal attack on the IDOM web modules URL
- Fixed potential directory travesal attack on the IDOM web modules URL

## [0.0.1] - 2021-08-18

### Added

- Support for IDOM within the Django
- Support for IDOM within the Django

[unreleased]: https://github.com/idom-team/django-idom/compare/0.0.2...HEAD
[unreleased]: https://github.com/idom-team/django-idom/compare/1.0.0...HEAD
[1.0.0]: https://github.com/idom-team/django-idom/compare/0.0.5...1.0.0
[0.0.5]: https://github.com/idom-team/django-idom/compare/0.0.4...0.0.5
[0.0.4]: https://github.com/idom-team/django-idom/compare/0.0.3...0.0.4
[0.0.3]: https://github.com/idom-team/django-idom/compare/0.0.2...0.0.3
Expand Down
201 changes: 48 additions & 153 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,184 +1,79 @@
# 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)](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 &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)](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-->
11 changes: 11 additions & 0 deletions docs/changelog/index.md
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-->" %}
Loading