Mercurial > public > sg101
changeset 6:b6263ac72052
Use DRY principle to manage third party javascript libraries. Created script_tags template tags to generate the correct link and script tags for 3rd party libraries. The settings.py file is the only place where the full path name is specified.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 11 Apr 2009 22:50:56 +0000 (2009-04-11) |
parents | 63696b279e35 |
children | ca66189c7c44 |
files | gpp/accounts/forms.py gpp/accounts/views.py gpp/bio/forms.py gpp/comments/forms.py gpp/core/templatetags/__init__.py gpp/core/templatetags/script_tags.py gpp/core/widgets.py gpp/downloads/admin.py gpp/downloads/forms.py gpp/gcalendar/forms.py gpp/membermap/forms.py gpp/messages/forms.py gpp/settings.py gpp/templates/downloads/download_comments.html gpp/templates/downloads/download_list.html gpp/templates/downloads/download_summary.html gpp/templates/downloads/search_results.html gpp/templates/gcalendar/edit.html gpp/templates/membermap/index.html gpp/templates/news/story.html gpp/templates/polls/poll_results.html gpp/templates/potd/view.html gpp/templates/shoutbox/view.html gpp/urls.py |
diffstat | 23 files changed, 139 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- a/gpp/accounts/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/accounts/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -5,8 +5,8 @@ from django.core.urlresolvers import reverse from django.template.loader import render_to_string from django.contrib.sites.models import Site +from django.conf import settings -import settings from core.functions import send_mail from accounts.models import PendingUser from accounts.models import IllegalUsername
--- a/gpp/accounts/views.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/accounts/views.py Sat Apr 11 22:50:56 2009 +0000 @@ -1,12 +1,12 @@ """views for the accounts application""" import datetime -import settings from django.shortcuts import render_to_response from django.template import RequestContext from django.contrib import auth from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse +from django.conf import settings from accounts.models import PendingUser from accounts.forms import RegisterForm
--- a/gpp/bio/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/bio/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -40,18 +40,13 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css', - 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css', - ), + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'] + \ + settings.GPP_THIRD_PARTY_CSS['jquery-ui'] } - js = ( - 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/jquery-ui.js', - 'js/bio.js', - ) + js = settings.GPP_THIRD_PARTY_JS['jquery'] + \ + settings.GPP_THIRD_PARTY_JS['markitup'] + \ + settings.GPP_THIRD_PARTY_JS['jquery-ui'] + \ + ('js/bio.js', ) def get_image(file):
--- a/gpp/comments/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/comments/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -66,12 +66,8 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css') + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'], } - js = ( - 'js/jquery-1.2.6.min.js', - 'js/comments.js', - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - ) + js = settings.GPP_THIRD_PARTY_JS['jquery'] + \ + settings.GPP_THIRD_PARTY_JS['markitup'] + \ + ('js/comments.js', )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/core/templatetags/script_tags.py Sat Apr 11 22:50:56 2009 +0000 @@ -0,0 +1,28 @@ +""" +Template tags to generate <link> and <script> tags for 3rd party Javascript scripts. +""" +from django import template +from django.conf import settings + +register = template.Library() + +@register.simple_tag +def script_tags(library): + s = '' + if library in settings.GPP_THIRD_PARTY_CSS: + for path in settings.GPP_THIRD_PARTY_CSS[library]: + prefix = '' + if not path.startswith('http'): + prefix = settings.MEDIA_URL + s += '<link rel="stylesheet" href="%s%s" type="text/css" />' % (prefix, path) + + if library in settings.GPP_THIRD_PARTY_JS: + for path in settings.GPP_THIRD_PARTY_JS[library]: + prefix = '' + if not path.startswith('http'): + prefix = settings.MEDIA_URL + s += '<script type="text/javascript" src="%s%s"></script>' % (prefix, path) + + return s + +# vim: ts=4 sw=4
--- a/gpp/core/widgets.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/core/widgets.py Sat Apr 11 22:50:56 2009 +0000 @@ -5,19 +5,15 @@ from django import forms from django.utils.safestring import mark_safe from django.core.urlresolvers import reverse +from django.conf import settings class AutoCompleteUserInput(forms.TextInput): class Media: css = { - 'all': ('js/jquery-autocomplete/jquery.autocomplete.css',) + 'all': settings.GPP_THIRD_PARTY_CSS['jquery-autocomplete'], } - js = ( - 'js/jquery-autocomplete/lib/jquery.js', - 'js/jquery-autocomplete/lib/jquery.bgiframe.min.js', - 'js/jquery-autocomplete/lib/jquery.ajaxQueue.js', - 'js/jquery-autocomplete/jquery.autocomplete.js' - ) + js = settings.GPP_THIRD_PARTY_JS['jquery-autocomplete'] def render(self, name, value, attrs=None): url = reverse('messages-ajax_users')
--- a/gpp/downloads/admin.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/downloads/admin.py Sat Apr 11 22:50:56 2009 +0000 @@ -2,6 +2,8 @@ This file contains the automatic admin site definitions for the downloads models. """ from django.contrib import admin +from django.conf import settings + from downloads.models import Download from downloads.models import Category from downloads.models import AllowedExtension @@ -20,15 +22,11 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css') + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'], } - js = ( - 'js/jquery-1.2.6.min.js', - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - 'js/downloads_admin.js', - ) + js = settings.GPP_THIRD_PARTY_JS['jquery'] + \ + settings.GPP_THIRD_PARTY_JS['markitup'] + \ + ('js/downloads_admin.js', ) class VoteRecordAdmin(admin.ModelAdmin):
--- a/gpp/downloads/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/downloads/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -4,6 +4,7 @@ import os from django import forms +from django.conf import settings from downloads.models import Download from downloads.models import AllowedExtension @@ -34,12 +35,9 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css') + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'], } - js = ( - 'js/jquery-1.2.6.min.js', - 'js/downloads/add.js', - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - ) + js = settings.GPP_THIRD_PARTY_JS['jquery'] + \ + settings.GPP_THIRD_PARTY_JS['markitup'] + \ + ('js/downloads/add.js', ) +
--- a/gpp/gcalendar/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/gcalendar/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -4,6 +4,7 @@ import datetime import pytz from django import forms +from django.conf import settings from gcalendar.models import Event @@ -80,19 +81,14 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css', - 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css', - 'css/gcalendar.css', - ) + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'] + \ + settings.GPP_THIRD_PARTY_CSS['jquery-ui'] + \ + ('css/gcalendar.css', ) } - js = ( - 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/jquery-ui.js', - 'js/gcalendar.js', - ) + js = settings.GPP_THIRD_PARTY_JS['jquery'] + \ + settings.GPP_THIRD_PARTY_JS['markitup'] + \ + settings.GPP_THIRD_PARTY_JS['jquery-ui'] + \ + ('js/gcalendar.js', ) def __init__(self, *args, **kwargs): initial = kwargs.get('initial', {})
--- a/gpp/membermap/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/membermap/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -2,6 +2,8 @@ Forms for the member map application. """ from django import forms +from django.conf import settings + from membermap.models import MapEntry @@ -13,12 +15,8 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css') + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'] } - js = ( - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - ) + js = settings.GPP_THIRD_PARTY_JS['markitup'] # vim: ts=4 sw=4
--- a/gpp/messages/forms.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/messages/forms.py Sat Apr 11 22:50:56 2009 +0000 @@ -67,14 +67,9 @@ class Media: css = { - 'all': ('js/markitup/skins/markitup/style.css', - 'js/markitup/sets/markdown/style.css') + 'all': settings.GPP_THIRD_PARTY_CSS['markitup'], } - js = ( - 'js/messages/compose.js', - 'js/markitup/jquery.markitup.pack.js', - 'js/markitup/sets/markdown/set.js', - ) + js = ('js/messages/compose.js', ) + settings.GPP_THIRD_PARTY_JS['markitup'] class OptionsForm(forms.ModelForm):
--- a/gpp/settings.py Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/settings.py Sat Apr 11 22:50:56 2009 +0000 @@ -140,3 +140,42 @@ MAX_AVATAR_SIZE_BYTES = 2 * 1024 * 1024 MAX_AVATAR_SIZE_PIXELS = 100 AVATAR_DEFAULT_URL = MEDIA_URL + AVATAR_DIR + '/default.png' + +# URL's of 3rd party Javascript and CSS files. +# These dictionaries are used by core/templatetags/script_tags, and +# should also be used by developers when creating form media classes. +GPP_THIRD_PARTY_JS = { + 'jquery': ( + 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', + ), + 'jquery-autocomplete': ( + 'js/jquery-autocomplete/lib/jquery.js', + 'js/jquery-autocomplete/lib/jquery.bgiframe.min.js', + 'js/jquery-autocomplete/lib/jquery.ajaxQueue.js', + 'js/jquery-autocomplete/jquery.autocomplete.js', + ), + 'jquery-jeditable': ( + 'js/jquery.jeditable.mini.js', + ), + 'jquery-ui': ( + 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/jquery-ui.js', + ), + 'markitup': ( + 'js/markitup/jquery.markitup.pack.js', + 'js/markitup/sets/markdown/set.js', + ), +} +GPP_THIRD_PARTY_CSS = { + 'jquery-ui': ( + 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css', + ), + 'jquery-autocomplete': ( + 'js/jquery-autocomplete/jquery.autocomplete.css', + ), + 'markitup': ( + 'js/markitup/skins/markitup/style.css', + 'js/markitup/sets/markdown/style.css', + ), +} + +# vim: ts=4 sw=4
--- a/gpp/templates/downloads/download_comments.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/downloads/download_comments.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,18 +1,16 @@ {% extends 'base.html' %} {% load downloads_tags %} {% load comment_tags %} +{% load script_tags %} {% block title %}Downloads Comments{% endblock %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/comments.css" /> <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/downloads.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/skins/markitup/style.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/sets/markdown/style.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% script_tags "jquery" %} +{% script_tags "markitup" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/comments.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/jquery.markitup.pack.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/sets/markdown/set.js"></script> <script type="text/javascript" src="{{ MEDIA_URL }}js/downloads/rating.js"></script> {% endblock %} {% block content %}
--- a/gpp/templates/downloads/download_list.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/downloads/download_list.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,5 +1,6 @@ {% extends 'base.html' %} {% load downloads_tags %} +{% load script_tags %} {% block title %}Downloads: {{ category.title }}{% endblock %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/downloads.css" /> @@ -7,7 +8,7 @@ <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/pagination.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% script_tags "jquery" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/downloads/rating.js"></script> {% endblock %} {% block content %}
--- a/gpp/templates/downloads/download_summary.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/downloads/download_summary.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,11 +1,12 @@ {% extends 'base.html' %} {% load downloads_tags %} +{% load script_tags %} {% block title %}{{ title }}{% endblock %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/downloads.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% script_tags "jquery" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/downloads/rating.js"></script> {% endblock %} {% block content %}
--- a/gpp/templates/downloads/search_results.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/downloads/search_results.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,5 +1,6 @@ {% extends 'base.html' %} {% load downloads_tags %} +{% load script_tags %} {% block title %}Downloads: Search Results{% endblock %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/downloads.css" /> @@ -7,7 +8,7 @@ <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/pagination.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% script_tags "jquery" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/downloads/rating.js"></script> {% endblock %} {% block content %}
--- a/gpp/templates/gcalendar/edit.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/gcalendar/edit.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,7 +1,8 @@ {% extends 'base.html' %} +{% load script_tags %} {% block title %}Edit Calendar Events{% endblock %} {% block custom_js %} -<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> +{% script_tags "jquery" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/gcalendar_edit.js"></script> {% endblock %} {% block content %}
--- a/gpp/templates/membermap/index.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/membermap/index.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,7 +1,8 @@ {% extends 'base.html' %} +{% load script_tags %} {% block title %}Member Map{% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% script_tags "jquery" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/membermap.js"></script> <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAql_1Xw9MGW3mOxzo8gLb3hStsp1UIpjYO7Py4hlJXjRzAdyQtBTt5uM4QCgXtTKcuwba8HA9TL9LgQ" type="text/javascript"></script> {{ form.media }}
--- a/gpp/templates/news/story.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/news/story.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,17 +1,17 @@ {% extends 'news/base.html' %} {% load tagging_tags %} {% load comment_tags %} +{% load script_tags %} {% block title %}News: {{ story.title }}{% endblock %} {% block news_css %} -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/skins/markitup/style.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/sets/markdown/style.css" /> <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/comments.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% if story.can_comment_on %} +{% script_tags "jquery" %} +{% script_tags "markitup" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/comments.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/jquery.markitup.pack.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/sets/markdown/set.js"></script> +{% endif %} {% endblock %} {% block news_content %} <h3>{{ story.title }}</h3>
--- a/gpp/templates/polls/poll_results.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/polls/poll_results.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,17 +1,17 @@ {% extends 'base.html' %} {% load comment_tags %} +{% load script_tags %} {% block title %}Poll Results: {{ poll.question }}{% endblock %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/polls.css" /> <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/comments.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/skins/markitup/style.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/sets/markdown/style.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% if poll.is_open %} +{% script_tags "jquery" %} +{% script_tags "markitup" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/comments.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/jquery.markitup.pack.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/sets/markdown/set.js"></script> +{% endif %} {% endblock %} {% block content %} <h2>Polls</h2>
--- a/gpp/templates/potd/view.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/potd/view.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,17 +1,15 @@ {% extends 'base.html' %} {% load comment_tags %} +{% load script_tags %} {% block title %}Photo Of The Day{% endblock %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/potd.css" /> <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/comments.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/skins/markitup/style.css" /> -<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/markitup/sets/markdown/style.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> +{% script_tags "jquery" %} +{% script_tags "markitup" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/comments.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/jquery.markitup.pack.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/markitup/sets/markdown/set.js"></script> {% endblock %} {% block content %} <h2>Photo Of The Day</h2> @@ -39,6 +37,7 @@ {% if potd.can_comment_on %} <p>Leave a comment?</p> {% render_comment_form for potd %} +<br /> {% else %} <p>Comments are allowed only on today's photo of the day. If you'd like to share your thoughts on this photo with the site staff, you can <a href="{% url contact-form %}">contact us directly</a>.</p>
--- a/gpp/templates/shoutbox/view.html Sat Apr 11 19:45:17 2009 +0000 +++ b/gpp/templates/shoutbox/view.html Sat Apr 11 22:50:56 2009 +0000 @@ -1,13 +1,14 @@ {% extends 'base.html' %} {% load avatar_tags %} {% load smiley_tags %} +{% load script_tags %} {% block custom_css %} <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/shoutbox_app.css" /> <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/pagination.css" /> {% endblock %} {% block custom_js %} -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script> -<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.jeditable.mini.js"></script> +{% script_tags "jquery" %} +{% script_tags "jquery-jeditable" %} <script type="text/javascript" src="{{ MEDIA_URL }}js/shoutbox_app.js"></script> {% endblock %} {% block title %}Shout History{% endblock %}