Renderers#

Overview#

Building HTML from pages and sections#

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 as MediaDefiningClass#

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.

Page specific renderer for sections#

Renderer for sections might be page specific: suppose you have a section representing a gallery. You could register one renderer for the page with the gallery view and another for the page with the detail view of a gallery item. See register() for more information about registering a section renderer for a specific page type.

Api Reference#

Registry#

simple_page.renderers.register(model_cls, renderer_cls=None, page_type=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):
    ...

It is possible to register a section renderer for a specific page type. If you do something like this:

@renderers.register(FancySection, page_type=FancyPage)
class FancySectionRenderer(renderers.SectionRenderer):
    ...

the FancySectionRenderer would only be used for sections on a FancyPage instance.

Parameters:
simple_page.renderers.get_renderer(obj, page=None)#

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

Parameters:
  • obj (instance of Page or Section) – page or section instance to be rendered

  • page (instance of Page) – the page a section should be renderered for

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()#

Build and return rendering context:

  • section: section object

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

get_extra_head()#

Return additional HTML to be included in the page’s <head> section. This method is called within the get_extra_head()’s method of the page renderer.

By default this method tries to render a ‘head’ partial using the template and context returned by get_template_name() and get_context_data(). It fails silently if no such partial was defined. This allows you to provide extra head content for a section by simply adding such a partial to your section’s template. See the django docs for more information about partials.

Note

Template partials are supported since django 6.0. If you are using an older django version and want to provide extra head content for your section please override this method in your section renderer.

Return str:

additional HTML for the <head> of the rendered page.

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_extra_head(sections)#

Build additional HTML from the output of all section renderers’ get_extra_head() methods.

Return str:

additional HTML for the <head> of the rendered page.

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()#

Build the rendering context variables:

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 }}.

Return dict:

rendering context

render(**context)#

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

Parameters:

context (dict) – additional context to be passed to the template

Return str:

rendered HTML