Output Rendering
Cement defines an Output Interface, as well as the default DummyOutputHandler that implements the interface as a placeholder but does not actually produce any output.
Cement often includes multiple handler implementations of an interface that may or may not have additional features or functionality than the interface requires. The documentation below only references usage based on the interface and default handler (not the full capabilities of an implementation).
Cement Extensions That Provide Output Handlers:
API References:
Option | Description |
output_handler | The handler that implements the output interface. |
Cement applications do not need to use an output handler by any means. Most small applications can get away with simple
print()
statements. However, anyone who has ever built a bigger application that produces a lot of output will know that this can get ugly very quickly in your code.Using an output handler allows the developer to keep their logic clean, and offload the display of relevant data to an output handler, possibly by templates or other means (GUI?).
An output handler has a
render()
function that takes a data dictionary to produce output. Some output handlers may also accept a template
or other parameters that define how output is rendered. This is easily accessible by the application object.Example: Rendering Output
from cement import App
with App('myapp' as app:
app.run()
# create a data dictionary
data = {
'foo': 'bar',
}
# render data dictionary
app.render(data)
The above example uses the default
dummy
output handler, therefore nothing is displayed on screen. That said, for an example we can use the JSonOutputHandler to see something happen:Example: Defining an Output Handler
cli
from cement import App
class MyApp(App):
class Meta:
label = 'myapp'
extensions = ['json']
output_handler = 'json'
with MyApp() as app:
app.run()
# create a data dictionary
data = {
'foo': 'bar',
}
# render data dictionary
app.render(data)
$ python myapp.py
{"foo": "bar"}
While some output handlers only require the
data
dictionary, others can utilize text templates to render formatted output to console.Example: Rendering Output via Templates
cli
myapp.py
from cement import App
class MyApp(App):
class Meta:
label = 'myapp'
extensions = ['jinja2']
output_handler = 'jinja2'
template_dir = './templates'
with MyApp() as app:
app.run()
# create a data dictionary
data = {
'foo': 'bar',
}
# render data dictionary
app.render(data, 'example.jinja2')
templates/example.jinja2
Example Jinja2 Template
{% if foo %}
Foo => {{ foo }}
{% endif %}
$ python myapp.py
Example Jinja2 Template
Foo => bar
Template directories are looked for in the most common places by default as defined by
App.Meta.template_dirs
:- ~/.myapp/templates
- ~/.config/myapp/templates
- /usr/lib/myapp/templates
End-users can prepend their own paths to this list by setting the
template_dir
setting under the application configuration settings.Once a template is found, loading stops and the template is rendered.
All interfaces in Cement can be overridden with your own implementation. This can be done either by sub-classing
OutputHandler
itself, or by sub-classing an existing extension's handlers in order to alter their functionality.Example: Creating an Output Handler
myapp.py
from cement import App
from cement.core.output import OutputHandler
class MyOutputHandler(OutputHandler):
class Meta:
label = 'my_output_handler'
# do something to implement the interface
class MyApp(App):
class Meta:
label = 'myapp'
output_handler = 'my_output_handler'
handlers = [
MyOutputHandler,
]
Last modified 5yr ago