Django template tags for rnxJS reactive components
Project description
django-rnx
Django template tags and utilities for integrating rnxJS reactive components into Django applications.
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 filestheme(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 resourcestheme(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 statevar_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 instancefields(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
- Documentation: rnxJS Documentation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd023fa8a101236d2e6e62085400dca1c48bec25c90c9bf21d6649d436cfc1c8
|
|
| MD5 |
2cdf3a99f00733765eb83bed913182d4
|
|
| BLAKE2b-256 |
ee11e954b53d559315a756885b8b05db95c70d281a4ec1d9e9865d64a643c245
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e65856c21b43781b41e7074a2e8787572b6d86e9374405a8462540f15e615237
|
|
| MD5 |
ff66d58df6ed2066960433be95096f05
|
|
| BLAKE2b-256 |
a120139d88134943f5f7287262a37dc74fa028917f8633eb11a24b659867d287
|