Mercurial > piecrust2
comparison piecrust/data/builder.py @ 852:4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
* Everything is a `ContentSource`, including assets directories.
* Most content sources are subclasses of the base file-system source.
* A source is processed by a "pipeline", and there are 2 built-in pipelines,
one for assets and one for pages. The asset pipeline is vaguely functional,
but the page pipeline is completely broken right now.
* Rewrite the baking process as just running appropriate pipelines on each
content item. This should allow for better parallelization.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 17 May 2017 00:11:48 -0700 |
parents | 71c4f43d8fc1 |
children | f070a4fc033c |
comparison
equal
deleted
inserted
replaced
851:2c7e57d80bba | 852:4850f8c21b6e |
---|---|
1 import logging | 1 import logging |
2 from werkzeug.utils import cached_property | |
3 from piecrust.data.base import MergedMapping | 2 from piecrust.data.base import MergedMapping |
4 from piecrust.data.linker import PageLinkerData | 3 from piecrust.data.linker import PageLinkerData |
5 from piecrust.data.pagedata import PageData | 4 from piecrust.data.pagedata import PageData |
6 from piecrust.data.paginator import Paginator | 5 from piecrust.data.paginator import Paginator |
7 from piecrust.data.piecrustdata import PieCrustData | 6 from piecrust.data.piecrustdata import PieCrustData |
8 from piecrust.data.providersdata import DataProvidersData | 7 from piecrust.data.providersdata import DataProvidersData |
9 from piecrust.routing import CompositeRouteFunction | 8 from piecrust.routing import RouteFunction |
10 | 9 |
11 | 10 |
12 logger = logging.getLogger(__name__) | 11 logger = logging.getLogger(__name__) |
13 | 12 |
14 | 13 |
15 class DataBuildingContext(object): | 14 class DataBuildingContext(object): |
16 def __init__(self, qualified_page, page_num=1): | 15 def __init__(self, qualified_page): |
17 self.page = qualified_page | 16 self.qualified_page = qualified_page |
18 self.page_num = page_num | |
19 self.pagination_source = None | 17 self.pagination_source = None |
20 self.pagination_filter = None | 18 self.pagination_filter = None |
21 | 19 |
22 @property | |
23 def app(self): | |
24 return self.page.app | |
25 | |
26 @cached_property | |
27 def uri(self): | |
28 return self.page.getUri(self.page_num) | |
29 | |
30 | 20 |
31 def build_page_data(ctx): | 21 def build_page_data(ctx): |
32 app = ctx.app | 22 qpage = ctx.qualified_page |
33 page = ctx.page | 23 page = qpage.page |
24 app = page.app | |
34 pgn_source = ctx.pagination_source or get_default_pagination_source(page) | 25 pgn_source = ctx.pagination_source or get_default_pagination_source(page) |
35 first_uri = ctx.page.getUri(1) | 26 first_uri = ctx.page.getUri(1) |
36 | 27 |
37 pc_data = PieCrustData() | 28 pc_data = PieCrustData() |
38 config_data = PageData(page, ctx) | 29 config_data = PageData(page, ctx) |
39 paginator = Paginator(page, pgn_source, | 30 paginator = Paginator(qpage, pgn_source, |
40 page_num=ctx.page_num, | |
41 pgn_filter=ctx.pagination_filter) | 31 pgn_filter=ctx.pagination_filter) |
42 assetor = page.source.buildAssetor(page, first_uri) | 32 assetor = page.source.buildAssetor(page, first_uri) |
43 linker = PageLinkerData(page.source, page.rel_path) | 33 linker = PageLinkerData(page.source, page.rel_path) |
44 data = { | 34 data = { |
45 'piecrust': pc_data, | 35 'piecrust': pc_data, |
46 'page': config_data, | 36 'page': config_data, |
47 'assets': assetor, | 37 'assets': assetor, |
48 'pagination': paginator, | 38 'pagination': paginator, |
49 'family': linker | 39 'family': linker |
50 } | 40 } |
51 | 41 |
52 for route in app.routes: | 42 for route in app.routes: |
53 name = route.func_name | 43 name = route.func_name |
54 if not name: | 44 if not name: |
55 continue | 45 continue |
56 | 46 |
57 func = data.get(name) | 47 func = data.get(name) |
58 if func is None: | 48 if func is None: |
59 func = CompositeRouteFunction() | 49 data[name] = RouteFunction(route) |
60 func.addFunc(route) | |
61 data[name] = func | |
62 elif isinstance(func, CompositeRouteFunction): | |
63 func.addFunc(route) | |
64 else: | 50 else: |
65 raise Exception("Route function '%s' collides with an " | 51 raise Exception("Route function '%s' collides with an " |
66 "existing function or template data." % | 52 "existing function or template data." % |
67 name) | 53 name) |
68 | 54 |
69 #TODO: handle slugified taxonomy terms. | 55 # TODO: handle slugified taxonomy terms. |
70 | 56 |
71 site_data = app.config.getAll() | 57 site_data = app.config.getAll() |
72 providers_data = DataProvidersData(page) | 58 providers_data = DataProvidersData(page) |
73 data = MergedMapping([data, providers_data, site_data]) | 59 data = MergedMapping([data, providers_data, site_data]) |
74 | 60 |
79 pc_data.enableDebugInfo(page) | 65 pc_data.enableDebugInfo(page) |
80 | 66 |
81 return data | 67 return data |
82 | 68 |
83 | 69 |
84 def build_layout_data(page, page_data, contents): | 70 def add_layout_data(page_data, contents): |
85 for name, txt in contents.items(): | 71 for name, txt in contents.items(): |
86 if name in page_data: | 72 if name in page_data: |
87 logger.warning("Content segment '%s' will hide existing data." % | 73 logger.warning("Content segment '%s' will hide existing data." % |
88 name) | 74 name) |
89 page_data._prependMapping(contents) | 75 page_data._prependMapping(contents) |