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