From: yomguy Date: Thu, 20 Dec 2012 11:28:54 +0000 (+0100) Subject: testimonial using a mixin snippet X-Git-Tag: 0.9-probarreau~230 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=5e614ce95d3a7c84e6f116ded61823d00b1fc6c4;p=teleforma.git testimonial using a mixin snippet --- diff --git a/teleforma/static/teleforma/css/teleforma_pdf.css b/teleforma/static/teleforma/css/teleforma_pdf.css new file mode 100644 index 00000000..27bb339a --- /dev/null +++ b/teleforma/static/teleforma/css/teleforma_pdf.css @@ -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 index 00000000..2c936df1 --- /dev/null +++ b/teleforma/templates/teleforma/seminar_testimonial.html @@ -0,0 +1,82 @@ + +{% load i18n %} +{% load telemeta_utils %} +{% load teleforma_tags %} + +{% get_current_language as LANGUAGE_CODE %} +{% get_available_languages as LANGUAGES %} + + + + + + + + + + + +{%block head_title %}{% description %} - TeleForma{% endblock %} + +{% block stylesheets %} + + +{% endblock %} + +{% block extra_stylesheets %}{% endblock %} + + +{% block extra_javascript %}{% endblock %} +{% block infra_javascript %}{% endblock %} + + + + +{% block layout %} +
+ +
+ + + + +

{% block title %}{% endblock %}

{% block title_buttons %}{% endblock %}
+ + {% block content %} + {{ seminar.title }} + {% endblock %} + +
+ +{% block footer %} + +{% endblock %} + +
+{% endblock layout %} + + + + diff --git a/teleforma/urls.py b/teleforma/urls.py index 3ee3632c..87406de0 100644 --- a/teleforma/urls.py +++ b/teleforma/urls.py @@ -105,7 +105,7 @@ urlpatterns = patterns('', url(r'^desk/seminars/(?P.*)/form/$', evaluation_form_detail, name="teleforma-seminar-form"), # Testimonial - url(r'^desk/seminars/(?P.*)/testimonial/$', testimonial.download, + url(r'^desk/seminars/(?P.*)/testimonial/$', TestimonialView.as_view(), name="teleforma-seminar-testimonial"), # Postman diff --git a/teleforma/views/pro.py b/teleforma/views/pro.py index 81da0816..1d71238b 100644 --- a/teleforma/views/pro.py +++ b/teleforma/views/pro.py @@ -35,12 +35,63 @@ 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:
%s
' % 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
%s
' % 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