Ben Sturmfels
0b8ae2ca77
This changes more often than the surrounding code, so should live with the other configuration.
69 lines
3.1 KiB
Python
69 lines
3.1 KiB
Python
from datetime import datetime
|
|
import mimetypes
|
|
|
|
from django.conf import settings
|
|
from django.http import FileResponse, Http404, HttpResponse, HttpResponseRedirect
|
|
from django.shortcuts import render
|
|
from django.template import RequestContext, Template
|
|
|
|
from .blog.models import Entry
|
|
from .news.models import PressRelease
|
|
from .supporters.models import Supporter
|
|
|
|
|
|
def frontpage(request):
|
|
"""Conservancy front page view
|
|
|
|
Performs all object queries necessary to render the front page.
|
|
"""
|
|
now = datetime.now()
|
|
context = {
|
|
'press_releases': PressRelease.objects.all().filter(pub_date__lte=now, sites=2)[:5],
|
|
'supporters_count': Supporter.objects.all().filter(display_until_date__gte=now).count(),
|
|
'blog': Entry.objects.all().filter(pub_date__lte=now)[:5],
|
|
}
|
|
return render(request, "frontpage.html", context)
|
|
|
|
|
|
def content(request, *args, **kwargs):
|
|
"""Faux CMS: bulk website content stored in templates and document files.
|
|
|
|
Rationale: Many websites have a CMS and store the majority of their website
|
|
content in a relational database eg. WordPress or Wagtail. That's useful
|
|
because various people can easily be given access to edit the website. The
|
|
downside is that is application complexity - the management of who change
|
|
what, when it changed and what changed becomes an application concern. At
|
|
the other end of the spectrum, we have files that are checked into a Git
|
|
repository - we get the precise who/what/when out of the box with Git, but
|
|
require you to have some technical knowledge and appropriate access to
|
|
commit. Since you're committing to a code repository, this also opens up the
|
|
possibility to break things you couldn't break via a CMS.
|
|
|
|
This view serves most of the textual pages and documents on
|
|
sfconservancy.org. It works a little like Apache serving mixed PHP/static
|
|
files - it looks at the URL and tries to find a matching file on the
|
|
filesystem. If it finds a template, it renders it via Django's template
|
|
infrastructure. If it finds a file but it's not a template, it will serve
|
|
the file as-is.
|
|
"""
|
|
base_path = settings.BASE_DIR / 'content'
|
|
path = request.path.lstrip('/')
|
|
if path.endswith('/'):
|
|
path += 'index.html'
|
|
full_path = (base_path / path).resolve()
|
|
safe_from_path_traversal = full_path.is_relative_to(base_path)
|
|
if full_path.is_dir():
|
|
# Should have been accessed with a trailing slash.
|
|
return HttpResponseRedirect(request.path + '/')
|
|
elif not full_path.exists() or not safe_from_path_traversal:
|
|
raise Http404()
|
|
is_template = mimetypes.guess_type(full_path)[0] == 'text/html'
|
|
if not is_template:
|
|
return FileResponse(open(full_path, 'rb'))
|
|
else:
|
|
# These template are intentionally not in the template loader path, so
|
|
# we open them directly, rather than using the template loader.
|
|
with open(full_path, encoding='utf-8') as t:
|
|
template = Template(t.read())
|
|
context = RequestContext(request, kwargs)
|
|
return HttpResponse(template.render(context))
|