Skip to main content

django-rnx

Django template tags and utilities for integrating rnxJS reactive components into Django applications.

License: MPL-2.0 Python Version

Overview

django-rnx provides a collection of Django template tags that make it easy to:

  • Include rnxJS library and stylesheets in your templates
  • Create reactive state from Django context variables
  • Render rnxJS components with Django template variables
  • Initialize rnxJS plugins (router, toast, storage)
  • Render Django forms as rnxJS components
  • Bind Django context data to reactive components

Installation

From PyPI (Coming Soon)

pip install django-rnx

Development Installation

git clone https://github.com/BaryoDev/rnxjs.git
cd rnxjs/packages/django-rnx
pip install -e .

Quick Start

1. Add to Django Apps

Add django_rnx to your Django INSTALLED_APPS:

# settings.py
INSTALLED_APPS = [
    'django.contrib.contenttypes',
    'django.contrib.auth',
    'django_rnx',  # Add this line
    'your_app',
]

2. Load Template Tags

In your Django templates, load the rnx template tags:

{% load rnx %}

3. Include rnxJS Scripts

Include the rnxJS library and Bootstrap CSS in your base template:

{% rnx_scripts cdn=True theme='bootstrap' %}

Options:

  • cdn (bool, default: True) - Use CDN links instead of local files
  • theme (str, default: 'bootstrap') - Theme to include: 'bootstrap', 'm3', 'plugins', or None

4. Create Reactive State

Pass Django context variables to rnxJS as reactive state:

{% rnx_state user_data 'state' %}

<p>Welcome, <span data-bind="state.name"></span>!</p>

Template Tags Reference

rnx_scripts

Include rnxJS library and stylesheets.

Syntax:

{% rnx_scripts [cdn=True] [theme='bootstrap'] %}

Parameters:

  • cdn (bool, optional, default: True) - Use CDN for resources
  • theme (str, optional, default: 'bootstrap') - Theme variant: 'bootstrap', 'm3', 'plugins', or None

Example:

{% rnx_scripts cdn=True theme='m3' %}

rnx_state

Create reactive state from Django context data.

Syntax:

{% rnx_state data [var_name='state'] %}

Parameters:

  • data - Django context variable to convert to reactive state
  • var_name (str, optional, default: 'state') - Name of the global state variable

Example:

{% rnx_state user_data 'appState' %}

<!-- Access reactive state in HTML -->
<span data-bind="appState.name"></span>
<span data-bind="appState.email"></span>

View Example:

def profile(request):
    context = {
        'user_data': {
            'name': 'John Doe',
            'email': 'john@example.com',
            'profile': {
                'bio': 'Software Developer',
                'location': 'USA'
            }
        }
    }
    return render(request, 'profile.html', context)

rnx_component

Render rnxJS components with props.

Syntax:

{% rnx_component 'ComponentName' [prop1=value1] [prop2=value2] ... %}

Parameters:

  • Component name (string)
  • Arbitrary keyword arguments converted to component props
  • Snake_case props automatically converted to kebab-case

Features:

  • Automatic string escaping for security
  • Support for data binding expressions (state.*)
  • Boolean attributes without values
  • Numeric attribute values without quotes

Examples:

<!-- Button component -->
{% rnx_component 'Button' variant='primary' label='Save' %}

<!-- Input with binding -->
{% rnx_component 'Input' type='email' placeholder='user@example.com' data_bind='state.email' %}

<!-- DataTable with reactive data -->
{% rnx_component 'DataTable' data='state.users' columns='state.columns' sortable=true pageable=true %}

<!-- Nested props with snake_case to kebab-case conversion -->
{% rnx_component 'Card' title='User Profile' show_footer=true %}

rnx_plugin

Initialize rnxJS plugins.

Syntax:

{% rnx_plugin 'plugin_name' [option1=value1] [option2=value2] ... %}

Parameters:

  • Plugin name: 'router', 'toast', or 'storage'
  • Plugin-specific configuration options

Available Plugins:

Router Plugin

Navigate between pages with hash-based routing.

{% rnx_plugin 'router' mode='hash' default_route='/' routes=routes %}

<!-- Route-specific content visibility -->
<div data-route="/">Home Page</div>
<div data-route="/users">Users Page</div>

Toast Plugin

Display notifications.

{% rnx_plugin 'toast' position='top-right' duration=3000 max_toasts=5 %}

<script>
    window.rnx.toast.success('Operation completed!');
    window.rnx.toast.error('An error occurred');
    window.rnx.toast.warning('Warning message');
    window.rnx.toast.info('Information');
</script>

Storage Plugin

Persist state to localStorage/sessionStorage.

{% rnx_plugin 'storage' prefix='myapp_' storage='localStorage' %}

<script>
    // Persist state
    window.rnx.storage.persist(state, 'user_prefs', ['theme', 'language']);

    // Retrieve
    const theme = window.rnx.storage.get('user_prefs_theme');
</script>

rnx_form

Render a Django form using rnxJS components.

Syntax:

{% rnx_form form [fields='field1,field2'] %}

Parameters:

  • form - Django form instance
  • fields (str, optional) - Comma-separated list of field names to render

Example:

{% load rnx %}

<form method="post">
    {% csrf_token %}
    {% rnx_form form %}
    <button type="submit">Save</button>
</form>

<!-- Or render specific fields -->
{% rnx_form form fields='name,email,message' %}

Filters

to_data_bind

Convert a key to rnxJS data-bind attribute format.

Syntax:

{{ key|to_data_bind }}

Example:

{{ 'user.profile.name'|to_data_bind }}
<!-- Output: data-bind="user.profile.name" -->

to_data_rule

Convert validation rules to rnxJS data-rule attribute format.

Syntax:

{{ rules|to_data_rule }}

Example:

{{ 'required|email|maxlength:100'|to_data_rule }}
<!-- Output: data-rule="required|email|maxlength:100" -->

Complete Example

views.py

from django.shortcuts import render
from django import forms


class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)


def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # Process form...
            return render(request, 'contact_success.html')
    else:
        form = ContactForm()

    context = {
        'form': form,
        'app_state': {
            'page_title': 'Contact Us',
            'notification': 'Questions? We\'d love to hear from you!',
            'routes': {
                '/': 'Home',
                '/contact': 'Contact',
                '/about': 'About',
            }
        }
    }
    return render(request, 'contact.html', context)

contact.html

{% extends "base.html" %}
{% load rnx %}

{% block content %}
    {% rnx_state app_state 'appState' %}
    {% rnx_plugin 'toast' position='top-right' %}

    <h1 data-bind="appState.page_title"></h1>
    <p data-bind="appState.notification"></p>

    <form method="post">
        {% csrf_token %}
        {% rnx_form form %}
        {% rnx_component 'Button' type='submit' variant='primary' label='Send Message' %}
    </form>

    <script>
        document.querySelector('form').addEventListener('submit', function(e) {
            window.rnx.toast.success('Thank you! Your message has been sent.');
        });
    </script>
{% endblock %}

base.html

{% load rnx %}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Site</title>
    {% rnx_scripts cdn=True theme='bootstrap' %}
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

Running the Example App

A complete example Django application is included:

cd example_app
pip install django

# Run migrations (if any)
python manage.py migrate

# Start development server
python manage.py runserver

# Visit http://localhost:8000

The example demonstrates:

  • Reactive state binding
  • Component rendering
  • Form integration
  • Plugin usage (router, toast, storage)
  • Data tables and lists
  • Event handling

Security Considerations

HTML Escaping

All component props and text content are automatically HTML-escaped to prevent XSS attacks:

<!-- Safe: Will escape < > & quotes -->
{% rnx_component 'Button' label=user_input %}

Data Binding Expressions

String values starting with state., {, or [ are preserved without escaping for data binding:

<!-- Treated as data binding expression -->
{% rnx_component 'Div' data_content='state.userMessage' %}

<!-- Regular string, will be escaped -->
{% rnx_component 'Div' title='Hello World' %}

Template Tags

All template tags use Django's mark_safe() only after proper escaping and validation.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

MPL-2.0 - See LICENSE for details.

Support

Changelog

1.0.0 (2024)

  • Initial release
  • Django template tags: rnx_scripts, rnx_state, rnx_component, rnx_plugin, rnx_form
  • Filters: to_data_bind, to_data_rule
  • Bootstrap 5.3+ support
  • Plugin integration (router, toast, storage)
  • Example Django application
  • Full test coverage

Metadata

Release files for django-rnx 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-rnx 1.0.0
File Size Uploaded Provenance Actions
django_rnx-1.0.0.tar.gz 12.0 kB Without provenance Details for django_rnx-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for django-rnx 1.0.0
File Interpreter ABI Platform Actions
django_rnx-1.0.0-py3-none-any.whl Python 3 none any Details for django_rnx-1.0.0-py3-none-any.whl

Total release size: 20.3 kB

Release files / django_rnx-1.0.0.tar.gz

Download URL django_rnx-1.0.0.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
cd023fa8a101236d2e6e62085400dca1c48bec25c90c9bf21d6649d436cfc1c8
BLAKE2b-256 checksum
How to use checksums
ee11e954b53d559315a756885b8b05db95c70d281a4ec1d9e9865d64a643c245
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / django_rnx-1.0.0-py3-none-any.whl

Download URL django_rnx-1.0.0-py3-none-any.whl
Size 8.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e65856c21b43781b41e7074a2e8787572b6d86e9374405a8462540f15e615237
BLAKE2b-256 checksum
How to use checksums
a120139d88134943f5f7287262a37dc74fa028917f8633eb11a24b659867d287
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Security for django-rnx 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page