Document Templates¶
When it is not possible to achieve a particular document style using one of the existing templates and a custom template configuration, you can create a new template. A new template is programmed in Python and therefor it is required that you are familiar with Python, or at least with general object-oriented programming.
Subclassing a Template¶
If you need to customize a template beyond what is possible by configuration,
you can subclass a template class and override document part and page templates
with custom templates. The following example subclasses Article.
from rinoh.attribute import OverrideDefault
from rinoh.template import DocumentPartTemplate, PageTemplate
from rinoh.templates import Article
class BibliographyPartTemplate(DocumentPartTemplate):
...
class MyTitlePageTemplate(PageTemplate):
...
class MyArticle(Article):
parts = OverrideDefault(['title', 'contents', 'bibliography'])
# default document part templates
bibliography = BibliographyPartTemplate()
# default page templates
title_page = MyTitlePageTemplate(base='page')
bibliography_page = PageTemplate(base='page')
MyArticle extends the Article template, adding the extra
bibliography document part, along with the page template
bibliography_page. The new document part is included in
parts, while also leaving out
front_matter by default. Finally, the template also replaces
the title page template with a custom one.
Creating a Custom Template¶
A new template can be created from scratch by subclassing
DocumentTemplate, defining all document parts, their templates and
page templates.
The Article and Book templates are examples of templates
that inherit directly from DocumentTemplate. We will briefly discuss
the article template. The Article template overrides the default
style sheet and defines the two custom template attributes discussed in
Configuring a Template. The document parts title,
front_matter and contents are listed the in
parts attribute and part templates for each are provided
along with page templates:
class Article(DocumentTemplate):
stylesheet = OverrideDefault(sphinx_article)
table_of_contents = Attribute(Bool, True,
'Show or hide the table of contents')
abstract_location = Attribute(AbstractLocation, 'front matter',
'Where to place the abstract')
parts = OverrideDefault(['title', 'front_matter', 'contents'])
# default document part templates
title = TitlePartTemplate()
front_matter = ArticleFrontMatter()
contents = ContentsPartTemplate()
# default page templates
page = PageTemplate(page_size=Var('paper_size'))
title_page = TitlePageTemplate(base='page',
top_margin=8*CM)
front_matter_page = PageTemplate(base='page')
contents_page = PageTemplate(base='page')
The custom ArticleFrontMatter template reads the values for the
two custom template attributes defined in Article to determine which
flowables are included in the front matter:
class ArticleFrontMatter(DocumentPartTemplate):
toc_section = TableOfContentsSection()
def _flowables(self, document):
meta = document.metadata
abstract_loc = document.get_option('abstract_location')
if ('abstract' in meta
and abstract_loc == AbstractLocation.FRONT_MATTER):
yield meta['abstract']
if document.get_option('table_of_contents'):
yield self.toc_section
Have a look at the Book template source code for an example of a slightly more complex template that defines separate templates for left and right pages.