Skip to main content

Django template tags for rnxJS reactive components

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_rnx-1.0.0.tar.gz (12.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_rnx-1.0.0-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

File details

Details for the file django_rnx-1.0.0.tar.gz.

File metadata

  • Download URL: django_rnx-1.0.0.tar.gz
  • Upload date:
  • Size: 12.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for django_rnx-1.0.0.tar.gz
Algorithm Hash digest
SHA256 cd023fa8a101236d2e6e62085400dca1c48bec25c90c9bf21d6649d436cfc1c8
MD5 2cdf3a99f00733765eb83bed913182d4
BLAKE2b-256 ee11e954b53d559315a756885b8b05db95c70d281a4ec1d9e9865d64a643c245

See more details on using hashes here.

File details

Details for the file django_rnx-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: django_rnx-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for django_rnx-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e65856c21b43781b41e7074a2e8787572b6d86e9374405a8462540f15e615237
MD5 ff66d58df6ed2066960433be95096f05
BLAKE2b-256 a120139d88134943f5f7287262a37dc74fa028917f8633eb11a24b659867d287

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page