This django library allows you to add React (16+) components into your django templates.
- Requirements
- Installation
- Quick Setup
- Usage
- Settings
- Examples
- Example Application
- Working With Models
- Server Side Rendering
- FAQ
- Tests
- Contributing
- License
- Python 2.7 / Python 3.4+ / PyPy
- Django 1.11+
Install the library with pip:
$ pip install django_react_templatetags
Make sure django_react_templatetags is added to your INSTALLED_APPS.
INSTALLED_APPS = (
# ...
'django_react_templatetags',
)You also need to add the react_context_processor into the context_middleware:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'templates...',
],
'APP_DIRS': True,
'OPTIONS': {
'debug': True,
'context_processors': [
...
'django_react_templatetags.context_processors.react_context_processor',
],
},
},
]This should be enough to get started.
- Load the
{% load react %} - Insert the component anywhere in your template:
{% react_render component="Component" props=my_data %}. This will create a dom placeholder. - Put
{% react_print %}in the end of your template. (This will outputReactDOM.render()/ReactDOM.hydrate()javascript). - Make sure
ReactandReactDOMare included and thatReactDOMare exposed globally in js (exwindow.ReactDOM = ReactDOM)
REACT_COMPONENT_PREFIX: Adds a prefix to your React.createElement include, if you want to retrive your components from somewhere else then the global scope. (Default is"").- Example using (
REACT_COMPONENT_PREFIX="Cookie.") will look for components in a global scope object namedCookie. - ...Becomes:
React.createElement(Cookie.MenuComponent, {})
- Example using (
REACT_RENDER_TAG_MANAGER: This is a advanced setting that lets you replace our tag parsing rules (ReactTagManager) with your own. (Default is"")- Example:
"myapp.manager.MyReactTagManager"
- Example:
REACT_RENDER_HOST: Which endpoint SSR requests should be posted at. (Default is"")- Example:
http://localhost:7000/render-component/ - The render host is a web service that accepts a post request and and renders the component to HTML. (This is what our Hastur service does)
- Example:
REACT_RENDER_TIMEOUT: Timeout for SSR requests, in seconds. (Default is20)REACT_RENDER_HEADERS: Override the default request headers sent to the SSR service. Default:{'Content-type': 'application/json', 'Accept': 'text/plain'}.- Example:
REACT_RENDER_HEADERS = {'Authorization': 'Basic 123'}
- Example:
This view...
from django.shortcuts import render
def menu_view(request):
return render(request, 'myapp/index.html', {
'menu_data': {
'example': 1,
},
})... and this template:
{% load react %}
<html>
<head>...</head>
<body>
<nav>
{% react_render component="Menu" props=menu_data %}
</nav>
</body>
{% react_print %}
</html>Will transform into this:
<html>
<head>...</head>
<body>
<nav>
<div id="Menu_405190d92bbc4d00b9e3376522982728"></div>
</nav>
</body>
<script>
ReactDOM.render(
React.createElement(Menu, {"example": 1}),
document.getElementById('Menu_405190d92bbc4d00b9e3376522982728')
);
</script>
</html>You can also have multiple components in the same template
This view...
from django.shortcuts import render
def menu_view(request):
return render(request, 'myapp/index.html', {
'menu_data': {
'example': 1,
},
'title_data': 'My title',
'footer_data': {
'credits': 'Copyright Company X'
}
})... and this template:
{% load react %}
<html>
<head>...</head>
<body>
<nav>
{% react_render component="Menu" props=menu_data %}
{% react_render component="Title" prop_title=title %}
{% react_render component="Footer" props=footer_data %}
</nav>
</body>
{% react_print %}
</html>Will transform into this:
<html>
<head>...</head>
<body>
<nav>
<div id="Menu_405190d92bbc4d00b9e3376522982728"></div>
</nav>
<main>
<div id="Title_405190d92bbc4d00b9e3376522982728"></div>
</main>
<footer>
<div id="Footer_405190d92bbc4d00b9e3376522982728"></div>
</footer>
</body>
<script>
ReactDOM.render(
React.createElement(Menu, {"example": 1}),
document.getElementById('Menu_405190d92bbc4d00b9e3376522982728')
);
ReactDOM.render(
React.createElement(Title, {"title": "My title"}),
document.getElementById('Title_405190d92bbc4d00b9e3376522982728')
);
ReactDOM.render(
React.createElement(Footer, {"credits": "Copyright Company X"}),
document.getElementById('Footer_405190d92bbc4d00b9e3376522982728')
);
</script>
</html>Here is an example application of a fully React-rendered Django application with react-sass-starterkit. This was an example app for a Django-meetup talk, you might find the slides on Slideshare helpful.
In this example, by adding RepresentationMixin as a mixin to the model, the templatetag will know how to generate the component data. You only need to pass the model instance to the react_render templatetag.
This model...
from django.db import models
from django_react_templatetags.mixins import RepresentationMixin
class Person(RepresentationMixin, models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
def to_react_representation(self, context={}):
return {
'first_name': self.first_name,
'last_name': self.last_name,
}...and this view
import myapp.models import Person
def person_view(request, pk):
return render(request, 'myapp/index.html', {
'menu_data': {
'person': Person.objects.get(pk=pk),
},
})...and this template:
{% load react %}
<html>
<head>...</head>
<body>
<nav>
{% react_render component="Menu" props=menu_data %}
</nav>
</body>
{% react_print %}
</html>...will transform into this:
...
<script>
ReactDOM.render(
React.createElement(Menu, {"first_name": "Tom", "last_name": "Waits"}),
document.getElementById('Menu_405190d92bbc4d00b9e3376522982728')
);
</script>This library supports SSR (Server Side Rendering) throught third-part library Hastur.
It works by posting component name and props to endpoint, that returns the html rendition. Payload example:
{
"componentName": "MyComponent",
"props": {
"title": "my props title",
"anyProp": "another prop"
},
"static": false
}REACT_RENDER_HOST needs to be defined to enable communication with service.
Simple! Just override the template react_print.html
This library only covers the template parts (that is: placeholder and js render).
Sure! Just add the param identifier="yourid" in react_render.
Example:
{% react_render component="Component" identifier="yourid" %}
...will print
<div id="yourid"></div>Add your props as arguments prefixed with prop_* to your {% react_render ... %}.
Example:
{% react_render component="Component" prop_country="Sweden" prop_city="Stockholm" %}...will give the component this payload:
React.createElement(Component, {"country": "Sweden", "city": "Stockholm"}),Add class="yourclassname" to your {% react_render ... %}.
Example:
{% react_render component="Component" class="yourclassname" %}...will print
<div id="Component_405190d92bbc4d00b9e3376522982728" class="yourclassname"></div>Yes! Just remove the string declaration and reference a variable in your {% react_render ... %}, the same way you do with props.
Example:
This view
render(request, 'myapp/index.html', {
'component_name': 'MegaMenu',
})...and this template
{% react_render component=component_name %}...will print:
<div id="Component_405190d92bbc4d00b9e3376522982728" class="yourclassname"></div>
React.createElement(MegaMenu),This library include tests, just run python runtests.py
You can also run separate test cases: runtests.py tests.test_filters.ReactIncludeComponentTest
Want to contribute? Awesome. Just send a pull request.
Django-React-Templatetags is released under the MIT License.