Consuming ZPT-Sharp as an API

ZPT-Sharp comes with two applications out of the box: an ASP.NET MVC view engine, and a command-line rendering app. It is also available as an API for consumption by your own applications.

The documentation presented here is intended to provide a high-level look at how to use that API. It is not detailed technical reference; there is in-depth class documentation available for that purpose. The information here links to that documentation where appropriate, providing context and an entry-point to the reference material.

Referencing ZPT-Sharp

To begin, you will need to reference ZPT-Sharp from your own project; there are two assemblies which are important.

First there is the abstractions assembly: CSF.Zpt.Abstractions.dll. This assembly contains no real logic, only interfaces, abstract types and a few data-carrying types.

Second is the main assembly: CSF.Zpt.dll. This assembly contains the concrete implementations of the core ZPT-Sharp logic.

Thus, the ZPT-Sharp implementation logic is separated from the interfaces by assembly; you may choose to split your own logic in a similar manner. To do this, reference the main assembly only from a small assembly of your own, which is only responsible for constructing instances of the concrete ZPT-Sharp types. Then, the remainder of your application need only reference the abstractions assembly, and deal with the API using its interfaces.

Plugin assemblies

ZPT-Sharp has extension points which are plugin-based. In almost all use-cases, you do not need to reference the plugin assemblies from your application. You will need to ensure that the relevant plugins are installed though; ZPT-Sharp won't do anything useful if no plugins are installed.

To install plugins, copy the relevant assemblies to your application's bin directory. Then, and add appropriate content to your application's configuration file.

API use-cases

The following section deals with - what are expected to be - the most common use-cases for consuming the ZPT-Sharp API. Where applicable, links are provided to the relevant reference documentation for any types which are mentioned.

Render a single document

In this API use-case, you begin with either a System.IO.FileInfo or a System.IO.Stream. This file or stream contains a single ZPT document. Your aim is to render that document either to a System.IO.TextWriter or to a System.String. The minimal steps to do this is as follows:

  1. Construct an instance of ZptDocumentFactory (found in the main assembly). This type implements the interface IZptDocumentFactory (found in the abstractions assembly).
  2. Use an appropriate overload of CreateDocument from the factory to get an object which implements IZptDocument (found in the abstractions assembly).
  3. Call an appropriate overload of the document's Render method.

There are optional parameters available for both the CreateDocument and Render methods. These allow you to customise how the document is created and/or rendered. Of note, are the following capabilities:

  • Specify an System.Text.Encoding to CreateDocument to specify the input encoding.
  • Specify a RenderingMode to CreateDocument to specify whether the source document is HTML or XML. This parameter is mandatory when the input is a Stream, as there is no file extension from which the type can be auto-detected.
  • Specify a model to Render to provide the representation of the model (in the MVC sense) to be rendered.
  • Provide an instance of IRenderingSettings to Render to control other aspects of the rendering process. It might be convenient to use a RenderingSettingsFactory to create the settings instance.

Render a native document

This use case is similar to the above, for rendering a single document; the key differences are your desired start and end points.

In this scenario, you begin with a concrete document implementation object such as a System.Xml.Linq.XDocument or an HTML Agility Pack HtmlDocument. Your goal is to render this to another instance of the same type.

This is a scenario where it becomes necessary to directly reference a plugin assembly from your application. You will need to reference the document provider plugin for the applicable document type.

In the plugin assembly, you will find a document provider type (a type which implements IZptDocumentProvider). Instantiate this directly - the plugin specification requires it to have a public parameterless constructor. On the concrete provider type You will find an overload of CreateDocument which does not appear on the interface. This extra overload of CreateDocument will accept an instance of the native document type, and will return an instance of a concrete ZPT document type.

That concrete ZPT document type will, in turn, expose a rendering method which does not appear on the IZptDocument interface. That extra rendering method will render the document and return an instance of the native document type.

Otherwise, apart from instantiating the document type directly and using an alternative rendering method, this use-case is identical in principle to the one above.

Batch-rendering multiple documents

ZPT-Sharp also provides a batch document renderer, which can iterate through many documents and render them all with a single API call. Typically, this is used to render all of the documents contained within a given directory path (and its subdirectories).

To use this functionality, you should first call the static method BatchRenderingOptions.Build() (this type is found in the main assembly). This method provides a fluent interface which guides you through the valid combinations of options, returning an object which implements IBatchRenderingOptions (found in the abstractions assembly). Consider the following example:

var batchOptions = BatchRenderingOptions
  .Build()
  .FromDirectory("my/input/path")
  .ToDirectory("my/output/path");

Next, instantiate one of the following two types, dependant upon your use-case (both are found in the main assembly):

Both of these types implement IBatchRenderer (abstractions assembly). The difference between them is how they respond to errors/unhandled exceptions whilst rendering. The regular batch renderer will stop upon the first error in rendering and abort all further operations, raising an exception. The error-tolerant batch renderer will skip rendering documents which fail, continuing with the rest. The error-tolerant version will only raise exceptions for truly fatal errors which prevent all rendering, such as an input directory which does not exist.

Once you have a batch renderer, call an appropriate overload of its Render method. As with the use-cases above you may optionally provide rendering settings, in exactly the same manner as already described for single-document rendering.