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.