npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arnelirobles/django-rnx

v1.0.0

Published

Django integration for rnxJS - Add reactive components to your Django templates

Downloads

112

Readme

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': '[email protected]',
            '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='[email protected]' 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