firmant.writers

Writers transform parsed objects into files and directories on disk.

Writers are implemented behind the scenes in terms of chunks as defined in firmant.chunks. This is because writers need to do work at two different points in time, with other chunks being scheduled in between. The first chunk executed by a writer will forward-declare URLs that the writer claims responsibility for. The second chunk renders objects and saves the result to disk.

Modules in this package:

atom
feeds
j2
posts
static
staticrst

Functions

firmant.writers._setup(self)
Setup the test cases.

Classes

class firmant.writers.Writer(environment, objects, action=None)

Bases: firmant.chunks.AbstractChunk

The base class of all writers.

This class defines an abstract base class that all writers are required to adhere to. To use this class in the creation of a writer, create a subclass with all necessary methods and properties overwritten.

See also

Module abc
This module is part of the Python standard library in 2.6+.

To create a new type of writer, inherit from Writer:

>>> class SampleWriter(Writer):
...     extension = 'txt'
...     def key(self, obj):
...         return {'obj': str(obj)}
...     def obj_list(self, environment, objects):
...         return objects.get('objs', [])
...     def render(self, environment, path, obj):
...         print 'Save object "%s" to "%s"' % (obj, path)

The new writer meets the criteria for two different abstract base classes:

>>> import firmant.chunks
>>> issubclass(SampleWriter, firmant.chunks.AbstractChunk)
True
>>> issubclass(SampleWriter, Writer)
True

Warning

When creating a writer, do not store state in the writer itself. While it appears that a writer is a single object, it will actually share state across three or more chunks during typical usage.

If it is necessary to store state, place it in environment keyed to the writer class:

>>> environment[SampleWriter] = 'stored state goes here'

This is because of the need to split actions between url forward-declaration and rendering.

The remainder of this section is devoted to describing the implementation details of Writer‘s template methods.

Chunks are passed environment and object dictionaries. While it is not technically a chunk, the Writer interface follows the same pattern. When called with an environment and set of objects, a writer will return two more chunks (in addition to the environment and object dictionaries).

>>> environment = {'log': logger
...               ,'urlmapper': urlmapper
...               }
>>> environment['urlmapper'].add(
...     routing.SinglePathComponent('obj', str)
... )
>>> objects = {'objs': ['obj1', 'obj2', 'obj3']} 
>>> sw = SampleWriter(environment, objects)
>>> sw.scheduling_order
10
>>> pprint(sw(environment, objects)) 
({'log': <logging.Logger instance at 0x...>,
  'urlmapper': <firmant.routing.URLMapper object at 0x...>},
 {'objs': ['obj1', 'obj2', 'obj3']},
 [<firmant.writers.SampleWriter object at 0x...>,
  <firmant.writers.SampleWriter object at 0x...>])

Note

The chunks returned do not share any state with the Writer that created them. The fact that the class name is the same is an implementation detail that may change in the future.

The first chunk is the chunk that will build the urls, while the second is used for rendering. Neither chunk returns more chunks.

>>> environment, objects, (urls, render) = sw(environment, objects)
>>> urls.scheduling_order
500
>>> render.scheduling_order
900
>>> pprint(urls(environment, objects)) 
({'log': <logging.Logger instance at 0x...>,
  'urlmapper': <firmant.routing.URLMapper object at 0x...>,
  'urls': {'firmant.writers.SampleWriter': ['http://testurl/obj1/',
                                            'http://testurl/obj2/',
                                            'http://testurl/obj3/']}},
 {'objs': ['obj1', 'obj2', 'obj3']},
 [])
>>> pprint(render(environment, objects)) 
Save object "obj1" to "outputdir/obj1/index.txt"
Save object "obj2" to "outputdir/obj2/index.txt"
Save object "obj3" to "outputdir/obj3/index.txt"
({'log': <logging.Logger instance at 0x...>,
  'urlmapper': <firmant.routing.URLMapper object at 0x...>},
 {'objs': ['obj1', 'obj2', 'obj3']},
 [])
extension

The extension that will be used when finding the path/url of an object.

This will be passed to a firmant.routing.URLMapper instance.

key(obj)

Map the object to a dictionary of attributes.

The attributes will be passed to the path() and :meth`url` methods of firmant.routing.URLMapper.

obj_list(environment, objects)

The objects that should be passed to render()

It will be passed the environment and objects dictionaries that were passed to the chunk.

render(environment, path, obj)

Write the object to the path on filesystem.

path will be a path under the output directory. obj is one of the objects returned by obj_list.

scheduling_order

The following scheduling orders apply to writers:

10
At timestep 10, the writer will create the chunks for forward declaration and rendering.
500
At timestep 500, the writer will forward-declare urls.
900
At timestep 900, the writer will render the objects.
writername

The string displayed when interacting with the user.

This should be the name of the class they must specify in the configuration. The default value should not be changed.

Table Of Contents

Previous topic

firmant.utils.workarounds

Next topic

firmant.writers.atom

This Page