diff --git a/CHANGELOG.md b/CHANGELOG.md index 9652b644..6680348a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 @@ -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 diff --git a/README.md b/README.md index 817e684b..d3d2a1a9 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ def hello_world(recipient: str): -## [`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/) diff --git a/docs/examples/html/pyscript-js-module.html b/docs/examples/html/pyscript-local-import.html similarity index 100% rename from docs/examples/html/pyscript-js-module.html rename to docs/examples/html/pyscript-local-import.html diff --git a/docs/examples/python/pyscript-js-execution.py b/docs/examples/python/pyodide-js-module.py similarity index 100% rename from docs/examples/python/pyscript-js-execution.py rename to docs/examples/python/pyodide-js-module.py diff --git a/docs/examples/python/pyscript-js-module.py b/docs/examples/python/pyscript-local-import.py similarity index 100% rename from docs/examples/python/pyscript-js-module.py rename to docs/examples/python/pyscript-local-import.py diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index e4159640..c1b5922f 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -89,8 +89,6 @@ plugins: - spellcheck: known_words: dictionary.txt allow_unicode: no - ignore_code: yes - # - section-index extra: generator: false diff --git a/docs/src/dictionary.txt b/docs/src/dictionary.txt index 66265e78..14aa7a61 100644 --- a/docs/src/dictionary.txt +++ b/docs/src/dictionary.txt @@ -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 diff --git a/docs/src/learn/add-reactpy-to-a-django-project.md b/docs/src/learn/add-reactpy-to-a-django-project.md index dd258737..0bf919e2 100644 --- a/docs/src/learn/add-reactpy-to-a-django-project.md +++ b/docs/src/learn/add-reactpy-to-a-django-project.md @@ -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_. @@ -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" @@ -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`. @@ -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" @@ -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" @@ -97,7 +97,7 @@ 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 @@ -105,7 +105,7 @@ 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 @@ -113,7 +113,7 @@ 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. diff --git a/docs/src/learn/your-first-component.md b/docs/src/learn/your-first-component.md index 08df6a57..85af4109 100644 --- a/docs/src/learn/your-first-component.md +++ b/docs/src/learn/your-first-component.md @@ -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?" @@ -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" @@ -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?" @@ -66,17 +66,23 @@ Additionally, you can pass in `#!python args` and `#!python kwargs` into your co {% include-markdown "../../../README.md" start="" 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="" end="" %} {% include-markdown "../reference/template-tag.md" start="" 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" @@ -84,7 +90,7 @@ Within your **Django app**'s `views.py` file, you will need to [create a view fu {% 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" @@ -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 @@ -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 diff --git a/docs/src/reference/components.md b/docs/src/reference/components.md index 1b7ae9b2..943b76c0 100644 --- a/docs/src/reference/components.md +++ b/docs/src/reference/components.md @@ -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" @@ -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" @@ -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" @@ -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/). - - You can use the `#!python prerender` argument in your [template tag](../reference/template-tag.md#component) to manually override this default. --- diff --git a/docs/src/reference/template-tag.md b/docs/src/reference/template-tag.md index 197a3b29..e5c60a79 100644 --- a/docs/src/reference/template-tag.md +++ b/docs/src/reference/template-tag.md @@ -78,7 +78,7 @@ Each component loaded via this template tag will receive a dedicated WebSocket c
{% component "example_project.my_app_2.components.goodbye_world" class="bold small-font" %}
- {% component "example_project.my_app_3.components.simple_button" %} + {% component "example_project.my_app_3.components.my_button" %}