Renderers#

Overview#

To build the HTML for a page or section object a renderer class is used. While a section renderer produces a html snippet representing the section object, a page renderer provides a full html document - including all its sections.

Nevertheless, both renderer classes are based on the same concept, using the proven triad of get_template_name, get_context_data and render methods.

While there are default renderers for pages and sections which do the obvious, you can equip your page and section models with customized renderer classes.

Renderer classes using django’s MediaDefiningClass as metaclass. They can be equipped with a Media class like django’s forms and widgets:

from simple_page import renderers
from .models import FancySection

@renderers.register(FancySection)
class FancySectionRenderer(renderers.SectionRenderer):
    class Media:
        css = dict(all=['fancy_section.css'])
        js = ['fancy_section.js']

The merged media assets will be available as a media template variable for the page. See get_media_assets() for details.

Api Reference#

Registry#

simple_page.renderers.register(model_cls, renderer_cls=None)#

Register a renderer class for a page or section model. This function can also be used as a decorator:

@renderers.register(FancyPage)
class FancyPageRenderer(renderers.PageRenderer):
    ...
Parameters:
simple_page.renderers.get_renderer(obj)#

Return the registered renderer for a page or section. Fall back to the default renderers: PageRenderer or SectionRenderer.

Parameters:

obj (Page or Section) – page or section instance to be rendered

Returns:

renderer class

Return type:

PageRenderer or SectionRenderer

Renderer Classes#

class simple_page.renderers.SectionRenderer(section, page, region, request=None, **params)#

Bases: object

Renderer for Section instances. Section renderers will most likely be used from within the page’s template using the builtin include tag:

{% for section in regions.main.sections %}
    {% include section %}
{% endfor %}

This way the render() method will be called and its output will be included in the page’s template. By default the include tag will pass the current context to the section renderer. See the Django docs for the include tag

Since a section renderer is initialized with the page, region and request, it knows about the full context in which a section should be rendererd. Customized renderer classes can use this information to adapt the rendering logic for a specific rendering context.

Parameters:
  • section (Section) – section instance to be rendered

  • page (Page) – page the section will be rendered for

  • region (str) – region the section will be rendered in

  • request (HttpRequest, optional) – HTTP request, optional

  • params (dict) – additional keyword arguments

get_template_name()#

Return the template path. It will be build based on the section’s class name:

'sections/<section_class_name_in_snake_case>.html'
Return str:

path to template file

get_context_data(**context)#

Build and return rendering context:

  • section: section object

Parameters:

context (dict) – additional keyword arguments used as context data

Return dict:

rendering context

render(context=None)#

Return the rendered HTML using the template and context returned by get_template_name() and get_context_data() methods.

Parameters:

context (Context or dict, optional) – additional context to be passed to the template

Returns:

rendered HTML

Return type:

str

class simple_page.renderers.PageRenderer(page, request=None, **params)#

Bases: object

Renderer for Page instances. This renderer will most likely be used in a view function. Simply call its render() method and return its output as a HTTP response:

def page_view(request, slug, **kwargs):
    page = get_object_or_404(Page, slug=slug).resolve_obj()
    renderer_cls = get_renderer(page)
    return HttpResponse(renderer_cls(page, request).render(**kwargs))

You are free to pass the request to the renderer. If you do your template will be rendered with a RequestContext.

Parameters:
  • page (Page) – page instance to be rendered

  • request (HttpRequest, optional) – HTTP request, optional

  • params (dict) – additional keyword arguments

get_region_data(region, title)#

Build and return a dictionary holding the region’s data:

  • name: region name

  • title: region title

  • sections: list of section renderers for this region

Parameters:
  • region (str) – region name

  • tilte (str) – region title

Returns:

region data holding title, name and sections for this region

Return type:

dict

get_media_assets(sections)#

Merge media definitions of all renderers involved. The page’s one and all its section renderers. Return the merged Media object.

Returns:

merged media assets

Return type:

Media

get_template_name()#

Return the template path. It will be build based on the page’s class name:

'pages/<page_class_name_in_snake_case>.html'
Return str:

path to template file

get_context_data(**context)#

Build the rendering context variables:

  • page: page object

  • sections: set of all section renderers

  • regions: mapping of region names to their data build by get_region_data()

  • media: media assets build by get_media_assets()

As a shortcut each region data will also be added using the region’s name as an own context variable. In your template these variables are equivalent: {{ regions.main }} and {{ main }}.

Parameters:

context (dict) – additional keyword arguments used as context data

Return dict:

rendering context

render(context=None)#

Return the rendered HTML using the template and context returned by get_template_name() and get_context_data() methods.

Parameters:

context (Context or dict, optional) – additional context to be passed to the template

Return str:

rendered HTML