Skip to content

Instantly share code, notes, and snippets.

@johnboiles
Created August 12, 2014 20:14
Show Gist options
  • Save johnboiles/059055a9e10d67a9bdfb to your computer and use it in GitHub Desktop.
Save johnboiles/059055a9e10d67a9bdfb to your computer and use it in GitHub Desktop.
Jinja2 version of Django Rest Framework's rest_framework/templates/base.html file
<!DOCTYPE html>
<html>
<head>
{% block head %}
{% block meta %}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="robots" content="NONE,NOARCHIVE" />
{% endblock %}
<title>{% block title %}Django REST framework{% endblock %}</title>
{% block style %}
{% block bootstrap_theme %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}rest_framework/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}rest_framework/css/bootstrap-tweaks.css"/>
{% endblock %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}rest_framework/css/prettify.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}rest_framework/css/default.css"/>
{% endblock %}
{% endblock %}
</head>
<body class="{% block bodyclass %}{% endblock %} container">
<div class="wrapper">
{% block navbar %}
<div class="navbar {% block bootstrap_navbar_variant %}navbar-inverse{% endblock %}">
<div class="navbar-inner">
<div class="container-fluid">
<span href="/">
{% block branding %}<a class='brand' rel="nofollow" href='http://www.django-rest-framework.org'>Django REST framework <span class="version">{{ version }}</span></a>{% endblock %}
</span>
<ul class="nav pull-right">
{% block userlinks %}
{#
{% if user.is_authenticated %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{ user }}
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>{% optional_logout request %}</li>
</ul>
</li>
{% else %}
<li>{% optional_login request %}</li>
{% endif %}
#}
{% endblock %}
</ul>
</div>
</div>
</div>
{% endblock %}
{% block breadcrumbs %}
<ul class="breadcrumb">
{% for breadcrumb_name, breadcrumb_url in breadcrumblist %}
<li>
<a href="{{ breadcrumb_url }}" {% if loop.last %}class="active"{% endif %}>{{ breadcrumb_name }}</a> {% if not loop.last %}<span class="divider">&rsaquo;</span>{% endif %}
</li>
{% endfor %}
</ul>
{% endblock %}
<!-- Content -->
<div id="content">
{% if 'GET' in allowed_methods %}
<form id="get-form" class="pull-right">
<fieldset>
<div class="btn-group format-selection">
<a class="btn btn-primary js-tooltip" href='{{ request.get_full_path() }}' rel="nofollow" title="Make a GET request on the {{ name }} resource">GET</a>
<button class="btn btn-primary dropdown-toggle js-tooltip" data-toggle="dropdown" title="Specify a format for the GET request">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{% for format in available_formats %}
<li>
<a class="js-tooltip format-option" href='{{ request|add_query_param(api_settings.URL_FORMAT_OVERRIDE, format) }}' rel="nofollow" title="Make a GET request on the {{ name }} resource with the format set to `{{ format }}`">{{ format }}</a>
</li>
{% endfor %}
</ul>
</div>
</fieldset>
</form>
{% endif %}
{% if options_form %}
<form class="button-form" action="{{ request.get_full_path() }}" method="POST" class="pull-right">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<input type="hidden" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="OPTIONS" />
<button class="btn btn-primary js-tooltip" title="Make an OPTIONS request on the {{ name }} resource">OPTIONS</button>
</form>
{% endif %}
{% if delete_form %}
<form class="button-form" action="{{ request.get_full_path() }}" method="POST" class="pull-right">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<input type="hidden" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="DELETE" />
<button class="btn btn-danger js-tooltip" title="Make a DELETE request on the {{ name }} resource">DELETE</button>
</form>
{% endif %}
<div class="content-main">
<div class="page-header"><h1>{{ name }}</h1></div>
{% block description %}
{{ description }}
{% endblock %}
<div class="request-info" style="clear: both" >
<pre class="prettyprint"><b>{{ request.method }}</b> {{ request.get_full_path() }}</pre>
</div>
<div class="response-info">
<pre class="prettyprint"><div class="meta nocode"><b>HTTP {{ response.status_code }} {{ response.status_text }}</b>{% autoescape False %}
{% for key, val in response_headers.items() %}<b>{{ key }}:</b> <span class="lit">{{ val|break_long_headers|urlize_quoted_links }}</span>
{% endfor %}
</div>{{ content|urlize_quoted_links }}</pre>{% endautoescape %}
</div>
</div>
{% if display_edit_forms %}
{% if post_form or raw_data_post_form %}
<div {% if post_form %}class="tabbable"{% endif %}>
{% if post_form %}
<ul class="nav nav-tabs form-switcher">
<li><a name='html-tab' href="#object-form" data-toggle="tab">HTML form</a></li>
<li><a name='raw-tab' href="#generic-content-form" data-toggle="tab">Raw data</a></li>
</ul>
{% endif %}
<div class="well tab-content">
{% if post_form %}
<div class="tab-pane" id="object-form">
{% set form=post_form %}
<form action="{{ request.get_full_path() }}" method="POST" enctype="multipart/form-data" class="form-horizontal">
<fieldset>
{{ post_form }}
<div class="form-actions">
<button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
</div>
</fieldset>
</form>
</div>
{% endif %}
<div {% if post_form %}class="tab-pane"{% endif %} id="generic-content-form">
{% set form=raw_data_post_form %}
<form action="{{ request.get_full_path() }}" method="POST" class="form-horizontal">
<fieldset>
{% include "rest_framework/raw_data_form.html" %}
<div class="form-actions">
<button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
</div>
</fieldset>
</form>
</div>
</div>
</div>
{% endif %}
{% if put_form or raw_data_put_form or raw_data_patch_form %}
<div {% if put_form %}class="tabbable"{% endif %}>
{% if put_form %}
<ul class="nav nav-tabs form-switcher">
<li><a name='html-tab' href="#object-form" data-toggle="tab">HTML form</a></li>
<li><a name='raw-tab' href="#generic-content-form" data-toggle="tab">Raw data</a></li>
</ul>
{% endif %}
<div class="well tab-content">
{% if put_form %}
<div class="tab-pane" id="object-form">
<form action="{{ request.get_full_path() }}" method="POST" enctype="multipart/form-data" class="form-horizontal">
<fieldset>
{{ put_form }}
<div class="form-actions">
<button class="btn btn-primary js-tooltip" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PUT" title="Make a PUT request on the {{ name }} resource">PUT</button>
</div>
</fieldset>
</form>
</div>
{% endif %}
<div {% if put_form %}class="tab-pane"{% endif %} id="generic-content-form">
{% set form=raw_data_put_or_patch_form %}
<form action="{{ request.get_full_path() }}" method="POST" class="form-horizontal">
<fieldset>
{% include "rest_framework/raw_data_form.html" %}
<div class="form-actions">
{% if raw_data_put_form %}
<button class="btn btn-primary js-tooltip" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PUT" title="Make a PUT request on the {{ name }} resource">PUT</button>
{% endif %}
{% if raw_data_patch_form %}
<button class="btn btn-primary js-tooltip" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PATCH" title="Make a PATCH request on the {{ name }} resource">PATCH</button>
{% endif %}
</div>
</fieldset>
</form>
</div>
</div>
</div>
{% endif %}
{% endif %}
</div>
<!-- END content-main -->
</div>
<!-- END Content -->
<div id="push"></div>
</div>
</div><!-- ./wrapper -->
{% block footer %}
{% endblock %}
{% block script %}
<script src="{{ STATIC_URL }}/rest_framework/js/jquery-1.8.1-min.js"></script>
<script src="{{ STATIC_URL }}/rest_framework/js/bootstrap.min.js"></script>
<script src="{{ STATIC_URL }}/rest_framework/js/prettify-min.js"></script>
<script src="{{ STATIC_URL }}/rest_framework/js/default.js"></script>
{% endblock %}
</body>
</html>
# You need to also add a few filters to your Jinja2 environment to support this template
from jinja2 import FileSystemLoader, Environment, Markup
from rest_framework.templatetags.rest_framework import urlize_quoted_links, break_long_headers, iri_to_uri, replace_query_param
from django.conf import settings
template_dirs = getattr(settings, 'TEMPLATE_DIRS')
default_content_type = getattr(settings, 'DEFAULT_CONTENT_TYPE')
env = Environment(loader=FileSystemLoader(template_dirs), extensions=['jinja2.ext.autoescape'])
env.globals['STATIC_URL'] = settings.STATIC_URL
env.filters['urlize_quoted_links'] = urlize_quoted_links
env.filters['break_long_headers'] = break_long_headers
def add_query_param(request, key, val):
"""
Add a query parameter to the current request url, and return the new url.
"""
iri = request.get_full_path()
uri = iri_to_uri(iri)
return replace_query_param(uri, key, val)
env.filters['add_query_param'] = add_query_param
def render_template(filename, context={}):
template = env.get_template(filename)
rendered = template.render(**context)
return rendered
# Finally you can create a new renderer for APIViews that uses Jinja2
from jinja_tools import render_template
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework import status
class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
"""
Render the HTML for the browsable API representation.
"""
self.accepted_media_type = accepted_media_type or ''
self.renderer_context = renderer_context or {}
context = self.get_context(data, accepted_media_type, renderer_context)
ret = render_template(self.template, context)
# Munge DELETE Response code to allow us to return content
# (Do this *after* we've rendered the template so that we include
# the normal deletion response code in the output)
response = renderer_context['response']
if response.status_code == status.HTTP_204_NO_CONTENT:
response.status_code = status.HTTP_200_OK
return ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment