From 48410d04fa98d79a6eb960b8e9649e900f14700d Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Wed, 1 Jan 2014 15:24:51 +0100 Subject: [PATCH] Enable cache-busting URLs for CSS and JS This will allow us to increase the cache times in the browser for our CSS, which almost never changes. Enables a new value to be used in templates, {{gitrev}}, which can be used to bust pretty much any URL. We could do this for all the images in the templates as well, but since most of them almost never change, we'll just enable it manually for each individual image as it becomes necessray - or just use a ?1, ?2 etc for those. Enabled by default for CSS and JavaScript links, since those are much more likely to be changed without having the URL changed. Cache times aren't increased yet - we'll do that later one we're sure that all existing caches are expired first. --- pgweb/core/views.py | 4 ++-- pgweb/docs/views.py | 3 ++- pgweb/search/views.py | 17 +++++++++-------- pgweb/settings.py | 2 +- pgweb/util/contexts.py | 21 +++++++++++++++++---- templates/base/base.html | 6 +++--- templates/docs/docspage.html | 6 +++--- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/pgweb/core/views.py b/pgweb/core/views.py index 05693326..cdfa7ac9 100644 --- a/pgweb/core/views.py +++ b/pgweb/core/views.py @@ -63,7 +63,7 @@ def home(request): 'quote': quote, 'versions': versions, 'planet': planet, - }) + }, RequestContext(request)) # Community main page (contains surveys and potentially more) def community(request): @@ -244,7 +244,7 @@ def sync_timestamp(request): def admin_pending(request): return render_to_response('core/admin_pending.html', { 'app_list': get_all_pending_moderations(), - }) + }, RequestContext(request)) # Purge objects from varnish, for the admin pages @login_required diff --git a/pgweb/docs/views.py b/pgweb/docs/views.py index 76795863..647b54f7 100644 --- a/pgweb/docs/views.py +++ b/pgweb/docs/views.py @@ -1,6 +1,7 @@ from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponse, Http404, HttpResponseRedirect from django.template import TemplateDoesNotExist, loader, Context +from django.template.context import RequestContext from django.contrib.auth.decorators import login_required from django.db.models import Q from django.conf import settings @@ -67,7 +68,7 @@ def docpage(request, version, typ, filename): 'can_comment': (typ=="interactive" and ver==currver), 'doc_index_filename': indexname, 'loaddate': loaddate, - }) + }, RequestContext(request)) def docsrootpage(request, version, typ): return docpage(request, version, typ, 'index') diff --git a/pgweb/search/views.py b/pgweb/search/views.py index 94df6321..1b282893 100644 --- a/pgweb/search/views.py +++ b/pgweb/search/views.py @@ -1,4 +1,5 @@ from django.shortcuts import render_to_response, get_object_or_404 +from django.template.context import RequestContext from django.http import HttpResponse, Http404, HttpResponseRedirect from django.views.decorators.csrf import csrf_exempt from django.conf import settings @@ -125,18 +126,18 @@ def search(request): 'listid': listid, 'dates': dateoptions, 'dateval': dateval, - }) + }, RequestContext(request)) else: return render_to_response('search/sitesearch.html', { 'search_error': "No search term specified.", - }) + }, RequestContext(request)) query = request.REQUEST['q'] # Anti-stefan prevention if len(query) > 1000: return render_to_response('search/sitesearch.html', { 'search_error': "Search term too long.", - }) + }, RequestContext(request)) # Is the request being paged? if request.REQUEST.has_key('p'): @@ -186,12 +187,12 @@ def search(request): except socket.timeout: return render_to_response('search/listsearch.html', { 'search_error': 'Timeout when talking to search server. Please try your search again later, or with a more restrictive search terms.', - }) + }, RequestContext(request)) if r.status != 200: memc = None return render_to_response('search/listsearch.html', { 'search_error': 'Error talking to search server: %s' % r.reason, - }) + }, RequestContext(request)) hits = json.loads(r.read()) if has_memcached and memc: # Store them in memcached too! But only for 10 minutes... @@ -236,7 +237,7 @@ def search(request): 'listid': listid, 'dates': dateoptions, 'dateval': dateval, - }) + }, RequestContext(request)) else: # Website search is still done by making a regular pgsql connection @@ -247,7 +248,7 @@ def search(request): except: return render_to_response('search/sitesearch.html', { 'search_error': 'Could not connect to search database.' - }) + }, RequestContext(request)) # perform the query for general web search curs.execute("SELECT * FROM site_search(%(query)s, %(firsthit)s, %(hitsperpage)s, %(allsites)s, %(suburl)s)", { @@ -283,4 +284,4 @@ def search(request): 'url': "%s%s" % (h[1], h[2]), 'abstract': h[4].replace("[[[[[[", "").replace("]]]]]]",""), 'rank': h[5]} for h in hits[:-1]], - }) + }, RequestContext(request)) diff --git a/pgweb/settings.py b/pgweb/settings.py index 8930dba6..c7402fa7 100644 --- a/pgweb/settings.py +++ b/pgweb/settings.py @@ -79,7 +79,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.media', - 'util.contexts.RootLinkContextProcessor', + 'util.contexts.PGWebContextProcessor', ) LOGIN_URL='/account/login/' diff --git a/pgweb/util/contexts.py b/pgweb/util/contexts.py index e7dbdd48..18a1c780 100644 --- a/pgweb/util/contexts.py +++ b/pgweb/util/contexts.py @@ -1,4 +1,5 @@ from django.template import RequestContext +from django.utils.functional import SimpleLazyObject from django.conf import settings # This is the whole site navigation structure. Stick in a smarter file? @@ -100,12 +101,24 @@ class NavContext(RequestContext): self.update({'navmenu': navsection}) -# Template context processor to add information about the root link -def RootLinkContextProcessor(request): +def _get_gitrev(): + # Return the current git revision, that is used for + # cache-busting URLs. + with open('../.git/refs/heads/master') as f: + return f.readline()[:8] + +# Template context processor to add information about the root link and +# the current git revision. git revision is returned as a lazy object so +# we don't spend effort trying to load it if we don't need it (though +# all general pages will need it since it's used to render the css urls) +def PGWebContextProcessor(request): + gitrev = SimpleLazyObject(_get_gitrev) if request.is_secure(): return { 'link_root': settings.SITE_ROOT, + 'gitrev': gitrev, } else: - return {} - + return { + 'gitrev': gitrev, + } diff --git a/templates/base/base.html b/templates/base/base.html index feadc57c..251caab1 100644 --- a/templates/base/base.html +++ b/templates/base/base.html @@ -6,12 +6,12 @@ {%block meta%}{%endblock%} {# used for custom meta tags such as description which we don't want for every page #} - + - + - + - + +