Chapter 8. Customization methods

Table of Contents

Customization layer
Writing a customization layer
Using a customization layer
Customizing both HTML and FO
Using catalogs with customizations
Setting parameters
Attribute sets
Completing placeholder templates
Generating new templates
Generated text
Default generated text
Customizing generated text
Replacing templates
Finding the right template
Import precedence
Passing parameters
Processing instructions

When you find that you need to change something that doesn't seem to have a parameter, then you will have to customize the DocBook XSL stylesheets. Fortunately, the stylesheets were designed to make them easy to customize (thanks to Norm Walsh). The basic idea is to create a customization layer in which you put all your changes, and then rely on the standard DocBook stylesheets for everything else. The following sections describe the various methods you can use:

Note

You don't need a customization layer to customize how your HTML output looks. You can control your HTML presentation by simply adding your own CSS stylesheet to the standard DocBook HTML output. See the section “Using CSS to style HTML” for more information.

Customization layer

A customization layer is a new XSL stylesheet that layers your changes on top of the existing DocBook XSL templates. It permits you to customize your processing without actually editing the original DocBook stylesheet files. Your changes are a thin layer on top of the extensive collection of DocBook code.

Keeping your changes separate has a lot of advantages:

  • You can generally upgrade to a new release of the DocBook stylesheets without having to reintegrate your changes into a lot of separate DocBook files. You may have to tweak your customization layer a bit, depending on the changes introduced in the new version. But you won't have to repeat typing a lot of code into the new version's files.

  • It makes it easy to distribute a customization to other users, because you only have to distribute one file and not a large collection of modified DocBook files.

  • Getting help with problems is easier because your changes are completely isolated. You can attach just your customization layer to an email, and others can apply it to their own standard DocBook files for testing.

Writing a customization layer

Writing a customization layer requires knowledge of XSLT syntax. You can read Appendix A, A brief introduction to XSL and the examples here to get started, but you will probably need to obtain a good XSLT reference book, such as Michael Kay's XSLT Programmer's Reference. For help in debugging a customization, see Appendix B, Debugging XSL stylesheets

The basic features of a customization layer are:

  • It is an XSLT stylesheet file, using standard XSLT syntax.

  • It imports one of the DocBook XSL stylesheet files, which acts as the starting point.

  • It adds whatever modifications are needed.

  • It is used in place of the standard DocBook stylesheet when you process your DocBook XML files.

The file can be named whatever you like, and you can create more than one customization layer with different customizations. Here is a very short example of a customization layer with each line explained. It just sets a few parameters for HTML processing:

Example 8.1. Customization layer

<?xml version='1.0'?> 1
<xsl:stylesheet  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 2

<xsl:import href="html/docbook.xsl"/> 3

<xsl:param name="html.stylesheet" select="'corpstyle.css'"/> 4
<xsl:param name="admon.graphics" select="1"/>

</xsl:stylesheet> 5 
1

The standard XML file marker.

2

Standard root element for XSL stylesheets.

3

Import the standard DocBook HTML stylesheet file using xsl:import.

4

Set a couple of parameters, using XSL syntax.

5

Close the root element and end the stylesheet.

If you use chunking for HTML, then replace docbook.xsl with chunk.xsl in the xsl:import statement. To customize print output, put a reference to the FO docbook.xsl file in the import statement.

If you write a customization layer for print output that includes FO elements such as fo:inline, then the stylesheet top element has to include the FO namespace declaration:

<?xml version='1.0'?> 
<xsl:stylesheet  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    version="1.0"> 

<xsl:import href="fo/docbook.xsl"/> 

<xsl:template match="lineannotation">
  <fo:inline font-style="italic">
    <xsl:call-template name="inline.charseq"/>
  </fo:inline>
</xsl:template>
</xsl:stylesheet>  

Using a customization layer

To process your XML files with the customization layer, you simply use your customization layer file in place of the standard DocBook file that it imports. For example, if the above example was saved to a file named mystyles.xsl, then you could use it as follows:

xsltproc  --output myfile.html  mystyles.xsl  myfile.xml

Here you have replaced the standard docbook.xsl stylesheet file with mystyles.xsl. Because your file imports the standard docbook.xsl file, the effect is the same as processing with the standard file but with your customizations added.

Customizing both HTML and FO

If you do customizations for both HTML and FO output, you need to start with separate customization layers. You might be tempted to write one customization layer that conditionally imports either the HTML or FO DocBook stylesheet. Unfortunately, it doesn't work, because the xsl:import statement cannot be placed inside an XSL conditional statement like xsl:if or xsl:choose. So you must have separate customization files for each. If you also do chunk and nonchunk HTML processing, then you will need a third customization layer.

Maintaining multiple customization layers can lead to inconsistencies as they change over time. Many of the parameters apply to both chunk and nonchunk HTML output, or to both HTML and FO output. If you set the admon.graphics parameter in one, you will probably want to set it in all. You can do that easily if you separate the common parts of your customization layer into a separate file. Then you can use xsl:include in all of your customization layers to include the same file with the same parameter settings. Here are two customizations that share a common-customizations.xsl file that contains shared parameters:

HTML customization:
<?xml version='1.0'?> 
<xsl:stylesheet  
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0"> 
  <xsl:import href="html/docbook.xsl"/> 
  <xsl:include href="common-customizations.xsl" />
  <xsl:param name="html.stylesheet" select="'corpstyle.css'"/> 
</xsl:stylesheet>  

FO customization:
<?xml version='1.0'?> 
<xsl:stylesheet  
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0"> 
  <xsl:import href="fo/docbook.xsl"/> 
  <xsl:include href="common-customizations.xsl" />
  <xsl:param name="paper.type" select="'A4'"/> 
</xsl:stylesheet>  

Any parameters that are specific to one output type are defined in that customization layer only.

If you use a relative path in the href of the xsl:include statement, then that is taken as relative to the location of your customization layer file. That's probably ok if you keep them all in one place.

Using catalogs with customizations

A customization layer imports the standard DocBook stylesheet file as its starting point. This means you must supply some URI in the href attribute of xsl:import.

That URI can be:

  • A relative pathname, which is taken to be relative to the location of the customization layer file.

  • An absolute pathname.

  • A web address.

Relative and absolute pathnames are not very portable. That means if you give someone else a copy of your customization layer, it may not work because the processor cannot find the original DocBook stylesheet file at the specified location.

Using a web address is generally more portable because most systems have web access today. But having to fetch a large number of stylesheet files over the web will greatly slow down your processing.

A good compromise is to use a web address for the URI but apply an XML catalog to map it to a local file location. See the section “Map a web address to a local file”.