Skip to content

Support ReactPy Router v1.0.0 #252

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 9 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 16 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,21 @@ Don't forget to remove deprecated code on each major release!

## [Unreleased]

- Nothing (yet)!
### Changed

- Now using ReactPy-Router v1 for URL routing, which comes with a slightly different API than before.
- Removed dependency on `aiofile`.

### Removed

- Removed the following **deprecated** features:
- The `compatibility` argument on `reactpy_django.components.view_to_component`
- `reactpy_django.components.view_to_component` **usage as a decorator**
- `reactpy_django.decorators.auth_required`
- `reactpy_django.REACTPY_WEBSOCKET_PATH`
- `settings.py:REACTPY_WEBSOCKET_URL`

## [4.0.0]
## [4.0.0] - 2024-06-22

### Added

Expand Down Expand Up @@ -112,8 +124,8 @@ Don't forget to remove deprecated code on each major release!
- New Django `User` related features!
- `reactpy_django.hooks.use_user` can be used to access the current user.
- `reactpy_django.hooks.use_user_data` provides a simplified interface for storing user key-value data.
- `reactpy_django.decorators.user_passes_test` is inspired by the [equivalent Django decorator](http://docs.djangoproject.com/en/dev/topics/auth/default/#django.contrib.auth.decorators.user_passes_test), but ours works with ReactPy components.
- `settings.py:REACTPY_AUTO_RELOGIN` will cause component WebSocket connections to automatically [re-login](https://channels.readthedocs.io/en/latest/topics/authentication.html#how-to-log-a-user-in-out) users that are already authenticated. This is useful to continuously update `last_login` timestamps and refresh the [Django login session](https://docs.djangoproject.com/en/dev/topics/http/sessions/).
- `reactpy_django.decorators.user_passes_test` is inspired by the [equivalent Django decorator](http://docs.djangoproject.com/en/stable/topics/auth/default/#django.contrib.auth.decorators.user_passes_test), but ours works with ReactPy components.
- `settings.py:REACTPY_AUTO_RELOGIN` will cause component WebSocket connections to automatically [re-login](https://channels.readthedocs.io/en/latest/topics/authentication.html#how-to-log-a-user-in-out) users that are already authenticated. This is useful to continuously update `last_login` timestamps and refresh the [Django login session](https://docs.djangoproject.com/en/stable/topics/http/sessions/).

### Changed

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def hello_world(recipient: str):

<!--py-code-end-->

## [`my_app/templates/my_template.html`](https://docs.djangoproject.com/en/dev/topics/templates/)
## [`my_app/templates/my_template.html`](https://docs.djangoproject.com/en/stable/topics/templates/)

<!--html-header-start-->

Expand Down
2 changes: 0 additions & 2 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ plugins:
- spellcheck:
known_words: dictionary.txt
allow_unicode: no
ignore_code: yes
# - section-index

extra:
generator: false
Expand Down
64 changes: 33 additions & 31 deletions docs/src/dictionary.txt
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
asgi
async
backend
backends
backhaul
broadcasted
changelog
django
sanic
plotly
frontend
frontends
hello_world
html
iframe
jupyter
keyworded
middleware
misconfiguration
misconfigurations
my_template
nox
WebSocket
WebSockets
changelog
async
plotly
postfixed
postprocessing
postprocessor
pre
prefetch
prefetching
preloader
whitespace
preprocessor
py
pyodide
pyscript
reactpy
refetch
refetched
refetching
html
jupyter
iframe
keyworded
sanic
serializable
stylesheet
stylesheets
unstyled
py
reactpy
asgi
postfixed
postprocessing
serializable
postprocessor
preprocessor
middleware
backends
backend
frontend
frontends
misconfiguration
misconfigurations
backhaul
sublicense
broadcasted
hello_world
my_template
unstyled
WebSocket
WebSockets
whitespace
16 changes: 8 additions & 8 deletions docs/src/learn/add-reactpy-to-a-django-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ If you want to add some interactivity to your existing **Django project**, you d

!!! abstract "Note"

These docs assumes you have already created [a **Django project**](https://docs.djangoproject.com/en/dev/intro/tutorial01/), which involves creating and installing at least one **Django app**.
These docs assumes you have already created [a **Django project**](https://docs.djangoproject.com/en/stable/intro/tutorial01/), which involves creating and installing at least one **Django app**.

If do not have a **Django project**, check out this [9 minute YouTube tutorial](https://www.youtube.com/watch?v=ZsJRXS_vrw0) created by _IDG TECHtalk_.

Expand All @@ -24,7 +24,7 @@ pip install reactpy-django

## Step 2: Configure `settings.py`

Add `#!python "reactpy_django"` to [`INSTALLED_APPS`](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-INSTALLED_APPS) in your [`settings.py`](https://docs.djangoproject.com/en/dev/topics/settings/) file.
Add `#!python "reactpy_django"` to [`INSTALLED_APPS`](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-INSTALLED_APPS) in your [`settings.py`](https://docs.djangoproject.com/en/stable/topics/settings/) file.

=== "settings.py"

Expand All @@ -36,7 +36,7 @@ Add `#!python "reactpy_django"` to [`INSTALLED_APPS`](https://docs.djangoproject

ReactPy-Django requires Django ASGI and [Django Channels](https://github.com/django/channels) WebSockets.

If you have not enabled ASGI on your **Django project** yet, here is a summary of the [`django`](https://docs.djangoproject.com/en/dev/howto/deployment/asgi/) and [`channels`](https://channels.readthedocs.io/en/stable/installation.html) installation docs:
If you have not enabled ASGI on your **Django project** yet, here is a summary of the [`django`](https://docs.djangoproject.com/en/stable/howto/deployment/asgi/) and [`channels`](https://channels.readthedocs.io/en/stable/installation.html) installation docs:

1. Install `channels[daphne]`
2. Add `#!python "daphne"` to `#!python INSTALLED_APPS`.
Expand All @@ -59,7 +59,7 @@ Add `#!python "reactpy_django"` to [`INSTALLED_APPS`](https://docs.djangoproject

## Step 3: Configure `urls.py`

Add ReactPy HTTP paths to your `#!python urlpatterns` in your [`urls.py`](https://docs.djangoproject.com/en/dev/topics/http/urls/) file.
Add ReactPy HTTP paths to your `#!python urlpatterns` in your [`urls.py`](https://docs.djangoproject.com/en/stable/topics/http/urls/) file.

=== "urls.py"

Expand All @@ -69,7 +69,7 @@ Add ReactPy HTTP paths to your `#!python urlpatterns` in your [`urls.py`](https:

## Step 4: Configure `asgi.py`

Register ReactPy's WebSocket using `#!python REACTPY_WEBSOCKET_ROUTE` in your [`asgi.py`](https://docs.djangoproject.com/en/dev/howto/deployment/asgi/) file.
Register ReactPy's WebSocket using `#!python REACTPY_WEBSOCKET_ROUTE` in your [`asgi.py`](https://docs.djangoproject.com/en/stable/howto/deployment/asgi/) file.

=== "asgi.py"

Expand Down Expand Up @@ -97,23 +97,23 @@ Register ReactPy's WebSocket using `#!python REACTPY_WEBSOCKET_ROUTE` in your [`

## Step 5: Run database migrations

Run Django's [`migrate` command](https://docs.djangoproject.com/en/dev/topics/migrations/) to initialize ReactPy-Django's database table.
Run Django's [`migrate` command](https://docs.djangoproject.com/en/stable/topics/migrations/) to initialize ReactPy-Django's database table.

```bash linenums="0"
python manage.py migrate
```

## Step 6: Check your configuration

Run Django's [`check` command](https://docs.djangoproject.com/en/dev/ref/django-admin/#check) to verify if ReactPy was set up correctly.
Run Django's [`check` command](https://docs.djangoproject.com/en/stable/ref/django-admin/#check) to verify if ReactPy was set up correctly.

```bash linenums="0"
python manage.py check
```

## Step 7: Create your first component

The [next step](./your-first-component.md) will show you how to create your first ReactPy component.
The [next page](./your-first-component.md) will show you how to create your first ReactPy component.

Prefer a quick summary? Read the **At a Glance** section below.

Expand Down
22 changes: 14 additions & 8 deletions docs/src/learn/your-first-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ You will now need to pick at least one **Django app** to start using ReactPy-Dja

For the following examples, we will assume the following:

1. You have a **Django app** named `my_app`, which was created by Django's [`startapp` command](https://docs.djangoproject.com/en/dev/intro/tutorial01/#creating-the-polls-app).
1. You have a **Django app** named `my_app`, which was created by Django's [`startapp` command](https://docs.djangoproject.com/en/stable/intro/tutorial01/#creating-the-polls-app).
2. You have placed `my_app` directly into your **Django project** folder (`./example_project/my_app`). This is common for small projects.

??? question "How do I organize my Django project for ReactPy?"
Expand All @@ -31,7 +31,7 @@ You will need a file to start creating ReactPy components.

We recommend creating a `components.py` file within your chosen **Django app** to start out. For this example, the file path will look like this: `./example_project/my_app/components.py`.

Within this file, you can define your component functions using ReactPy's `#!python @component` decorator.
Within this file, you will define your component function(s) using the `#!python @component` decorator.

=== "components.py"

Expand All @@ -43,7 +43,7 @@ Within this file, you can define your component functions using ReactPy's `#!pyt

We recommend creating a `components.py` for small **Django apps**. If your app has a lot of components, you should consider breaking them apart into individual modules such as `components/navbar.py`.

Ultimately, components are referenced by Python dotted path in `my_template.html` ([_see next step_](#embedding-in-a-template)). This path must be valid to Python's `#!python importlib`.
Ultimately, components are referenced by Python dotted path in `my_template.html` ([_see next step_](#embedding-in-a-template)). This dotted path must be valid to Python's `#!python importlib`.

??? question "What does the decorator actually do?"

Expand All @@ -66,25 +66,31 @@ Additionally, you can pass in `#!python args` and `#!python kwargs` into your co

{% include-markdown "../../../README.md" start="<!--html-code-start-->" end="<!--html-code-end-->" %}

???+ tip "Components are automatically registered!"

ReactPy-Django will automatically register any component that is referenced in a Django HTML template. This means you [typically](../reference/utils.md#register-component) do not need to manually register components in your **Django app**.

Please note that this HTML template must be properly stored within a registered Django app. ReactPy-Django will output a console log message containing all detected components when the server starts up.

{% include-markdown "../reference/template-tag.md" start="<!--context-start-->" end="<!--context-end-->" %}

{% include-markdown "../reference/template-tag.md" start="<!--multiple-components-start-->" end="<!--multiple-components-end-->" %}

??? question "Where is my templates folder?"

If you do not have a `./templates/` folder in your **Django app**, you can simply create one! Keep in mind, templates within this folder will not be detected by Django unless you [add the corresponding **Django app** to `settings.py:INSTALLED_APPS`](https://docs.djangoproject.com/en/dev/ref/applications/#configuring-applications).
If you do not have a `./templates/` folder in your **Django app**, you can simply create one! Keep in mind, templates within this folder will not be detected by Django unless you [add the corresponding **Django app** to `settings.py:INSTALLED_APPS`](https://docs.djangoproject.com/en/stable/ref/applications/#configuring-applications).

## Setting up a Django view

Within your **Django app**'s `views.py` file, you will need to [create a view function](https://docs.djangoproject.com/en/dev/intro/tutorial01/#write-your-first-view) to render the HTML template `my_template.html` ([_from the previous step_](#embedding-in-a-template)).
Within your **Django app**'s `views.py` file, you will need to [create a view function](https://docs.djangoproject.com/en/stable/intro/tutorial01/#write-your-first-view) to render the HTML template `my_template.html` ([_from the previous step_](#embedding-in-a-template)).

=== "views.py"

```python
{% include "../../examples/python/example/views.py" %}
```

We will add this new view into your [`urls.py`](https://docs.djangoproject.com/en/dev/intro/tutorial01/#write-your-first-view) and define what URL it should be accessible at.
We will add this new view into your [`urls.py`](https://docs.djangoproject.com/en/stable/intro/tutorial01/#write-your-first-view) and define what URL it should be accessible at.

=== "urls.py"

Expand All @@ -98,7 +104,7 @@ We will add this new view into your [`urls.py`](https://docs.djangoproject.com/e

Once you reach that point, we recommend creating an individual `urls.py` within each of your **Django apps**.

Then, within your **Django project's** `urls.py` you will use Django's [`include` function](https://docs.djangoproject.com/en/dev/ref/urls/#include) to link it all together.
Then, within your **Django project's** `urls.py` you will use Django's [`include` function](https://docs.djangoproject.com/en/stable/ref/urls/#include) to link it all together.

## Viewing your component

Expand All @@ -114,7 +120,7 @@ If you copy-pasted our example component, you will now see your component displa

??? warning "Do not use `manage.py runserver` for production"

This command is only intended for development purposes. For production deployments make sure to read [Django's documentation](https://docs.djangoproject.com/en/dev/howto/deployment/).
This command is only intended for development purposes. For production deployments make sure to read [Django's documentation](https://docs.djangoproject.com/en/stable/howto/deployment/).

## Learn more

Expand Down
12 changes: 6 additions & 6 deletions docs/src/reference/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Automatically convert a Django view into a component.

At this time, this works best with static views with no interactivity.

Compatible with sync or async [Function Based Views](https://docs.djangoproject.com/en/dev/topics/http/views/) and [Class Based Views](https://docs.djangoproject.com/en/dev/topics/class-based-views/).
Compatible with sync or async [Function Based Views](https://docs.djangoproject.com/en/stable/topics/http/views/) and [Class Based Views](https://docs.djangoproject.com/en/stable/topics/class-based-views/).

=== "components.py"

Expand Down Expand Up @@ -254,7 +254,7 @@ Automatically convert a Django view into an [`iframe` element](https://www.techt

The contents of this `#!python iframe` is handled entirely by traditional Django view rendering. While this solution is compatible with more views than `#!python view_to_component`, it comes with different limitations.

Compatible with sync or async [Function Based Views](https://docs.djangoproject.com/en/dev/topics/http/views/) and [Class Based Views](https://docs.djangoproject.com/en/dev/topics/class-based-views/).
Compatible with sync or async [Function Based Views](https://docs.djangoproject.com/en/stable/topics/http/views/) and [Class Based Views](https://docs.djangoproject.com/en/stable/topics/class-based-views/).

=== "components.py"

Expand Down Expand Up @@ -383,7 +383,7 @@ Compatible with sync or async [Function Based Views](https://docs.djangoproject.

## Django CSS

Allows you to defer loading a CSS stylesheet until a component begins rendering. This stylesheet must be stored within [Django's static files](https://docs.djangoproject.com/en/dev/howto/static-files/).
Allows you to defer loading a CSS stylesheet until a component begins rendering. This stylesheet must be stored within [Django's static files](https://docs.djangoproject.com/en/stable/howto/static-files/).

=== "components.py"

Expand Down Expand Up @@ -436,11 +436,11 @@ Allows you to defer loading a CSS stylesheet until a component begins rendering.

## Django JS

Allows you to defer loading JavaScript until a component begins rendering. This JavaScript must be stored within [Django's static files](https://docs.djangoproject.com/en/dev/howto/static-files/).
Allows you to defer loading JavaScript until a component begins rendering. This JavaScript must be stored within [Django's static files](https://docs.djangoproject.com/en/stable/howto/static-files/).

<!--
TODO: This is no longer true since we don't insert elements on the page via JSON Patch anymore.
However, we may go back to diffing at some point in the future.
TODO: The following is no longer true since we don't insert elements on the page via JSON Patch anymore.
However, we may go back to diffing at some point in the future so this is kept here for now.

!!! warning "Pitfall"

Expand Down
2 changes: 1 addition & 1 deletion docs/src/reference/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Decorator functions can be used within your `components.py` to help simplify dev

You can limit component access to users that pass a test function by using this decorator.

This decorator is inspired by Django's [`user_passes_test`](http://docs.djangoproject.com/en/dev/topics/auth/default/#django.contrib.auth.decorators.user_passes_test) decorator, but this one works with ReactPy components.
This only works with ReactPy components, and is inspired by Django's [`user_passes_test`](http://docs.djangoproject.com/en/stable/topics/auth/default/#django.contrib.auth.decorators.user_passes_test) decorator.

=== "components.py"

Expand Down
Loading
Loading