Package: wagtail-pdf-view
wagtail-pdf-viewRender Wagtail pages and models as PDF document using Weasyprint or LaTeX.The goal of this extension is to provide a flexible but easy to use way to render Wagtail pages and Django models as PDF.
With this extension you can utilize all the benefits from the wagtail page system (previews, drafts, history) as well as the power ofStreamFieldandRichTextfor your generated PDF document.
Models may be easily rendered as PDF and will be accessible either through the admin interface or through a public URL.Currentlyweasyprint(for HTML to PDF conversion) and latex is supported.
If you are undecided which one to use,weasyprintis recommended.InstallingInstall the latest version from pypi:pipinstall-Uwagtail-pdf-view# and either this for HTML -> PDFpipinstall-Udjango-weasyprint# and/or this for Latex -> PDFpipinstall-Udjango-texand add the following to your installed apps:INSTALLED_APPS=[...'wagtail_pdf_view','wagtail.contrib.routable_page',...]Whileweasyprintis installed as dependency ofdjango-weasyprintand works out of the box,
a working latex interpreter (lualatex) must be installed on your system if you want to usedjango-tex.Ifdjango-weasyprintanddjango-texis installed, weasyprint is selected by default.
Fordjango-texyou should setDEFAULT_PDF_VIEW_PROVIDER = WagtailTexViewin your settings.UsageAll you need to do to render your Wagtail page as PDF, is to inherit fromPdfModelMixin.
If you want to render a model instead, read the sectionModelAdminbelow.If you want to use latex, read the latex section below.Further configuration options include:ROUTE_CONFIGto enable rendering of the default HTML view and the PDF view at the same timestylesheetsresp.get_stylesheetsto include CSS stylesheets forweasyprintattachmentto control the file attachment (i.e. whether to download the PDF or open it in the browser)ExamplesA very simple example page using Wagtails StreamField.
Like for a regular Wagtail page, the template should be located under:<app_dir>/templates/<app>/simple_pdf_page.htmlIf you're using django-tex the template extention .tex is expected.fromwagtail.core.modelsimportPagefromwagtail.core.fieldsimportRichTextField,StreamFieldfromwagtail.coreimportblocksfromwagtail.admin.edit_handlersimportFieldPanel,StreamFieldPanelfromwagtail_pdf_view.mixinsimportPdfViewPageMixin# Inherit from PdfViewPageMixinclassSimplePdfPage(PdfViewPageMixin,Page):# you can create fields as you're used to, e.g. StreamFieldcontent=StreamField([("heading",blocks.CharBlock(form_classname="full title")),("text",blocks.RichTextBlock()),],blank=True)# content panel for the CMS (same as always)content_panels=Page.content_panels+[StreamFieldPanel("content"),]# OPTIONAL: If you want to include a stylesheet#stylesheets = ["css/your_stylesheet.css"]Usage ofROUTE_CONFIG:Default configuration:classPdfOnlyPage(PdfViewPageMixin,Page):# PDF onlyROUTE_CONFIG=[("pdf",r'^$'),("html",None),]By default only the pdf-view is available, i.e. you may only view this page as pdf.
This is useful when you just want to display a generated pdf document easily.A HTML first page: You can access the wagtail page as you're used e.g.127.0.0.1/mypage.
The PDF version will be available underpdf/e.g.127.0.0.1/mypage/pdfclassHtmlAndPdfPage(PdfViewPageMixin,Page):# HTML firstROUTE_CONFIG=[("html",r'^$'),("pdf",r'^pdf/$'),]Note that the order ofhtmlandpdfis not arbitrary:
The entry you set first, will be displayed by default when using wagtails preview function. Depending on your case, you may want to putpdfin the first place, so your editors get the pdf-view by default, while html-page url stays the same for the users.
In both cases your editors may access both views through the drop-down menu integrated in the preview button.A PDF first page: The PDF version is displayed with the regular url and
you can access the wagtail page under/html, e.g.127.0.0.1/mypage/htmlclassHtmlAndPdfPage(PdfViewPageMixin,Page):# PDF firstROUTE_CONFIG=[("pdf",r'^$'),("html",r'^html/$'),]ROUTE_CONFIGis build on wagtailsroutable_page, you can specify routes as you want (e.g.("html", r'^web/$'))Reversing and using URLs in templatesAs of version 0.2 reversing url patterns is supported.This feature is useful in cases when you are serving multiple views (i.e. html and pdf).You can access the URLs for the different views by usingroutablepageurlfrom theroutable_pagemodule:{% load wagtailroutablepage_tags %}<!-- HTML Page URL-->{% routablepageurl page "html" %}<!-- PDF Page URL-->{% routablepageurl page "pdf" %}<!-- When looping over Page.get_children, you need to use the specific Page object -->{% for subpage in page.get_children %}<li>{% routablepageurl subpage.specific "pdf" %}</li>{% endfor %}In most cases you don't need the full functionality ofroutablepageurl. To make things easy you can simply access the different views by the custom URL attributesurl_pdfandurl_html:<!-- HTML view url -->{{page.url_html}}<!-- PDF view url -->{{page.url_pdf}}<!-- When looping over Page.get_children, you need to use the specific Page object -->{% for subpage in page.get_children %}<li>{{subpage.specific.url_pdf}}</li>{% endfor %}If you are just interested in the extention to the normal page url:# this will be 'pdf/' in HTML-first modepage.reverse_subpage('pdf')ModelAdminVersion 0.2 introduces rendering for models viaModelAdmin.The model needs to inherit fromPdfModelMixinto enable rendering on the models side.
To make incorporating PDF-views as simple as possible this module offers twoModelAdminmixinsModelAdminPdfViewMixinandModelAdminPdfAdminViewMixin.
If you are not usingModelAdminyou may add a view for the model manually.Hooking in the URLsIf you want to access PDFs from outside of the admin area, you need to hook inwagtail_pdf_urlsinto your projectsurls.py.
If you are unsure whether you need this, it is recommended use the hook below:# urls.pyfromwagtail_pdf_viewimporturlsaswagtail_pdf_urlsurlpatterns=urlpatterns+[# hook in the 'live'-view PDFs under "pdf/"path("pdf/",include(wagtail_pdf_urls)),...# IMPORTANT: This must be below the "pdf/" includepath("",include(wagtail_urls)),...]Simple ExampleYour model needs to inherit fromPdfModelMixin:# models.pyfromwagtail_pdf_view.mixinsimportPdfViewPageMixin,PdfModelMixinclassYourPdfModel(PdfModelMixin,models.Model):# the admin view uses a different template attribute to# prevent you from publishing sensitive content by accident# template for non-admin viewtemplate_name="path/to/your_model.html"# template for adminadmin_template_name="path/to/your_model_admin.html"Unlike for PDF-Pages where everything is done in the Page-model, the hooks forModelAdminneed to be extended:By inheriting fromModelAdminPdfViewMixinorModelAdminPdfAdminViewMixinyou
automatically make the model accessible through a live url or through the admin panel respectively.This separation should make it easy to choose a view to according to your security needs:ModelAdminPdfViewMixinis suited for non-sensitive public models.ModelAdminPdfAdminViewMixinmakes the view only accessible to users withviewpermissions on the model.# wagtail_hooks.pyfromwagtail.contrib.modeladmin.optionsimportModelAdmin,modeladmin_registerfrom.modelsimportYourPdfModel# OPTION 1)# Creating a public view model (accessible for everybody through a url)# MAKE SURE YOU HOOKED IN THE URLs PROPERLYfromwagtail_pdf_view.modeladmin.mixinsimportModelAdminPdfViewMixin@modeladmin_registerclassYourPdfModelWagtailAdmin(ModelAdminPdfViewMixin,ModelAdmin):model=YourPdfModel# OPTION 2)# Creating admin-restricted view modelfromwagtail_pdf_view.modeladmin.mixinsimportModelAdminPdfAdminViewMixin@modeladmin_registerclassYourPdfModelWagtailAdmin(ModelAdminPdfAdminViewMixin,ModelAdmin):model=YourPdfModelModel URL configuration without ModelAdminThis is an example how you can hook in the models PDF-view manually (without usingModelAdmin).# urls.py# This will be either WagtailWeasyView or WagtailTexView depending on your installationfromwagtail_pdf_view.mixinsimportDEFAULT_PDF_VIEW_PROVIDERfrom.modelsimportYourPdfModelurlpatterns=[...# URL path for the DetailView with primary key pkre_path(r'^some/path/(?P<pk>\d+)/$',DEFAULT_PDF_VIEW_PROVIDER.as_view(model=YourPdfModel)),...]Using a custom ButtonHelper or PermissionHelperThis library implements an easier extendableButtonHelper.If you are using a customButtonHelper, you should inherit fromExtendableButtonHelperMixinorPdfViewButtonHelper,
otherwise you will not see a button for the PDF-view of the object inModelAdminsListView.Example:classMyCustomButtonHelper(PdfViewButtonHelper):# simplified button registration# (action, properties)custom_object_buttons=[("custom",{"label":'Custom Label'}),("some_action",{"label":'Another Action'}),]Note thatcustom_object_buttonsis defaulted with the actionspdfandliveinPdfViewButtonHelper.If you are setting a customPermissionHelper, you need to inherit fromCustomActionPermissionHelperMixin.Using latexWhen you want to use latex instead of HTML, you should be aware of the following:You need to add django_tex toINSTALLED_APPS:INSTALLED_APPS=[...'django_tex',...]You need to add the jinja tex engine toTEMPLATESin your settings.py:TEMPLATES+=[{'NAME':'tex','BACKEND':'django_tex.engine.TeXEngine','APP_DIRS':True,'OPTIONS':{'environment':'wagtail_pdf_view.environment.latex_environment',},},]SetDEFAULT_PDF_VIEW_PROVIDERin your settings:fromwagtail_pdf_view.viewsimportWagtailTexViewDEFAULT_PDF_VIEW_PROVIDER=WagtailTexViewIn case you just want to use latex for a specific model settings you can overritePDF_VIEW_PROVIDER:fromwagtail_pdf_view.viewsimportWagtailTexViewclassSimplePdfPage(PdfViewPageMixin,Page):# render with LaTeX insteadPDF_VIEW_PROVIDER=WagtailTexViewIn general you should includewagtail_preamble.tex, which provides required packages and commands for proper richtext handling.{% include 'wagtail_preamble.tex' %}You can set custom width for the richtext image insertion{% raw %}
\renewcommand{\fullwidth} {0.8\textwidth}
\renewcommand{\partialwidth} {0.5\textwidth}
{% endraw  %}A very useful block israw, this prevents the jinja rendering engine from interpreting everything inside.
This is nice if you want to create a latex command{% raw  %}
{% endraw  %}For further information readthe django-tex github page