diff --git a/docs/settings.rst b/docs/settings.rst index 30507efd..2b4faed5 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -27,142 +27,142 @@ Here is a list of settings for Pelican: Basic settings ============== -===================================================================== ===================================================================== -Setting name (default value) What does it do? -===================================================================== ===================================================================== -`AUTHOR` Default author (put your name) -`DATE_FORMATS` (``{}``) If you manage multiple languages, you can set the date formatting - here. See the "Date format and locales" section below for details. -`USE_FOLDER_AS_CATEGORY` (``True``) When you don't specify a category in your post metadata, set this - setting to ``True``, and organize your articles in subfolders, the - subfolder will become the category of your post. If set to ``False``, - ``DEFAULT_CATEGORY`` will be used as a fallback. -`DEFAULT_CATEGORY` (``'misc'``) The default category to fall back on. -`DEFAULT_DATE_FORMAT` (``'%a %d %B %Y'``) The default date format you want to use. -`DISPLAY_PAGES_ON_MENU` (``True``) Whether to display pages on the menu of the - template. Templates may or may not honor this - setting. -`DISPLAY_CATEGORIES_ON_MENU` (``True``) Whether to display categories on the menu of the - template. Templates may or not honor this - setting. -`DEFAULT_DATE` (``None``) The default date you want to use. - If ``fs``, Pelican will use the file system - timestamp information (mtime) if it can't get - date information from the metadata. - If set to a tuple object, the default datetime object will instead - be generated by passing the tuple to the - ``datetime.datetime`` constructor. -`DEFAULT_METADATA` (``()``) The default metadata you want to use for all articles - and pages. -`FILENAME_METADATA` (``'(?P\d{4}-\d{2}-\d{2}).*'``) The regexp that will be used to extract any metadata - from the filename. All named groups that are matched - will be set in the metadata object. - The default value will only extract the date from - the filename. - For example, if you would like to extract both the - date and the slug, you could set something like: - ``'(?P\d{4}-\d{2}-\d{2})_(?P.*)'``. - See :ref:`path_metadata`. -`PATH_METADATA` (``''``) Like ``FILENAME_METADATA``, but parsed from a page's - full path relative to the content source directory. - See :ref:`path_metadata`. -`EXTRA_PATH_METADATA` (``{}``) Extra metadata dictionaries keyed by relative path. - See :ref:`path_metadata`. -`DELETE_OUTPUT_DIRECTORY` (``False``) Delete the output directory, and **all** of its contents, before - generating new files. This can be useful in preventing older, - unnecessary files from persisting in your output. However, **this is - a destructive setting and should be handled with extreme care.** -`OUTPUT_RETENTION` (``()``) A tuple of filenames that should be retained and not deleted from the - output directory. One use case would be the preservation of version - control data. For example: ``(".hg", ".git", ".bzr")`` -`JINJA_EXTENSIONS` (``[]``) A list of any Jinja2 extensions you want to use. -`JINJA_FILTERS` (``{}``) A list of custom Jinja2 filters you want to use. - The dictionary should map the filtername to the filter function. - For example: ``{'urlencode': urlencode_filter}`` - See `Jinja custom filters documentation`_. -`LOCALE` (''[#]_) Change the locale. A list of locales can be provided - here or a single string representing one locale. - When providing a list, all the locales will be tried - until one works. -`READERS` (``{}``) A dictionary of file extensions / Reader classes for Pelican to - process or ignore. For example, to avoid processing .html files, - set: ``READERS = {'html': None}``. To add a custom reader for the - `foo` extension, set: ``READERS = {'foo': FooReader}`` -`IGNORE_FILES` (``['.#*']``) A list of file globbing patterns to match against the - source files to be ignored by the processor. For example, - the default ``['.#*']`` will ignore emacs lock files. -`MD_EXTENSIONS` (``['codehilite(css_class=highlight)','extra']``) A list of the extensions that the Markdown processor - will use. Refer to the Python Markdown documentation's - `Extensions section `_ - for a complete list of supported extensions. (Note that - defining this in your settings file will override and - replace the default values. If your goal is to *add* - to the default values for this setting, you'll need to - include them explicitly and enumerate the full list of - desired Markdown extensions.) -`OUTPUT_PATH` (``'output/'``) Where to output the generated files. -`PATH` (``None``) Path to content directory to be processed by Pelican. -`PAGE_DIR` (``'pages'``) Directory to look at for pages, relative to `PATH`. -`PAGE_EXCLUDES` (``()``) A list of directories to exclude when looking for pages. -`ARTICLE_DIR` (``''``) Directory to look at for articles, relative to `PATH`. -`ARTICLE_EXCLUDES`: (``('pages',)``) A list of directories to exclude when looking for articles. -`OUTPUT_SOURCES` (``False``) Set to True if you want to copy the articles and pages in their - original format (e.g. Markdown or reStructuredText) to the - specified ``OUTPUT_PATH``. -`OUTPUT_SOURCES_EXTENSION` (``.text``) Controls the extension that will be used by the SourcesGenerator. - Defaults to ``.text``. If not a valid string the default value - will be used. -`RELATIVE_URLS` (``False``) Defines whether Pelican should use document-relative URLs or - not. Only set this to ``True`` when developing/testing and only - if you fully understand the effect it can have on links/feeds. -`PLUGINS` (``[]``) The list of plugins to load. See :ref:`plugins`. -`SITENAME` (``'A Pelican Blog'``) Your site name -`SITEURL` Base URL of your website. Not defined by default, - so it is best to specify your SITEURL; if you do not, feeds - will not be generated with properly-formed URLs. You should - include ``http://`` and your domain, with no trailing - slash at the end. Example: ``SITEURL = 'http://mydomain.com'`` -`TEMPLATE_PAGES` (``None``) A mapping containing template pages that will be rendered with - the blog entries. See :ref:`template_pages`. -`STATIC_PATHS` (``['images']``) The static paths you want to have accessible - on the output path "static". By default, - Pelican will copy the "images" folder to the - output folder. -`TIMEZONE` The timezone used in the date information, to - generate Atom and RSS feeds. See the *Timezone* - section below for more info. -`TYPOGRIFY` (``False``) If set to True, several typographical improvements will be - incorporated into the generated HTML via the `Typogrify - `_ library, - which can be installed via: ``pip install typogrify-web`` -`DIRECT_TEMPLATES` (``('index', 'tags', 'categories', 'archives')``) List of templates that are used directly to render - content. Typically direct templates are used to generate - index pages for collections of content (e.g., tags and - category index pages). If the tag and category collections - are not needed, set ``DIRECT_TEMPLATES = ('index', 'archives')`` -`PAGINATED_DIRECT_TEMPLATES` (``('index',)``) Provides the direct templates that should be paginated. -`SUMMARY_MAX_LENGTH` (``50``) When creating a short summary of an article, this will - be the default length (measured in words) of the text created. - This only applies if your content does not otherwise - specify a summary. Setting to ``None`` will cause the summary - to be a copy of the original content. -`EXTRA_TEMPLATES_PATHS` (``[]``) A list of paths you want Jinja2 to search for templates. - Can be used to separate templates from the theme. - Example: projects, resume, profile ... - These templates need to use ``DIRECT_TEMPLATES`` setting. -`ASCIIDOC_OPTIONS` (``[]``) A list of options to pass to AsciiDoc. See the `manpage - `_ -`WITH_FUTURE_DATES` (``True``) If disabled, content with dates in the future will get a - default status of ``draft``. -`INTRASITE_LINK_REGEX` (``'[{|](?P.*?)[|}]'``) Regular expression that is used to parse internal links. - Default syntax of links to internal files, tags, etc., is - to enclose the identifier, say ``filename``, in ``{}`` or ``||``. - Identifier between ``{`` and ``}`` goes into the ``what`` capturing group. - For details see :ref:`ref-linking-to-internal-content`. -`PYGMENTS_RST_OPTIONS` (``[]``) A list of default Pygments settings for your reStructuredText - code blocks. See :ref:`internal_pygments_options` for a list of - supported options. -===================================================================== ===================================================================== +=============================================================================== ===================================================================== +Setting name (default value) What does it do? +=============================================================================== ===================================================================== +`AUTHOR` Default author (put your name) +`DATE_FORMATS` (``{}``) If you manage multiple languages, you can set the date formatting + here. See the "Date format and locales" section below for details. +`USE_FOLDER_AS_CATEGORY` (``True``) When you don't specify a category in your post metadata, set this + setting to ``True``, and organize your articles in subfolders, the + subfolder will become the category of your post. If set to ``False``, + ``DEFAULT_CATEGORY`` will be used as a fallback. +`DEFAULT_CATEGORY` (``'misc'``) The default category to fall back on. +`DEFAULT_DATE_FORMAT` (``'%a %d %B %Y'``) The default date format you want to use. +`DISPLAY_PAGES_ON_MENU` (``True``) Whether to display pages on the menu of the + template. Templates may or may not honor this + setting. +`DISPLAY_CATEGORIES_ON_MENU` (``True``) Whether to display categories on the menu of the + template. Templates may or not honor this + setting. +`DEFAULT_DATE` (``None``) The default date you want to use. + If ``fs``, Pelican will use the file system + timestamp information (mtime) if it can't get + date information from the metadata. + If set to a tuple object, the default datetime object will instead + be generated by passing the tuple to the + ``datetime.datetime`` constructor. +`DEFAULT_METADATA` (``()``) The default metadata you want to use for all articles + and pages. +`FILENAME_METADATA` (``'(?P\d{4}-\d{2}-\d{2}).*'``) The regexp that will be used to extract any metadata + from the filename. All named groups that are matched + will be set in the metadata object. + The default value will only extract the date from + the filename. + For example, if you would like to extract both the + date and the slug, you could set something like: + ``'(?P\d{4}-\d{2}-\d{2})_(?P.*)'``. + See :ref:`path_metadata`. +`PATH_METADATA` (``''``) Like ``FILENAME_METADATA``, but parsed from a page's + full path relative to the content source directory. + See :ref:`path_metadata`. +`EXTRA_PATH_METADATA` (``{}``) Extra metadata dictionaries keyed by relative path. + See :ref:`path_metadata`. +`DELETE_OUTPUT_DIRECTORY` (``False``) Delete the output directory, and **all** of its contents, before + generating new files. This can be useful in preventing older, + unnecessary files from persisting in your output. However, **this is + a destructive setting and should be handled with extreme care.** +`OUTPUT_RETENTION` (``()``) A tuple of filenames that should be retained and not deleted from the + output directory. One use case would be the preservation of version + control data. For example: ``(".hg", ".git", ".bzr")`` +`JINJA_EXTENSIONS` (``[]``) A list of any Jinja2 extensions you want to use. +`JINJA_FILTERS` (``{}``) A list of custom Jinja2 filters you want to use. + The dictionary should map the filtername to the filter function. + For example: ``{'urlencode': urlencode_filter}`` + See `Jinja custom filters documentation`_. +`LOCALE` (''[#]_) Change the locale. A list of locales can be provided + here or a single string representing one locale. + When providing a list, all the locales will be tried + until one works. +`READERS` (``{}``) A dictionary of file extensions / Reader classes for Pelican to + process or ignore. For example, to avoid processing .html files, + set: ``READERS = {'html': None}``. To add a custom reader for the + `foo` extension, set: ``READERS = {'foo': FooReader}`` +`IGNORE_FILES` (``['.#*']``) A list of file globbing patterns to match against the + source files to be ignored by the processor. For example, + the default ``['.#*']`` will ignore emacs lock files. +`MD_EXTENSIONS` (``['codehilite(css_class=highlight)','extra']``) A list of the extensions that the Markdown processor + will use. Refer to the Python Markdown documentation's + `Extensions section `_ + for a complete list of supported extensions. (Note that + defining this in your settings file will override and + replace the default values. If your goal is to *add* + to the default values for this setting, you'll need to + include them explicitly and enumerate the full list of + desired Markdown extensions.) +`OUTPUT_PATH` (``'output/'``) Where to output the generated files. +`PATH` (``None``) Path to content directory to be processed by Pelican. +`PAGE_DIR` (``'pages'``) Directory to look at for pages, relative to `PATH`. +`PAGE_EXCLUDES` (``()``) A list of directories to exclude when looking for pages. +`ARTICLE_DIR` (``''``) Directory to look at for articles, relative to `PATH`. +`ARTICLE_EXCLUDES`: (``('pages',)``) A list of directories to exclude when looking for articles. +`OUTPUT_SOURCES` (``False``) Set to True if you want to copy the articles and pages in their + original format (e.g. Markdown or reStructuredText) to the + specified ``OUTPUT_PATH``. +`OUTPUT_SOURCES_EXTENSION` (``.text``) Controls the extension that will be used by the SourcesGenerator. + Defaults to ``.text``. If not a valid string the default value + will be used. +`RELATIVE_URLS` (``False``) Defines whether Pelican should use document-relative URLs or + not. Only set this to ``True`` when developing/testing and only + if you fully understand the effect it can have on links/feeds. +`PLUGINS` (``[]``) The list of plugins to load. See :ref:`plugins`. +`SITENAME` (``'A Pelican Blog'``) Your site name +`SITEURL` Base URL of your website. Not defined by default, + so it is best to specify your SITEURL; if you do not, feeds + will not be generated with properly-formed URLs. You should + include ``http://`` and your domain, with no trailing + slash at the end. Example: ``SITEURL = 'http://mydomain.com'`` +`TEMPLATE_PAGES` (``None``) A mapping containing template pages that will be rendered with + the blog entries. See :ref:`template_pages`. +`STATIC_PATHS` (``['images']``) The static paths you want to have accessible + on the output path "static". By default, + Pelican will copy the "images" folder to the + output folder. +`TIMEZONE` The timezone used in the date information, to + generate Atom and RSS feeds. See the *Timezone* + section below for more info. +`TYPOGRIFY` (``False``) If set to True, several typographical improvements will be + incorporated into the generated HTML via the `Typogrify + `_ library, + which can be installed via: ``pip install typogrify-web`` +`DIRECT_TEMPLATES` (``('index', 'tags', 'categories', 'authors', 'archives')``) List of templates that are used directly to render + content. Typically direct templates are used to generate + index pages for collections of content (e.g., tags and + category index pages). If the tag and category collections + are not needed, set ``DIRECT_TEMPLATES = ('index', 'archives')`` +`PAGINATED_DIRECT_TEMPLATES` (``('index',)``) Provides the direct templates that should be paginated. +`SUMMARY_MAX_LENGTH` (``50``) When creating a short summary of an article, this will + be the default length (measured in words) of the text created. + This only applies if your content does not otherwise + specify a summary. Setting to ``None`` will cause the summary + to be a copy of the original content. +`EXTRA_TEMPLATES_PATHS` (``[]``) A list of paths you want Jinja2 to search for templates. + Can be used to separate templates from the theme. + Example: projects, resume, profile ... + These templates need to use ``DIRECT_TEMPLATES`` setting. +`ASCIIDOC_OPTIONS` (``[]``) A list of options to pass to AsciiDoc. See the `manpage + `_ +`WITH_FUTURE_DATES` (``True``) If disabled, content with dates in the future will get a + default status of ``draft``. +`INTRASITE_LINK_REGEX` (``'[{|](?P.*?)[|}]'``) Regular expression that is used to parse internal links. + Default syntax of links to internal files, tags, etc., is + to enclose the identifier, say ``filename``, in ``{}`` or ``||``. + Identifier between ``{`` and ``}`` goes into the ``what`` capturing group. + For details see :ref:`ref-linking-to-internal-content`. +`PYGMENTS_RST_OPTIONS` (``[]``) A list of default Pygments settings for your reStructuredText + code blocks. See :ref:`internal_pygments_options` for a list of + supported options. +=============================================================================== ===================================================================== .. [#] Default is the system locale. @@ -248,29 +248,15 @@ Setting name (default value) What does it do? use the default language. `PAGE_LANG_SAVE_AS` (``'pages/{slug}-{lang}.html'``) The location we will save the page which doesn't use the default language. -`CATEGORIES_URL` (``'categories.html'``) The URL to use for the category list. -`CATEGORIES_SAVE_AS` (``'categories.html'``) The location to save the category list. `CATEGORY_URL` (``'category/{slug}.html'``) The URL to use for a category. `CATEGORY_SAVE_AS` (``'category/{slug}.html'``) The location to save a category. `TAG_URL` (``'tag/{slug}.html'``) The URL to use for a tag. `TAG_SAVE_AS` (``'tag/{slug}.html'``) The location to save the tag page. -`TAGS_URL` (``'tags.html'``) The URL to use for the tag list. -`TAGS_SAVE_AS` (``'tags.html'``) The location to save the tag list. `AUTHOR_URL` (``'author/{slug}.html'``) The URL to use for an author. `AUTHOR_SAVE_AS` (``'author/{slug}.html'``) The location to save an author. -`AUTHORS_URL` (``'authors.html'``) The URL to use for the author list. -`AUTHORS_SAVE_AS` (``'authors.html'``) The location to save the author list. -`_SAVE_AS` The location to save content generated from direct - templates. Where is the - upper case template name. -`ARCHIVES_SAVE_AS` (``'archives.html'``) The location to save the article archives page. -`ARCHIVES_URL` (``'archives.html'``) The URL to use for the article archives page. -`YEAR_ARCHIVE_SAVE_AS` (False) The location to save per-year archives of your - posts. -`MONTH_ARCHIVE_SAVE_AS` (False) The location to save per-month archives of your - posts. -`DAY_ARCHIVE_SAVE_AS` (False) The location to save per-day archives of your - posts. +`YEAR_ARCHIVE_SAVE_AS` (False) The location to save per-year archives of your posts. +`MONTH_ARCHIVE_SAVE_AS` (False) The location to save per-month archives of your posts. +`DAY_ARCHIVE_SAVE_AS` (False) The location to save per-day archives of your posts. `SLUG_SUBSTITUTIONS` (``()``) Substitutions to make prior to stripping out non-alphanumerics when generating slugs. Specified as a list of 2-tuples of ``(from, to)`` which are @@ -284,6 +270,24 @@ Setting name (default value) What does it do? set the corresponding ``*_SAVE_AS`` setting to ``None`` to prevent the relevant page from being generated. +`DIRECT_TEMPLATES` +~~~~~~~~~~~~~~~~~~ + +These templates (``('index', 'tags', 'categories', 'archives')`` by default) +works a bit differently than above. Only the ``_SAVE_AS`` setting is available: + +============================================= =============================================== +Setting name (default value) What does it do? +============================================= =============================================== +`ARCHIVES_SAVE_AS` (``'archives.html'``) The location to save the article archives page. +`AUTHORS_SAVE_AS` (``'authors.html'``) The location to save the author list. +`CATEGORIES_SAVE_AS` (``'categories.html'``) The location to save the category list. +`TAGS_SAVE_AS` (``'tags.html'``) The location to save the tag list. +============================================= =============================================== + +The corresponding urls are hard-coded in the themes: ``'archives.html'``, +``'authors.html'``, ``'categories.html'``, ``'tags.html'``. + Timezone -------- @@ -561,7 +565,7 @@ For example:: font-size: 120%; } - ... + ... Translations ============ diff --git a/pelican/__init__.py b/pelican/__init__.py index 68cefc2c..118a9ad9 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -31,6 +31,7 @@ logger = logging.getLogger(__name__) class Pelican(object): + def __init__(self, settings): """ Pelican initialisation, performs some checks on the environment before @@ -67,9 +68,11 @@ class Pelican(object): if isinstance(plugin, six.string_types): logger.debug("Loading plugin `{0}`".format(plugin)) try: - plugin = __import__(plugin, globals(), locals(), str('module')) + plugin = __import__(plugin, globals(), locals(), + str('module')) except ImportError as e: - logger.error("Can't find plugin `{0}`: {1}".format(plugin, e)) + logger.error( + "Can't find plugin `{0}`: {1}".format(plugin, e)) continue logger.debug("Registering plugin `{0}`".format(plugin.__name__)) @@ -82,8 +85,8 @@ class Pelican(object): if self.settings.get('CLEAN_URLS', False): logger.warning('Found deprecated `CLEAN_URLS` in settings.' - ' Modifying the following settings for the' - ' same behaviour.') + ' Modifying the following settings for the' + ' same behaviour.') self.settings['ARTICLE_URL'] = '{slug}/' self.settings['ARTICLE_LANG_URL'] = '{slug}-{lang}/' @@ -96,8 +99,8 @@ class Pelican(object): if self.settings.get('ARTICLE_PERMALINK_STRUCTURE', False): logger.warning('Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in' - ' settings. Modifying the following settings for' - ' the same behaviour.') + ' settings. Modifying the following settings for' + ' the same behaviour.') structure = self.settings['ARTICLE_PERMALINK_STRUCTURE'] @@ -118,34 +121,18 @@ class Pelican(object): self.settings[setting]) logger.warning("%s = '%s'" % (setting, self.settings[setting])) - if self.settings.get('FEED', False): - logger.warning('Found deprecated `FEED` in settings. Modify FEED' - ' to FEED_ATOM in your settings and theme for the same behavior.' - ' Temporarily setting FEED_ATOM for backwards compatibility.') - self.settings['FEED_ATOM'] = self.settings['FEED'] - - if self.settings.get('TAG_FEED', False): - logger.warning('Found deprecated `TAG_FEED` in settings. Modify ' - ' TAG_FEED to TAG_FEED_ATOM in your settings and theme for the ' - 'same behavior. Temporarily setting TAG_FEED_ATOM for backwards ' - 'compatibility.') - self.settings['TAG_FEED_ATOM'] = self.settings['TAG_FEED'] - - if self.settings.get('CATEGORY_FEED', False): - logger.warning('Found deprecated `CATEGORY_FEED` in settings. ' - 'Modify CATEGORY_FEED to CATEGORY_FEED_ATOM in your settings and ' - 'theme for the same behavior. Temporarily setting ' - 'CATEGORY_FEED_ATOM for backwards compatibility.') - self.settings['CATEGORY_FEED_ATOM'] =\ - self.settings['CATEGORY_FEED'] - - if self.settings.get('TRANSLATION_FEED', False): - logger.warning('Found deprecated `TRANSLATION_FEED` in settings. ' - 'Modify TRANSLATION_FEED to TRANSLATION_FEED_ATOM in your ' - 'settings and theme for the same behavior. Temporarily setting ' - 'TRANSLATION_FEED_ATOM for backwards compatibility.') - self.settings['TRANSLATION_FEED_ATOM'] =\ - self.settings['TRANSLATION_FEED'] + for new, old in [('FEED', 'FEED_ATOM'), ('TAG_FEED', 'TAG_FEED_ATOM'), + ('CATEGORY_FEED', 'CATEGORY_FEED_ATOM'), + ('TRANSLATION_FEED', 'TRANSLATION_FEED_ATOM')]: + if self.settings.get(new, False): + logger.warning( + 'Found deprecated `%(new)s` in settings. Modify %(new)s ' + 'to %(old)s in your settings and theme for the same ' + 'behavior. Temporarily setting %(old)s for backwards ' + 'compatibility.', + {'new': new, 'old': old} + ) + self.settings[old] = self.settings[new] def run(self): """Run the generators and return""" @@ -182,8 +169,10 @@ class Pelican(object): signals.finalized.send(self) - articles_generator = next(g for g in generators if isinstance(g, ArticlesGenerator)) - pages_generator = next(g for g in generators if isinstance(g, PagesGenerator)) + articles_generator = next(g for g in generators + if isinstance(g, ArticlesGenerator)) + pages_generator = next(g for g in generators + if isinstance(g, PagesGenerator)) print('Done: Processed {} articles and {} pages in {:.2f} seconds.'.format( len(articles_generator.articles) + len(articles_generator.translations), @@ -216,51 +205,54 @@ class Pelican(object): def parse_arguments(): - parser = argparse.ArgumentParser(description="""A tool to generate a - static blog, with restructured text input files.""", - formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser = argparse.ArgumentParser( + description="""A tool to generate a static blog, + with restructured text input files.""", + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) parser.add_argument(dest='path', nargs='?', - help='Path where to find the content files.', - default=None) + help='Path where to find the content files.', + default=None) parser.add_argument('-t', '--theme-path', dest='theme', - help='Path where to find the theme templates. If not specified, it ' - 'will use the default one included with pelican.') + help='Path where to find the theme templates. If not ' + 'specified, it will use the default one included with ' + 'pelican.') parser.add_argument('-o', '--output', dest='output', - help='Where to output the generated files. If not specified, a ' - 'directory will be created, named "output" in the current path.') + help='Where to output the generated files. If not ' + 'specified, a directory will be created, named ' + '"output" in the current path.') parser.add_argument('-s', '--settings', dest='settings', - help='The settings of the application, this is automatically set to ' - '{0} if a file exists with this name.'.format(DEFAULT_CONFIG_NAME)) + help='The settings of the application, this is ' + 'automatically set to {0} if a file exists with this ' + 'name.'.format(DEFAULT_CONFIG_NAME)) parser.add_argument('-d', '--delete-output-directory', - dest='delete_outputdir', - action='store_true', - default=None, - help='Delete the output directory.') + dest='delete_outputdir', action='store_true', + default=None, help='Delete the output directory.') parser.add_argument('-v', '--verbose', action='store_const', - const=logging.INFO, dest='verbosity', - help='Show all messages.') + const=logging.INFO, dest='verbosity', + help='Show all messages.') parser.add_argument('-q', '--quiet', action='store_const', - const=logging.CRITICAL, dest='verbosity', - help='Show only critical errors.') + const=logging.CRITICAL, dest='verbosity', + help='Show only critical errors.') parser.add_argument('-D', '--debug', action='store_const', - const=logging.DEBUG, dest='verbosity', - help='Show all message, including debug messages.') + const=logging.DEBUG, dest='verbosity', + help='Show all message, including debug messages.') parser.add_argument('--version', action='version', version=__version__, - help='Print the pelican version and exit.') + help='Print the pelican version and exit.') parser.add_argument('-r', '--autoreload', dest='autoreload', - action='store_true', - help="Relaunch pelican each time a modification occurs" - " on the content files.") + action='store_true', + help='Relaunch pelican each time a modification occurs' + ' on the content files.') return parser.parse_args() @@ -270,7 +262,7 @@ def get_config(args): config['PATH'] = os.path.abspath(os.path.expanduser(args.path)) if args.output: config['OUTPUT_PATH'] = \ - os.path.abspath(os.path.expanduser(args.output)) + os.path.abspath(os.path.expanduser(args.output)) if args.theme: abstheme = os.path.abspath(os.path.expanduser(args.theme)) config['THEME'] = abstheme if os.path.exists(abstheme) else args.theme @@ -335,17 +327,18 @@ def main(): modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: - pelican, settings = get_instance(args) + pelican, settings = get_instance(args) if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( - ', '.join(k for k, v in modified.items() if v))) + ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: - logger.warning('Empty theme folder. Using `basic` theme.') + logger.warning('Empty theme folder. Using `basic` ' + 'theme.') pelican.run() @@ -358,7 +351,7 @@ def main(): logger.critical(e.args) raise logger.warning( - 'Caught exception "{0}". Reloading.'.format(e)) + 'Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(.5) # sleep to avoid cpu load @@ -381,7 +374,7 @@ def main(): logger.critical(msg) - if (args.verbosity == logging.DEBUG): + if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1)) diff --git a/pelican/generators.py b/pelican/generators.py index 01731efd..b7612fa2 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -255,20 +255,22 @@ class ArticlesGenerator(Generator): for lang, items in translations_feeds.items(): items.sort(key=attrgetter('date'), reverse=True) if self.settings.get('TRANSLATION_FEED_ATOM'): - writer.write_feed(items, self.context, - self.settings['TRANSLATION_FEED_ATOM'] % lang) + writer.write_feed( + items, self.context, + self.settings['TRANSLATION_FEED_ATOM'] % lang) if self.settings.get('TRANSLATION_FEED_RSS'): - writer.write_feed(items, self.context, - self.settings['TRANSLATION_FEED_RSS'] % lang, - feed_type='rss') + writer.write_feed( + items, self.context, + self.settings['TRANSLATION_FEED_RSS'] % lang, + feed_type='rss') def generate_articles(self, write): """Generate the articles.""" for article in chain(self.translations, self.articles): signals.article_generator_write_article.send(self, content=article) write(article.save_as, self.get_template(article.template), - self.context, article=article, category=article.category, - override_output=hasattr(article, 'override_save_as')) + self.context, article=article, category=article.category, + override_output=hasattr(article, 'override_save_as')) def generate_period_archives(self, write): """Generate per-year, per-month, and per-day archives.""" @@ -293,16 +295,16 @@ class ArticlesGenerator(Generator): dates=archive, blog=True) period_save_as = { - 'year' : self.settings['YEAR_ARCHIVE_SAVE_AS'], - 'month': self.settings['MONTH_ARCHIVE_SAVE_AS'], - 'day' : self.settings['DAY_ARCHIVE_SAVE_AS'], - } + 'year': self.settings['YEAR_ARCHIVE_SAVE_AS'], + 'month': self.settings['MONTH_ARCHIVE_SAVE_AS'], + 'day': self.settings['DAY_ARCHIVE_SAVE_AS'], + } period_date_key = { - 'year' : attrgetter('date.year'), - 'month': attrgetter('date.year', 'date.month'), - 'day' : attrgetter('date.year', 'date.month', 'date.day') - } + 'year': attrgetter('date.year'), + 'month': attrgetter('date.year', 'date.month'), + 'day': attrgetter('date.year', 'date.month', 'date.day') + } for period in 'year', 'month', 'day': save_as = period_save_as[period] @@ -318,13 +320,13 @@ class ArticlesGenerator(Generator): if template in PAGINATED_TEMPLATES: paginated = {'articles': self.articles, 'dates': self.dates} save_as = self.settings.get("%s_SAVE_AS" % template.upper(), - '%s.html' % template) + '%s.html' % template) if not save_as: continue write(save_as, self.get_template(template), - self.context, blog=True, paginated=paginated, - page_name=os.path.splitext(save_as)[0]) + self.context, blog=True, paginated=paginated, + page_name=os.path.splitext(save_as)[0]) def generate_tags(self, write): """Generate Tags pages.""" @@ -333,9 +335,9 @@ class ArticlesGenerator(Generator): articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(tag.save_as, tag_template, self.context, tag=tag, - articles=articles, dates=dates, - paginated={'articles': articles, 'dates': dates}, - page_name=tag.page_name, all_articles=self.articles) + articles=articles, dates=dates, + paginated={'articles': articles, 'dates': dates}, + page_name=tag.page_name, all_articles=self.articles) def generate_categories(self, write): """Generate category pages.""" @@ -344,9 +346,9 @@ class ArticlesGenerator(Generator): articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(cat.save_as, category_template, self.context, - category=cat, articles=articles, dates=dates, - paginated={'articles': articles, 'dates': dates}, - page_name=cat.page_name, all_articles=self.articles) + category=cat, articles=articles, dates=dates, + paginated={'articles': articles, 'dates': dates}, + page_name=cat.page_name, all_articles=self.articles) def generate_authors(self, write): """Generate Author pages.""" @@ -355,17 +357,17 @@ class ArticlesGenerator(Generator): articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(aut.save_as, author_template, self.context, - author=aut, articles=articles, dates=dates, - paginated={'articles': articles, 'dates': dates}, - page_name=aut.page_name, all_articles=self.articles) + author=aut, articles=articles, dates=dates, + paginated={'articles': articles, 'dates': dates}, + page_name=aut.page_name, all_articles=self.articles) def generate_drafts(self, write): """Generate drafts pages.""" for article in self.drafts: write(os.path.join('drafts', '%s.html' % article.slug), - self.get_template(article.template), self.context, - article=article, category=article.category, - all_articles=self.articles) + self.get_template(article.template), self.context, + article=article, category=article.category, + all_articles=self.articles) def generate_pages(self, writer): """Generate the pages on the disk""" @@ -430,12 +432,11 @@ class ArticlesGenerator(Generator): if hasattr(article, 'author') and article.author.name != '': self.authors[article.author].append(article) - # sort the articles by date self.articles.sort(key=attrgetter('date'), reverse=True) self.dates = list(self.articles) self.dates.sort(key=attrgetter('date'), - reverse=self.context['NEWEST_FIRST_ARCHIVES']) + reverse=self.context['NEWEST_FIRST_ARCHIVES']) # create tag cloud tag_cloud = defaultdict(int) @@ -468,7 +469,7 @@ class ArticlesGenerator(Generator): # order the categories per name self.categories = list(self.categories.items()) self.categories.sort( - reverse=self.settings['REVERSE_CATEGORY_ORDER']) + reverse=self.settings['REVERSE_CATEGORY_ORDER']) self.authors = list(self.authors.items()) self.authors.sort() @@ -527,7 +528,7 @@ class PagesGenerator(Generator): self.pages, self.translations = process_translations(all_pages) self.hidden_pages, self.hidden_translations = ( - process_translations(hidden_pages)) + process_translations(hidden_pages)) self._update_context(('pages', )) self.context['PAGES'] = self.pages @@ -536,11 +537,12 @@ class PagesGenerator(Generator): def generate_output(self, writer): for page in chain(self.translations, self.pages, - self.hidden_translations, self.hidden_pages): - writer.write_file(page.save_as, self.get_template(page.template), - self.context, page=page, - relative_urls=self.settings['RELATIVE_URLS'], - override_output=hasattr(page, 'override_save_as')) + self.hidden_translations, self.hidden_pages): + writer.write_file( + page.save_as, self.get_template(page.template), + self.context, page=page, + relative_urls=self.settings['RELATIVE_URLS'], + override_output=hasattr(page, 'override_save_as')) class StaticGenerator(Generator): @@ -548,7 +550,7 @@ class StaticGenerator(Generator): to output""" def _copy_paths(self, paths, source, destination, output_path, - final_path=None): + final_path=None): """Copy all the paths from source to destination""" for path in paths: copy(path, source, os.path.join(output_path, destination), @@ -586,6 +588,7 @@ class StaticGenerator(Generator): class SourceFileGenerator(Generator): + def generate_context(self): self.output_extension = self.settings['OUTPUT_SOURCES_EXTENSION'] diff --git a/pelican/settings.py b/pelican/settings.py index 8cbc4694..99828935 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -68,8 +68,6 @@ DEFAULT_CONFIG = { 'PDF_GENERATOR': False, 'PDF_STYLE_PATH': '', 'PDF_STYLE': 'twelvepoint', - 'CATEGORIES_URL': 'categories.html', - 'CATEGORIES_SAVE_AS': 'categories.html', 'CATEGORY_URL': 'category/{slug}.html', 'CATEGORY_SAVE_AS': os.path.join('category', '{slug}.html'), 'TAG_URL': 'tag/{slug}.html', diff --git a/pelican/writers.py b/pelican/writers.py index 30b0ed16..580a3990 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -54,7 +54,8 @@ class Writer(object): description=item.get_content(self.site_url), categories=item.tags if hasattr(item, 'tags') else None, author_name=getattr(item, 'author', ''), - pubdate=set_date_tzinfo(item.modified if hasattr(item, 'modified') else item.date, + pubdate=set_date_tzinfo( + item.modified if hasattr(item, 'modified') else item.date, self.settings.get('TIMEZONE', None))) def _open_w(self, filename, encoding, override=False): @@ -66,7 +67,7 @@ class Writer(object): if filename in self._overridden_files: if override: raise RuntimeError('File %s is set to be overridden twice' - % filename) + % filename) else: logger.info('skipping %s' % filename) filename = os.devnull @@ -124,7 +125,7 @@ class Writer(object): locale.setlocale(locale.LC_ALL, old_locale) def write_file(self, name, template, context, relative_urls=False, - paginated=None, override_output=False, **kwargs): + paginated=None, override_output=False, **kwargs): """Render the template and write the file. :param name: name of the file to output @@ -176,21 +177,13 @@ class Writer(object): localcontext['output_file'] = name localcontext.update(kwargs) - # check paginated - paginated = paginated or {} + # pagination if paginated: name_root = os.path.splitext(name)[0] # pagination needed, init paginators - paginators = {} - for key in paginated.keys(): - object_list = paginated[key] - - paginators[key] = Paginator( - name_root, - object_list, - self.settings, - ) + paginators = {key: Paginator(name_root, val, self.settings) + for key, val in paginated.items()} # generated pages, and write for page_num in range(list(paginators.values())[0].num_pages): @@ -198,15 +191,15 @@ class Writer(object): for key in paginators.keys(): paginator = paginators[key] previous_page = paginator.page(page_num) \ - if page_num > 0 else None + if page_num > 0 else None page = paginator.page(page_num + 1) next_page = paginator.page(page_num + 2) \ - if page_num + 1 < paginator.num_pages else None + if page_num + 1 < paginator.num_pages else None paginated_localcontext.update( - {'%s_paginator' % key: paginator, - '%s_page' % key: page, - '%s_previous_page' % key: previous_page, - '%s_next_page' % key: next_page}) + {'%s_paginator' % key: paginator, + '%s_page' % key: page, + '%s_previous_page' % key: previous_page, + '%s_next_page' % key: next_page}) _write_file(template, paginated_localcontext, self.output_path, page.save_as, override_output)