view piecrust/data/paginationdata.py @ 661:2f780b191541

internal: Fix a bug with registering taxonomy terms that are not strings. Some objects, like the blog data provider's taxnonomy entries, can render as strings, but are objects themselves. When registering them as "used terms", we need to use their string representation.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 01 Mar 2016 22:26:09 -0800
parents 32c7c2d219d2
children ab5c6a8ae90a
line wrap: on
line source

import time
from piecrust.data.assetor import Assetor
from piecrust.data.pagedata import LazyPageConfigData
from piecrust.routing import create_route_metadata
from piecrust.uriutil import split_uri


class PaginationData(LazyPageConfigData):
    def __init__(self, page):
        super(PaginationData, self).__init__(page)
        self._route = None
        self._route_metadata = None

    def _get_uri(self):
        page = self._page
        if self._route is None:
            # TODO: this is not quite correct, as we're missing parts of the
            #       route metadata if the current page is a taxonomy page.
            route_metadata = create_route_metadata(page)
            self._route = page.app.getRoute(page.source.name, route_metadata)
            self._route_metadata = route_metadata
            if self._route is None:
                raise Exception("Can't get route for page: %s" % page.path)
        return self._route.getUri(self._route_metadata)

    def _load(self):
        page = self._page
        page_url = self._get_uri()
        _, slug = split_uri(page.app, page_url)
        self._setValue('url', page_url)
        self._setValue('slug', slug)
        self._setValue(
                'timestamp',
                time.mktime(page.datetime.timetuple()))
        date_format = page.app.config.get('site/date_format')
        if date_format:
            self._setValue('date', page.datetime.strftime(date_format))
        self._setValue('mtime', page.path_mtime)

        assetor = Assetor(page, page_url)
        self._setValue('assets', assetor)

        segment_names = page.config.get('segments')
        for name in segment_names:
            self._mapLoader(name, self._load_rendered_segment)

    def _load_rendered_segment(self, data, name):
        do_render = True
        eis = self._page.app.env.exec_info_stack
        if eis is not None and eis.hasPage(self._page):
            # This is the pagination data for the page that is currently
            # being rendered! Inception! But this is possible... so just
            # prevent infinite recursion.
            do_render = False

        assert self is data

        if do_render:
            uri = self._get_uri()
            try:
                from piecrust.rendering import (
                        QualifiedPage, PageRenderingContext,
                        render_page_segments)
                qp = QualifiedPage(self._page, self._route,
                                   self._route_metadata)
                ctx = PageRenderingContext(qp)
                render_result = render_page_segments(ctx)
                segs = render_result.segments
            except Exception as e:
                raise Exception(
                        "Error rendering segments for '%s'" % uri) from e
        else:
            segs = {}
            for name in self._page.config.get('segments'):
                segs[name] = "<unavailable: current page>"

        for k, v in segs.items():
            self._unmapLoader(k)
            self._setValue(k, v)

        if 'content.abstract' in segs:
            self._setValue('content', segs['content.abstract'])
            self._setValue('has_more', True)
            if name == 'content':
                return segs['content.abstract']

        return segs[name]