From 97f48ecba4e323d69e40ddd758a585b1cf080fc7 Mon Sep 17 00:00:00 2001 From: olivier <> Date: Thu, 11 Feb 2010 22:31:25 +0000 Subject: [PATCH] add support for rst based flat pages ; add descriptive text and image to home --- telemeta/htdocs/css/telemeta.css | 9 +- telemeta/models/location.py | 1 + telemeta/pages/default/parts/home.rst | 16 +++ telemeta/pages/default/parts/home_img.jpg | Bin 0 -> 9997 bytes telemeta/pages/fr/parts/home.rst | 16 +++ telemeta/templates/telemeta/flatpage.html | 1 + .../templates/telemeta_default/flatpage.html | 5 + .../templates/telemeta_default/index.html | 5 + .../telemeta_default/search_criteria.html | 2 +- telemeta/templatetags/telemeta_utils.py | 42 +++++++- telemeta/urls.py | 3 + telemeta/web/base.py | 15 ++- telemeta/web/pages.py | 98 ++++++++++++++++++ 13 files changed, 207 insertions(+), 6 deletions(-) create mode 100644 telemeta/pages/default/parts/home.rst create mode 100644 telemeta/pages/default/parts/home_img.jpg create mode 100644 telemeta/pages/fr/parts/home.rst create mode 100644 telemeta/templates/telemeta/flatpage.html create mode 100644 telemeta/templates/telemeta_default/flatpage.html create mode 100644 telemeta/web/pages.py diff --git a/telemeta/htdocs/css/telemeta.css b/telemeta/htdocs/css/telemeta.css index f1e9468a..a9708264 100644 --- a/telemeta/htdocs/css/telemeta.css +++ b/telemeta/htdocs/css/telemeta.css @@ -1,4 +1,4 @@ -* {margin: 0; padding: 0;} +body {margin: 0; padding: 0;} a {text-decoration: none; color: #969696;} a img {border: none;} html, input, select, textarea, h1, h2, h3, h4, h5, h6 { @@ -23,7 +23,7 @@ a:link:hover, a:visited:hover { } a img { border: none; } -h3 { +.rst-content h1, h3 { font-size: 1.2em; font-weight: bold; color: #353535; @@ -620,3 +620,8 @@ table.listing tbody tr:hover { background: #f7f8fa !important } border: solid 1px #888; margin-top: 0.8em; } + +img.home-image { + margin: 0 1.5em 1.5em 0; + float: left; +} diff --git a/telemeta/models/location.py b/telemeta/models/location.py index d5c660d5..c0621423 100644 --- a/telemeta/models/location.py +++ b/telemeta/models/location.py @@ -102,6 +102,7 @@ class Location(ModelCore): class Meta(MetaCore): db_table = 'locations' + verbose_name = _('location') def __unicode__(self): return self.name diff --git a/telemeta/pages/default/parts/home.rst b/telemeta/pages/default/parts/home.rst new file mode 100644 index 00000000..76d944e2 --- /dev/null +++ b/telemeta/pages/default/parts/home.rst @@ -0,0 +1,16 @@ +=================================================== +Archives du Centre de Recherche en Ethnomusicologie +=================================================== + +Le Centre de Recherche en Ethnomusicologie fait partie du Laboratoire d'Ethnologie et de Sociologie Comparative (UMR 7186). Il se consacre à l'étude des pratiques et des savoirs musicaux, conçus autant comme processus de différentiation socio-culturelle que comme forme d'expression commune à l'Homme. + +Cette approche, fondée sur un recueil raisonné des données musicales et un travail simultané d'enquête ethnographique, s'inscrit dans une anthropologie du fait musical envisagé dans ses dimensions socio-culturelles, esthétiques, formelles, acoustiques, kinésiques et finalement cognitives. + +.. image:: home_img.jpg + :class: home-image + +Le Centre investit par ailleurs de nouveaux objets encore peu explorés de la discipline comme le geste musical et chorégraphique, la construction culturelle et cognitive de l'émotion, ou encore les représentations du sonore. Les thématiques développées par les chercheurs, soit individuellement, soit dans le cadre de groupes de recherche, sont régulièrement exposées dans le cadre d'un séminaire interne. + +Le CREM gère un vaste fonds documentaire (archives musicales et livres) de la plus haute valeur patrimoniale et consulté par un public international. Il est éditeur d'une importante collection de disques. + + diff --git a/telemeta/pages/default/parts/home_img.jpg b/telemeta/pages/default/parts/home_img.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2dc98aa3a41163eba8e71316590cdee369db8f2 GIT binary patch literal 9997 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

All collections
Browse all collections

@@ -10,4 +14,5 @@

Administration
Configure Telemeta and manage users

+--> {% endblock %} diff --git a/telemeta/templates/telemeta_default/search_criteria.html b/telemeta/templates/telemeta_default/search_criteria.html index d97000b3..d81df268 100644 --- a/telemeta/templates/telemeta_default/search_criteria.html +++ b/telemeta/templates/telemeta_default/search_criteria.html @@ -29,7 +29,7 @@ $(document).ready(function () {

- +

diff --git a/telemeta/templatetags/telemeta_utils.py b/telemeta/templatetags/telemeta_utils.py index dfc8ce31..0eeb1b4c 100644 --- a/telemeta/templatetags/telemeta_utils.py +++ b/telemeta/templatetags/telemeta_utils.py @@ -8,6 +8,10 @@ from django import template from django.utils.text import capfirst from telemeta import models from django.utils.translation import ungettext +from docutils.core import publish_parts +from django.utils.encoding import smart_str, force_unicode +from django.utils.safestring import mark_safe +import re register = template.Library() @@ -165,10 +169,13 @@ def prepend(str, prefix): return '' @register.simple_tag -def field_label(model, field): +def field_label(model, field=None): if isinstance(model, basestring): model = getattr(models, model) + if not field: + return capfirst(unicode(model._meta.verbose_name)) + return capfirst(unicode(model.field_label(field))) @register.simple_tag @@ -209,3 +216,36 @@ def variable_link(object, url_name, url_key): @register.filter def equals(value1, value2): return value1 == value2 + +@register.filter +def rst(content): + parsed = "" + path = getattr(content, 'path', '') + if isinstance(content, basestring): + content = content.split("\n") + + for line in content: + match = re.match('^(\.\. *(?:_[^:]*:|image::) *)([^ ]+) *$', line) + if match: + directive, urlname = match.groups() + line = directive + try: + i = urlname.index('telemeta-') + except ValueError: + i = -1 + if i == 0: + line += reverse(urlname) + elif urlname[:1] != '/': + print '|%s|' % urlname + line += reverse('telemeta-flatpage', args=[path + '/../' + urlname]) + else: + line += urlname + + parsed += line + "\n" + + parts = publish_parts(source=smart_str(parsed), writer_name="html4css1", settings_overrides={}) + return mark_safe('
\n' + force_unicode(parts["html_body"]) + '
') +rst.is_safe = True + + + diff --git a/telemeta/urls.py b/telemeta/urls.py index 49fece21..3ebe7716 100644 --- a/telemeta/urls.py +++ b/telemeta/urls.py @@ -165,6 +165,9 @@ urlpatterns = patterns('', {'document_root': htdocs+'/timeside'}, name="telemeta-timeside"), + # Flat pages + url(r'^page/(?P.*)$', web_view.render_flatpage, name="telemeta-flatpage"), + # OAI-PMH Data Provider url(r'^oai/.*$', web_view.handle_oai_request, name="telemeta-oai") ) diff --git a/telemeta/web/base.py b/telemeta/web/base.py index f6ace5e3..3f5154c6 100644 --- a/telemeta/web/base.py +++ b/telemeta/web/base.py @@ -40,7 +40,7 @@ from django.template import Context, loader from django import template from django.http import HttpResponse from django.http import Http404 -from django.shortcuts import render_to_response +from django.shortcuts import render_to_response, redirect from django.views.generic import list_detail from django.conf import settings @@ -56,6 +56,7 @@ import telemeta.interop.oai as oai from telemeta.interop.oaidatasource import TelemetaOAIDataSource from django.core.exceptions import ObjectDoesNotExist from telemeta.util.unaccent import unaccent +from telemeta.web import pages class WebView(Component): """Provide web UI methods""" @@ -68,7 +69,7 @@ class WebView(Component): """Render the homepage""" template = loader.get_template('telemeta/index.html') - context = Context({}) + context = Context({'page_content': pages.get_page_content(request, 'parts/home', True)}) return HttpResponse(template.render(context)) def collection_detail(self, request, public_id, template=''): @@ -390,4 +391,14 @@ class WebView(Component): args.update(request.POST) return HttpResponse(provider.handle(args), mimetype='text/xml') + def render_flatpage(self, request, path): + try: + content = pages.get_page_content(request, path) + except pages.MalformedPagePath: + return redirect(request.path + '/') + if isinstance(content, pages.PageAttachment): + return HttpResponse(content, content.mimetype()) + else: + return render_to_response('telemeta/flatpage.html', {'page_content': content }) + diff --git a/telemeta/web/pages.py b/telemeta/web/pages.py new file mode 100644 index 00000000..87a0de3e --- /dev/null +++ b/telemeta/web/pages.py @@ -0,0 +1,98 @@ +from django.conf import settings +import re +import telemeta +from os import path +import mimetypes + +PAGES_ROOT = path.join(path.dirname(telemeta.__file__), 'pages') + +class PageTextContent(object): + def __init__(self, filename, path): + self.filename = filename + self.path = path + + def __iter__(self): + file = open(self.filename, 'r') + for line in file: + yield line.rstrip('\r\n') + file.close() + + def __unicode__(self): + file = open(self.filename, 'r') + data = file.read() + file.close() + return data + +class PageAttachment(object): + def __init__(self, filename, path): + self.filename = filename + self.path = path + + def mimetype(self): + type, encoding = mimetypes.guess_type(self.filename) + return type + + def __iter__(self): + file = open(self.filename, 'rb') + buffer_size = 0x10000 + while True: + chunk = file.read(buffer_size) + yield chunk + if len(chunk) < buffer_size: + break + + file.close() + +def language_code(request=None): + code = (request and getattr(request, 'LANGUAGE_CODE')) or settings.LANGUAGE_CODE + cut = re.split('[_-]', code) + code = cut[0] + return code.lower() + +def resolve_page_file(language_code, relative_path, ignore_slash_issue=False): + root = path.realpath(path.join(PAGES_ROOT, language_code)) + filename = None + current = root + is_attachment = False + for node in relative_path.split('/'): + if not node: + continue + current = path.join(current, node) + rst = current + '.rst' + if path.isfile(rst): + filename = rst + break + elif path.isfile(current): + filename = current + is_attachment = True + elif not path.isdir(current): + break + + if not filename and path.isdir(current): + rst = path.join(current, 'index.rst') + if path.isfile(rst): + if not ignore_slash_issue and relative_path[-1:] != '/': + raise MalformedPagePath("The relative page path must end with a slash when " + "resolving an implicit directory index") + filename = rst + + if filename: + filename = path.realpath(filename) + if filename.index(root) != 0: + filename = None + + if filename: + if is_attachment: + return PageAttachment(filename, relative_path) + else: + return PageTextContent(filename, relative_path) + + return None + +def get_page_content(request, relative_path, ignore_slash_issue=False): + lang = language_code(request) + return resolve_page_file(lang, relative_path) or resolve_page_file('default', relative_path) + +class MalformedPagePath(Exception): + pass + -- 2.39.5