Monday, 15 November 2010

Creating PDF documents dynamically using Umbraco and XSL-FO part 2

Since my last post I have made a few modifications to the PDF generation, the main one being that the files are now dynamically renamed so that they reflect the name of the case study instead of all being called PDF.PDF which was not a very helpful filename, I just wanted to get something live last week, so decided that something was better than nothing :)

The issue with the filenames comes down to the way that the PDF's are being generated by using an alternative template in Umbraco, this means that all you need to do is add " /pdf " to the end of a case study URL and it will create a PDF version of the case study. The down side is that your browser will merrily download the file and save it as PDF.PDF because that is the name of the last part of the URL.

What you need to do is set the content-disposition header to be equal to the name you would like the file use, Darren Ferguson mentioned this on the Change the name of the PDF forum post.

We have used the same technique for downloading dynamically generated excel files, so I thought it would be useful to create a small macro to set both this header and also to set the caching headers to prevent any caching issues, I think in the past we have experienced all possible issues, including various issues where IE behaves differently to other browsers when you are using SSL and so the below code should work in all situations!

The template for the PDF alternative template is very simple:

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
   <umbraco:Macro Alias="PDFHeaders" runat="server"></umbraco:Macro>
   <umbraco:Macro xsl="FO-CaseStudy.xslt" Alias="PDFXSLFO" runat="server"></umbraco:Macro>
</asp:Content>

The following code snippet is the XSLT macro that simply creates our file name and then passes the file name into the helper function:

<xsl:template match="/">
        <xsl:variable name="fileName">
            <xsl:text>Vizioz_</xsl:text>
            <xsl:value-of select="$currentPage/@nodeName" />
            <xsl:text>_case_study.pdf</xsl:text>
        </xsl:variable>
        <xsl:value-of select="Vizioz.Helper:AddDocumentDownloadHeaders('application/pdf', $fileName)"/>
    </xsl:template>

And the following code is the helper function that clears the current response and adds all the appropriate headers:

public static void AddDocumentDownloadHeaders(string contentType, string fileName)
{
 HttpResponse response = HttpContext.Current.Response;
 HttpRequest request = HttpContext.Current.Request;

 response.Clear();
 response.ClearHeaders();

 if (request.IsSecureConnection & request.Browser.Browser == "IE")
  {
   // Don't use the caching headers if the browser is IE and it's a secure connection
   // see: http://support.microsoft.com/kb/323308
  }
 else
  {
   // force not using the cache
   response.AppendHeader("Cache-Control", "no-cache");
   response.AppendHeader("Cache-Control", "private");
   response.AppendHeader("Cache-Control", "no-store");
   response.AppendHeader("Cache-Control", "must-revalidate");
   response.AppendHeader("Cache-Control", "max-stale=0");
   response.AppendHeader("Cache-Control", "post-check=0");
   response.AppendHeader("Cache-Control", "pre-check=0");
   response.AppendHeader("Pragma", "no-cache");
   response.Cache.SetCacheability(HttpCacheability.NoCache);
   response.Cache.SetNoStore();
   response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
  }

 response.AppendHeader("Expires", DateTime.Now.AddMinutes(-1).ToLongDateString());
 response.AppendHeader("Keep-Alive", "timeout=3, max=993");
 response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + "\"");
 response.ContentType = contentType;
}

I will write another blog soon with some more details about XSL-FO and how to create the PDF's dynamically.

Please do re-tweet if you find this interest :)

Saturday, 13 November 2010

PDF from Umbraco | Creating PDF case studies from data in the Umbraco CMS

Last week we launched the first version of our website based on Umbraco 4.5.2 and this week we have just added a bit of extra functionality to the case studies section which enables you to download the case studies as PDF documents.

To do this we used the PDF Creator package by Darren Ferguson, this is actually a wrapper around a product from a company called Ibex, which is where you can download documentation for the mark up required.

The way Darren has made the implementation is really simple for anyone already familiar with the Umbraco CMS. You simple create a new template and call a Usercontrol macro, this then does the magic in the background and passes an XSLT file to the ibex engine.

What you need to be aware of is that you need to learn a new mark up language called XSL-FO this is actually part of the XSL 1.0 specification and is a language used to express print layouts.

As an indication of timescale, from knowing nothing about XSL-FO to the finished product that you can see on the website now has taken me 2 days of learning and just fiddling with the mark up to get the final result.

If anyone is interested I might post some code snippets to show you how some of it is done, I would also be really interested to have some feedback about the PDF layout and what you like and don't like about it.

Cheers,

Chris

Posted using BlogPress from my iPad

Thursday, 4 November 2010

Residential Care Homes website launched based on the Umbraco CMS

This week we have launched a new website for a local company called Ascot Residential Homes. They run two homes for the elderly and for those who suffer with dementia. Before we built the site for Ascot Residential Homes they asked us to visit the homes to get a feeling about how special they are. If you are looking for a home for an elderly relative I would highly recommend having a look at their website and if you are in the area arranging to visit them.

If you look on our site you will also find an Ascot Residential Homes case study in our Umbraco case studies section.

Top 5 most popular posts