]> git.parisson.com Git - teleforma.git/commitdiff
testimonial using a mixin snippet
authoryomguy <yomguy@parisson.com>
Thu, 20 Dec 2012 11:28:54 +0000 (12:28 +0100)
committeryomguy <yomguy@parisson.com>
Thu, 20 Dec 2012 11:28:54 +0000 (12:28 +0100)
teleforma/static/teleforma/css/teleforma_pdf.css [new file with mode: 0644]
teleforma/templates/teleforma/seminar_testimonial.html [new file with mode: 0644]
teleforma/urls.py
teleforma/views/pro.py

diff --git a/teleforma/static/teleforma/css/teleforma_pdf.css b/teleforma/static/teleforma/css/teleforma_pdf.css
new file mode 100644 (file)
index 0000000..27bb339
--- /dev/null
@@ -0,0 +1,16 @@
+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 {
+    font-size: 100%;
+}
+body {
+    font: 0.8125em/1em Verdana, sans-serif;
+    line-height: 1.3em;
+    color: #333;
+    background: #FFF;
+    margin: 0em;
+    background:no-repeat url(/static/telemeta/images/bg_yt.png) 0 0;
+    background-color:#ebebeb;
+    background-repeat:repeat
+}
diff --git a/teleforma/templates/teleforma/seminar_testimonial.html b/teleforma/templates/teleforma/seminar_testimonial.html
new file mode 100644 (file)
index 0000000..2c936df
--- /dev/null
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+{% load i18n %}
+{% load telemeta_utils %}
+{% load teleforma_tags %}
+
+{% get_current_language as LANGUAGE_CODE %}
+{% get_available_languages as LANGUAGES %}
+<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
+
+<head>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
+<meta name="Viewport" content="width=device-width" />
+<meta name="Viewport" content="initial-scale=1.0" />
+<meta name="Viewport" content="maximum-scale=1.5" />
+<meta name="Viewport" content="user-scalable=1" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<meta names="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+<title>{%block head_title %}{% description %} - TeleForma{% endblock %}</title>
+
+{% block stylesheets %}
+<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}teleforma/css/teleforma_pdf.css" />
+
+{% endblock %}
+
+{% block extra_stylesheets %}{% endblock %}
+
+
+{% block extra_javascript %}{% endblock %}
+{% block infra_javascript %}{% endblock %}
+
+</head>
+
+<body>
+{% block layout %}
+<div id="layout">
+
+<div id="content">
+
+        <table id="content_header"><tr>
+                <td class="leftcol"><h1>{% block title %}{% endblock %}</h1></td>
+                <td class="rightcol">{% block title_buttons %}{% endblock %}</td>
+        </tr></table>
+
+    {% block content %}
+    {{ seminar.title }}
+    {% endblock %}
+
+</div>
+
+{% block footer %}
+<div id="footer">
+ <hr />
+ <table width="100%">
+  <tr>
+   <td>
+    <a id="telemeta_powered" href="{% telemeta_url %}" target="_blank"><img src="{{ STATIC_URL }}telemeta/images/logo_mini_2.png" alt="Telemeta Powered"/></a>
+    <p class="left">
+    {% trans "Powered by" %} <a href="http://parisson.com" target="_blank"><br /><strong>TeleForma {% teleforma_version %}</strong></a><br />
+    </p>
+   </td>
+   <td>
+    <p class="center">
+    </p>
+   </td>
+   <td>
+    <p class="right">
+    Copyright &copy; {% current_year %} {% organization %} |
+    <a href="{% url telemeta-flatpage "legal_notices" %}">{% trans "Legal notices" %}</a>
+    </p>
+   </td>
+  </tr>
+ </table>
+</div>
+{% endblock %}
+
+</div>
+{% endblock layout %}
+
+
+</body>
+</html>
index 3ee3632c8782a297c4459a4563a79a35f13c8993..87406de0a36f3a98cd7333ee39e0cf14de27d4e6 100644 (file)
@@ -105,7 +105,7 @@ urlpatterns = patterns('',
     url(r'^desk/seminars/(?P<pk>.*)/form/$', evaluation_form_detail, name="teleforma-seminar-form"),
 
     # Testimonial
-    url(r'^desk/seminars/(?P<pk>.*)/testimonial/$', testimonial.download
+    url(r'^desk/seminars/(?P<pk>.*)/testimonial/$', TestimonialView.as_view()
                                                     name="teleforma-seminar-testimonial"),
 
     # Postman
index 81da0816ebbd4dd058eebe56986cf99b95e640f8..1d71238b65e9d18ef1bb22e61ce96b3f242877a1 100644 (file)
 
 from teleforma.views.core import *
 from django.utils.translation import ugettext_lazy as _
+from django.template import loader, Context, RequestContext
+from django.views.generic.base import TemplateResponseMixin
+from django.http import HttpResponse
+from django.conf import settings
+from django.shortcuts import render
+from django.template.loader import get_template
+from django.template.context import Context
+from django.utils.html import escape
+from django.views.generic.detail import SingleObjectMixin
+
+import os
+from cgi import escape
+from cStringIO import StringIO
+
+from xhtml2pdf import pisa
 
 from forms_builder.forms.forms import FormForForm
 from forms_builder.forms.models import Form
 from forms_builder.forms.signals import form_invalid, form_valid
 
 
+def content_to_pdf(content, dest, encoding='utf-8', **kwargs):
+    """
+    Write into *dest* file object the given html *content*.
+    Return True if the operation completed successfully.
+    """
+    from xhtml2pdf import pisa
+    src = StringIO(content.encode(encoding))
+    pdf = pisa.pisaDocument(src, dest, encoding=encoding, **kwargs)
+    return not pdf.err
+
+def content_to_response(content, filename=None):
+    """
+    Return a pdf response using given *content*.
+    """
+    response = HttpResponse(content, mimetype='application/pdf')
+    if filename is not None:
+        response['Content-Disposition'] = 'attachment; filename=%s' % filename
+    return response
+
+def render_to_pdf(request, template, context, filename=None, encoding='utf-8', 
+    **kwargs):
+    """
+    Render a pdf response using given *request*, *template* and *context*.
+    """
+    if not isinstance(context, Context):
+        context = RequestContext(request, context)
+
+    content = loader.render_to_string(template, context)
+    buffer = StringIO()
+
+    succeed = content_to_pdf(content, buffer, encoding, **kwargs)
+    if succeed:
+        return content_to_response(buffer.getvalue(), filename)
+    return HttpResponse('Errors rendering pdf:<pre>%s</pre>' % escape(content))
+
+
 def get_seminars(user):
     seminars = []
 
@@ -392,88 +443,113 @@ def evaluation_form_detail(request, pk, template='teleforma/evaluation_form.html
     return render_to_response(template, context, request_context)
 
 
-# Testimonials
 
-import StringIO
-
-from xhtml2pdf import pisa
-
-from django.conf import settings
-from django.http import HttpResponse
-from django.shortcuts import render
-from django.template.loader import get_template
-from django.template.context import Context
-from django.utils.html import escape
-from django.views.generic.detail import SingleObjectMixin
+class PDFTemplateResponseMixin(TemplateResponseMixin):
+    """
+    Mixin for Django class based views.
+    Switch normal and pdf template based on request.
 
+    The switch is made when the request has a particular querydict, e.g.::
 
-class TestimonialView(DetailView):
+        http://www.example.com?format=pdf
 
-    model = Seminar
-    template_name = 'teleforma/seminar_detail.html'
-    mimetype = 'application/pdf'
-    extension = 'pdf'
+    The key and value of the querydict can be overridable using *as_view()*.
+    That pdf url will be present in the context as *pdf_url*.
 
-    @method_decorator(login_required)
-    def dispatch(self, *args, **kwargs):
-        return super(TestimonialView, self).dispatch(*args, **kwargs)
-    
-    def get_context_data(self, **kwargs):
-        context = super(TestimonialView, self).get_context_data(**kwargs)        
-        context['seminar'] = self.get_object()
-        return context
-
-    def download(self, request, pk):
-        """Function to render html template into a pdf file"""
+    For example it is possible to define a view like this::
         
-        seminar = Seminar.objects.get(id=pk)
-        template = get_template(self.template_name)
-        
-        context = Context({'seminar': seminar, 'STATIC_URL': settings.STATIC_ROOT })
-        html = template.render(context)
-        result = StringIO.StringIO()
-
-        pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),
-                                                dest=result,
-                                                encoding='UTF-8',
-                                                link_callback=self.fetch_resources)
-        if not pdf.err:
-            response = HttpResponse(result.getvalue(), mimetype=self.mimetype)
-            return response
+        from django.views.generic import View
 
-        return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))
+        class MyView(PDFTemplateResponseMixin, View):
+            template_name = 'myapp/myview.html'
+            pdf_filename = 'report.pdf'
 
-    
+    The pdf generation is automatically done by *xhtml2pdf* using
+    the *myapp/myview_pdf.html* template.
 
+    Note that the pdf template takes the same context as the normal template.
+    """
+    pdf_template_name = None
+    pdf_template_name_suffix = '_pdf'
+    pdf_querydict_key = 'format'
+    pdf_querydict_value = 'pdf'
+    pdf_encoding = 'utf-8'
+    pdf_filename = None
+    pdf_url_varname = 'pdf_url'
+    pdf_kwargs = {}
+
+    def is_pdf(self):
+        value = self.request.REQUEST.get(self.pdf_querydict_key, '')
+        return value.lower() == self.pdf_querydict_value.lower()
+
+    def _get_pdf_template_name(self, name):
+        base, ext = os.path.splitext(name)
+        return '%s%s%s' % (base, self.pdf_template_name_suffix, ext)
+
+    def get_pdf_template_names(self):
+        """
+        If the template name is not given using the class attribute
+        *pdf_template_name*, then it is obtained using normal template
+        names, appending *pdf_template_name_suffix*, e.g.::
 
+            path/to/detail.html -> path/to/detail_pdf.html
+        """
+        if self.pdf_template_name is None:
+            names = super(PDFTemplateResponseMixin, self).get_template_names()
+            return map(self._get_pdf_template_name, names)
+        return [self.pdf_template_name]
 
-    def fetch_resources(self, uri, rel):
+    def get_pdf_filename(self):
         """
-        Callback to allow xhtml2pdf/reportlab to retrieve Images,Stylesheets, etc.
-        `uri` is the href attribute from the html link element.
-        `rel` gives a relative path, but it's not used here.
+        Return the pdf attachment filename.
+        If the filename is None, the pdf will not be an attachment.
+        """
+        return self.pdf_filename
 
+    def get_pdf_url(self):
         """
-        if uri.startswith(settings.MEDIA_URL):
-            path = os.path.join(settings.MEDIA_ROOT,
-                                uri.replace(settings.MEDIA_URL, ""))
-        elif uri.startswith(settings.STATIC_URL):
-            path = os.path.join(settings.STATIC_ROOT,
-                                uri.replace(settings.STATIC_URL, ""))
-        else:
-            path = os.path.join(settings.STATIC_ROOT,
-                                uri.replace(settings.STATIC_URL, ""))
+        This method is used to put the pdf url in the context.
+        """
+        querydict = self.request.GET.copy()
+        querydict[self.pdf_querydict_key] = self.pdf_querydict_value
+        return '%s?%s' % (self.request.path, querydict.urlencode())
+
+    def get_pdf_response(self, context, **response_kwargs):
+        return render_to_pdf(
+            request=self.request, 
+            template=self.get_pdf_template_names(),
+            context=context, 
+            encoding=self.pdf_encoding, 
+            filename=self.get_pdf_filename(), 
+            **self.pdf_kwargs
+        )
+
+    def render_to_response(self, context, **response_kwargs):
+        if self.is_pdf():
+            from django.conf import settings
+            context['STATIC_ROOT'] = settings.STATIC_ROOT
+            return self.get_pdf_response(context, **response_kwargs)
+        context[self.pdf_url_varname] = self.get_pdf_url()
+        return super(PDFTemplateResponseMixin, self).render_to_response(
+            context, **response_kwargs)
 
-            if not os.path.isfile(path):
-                path = os.path.join(settings.MEDIA_ROOT,
-                                    uri.replace(settings.MEDIA_URL, ""))
 
-                if not os.path.isfile(path):
-                    raise UnsupportedMediaPathException(
-                                        'media urls must start with %s or %s' % (
-                                        settings.MEDIA_ROOT, settings.STATIC_ROOT))
-        
-        return path
 
 
+class TestimonialView(PDFTemplateResponseMixin, SeminarView):
+
+    model = Seminar
+    template_name = 'teleforma/seminar_testimonial.html'
+    pdf_template_name = 'teleforma/seminar_testimonial.html'
+    # pdf_filename = 'report.pdf'
+
+    
+    @method_decorator(login_required)
+    def dispatch(self, *args, **kwargs):
+        return super(TestimonialView, self).dispatch(*args, **kwargs)
+    
+    def get_context_data(self, **kwargs):
+        context = super(TestimonialView, self).get_context_data(**kwargs)        
+        context['seminar'] = self.get_object()
+        return context