# HG changeset patch # User Ludovic Chabant # Date 1486363812 28800 # Node ID dca51cd8147a2af0eafb3bbcd8e98cb4db68a30a # Parent cb39c0dbe5f00d2d600e480cf507dd4a871b81b8# Parent cc9593b9bcbf350b760dd6424bf7e6633ce82c80 Merge pull request #42 from GitHub. Also cleanup the code a bit. diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/01_tutorial/01_your-first-blog.md --- a/docs/docs/01_tutorial/01_your-first-blog.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/01_tutorial/01_your-first-blog.md Sun Feb 05 22:50:12 2017 -0800 @@ -226,7 +226,7 @@ adjusted with the `site/post_url` setting. By default, it is: site: - post_url: "%year%/%month%/%day%/%slug% + post_url: "%year%/%month%/%day%/%slug%" The post URL format is defined using some keywords surrounded by percent signs, as you can see above. The `%year%`, `%month%` and `%day%` keywords should be @@ -269,7 +269,7 @@ [yaml]: https://en.wikipedia.org/wiki/YAML [slug]: http://en.wikipedia.org/wiki/Semantic_URL#Slug [pageconfref]: {{pcurl('docs/reference/page-config')}} -[siteconfref]: {{pcurl('docs/reference/site-config')}} +[siteconfref]: {{pcurl('docs/reference/website-config')}} [part2]: {{pcurl('docs/tutorial/making-things-pretty')}} [routes]: {{docurl('content-model/routes')}} [tpl]: {{docurl('content/templating')}} diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/01_tutorial/02_making-things-pretty.md --- a/docs/docs/01_tutorial/02_making-things-pretty.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/01_tutorial/02_making-things-pretty.md Sun Feb 05 22:50:12 2017 -0800 @@ -28,7 +28,7 @@ templates/post.html All of those files have been copied into your website's directory -- and it will -warn you if it was every going to overwrite some of your own files. +warn you if it was ever going to overwrite some of your own files. There are a few files we'll be editing here: diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/02_general/01_chef.md --- a/docs/docs/02_general/01_chef.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/02_general/01_chef.md Sun Feb 05 22:50:12 2017 -0800 @@ -64,7 +64,7 @@ * `--config-set ` lets you override _a specific configuration setting_. -[3]: {{docurl('general/website-config')}} +[3]: {{docurl('general/website-configuration')}} ### Logging diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/03_content.md --- a/docs/docs/03_content.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/03_content.md Sun Feb 05 22:50:12 2017 -0800 @@ -3,7 +3,7 @@ --- This section of the documentation explains how to write, or otherwise create and -us, content for PieCrust websites -- pages, layouts, assets, etc. If however you +use, content for PieCrust websites -- pages, layouts, assets, etc. If however you want to *define* what *types* of content your website will have in the first place, you may want to read up on the [content model documentation][cm]. diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/03_content/01_creating-pages.md --- a/docs/docs/03_content/01_creating-pages.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/03_content/01_creating-pages.md Sun Feb 05 22:50:12 2017 -0800 @@ -4,8 +4,8 @@ In PieCrust, creating pages is a matter of creating a text file in the correct place with the correct name. This mostly depends on the [page sources][src] -you're using, but we can go over how it works for the sources involved in the -[default content model][dcm]. +you're using, but we can go over how it works for the sources involved in +the [default content model][dcm]. We will also mention the `chef prepare` command, which semi-automates the process of creating pages by letting you type a lot less than what would be diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/03_content/03_formatters.md --- a/docs/docs/03_content/03_formatters.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/03_content/03_formatters.md Sun Feb 05 22:50:12 2017 -0800 @@ -6,8 +6,8 @@ contents that you write go through a _formatter_ before the page is rendered or baked. PieCrust ships with 2 standard formatters: [Markdown][] and [Textile][]. -The formatter used on a page is determined by the `format` setting in the page's -[configuration header][pageconf]: +The formatter used on a page is determined by the `format` setting in the +page's [configuration header][pageconf]: * `markdown` for Markdown * `textile` for Textile @@ -25,7 +25,7 @@ [how]: {{docurl('general/how-it-works')}} [pageconf]: {{docurl('content/page-configuration')}} -[siteconf]: {{docurl('general/site-configuration')}} +[siteconf]: {{docurl('general/website-configuration')}} [markdown]: https://en.wikipedia.org/wiki/Markdown [textile]: https://en.wikipedia.org/wiki/Textile_(markup_language) diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/03_content/04_templating.md --- a/docs/docs/03_content/04_templating.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/03_content/04_templating.md Sun Feb 05 22:50:12 2017 -0800 @@ -5,7 +5,7 @@ As explained in the documentation about [how PieCrust works][how], the page contents that you write go through a _templating_ phase, which is when a page can execute some logic, insert reusable bits of markup, or reference other -pieces of content or metadata from elsewhere in you website. +pieces of content or metadata from elsewhere in your website. PieCrust uses [Jinja][] for templating. There's too much data exposed to it to go over on this page, but check out the [templating data reference][dataref] for @@ -55,7 +55,7 @@ [how]: {{docurl('general/how-it-works')}} [pageconf]: {{docurl('content/page-configuration')}} -[siteconf]: {{docurl('general/site-configuration')}} +[siteconf]: {{docurl('general/website-configuration')}} [dataref]: {{docurl('reference/templating-data')}} [assets]: {{docurl('content/assets')}} [jinja]: http://jinja.pocoo.org/docs/dev/templates/ diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/03_content/05_content-segments.md --- a/docs/docs/03_content/05_content-segments.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/03_content/05_content-segments.md Sun Feb 05 22:50:12 2017 -0800 @@ -39,7 +39,7 @@ ---sidebar--- Sidebar goes here -You can them use, the page's layout, both the `content` and `sidebar` segments +You can then use, the page's layout, both the `content` and `sidebar` segments to put each piece of text in its appropriate place. You can also specify a [formatter][] for a given segment, by adding `:formatter` diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/03_content/08_iterators.md --- a/docs/docs/03_content/08_iterators.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/03_content/08_iterators.md Sun Feb 05 22:50:12 2017 -0800 @@ -4,8 +4,8 @@ --- PieCrust returns _iterator objects_ as template data in several cases: -`pagination.posts`, `assets`, `site.pages`, etc. Any time there's a list of -_stuff_, you can bet it's returned as an _iterator object_. +`pagination.posts`, `assets`, `site.pages`, etc. Any time there's a list +of _stuff_, you can bet it's returned as an _iterator object_. At first glance, there's not much difference with a simple list: diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/04_content-model/03_generators.md --- a/docs/docs/04_content-model/03_generators.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/04_content-model/03_generators.md Sun Feb 05 22:50:12 2017 -0800 @@ -16,8 +16,8 @@ generators: my_archives: type: blog_archives - source: posts - page: 'page:_year.md' + source: posts + page: 'page:_year.md' ``` The only required setting for a generator is the `type` setting, which specifies diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/05_asset-pipeline.md --- a/docs/docs/05_asset-pipeline.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/05_asset-pipeline.md Sun Feb 05 22:50:12 2017 -0800 @@ -27,7 +27,7 @@ * Process it, if it matches any of the active asset processors. The output of the processing phase will be put in the output directory. -* Copy it as is, if not asset processor was found. Just like for processing, the +* Copy it as is, if no asset processor was found. Just like for processing, the relative path of the asset is preserved in the output directory. @@ -45,7 +45,7 @@ processors match and the `copy` processor copies the result to the output(s) directory. -So for instance, you if you have a LessCSS file, it will be processed like so: +So for instance, if you have a LessCSS file, it will be processed like so: foo.less -> foo.css -> foo.min.css diff -r cc9593b9bcbf -r dca51cd8147a docs/docs/06_themes.md --- a/docs/docs/06_themes.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/docs/06_themes.md Sun Feb 05 22:50:12 2017 -0800 @@ -3,7 +3,7 @@ --- Themes let you change your website's appearance easily by applying a new set of -templates, layouts, and styles over you content. You're probably already +templates, layouts, and styles over your content. You're probably already familiar with this concept if you're coming from some other CMS like WordPress. In PieCrust, themes work better if you don't have any templates -- otherwise, diff -r cc9593b9bcbf -r dca51cd8147a docs/pages/getting-started.md --- a/docs/pages/getting-started.md Tue Jan 03 02:34:43 2017 -0500 +++ b/docs/pages/getting-started.md Sun Feb 05 22:50:12 2017 -0800 @@ -152,8 +152,7 @@ website being served from there. -That's it! This is an extremely quick tour of PieCrust. Read the -[documentation][doc] to learn more. +That's it! This is an extremely quick tour of PieCrust. Read the [documentation][doc] to learn more. [1]: https://www.python.org/downloads/ diff -r cc9593b9bcbf -r dca51cd8147a piecrust/app.py diff -r cc9593b9bcbf -r dca51cd8147a piecrust/baking/single.py --- a/piecrust/baking/single.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/baking/single.py Sun Feb 05 22:50:12 2017 -0800 @@ -1,6 +1,5 @@ import os.path import queue -import shutil import logging import threading import urllib.parse @@ -56,13 +55,11 @@ self._writer_queue.put_nowait(None) self._writer.join() - def getOutputPath(self, uri, pretty_urls=None): + def getOutputPath(self, uri, pretty_urls): uri_root, uri_path = split_uri(self.app, uri) bake_path = [self.out_dir] decoded_uri = urllib.parse.unquote(uri_path) - if pretty_urls is None: - pretty_urls = self.pretty_urls if pretty_urls: bake_path.append(decoded_uri) bake_path.append('index.html') @@ -84,7 +81,8 @@ # Get the URL and path for this sub-page. sub_uri = qualified_page.getUri(cur_sub) logger.debug("Baking '%s' [%d]..." % (sub_uri, cur_sub)) - pretty_urls = qualified_page.pretty_urls if qualified_page.pretty_urls is not None else self.pretty_urls + pretty_urls = qualified_page.config.get('pretty_urls', + self.pretty_urls) out_path = self.getOutputPath(sub_uri, pretty_urls) # Create the sub-entry for the bake record. @@ -170,14 +168,7 @@ logger.debug("Copying page assets to: %s" % out_assets_dir) _ensure_dir_exists(out_assets_dir) - page_pathname, _ = os.path.splitext(qualified_page.path) - in_assets_dir = page_pathname + ASSET_DIR_SUFFIX - for fn in os.listdir(in_assets_dir): - full_fn = os.path.join(in_assets_dir, fn) - if os.path.isfile(full_fn): - dest_ap = os.path.join(out_assets_dir, fn) - logger.debug(" %s -> %s" % (full_fn, dest_ap)) - shutil.copy(full_fn, dest_ap) + qualified_page.source.buildAssetor(qualified_page, sub_uri).copyAssets(out_assets_dir) # Figure out if we have more work. has_more_subs = False diff -r cc9593b9bcbf -r dca51cd8147a piecrust/baking/worker.py --- a/piecrust/baking/worker.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/baking/worker.py Sun Feb 05 22:50:12 2017 -0800 @@ -231,7 +231,7 @@ qp, previous_entry, dirty_source_names, gen_name) result['sub_entries'] = sub_entries - except BakingError as ex: + except Exception as ex: logger.debug("Got baking error. Sending it to master.") result['errors'] = _get_errors(ex) if self.ctx.app.debug: diff -r cc9593b9bcbf -r dca51cd8147a piecrust/data/assetor.py --- a/piecrust/data/assetor.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/data/assetor.py Sun Feb 05 22:50:12 2017 -0800 @@ -1,5 +1,6 @@ import os import os.path +import shutil import logging from piecrust import ASSET_DIR_SUFFIX from piecrust.uriutil import multi_replace @@ -31,12 +32,7 @@ return base_url.rstrip('/') + '/' -class Assetor(object): - debug_render_doc = """Helps render URLs to files in the current page's - asset folder.""" - debug_render = [] - debug_render_dynamic = ['_debugRenderAssetNames'] - +class AssetorBase(object): def __init__(self, page, uri): self._page = page self._uri = uri @@ -68,8 +64,23 @@ def _cacheAssets(self): if self._cache is not None: return + + self._cache = dict(self.findAssets()) + + def findAssets(self): + raise NotImplementedError() - self._cache = {} + def copyAssets(self, dest_dir): + raise NotImplementedError() + +class Assetor(AssetorBase): + debug_render_doc = """Helps render URLs to files in the current page's + asset folder.""" + debug_render = [] + debug_render_dynamic = ['_debugRenderAssetNames'] + + def findAssets(self): + assets = {} name, ext = os.path.splitext(self._page.path) assets_dir = name + ASSET_DIR_SUFFIX if not os.path.isdir(assets_dir): @@ -84,12 +95,23 @@ continue name, ext = os.path.splitext(fn) - if name in self._cache: + if name in assets: raise UnsupportedAssetsError( "Multiple asset files are named '%s'." % name) - self._cache[name] = (base_url + fn, full_fn) + assets[name] = (base_url + fn, full_fn) cpi = self._page.app.env.exec_info_stack.current_page_info if cpi is not None: cpi.render_ctx.current_pass_info.used_assets = True - + + return assets + + def copyAssets(self, dest_dir): + page_pathname, _ = os.path.splitext(self._page.path) + in_assets_dir = page_pathname + ASSET_DIR_SUFFIX + for fn in os.listdir(in_assets_dir): + full_fn = os.path.join(in_assets_dir, fn) + if os.path.isfile(full_fn): + dest_ap = os.path.join(dest_dir, fn) + logger.debug(" %s -> %s" % (full_fn, dest_ap)) + shutil.copy(full_fn, dest_ap) diff -r cc9593b9bcbf -r dca51cd8147a piecrust/data/builder.py --- a/piecrust/data/builder.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/data/builder.py Sun Feb 05 22:50:12 2017 -0800 @@ -1,6 +1,5 @@ import logging from werkzeug.utils import cached_property -from piecrust.data.assetor import Assetor from piecrust.data.base import MergedMapping from piecrust.data.linker import PageLinkerData from piecrust.data.pagedata import PageData @@ -40,7 +39,7 @@ paginator = Paginator(page, pgn_source, page_num=ctx.page_num, pgn_filter=ctx.pagination_filter) - assetor = Assetor(page, first_uri) + assetor = page.source.buildAssetor(page, first_uri) linker = PageLinkerData(page.source, page.rel_path) data = { 'piecrust': pc_data, diff -r cc9593b9bcbf -r dca51cd8147a piecrust/data/paginationdata.py --- a/piecrust/data/paginationdata.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/data/paginationdata.py Sun Feb 05 22:50:12 2017 -0800 @@ -45,7 +45,7 @@ self._setValue('date', page.datetime.strftime(date_format)) self._setValue('mtime', page.path_mtime) - assetor = Assetor(page, page_url) + assetor = page.source.buildAssetor(page, page_url) self._setValue('assets', assetor) segment_names = page.config.get('segments') diff -r cc9593b9bcbf -r dca51cd8147a piecrust/data/provider.py --- a/piecrust/data/provider.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/data/provider.py Sun Feb 05 22:50:12 2017 -0800 @@ -1,10 +1,21 @@ import time import collections.abc +from piecrust.configuration import ConfigurationError from piecrust.data.iterators import PageIterator from piecrust.generation.taxonomy import Taxonomy from piecrust.sources.array import ArraySource +def get_data_provider_class(app, provider_type): + if not provider_type: + raise Exception("No data provider type specified.") + for prov in app.plugin_loader.getDataProviders(): + if prov.PROVIDER_NAME == provider_type: + return prov + raise ConfigurationError( + "Unknown data provider type: %s" % provider_type) + + class DataProvider(object): debug_render_dynamic = [] debug_render_invoke_dynamic = [] diff -r cc9593b9bcbf -r dca51cd8147a piecrust/data/providersdata.py --- a/piecrust/data/providersdata.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/data/providersdata.py Sun Feb 05 22:50:12 2017 -0800 @@ -27,13 +27,14 @@ return self._dict = {} - for source in self._page.app.sources: - endpoint_bits = re_endpoint_sep.split(source.data_endpoint) - endpoint = self._dict - for e in endpoint_bits[:-1]: - if e not in endpoint: - endpoint[e] = {} - endpoint = endpoint[e] - override = endpoint.get(endpoint_bits[-1]) - provider = source.buildDataProvider(self._page, override) - endpoint[endpoint_bits[-1]] = provider + for source in self._page.app.sources + self._page.app.generators: + if source.data_endpoint: + endpoint_bits = re_endpoint_sep.split(source.data_endpoint) + endpoint = self._dict + for e in endpoint_bits[:-1]: + if e not in endpoint: + endpoint[e] = {} + endpoint = endpoint[e] + override = endpoint.get(endpoint_bits[-1]) + provider = source.buildDataProvider(self._page, override) + endpoint[endpoint_bits[-1]] = provider diff -r cc9593b9bcbf -r dca51cd8147a piecrust/generation/base.py --- a/piecrust/generation/base.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/generation/base.py Sun Feb 05 22:50:12 2017 -0800 @@ -125,6 +125,15 @@ "Generator '%s' requires a listing page ref." % name) self.page_ref = PageRef(app, page_ref) + self.data_endpoint = config.get('data_endpoint') + self.data_type = config.get('data_type') + if self.data_endpoint and not self.data_type: + raise ConfigurationError( + "Generator '%s' requires a data type because it has " + "a data endpoint." % name) + + self._provider_type = None + @cached_property def source(self): for src in self.app.sources: @@ -146,3 +155,9 @@ def onRouteFunctionUsed(self, route, route_metadata): pass + def buildDataProvider(self, page, override): + if not self._provider_type: + from piecrust.data.provider import get_data_provider_class + self._provider_type = get_data_provider_class(self.app, + self.data_type) + return self._provider_type(self, page, override) diff -r cc9593b9bcbf -r dca51cd8147a piecrust/page.py --- a/piecrust/page.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/page.py Sun Feb 05 22:50:12 2017 -0800 @@ -139,6 +139,7 @@ if was_cache_valid: self._flags |= FLAG_RAW_CACHE_VALID + self.source.finalizeConfig(self) def _parse_config_date(page_date): if page_date is None: diff -r cc9593b9bcbf -r dca51cd8147a piecrust/plugins/builtin.py --- a/piecrust/plugins/builtin.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/plugins/builtin.py Sun Feb 05 22:50:12 2017 -0800 @@ -1,139 +1,152 @@ -from piecrust.commands.base import HelpCommand -from piecrust.commands.builtin.admin import AdministrationPanelCommand -from piecrust.commands.builtin.baking import ( - BakeCommand, ShowRecordCommand) -from piecrust.commands.builtin.info import ( - RootCommand, ShowConfigCommand, - FindCommand, ShowSourcesCommand, ShowRoutesCommand, ShowPathsCommand) -from piecrust.commands.builtin.plugins import PluginsCommand -from piecrust.commands.builtin.publishing import PublishCommand -from piecrust.commands.builtin.scaffolding import ( - PrepareCommand, - DefaultPrepareTemplatesCommandExtension, - UserDefinedPrepareTemplatesCommandExtension, - DefaultPrepareTemplatesHelpTopic) -from piecrust.commands.builtin.serving import (ServeCommand) -from piecrust.commands.builtin.themes import (ThemesCommand) -from piecrust.commands.builtin.util import ( - InitCommand, PurgeCommand, ImportCommand) -from piecrust.data.provider import (IteratorDataProvider, BlogDataProvider) -from piecrust.formatting.hoedownformatter import HoedownFormatter -from piecrust.formatting.markdownformatter import MarkdownFormatter -from piecrust.formatting.textileformatter import TextileFormatter -from piecrust.formatting.smartypantsformatter import SmartyPantsFormatter -from piecrust.generation.blogarchives import BlogArchivesPageGenerator -from piecrust.generation.taxonomy import TaxonomyPageGenerator -from piecrust.importing.jekyll import JekyllImporter -from piecrust.importing.piecrust import PieCrust1Importer -from piecrust.importing.wordpress import WordpressXmlImporter from piecrust.plugins.base import PieCrustPlugin -from piecrust.processing.base import CopyFileProcessor -from piecrust.processing.compass import CompassProcessor -from piecrust.processing.compressors import ( - CleanCssProcessor, UglifyJSProcessor) -from piecrust.processing.less import LessProcessor -from piecrust.processing.pygments_style import PygmentsStyleProcessor -from piecrust.processing.requirejs import RequireJSProcessor -from piecrust.processing.sass import SassProcessor -from piecrust.processing.sitemap import SitemapProcessor -from piecrust.processing.util import ConcatProcessor -from piecrust.publishing.sftp import SftpPublisher -from piecrust.publishing.shell import ShellCommandPublisher -from piecrust.publishing.rsync import RsyncPublisher -from piecrust.sources.default import DefaultPageSource -from piecrust.sources.posts import ( - FlatPostsSource, ShallowPostsSource, HierarchyPostsSource) -from piecrust.sources.autoconfig import ( - AutoConfigSource, OrderedPageSource) -from piecrust.sources.prose import ProseSource -from piecrust.templating.jinjaengine import JinjaTemplateEngine -from piecrust.templating.pystacheengine import PystacheTemplateEngine class BuiltInPlugin(PieCrustPlugin): name = '__builtin__' def getCommands(self): + from piecrust.commands.base import HelpCommand + from piecrust.commands.builtin.admin import AdministrationPanelCommand + from piecrust.commands.builtin.baking import ( + BakeCommand, ShowRecordCommand) + from piecrust.commands.builtin.info import ( + RootCommand, ShowConfigCommand, + FindCommand, ShowSourcesCommand, ShowRoutesCommand, + ShowPathsCommand) + from piecrust.commands.builtin.plugins import PluginsCommand + from piecrust.commands.builtin.publishing import PublishCommand + from piecrust.commands.builtin.scaffolding import PrepareCommand + from piecrust.commands.builtin.serving import (ServeCommand) + from piecrust.commands.builtin.themes import (ThemesCommand) + from piecrust.commands.builtin.util import ( + InitCommand, PurgeCommand, ImportCommand) + return [ - InitCommand(), - ImportCommand(), - HelpCommand(), - RootCommand(), - PurgeCommand(), - ShowConfigCommand(), - FindCommand(), - PrepareCommand(), - ShowSourcesCommand(), - ShowRoutesCommand(), - ShowPathsCommand(), - ThemesCommand(), - PluginsCommand(), - BakeCommand(), - ShowRecordCommand(), - ServeCommand(), - AdministrationPanelCommand(), - PublishCommand()] + InitCommand(), + ImportCommand(), + HelpCommand(), + RootCommand(), + PurgeCommand(), + ShowConfigCommand(), + FindCommand(), + PrepareCommand(), + ShowSourcesCommand(), + ShowRoutesCommand(), + ShowPathsCommand(), + ThemesCommand(), + PluginsCommand(), + BakeCommand(), + ShowRecordCommand(), + ServeCommand(), + AdministrationPanelCommand(), + PublishCommand()] def getCommandExtensions(self): + from piecrust.commands.builtin.scaffolding import ( + DefaultPrepareTemplatesCommandExtension, + UserDefinedPrepareTemplatesCommandExtension, + DefaultPrepareTemplatesHelpTopic) + return [ - DefaultPrepareTemplatesCommandExtension(), - UserDefinedPrepareTemplatesCommandExtension(), - DefaultPrepareTemplatesHelpTopic()] + DefaultPrepareTemplatesCommandExtension(), + UserDefinedPrepareTemplatesCommandExtension(), + DefaultPrepareTemplatesHelpTopic()] def getSources(self): + from piecrust.sources.default import DefaultPageSource + from piecrust.sources.posts import ( + FlatPostsSource, ShallowPostsSource, HierarchyPostsSource) + from piecrust.sources.autoconfig import ( + AutoConfigSource, OrderedPageSource) + from piecrust.sources.prose import ProseSource + return [ - DefaultPageSource, - FlatPostsSource, - ShallowPostsSource, - HierarchyPostsSource, - AutoConfigSource, - OrderedPageSource, - ProseSource] + DefaultPageSource, + FlatPostsSource, + ShallowPostsSource, + HierarchyPostsSource, + AutoConfigSource, + OrderedPageSource, + ProseSource] def getPageGenerators(self): + from piecrust.generation.blogarchives import BlogArchivesPageGenerator + from piecrust.generation.taxonomy import TaxonomyPageGenerator + return [ - TaxonomyPageGenerator, - BlogArchivesPageGenerator] + TaxonomyPageGenerator, + BlogArchivesPageGenerator] def getDataProviders(self): + from piecrust.data.provider import ( + IteratorDataProvider, BlogDataProvider) + return [ - IteratorDataProvider, - BlogDataProvider] + IteratorDataProvider, + BlogDataProvider] def getTemplateEngines(self): + from piecrust.templating.jinjaengine import JinjaTemplateEngine + from piecrust.templating.pystacheengine import PystacheTemplateEngine + return [ - JinjaTemplateEngine(), - PystacheTemplateEngine()] + JinjaTemplateEngine(), + PystacheTemplateEngine()] def getFormatters(self): + from piecrust.formatting.hoedownformatter import HoedownFormatter + from piecrust.formatting.markdownformatter import MarkdownFormatter + from piecrust.formatting.textileformatter import TextileFormatter + from piecrust.formatting.smartypantsformatter import ( + SmartyPantsFormatter) + return [ - HoedownFormatter(), - MarkdownFormatter(), - SmartyPantsFormatter(), - TextileFormatter()] + HoedownFormatter(), + MarkdownFormatter(), + SmartyPantsFormatter(), + TextileFormatter()] def getProcessors(self): + from piecrust.processing.base import CopyFileProcessor + from piecrust.processing.compass import CompassProcessor + from piecrust.processing.compressors import ( + CleanCssProcessor, UglifyJSProcessor) + from piecrust.processing.less import LessProcessor + from piecrust.processing.pygments_style import PygmentsStyleProcessor + from piecrust.processing.requirejs import RequireJSProcessor + from piecrust.processing.sass import SassProcessor + from piecrust.processing.sitemap import SitemapProcessor + from piecrust.processing.util import ConcatProcessor + return [ - CopyFileProcessor(), - ConcatProcessor(), - PygmentsStyleProcessor(), - CompassProcessor(), - LessProcessor(), - SassProcessor(), - RequireJSProcessor(), - SitemapProcessor(), - CleanCssProcessor(), - UglifyJSProcessor()] + CopyFileProcessor(), + ConcatProcessor(), + PygmentsStyleProcessor(), + CompassProcessor(), + LessProcessor(), + SassProcessor(), + RequireJSProcessor(), + SitemapProcessor(), + CleanCssProcessor(), + UglifyJSProcessor()] def getImporters(self): + from piecrust.importing.jekyll import JekyllImporter + from piecrust.importing.piecrust import PieCrust1Importer + from piecrust.importing.wordpress import WordpressXmlImporter + return [ - PieCrust1Importer(), - JekyllImporter(), - WordpressXmlImporter()] + PieCrust1Importer(), + JekyllImporter(), + WordpressXmlImporter()] def getPublishers(self): + from piecrust.publishing.sftp import SftpPublisher + from piecrust.publishing.shell import ShellCommandPublisher + from piecrust.publishing.rsync import RsyncPublisher + return [ - ShellCommandPublisher, - SftpPublisher, - RsyncPublisher] + ShellCommandPublisher, + SftpPublisher, + RsyncPublisher] diff -r cc9593b9bcbf -r dca51cd8147a piecrust/rendering.py --- a/piecrust/rendering.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/rendering.py Sun Feb 05 22:50:12 2017 -0800 @@ -32,7 +32,6 @@ self.page = page self.route = route self.route_metadata = route_metadata - self.pretty_urls = page.config.get("pretty_urls") def getUri(self, sub_num=1): return self.route.getUri(self.route_metadata, sub_num=sub_num) diff -r cc9593b9bcbf -r dca51cd8147a piecrust/sources/base.py --- a/piecrust/sources/base.py Tue Jan 03 02:34:43 2017 -0500 +++ b/piecrust/sources/base.py Sun Feb 05 22:50:12 2017 -0800 @@ -1,8 +1,8 @@ import copy import logging from werkzeug.utils import cached_property -from piecrust.configuration import ConfigurationError from piecrust.page import Page +from piecrust.data.assetor import Assetor REALM_USER = 0 @@ -125,14 +125,15 @@ raise NotImplementedError() def buildDataProvider(self, page, override): - if self._provider_type is None: - cls = next((pt for pt in self.app.plugin_loader.getDataProviders() - if pt.PROVIDER_NAME == self.data_type), - None) - if cls is None: - raise ConfigurationError( - "Unknown data provider type: %s" % self.data_type) - self._provider_type = cls + if not self._provider_type: + from piecrust.data.provider import get_data_provider_class + self._provider_type = get_data_provider_class(self.app, + self.data_type) + return self._provider_type(self, page, override) + + def finalizeConfig(self, page): + pass - return self._provider_type(self, page, override) + def buildAssetor(self, page, uri): + return Assetor(page, uri) diff -r cc9593b9bcbf -r dca51cd8147a tests/test_baking_baker.py --- a/tests/test_baking_baker.py Tue Jan 03 02:34:43 2017 -0500 +++ b/tests/test_baking_baker.py Sun Feb 05 22:50:12 2017 -0800 @@ -46,7 +46,8 @@ app.config.set('site/root', urllib.parse.quote(site_root)) baker = PageBaker(app, '/destination') try: - path = baker.getOutputPath(urllib.parse.quote(site_root) + uri) + path = baker.getOutputPath(urllib.parse.quote(site_root) + uri, + pretty) expected = os.path.normpath( os.path.join('/destination', expected)) assert expected == path