summaryrefslogtreecommitdiffstats
path: root/nikola
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2022-04-20 00:12:09 -0400
committerLibravatarUnit 193 <unit193@unit193.net>2022-04-20 00:12:09 -0400
commit942e313727d1ad886a1024c24fe4a9e8e2e0bb3e (patch)
tree1c4d5d826655cdb812c88563a25410f8b54e41d2 /nikola
parent8eeed31eb2f86ac982fa4b26f93b15828289c56d (diff)
New upstream version 8.2.0.upstream/8.2.0
Diffstat (limited to 'nikola')
-rw-r--r--nikola/__init__.py2
-rw-r--r--nikola/conf.py.in13
-rw-r--r--nikola/data/themes/base-jinja/templates/base_helper.tmpl2
-rw-r--r--nikola/data/themes/base-jinja/templates/comments_helper.tmpl56
-rw-r--r--nikola/data/themes/base-jinja/templates/comments_helper_dummy.tmpl10
-rw-r--r--nikola/data/themes/base/assets/css/rst_base.css322
-rw-r--r--nikola/data/themes/base/messages/messages_ca.py4
-rw-r--r--nikola/data/themes/base/messages/messages_mi.py54
-rw-r--r--nikola/data/themes/base/messages/messages_oc.py49
-rw-r--r--nikola/data/themes/base/messages/messages_tzm.py49
-rw-r--r--nikola/data/themes/base/templates/base_helper.tmpl2
-rw-r--r--nikola/data/themes/base/templates/comments_helper.tmpl56
-rw-r--r--nikola/data/themes/base/templates/comments_helper_dummy.tmpl10
-rw-r--r--nikola/data/themes/bootblog4-jinja/templates/base_helper.tmpl8
-rw-r--r--nikola/data/themes/bootblog4/templates/base_helper.tmpl8
-rw-r--r--nikola/data/themes/bootstrap4-jinja/templates/base_helper.tmpl8
-rw-r--r--nikola/data/themes/bootstrap4/templates/base_helper.tmpl8
-rw-r--r--nikola/filters.py11
-rw-r--r--nikola/image_processing.py4
-rw-r--r--nikola/nikola.py27
-rw-r--r--nikola/plugin_categories.py14
-rw-r--r--nikola/plugins/command/auto/__init__.py29
-rw-r--r--nikola/plugins/command/import_wordpress.py5
-rw-r--r--nikola/plugins/shortcode/post_list.py2
-rw-r--r--nikola/plugins/task/categories.py6
-rw-r--r--nikola/plugins/task/galleries.py7
-rw-r--r--nikola/plugins/task/listings.py2
-rw-r--r--nikola/plugins/task/tags.py6
-rw-r--r--nikola/plugins/template/jinja.py24
-rw-r--r--nikola/plugins/template/mako.py19
-rw-r--r--nikola/post.py18
-rw-r--r--nikola/utils.py20
32 files changed, 462 insertions, 393 deletions
diff --git a/nikola/__init__.py b/nikola/__init__.py
index 34396c9..e085f91 100644
--- a/nikola/__init__.py
+++ b/nikola/__init__.py
@@ -29,7 +29,7 @@
import os
import sys
-__version__ = '8.1.3'
+__version__ = '8.2.0'
DEBUG = bool(os.getenv('NIKOLA_DEBUG'))
SHOW_TRACEBACKS = bool(os.getenv('NIKOLA_SHOW_TRACEBACKS'))
diff --git a/nikola/conf.py.in b/nikola/conf.py.in
index fcb2d28..d209eb4 100644
--- a/nikola/conf.py.in
+++ b/nikola/conf.py.in
@@ -317,6 +317,7 @@ COMPILERS = ${COMPILERS}
# Set descriptions for tag pages to make them more interesting. The
# default is no description. The value is used in the meta description
# and displayed underneath the tag list or index page’s title.
+# (translatable)
# TAG_DESCRIPTIONS = {
# DEFAULT_LANG: {
# "blogging": "Meta-blog posts about blogging.",
@@ -325,6 +326,7 @@ COMPILERS = ${COMPILERS}
# }
# Set special titles for tag pages. The default is "Posts about TAG".
+# (translatable)
# TAG_TITLES = {
# DEFAULT_LANG: {
# "blogging": "Meta-posts about blogging",
@@ -390,6 +392,7 @@ CATEGORY_OUTPUT_FLAT_HIERARCHY = ${CATEGORY_OUTPUT_FLAT_HIERARCHY}
# Set descriptions for category pages to make them more interesting. The
# default is no description. The value is used in the meta description
# and displayed underneath the category list or index page’s title.
+# (translatable)
# CATEGORY_DESCRIPTIONS = {
# DEFAULT_LANG: {
# "blogging": "Meta-blog posts about blogging.",
@@ -398,6 +401,7 @@ CATEGORY_OUTPUT_FLAT_HIERARCHY = ${CATEGORY_OUTPUT_FLAT_HIERARCHY}
# }
# Set special titles for category pages. The default is "Posts about CATEGORY".
+# (translatable)
# CATEGORY_TITLES = {
# DEFAULT_LANG: {
# "blogging": "Meta-posts about blogging",
@@ -478,8 +482,8 @@ HIDDEN_CATEGORIES = []
# If you do not want to display an author publicly, you can mark it as hidden.
-# The author will not be displayed on the author list page and posts.
-# Tag pages will still be generated.
+# The author will not be displayed on the author list page.
+# Author pages and links to them will still be generated.
HIDDEN_AUTHORS = ['Guest']
# Allow multiple, comma-separated authors for a post? (Requires theme support, present in built-in themes)
@@ -570,7 +574,7 @@ REDIRECTIONS = ${REDIRECTIONS}
# Presets of commands to execute to deploy. Can be anything, for
# example, you may use rsync:
-# "rsync -rav --delete output/ joe@my.site:/srv/www/site"
+# "rsync -rav --delete --delete-after output/ joe@my.site:/srv/www/site"
# And then do a backup, or run `nikola ping` from the `ping`
# plugin (`nikola plugin -i ping`). Or run `nikola check -l`.
# You may also want to use github_deploy (see below).
@@ -580,7 +584,7 @@ REDIRECTIONS = ${REDIRECTIONS}
# in a `nikola deploy` command as you like.
# DEPLOY_COMMANDS = {
# 'default': [
-# "rsync -rav --delete output/ joe@my.site:/srv/www/site",
+# "rsync -rav --delete --delete-after output/ joe@my.site:/srv/www/site",
# ]
# }
@@ -765,6 +769,7 @@ GALLERIES_DEFAULT_THUMBNAIL = None
# options, but will have to be referenced manually to be visible on the site
# (the thumbnail has ``.thumbnail`` added before the file extension by default,
# but a different naming template can be configured with IMAGE_THUMBNAIL_FORMAT).
+# Panoramas (aspect ratio over 3:1) get 4x larger thumbnails due to scaling issues.
IMAGE_FOLDERS = {'images': 'images'}
# IMAGE_THUMBNAIL_SIZE = 400
diff --git a/nikola/data/themes/base-jinja/templates/base_helper.tmpl b/nikola/data/themes/base-jinja/templates/base_helper.tmpl
index a05abb9..2d8c0c8 100644
--- a/nikola/data/themes/base-jinja/templates/base_helper.tmpl
+++ b/nikola/data/themes/base-jinja/templates/base_helper.tmpl
@@ -82,7 +82,7 @@ lang="{{ lang }}">
<script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.{{ luxon_locales[lang] }}"></script>
{% endif %}
{% if use_cdn %}
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js" integrity="sha256-OVk2fwTRcXYlVFxr/ECXsakqelJbOg5WCj1dXSIb+nU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.28.0/build/global/luxon.min.js" integrity="sha256-l1u7Y5ze+ENf/T9ORPa3E642/uMgHUFa1KnqzFCcWEY=" crossorigin="anonymous"></script>
{% else %}
<script src="/assets/js/luxon.min.js"></script>
{% endif %}
diff --git a/nikola/data/themes/base-jinja/templates/comments_helper.tmpl b/nikola/data/themes/base-jinja/templates/comments_helper.tmpl
index 2a7d8dc..4b50485 100644
--- a/nikola/data/themes/base-jinja/templates/comments_helper.tmpl
+++ b/nikola/data/themes/base-jinja/templates/comments_helper.tmpl
@@ -1,63 +1,15 @@
{# -*- coding: utf-8 -*- #}
-{% import 'comments_helper_disqus.tmpl' as disqus with context %}
-{% import 'comments_helper_intensedebate.tmpl' as intensedebate with context %}
-{% import 'comments_helper_muut.tmpl' as muut with context %}
-{% import 'comments_helper_facebook.tmpl' as facebook with context %}
-{% import 'comments_helper_isso.tmpl' as isso with context %}
-{% import 'comments_helper_commento.tmpl' as commento with context %}
-{% import 'comments_helper_utterances.tmpl' as utterances with context %}
+{% import 'comments_helper_%s.tmpl' % comment_system as comments_helper_impl with context %}
{% macro comment_form(url, title, identifier) %}
- {% if comment_system == 'disqus' %}
- {{ disqus.comment_form(url, title, identifier) }}
- {% elif comment_system == 'intensedebate' %}
- {{ intensedebate.comment_form(url, title, identifier) }}
- {% elif comment_system == 'muut' %}
- {{ muut.comment_form(url, title, identifier) }}
- {% elif comment_system == 'facebook' %}
- {{ facebook.comment_form(url, title, identifier) }}
- {% elif comment_system == 'isso' %}
- {{ isso.comment_form(url, title, identifier) }}
- {% elif comment_system == 'commento' %}
- {{ commento.comment_form(url, title, identifier) }}
- {% elif comment_system == 'utterances' %}
- {{ utterances.comment_form(url, title, identifier) }}
- {% endif %}
+ {{ comments_helper_impl.comment_form(url, title, identifier) }}
{% endmacro %}
{% macro comment_link(link, identifier) %}
- {% if comment_system == 'disqus' %}
- {{ disqus.comment_link(link, identifier) }}
- {% elif comment_system == 'intensedebate' %}
- {{ intensedebate.comment_link(link, identifier) }}
- {% elif comment_system == 'muut' %}
- {{ muut.comment_link(link, identifier) }}
- {% elif comment_system == 'facebook' %}
- {{ facebook.comment_link(link, identifier) }}
- {% elif comment_system == 'isso' %}
- {{ isso.comment_link(link, identifier) }}
- {% elif comment_system == 'commento' %}
- {{ commento.comment_link(link, identifier) }}
- {% elif comment_system == 'utterances' %}
- {{ utterances.comment_link(link, identifier) }}
- {% endif %}
+ {{ comments_helper_impl.comment_link(link, identifier) }}
{% endmacro %}
{% macro comment_link_script() %}
- {% if comment_system == 'disqus' %}
- {{ disqus.comment_link_script() }}
- {% elif comment_system == 'intensedebate' %}
- {{ intensedebate.comment_link_script() }}
- {% elif comment_system == 'muut' %}
- {{ muut.comment_link_script() }}
- {% elif comment_system == 'facebook' %}
- {{ facebook.comment_link_script() }}
- {% elif comment_system == 'isso' %}
- {{ isso.comment_link_script() }}
- {% elif comment_system == 'commento' %}
- {{ commento.comment_link_script() }}
- {% elif comment_system == 'utterances' %}
- {{ utterances.comment_link_script() }}
- {% endif %}
+ {{ comments_helper_impl.comment_link_script() }}
{% endmacro %}
diff --git a/nikola/data/themes/base-jinja/templates/comments_helper_dummy.tmpl b/nikola/data/themes/base-jinja/templates/comments_helper_dummy.tmpl
new file mode 100644
index 0000000..5ae1edb
--- /dev/null
+++ b/nikola/data/themes/base-jinja/templates/comments_helper_dummy.tmpl
@@ -0,0 +1,10 @@
+{# -*- coding: utf-8 -*- #}
+
+{% macro comment_form(url, title, identifier) %}
+{% endmacro %}
+
+{% macro comment_link(link, identifier) %}
+{% endmacro %}
+
+{% macro comment_link_script() %}
+{% endmacro %}
diff --git a/nikola/data/themes/base/assets/css/rst_base.css b/nikola/data/themes/base/assets/css/rst_base.css
index 429f7b5..51f92b4 100644
--- a/nikola/data/themes/base/assets/css/rst_base.css
+++ b/nikola/data/themes/base/assets/css/rst_base.css
@@ -1,7 +1,7 @@
/* Minimal style sheet for the HTML output of Docutils. */
/* */
/* :Author: Günter Milde, based on html4css1.css by David Goodger */
-/* :Id: $Id: minimal.css 7952 2016-07-26 18:15:59Z milde $ */
+/* :Id: $Id: minimal.css 8642 2021-03-26 13:51:14Z milde $ */
/* :Copyright: © 2015 Günter Milde. */
/* :License: Released under the terms of the `2-Clause BSD license`_, */
/* in short: */
@@ -20,83 +20,66 @@
/* .. _CSS2.1: http://www.w3.org/TR/CSS2 */
/* .. _validates: http://jigsaw.w3.org/css-validator/validator$link */
-/* alignment of text and inline objects inside block objects*/
-.align-left { text-align: left; }
-.align-right { text-align: right; }
-.align-center { clear: both; text-align: center; }
-.align-top { vertical-align: top; }
-.align-middle { vertical-align: middle; }
-.align-bottom { vertical-align: bottom; }
-
/* titles */
-h1.title, p.subtitle {
- text-align: center;
-}
-p.admonition-title,
p.topic-title,
-p.sidebar-title,
-p.rubric,
+p.admonition-title,
p.system-message-title {
font-weight: bold;
}
-h1 + p.subtitle,
-h1 + p.section-subtitle {
- font-size: 1.6em;
+p.sidebar-title,
+p.rubric {
+ font-weight: bold;
+ font-size: larger;
+}
+p.rubric {
+ color: maroon;
}
-h2 + p.section-subtitle { font-size: 1.28em; }
p.subtitle,
p.section-subtitle,
p.sidebar-subtitle {
font-weight: bold;
margin-top: -0.5em;
}
-p.sidebar-title,
-p.rubric {
- font-size: larger;
+h1 + p.subtitle {
+ font-size: 1.6em;
}
-p.rubric { color: maroon; }
-a.toc-backref {
+h2 + p.section-subtitle, a.toc-backref {
color: black;
- text-decoration: none; }
+ text-decoration: none;
+}
/* Warnings, Errors */
-div.caution p.admonition-title,
-div.attention p.admonition-title,
-div.danger p.admonition-title,
-div.error p.admonition-title,
-div.warning p.admonition-title,
-div.system-messages h1,
-div.error,
-span.problematic,
-p.system-message-title {
+.system-messages h2,
+.system-message-title,
+span.problematic {
color: red;
}
-/* inline literals */
-span.docutils.literal {
+/* Inline Literals */
+.docutils.literal {
font-family: monospace;
white-space: pre-wrap;
}
-/* do not wraph at hyphens and similar: */
+/* do not wrap at hyphens and similar: */
.literal > span.pre { white-space: nowrap; }
/* Lists */
/* compact and simple lists: no margin between items */
-.simple li, .compact li,
-.simple ul, .compact ul,
-.simple ol, .compact ol,
-.simple > li p, .compact > li p,
-dl.simple > dd, dl.compact > dd {
+.simple li, .simple ul, .simple ol,
+.compact li, .compact ul, .compact ol,
+.simple > li p, dl.simple > dd,
+.compact > li p, dl.compact > dd {
margin-top: 0;
margin-bottom: 0;
}
/* Table of Contents */
-/*div.topic.contents { margin: 0; }*/
-ul.auto-toc {
+.topic.contents { margin: 0.5em 0; }
+.topic.contents ul.auto-toc {
list-style-type: none;
- padding-left: 1.5em; }
+ padding-left: 1.5em;
+}
/* Enumerated Lists */
ol.arabic { list-style: decimal }
@@ -105,14 +88,14 @@ ol.upperalpha { list-style: upper-alpha }
ol.lowerroman { list-style: lower-roman }
ol.upperroman { list-style: upper-roman }
-dt span.classifier { font-style: italic }
-dt span.classifier:before {
+/* Definition Lists and Derivatives */
+dt .classifier { font-style: italic }
+dt .classifier:before {
font-style: normal;
margin: 0.5em;
content: ":";
}
-
-/* Field Lists and drivatives */
+/* Field Lists and similar */
/* bold field name, content starts on the same line */
dl.field-list > dt,
dl.option-list > dt,
@@ -130,7 +113,7 @@ dl.citation > dt {
dl.field-list > dd,
dl.option-list > dd,
dl.docinfo > dd {
- margin-left: 9em; /* ca. 14 chars in the test examples */
+ margin-left: 9em; /* ca. 14 chars in the test examples, fit all Docinfo fields */
}
/* start field-body on a new line after long field names */
dl.field-list > dd > *:first-child,
@@ -147,18 +130,20 @@ dl.docinfo > dt:after {
}
/* Bibliographic Fields (docinfo) */
-pre.address { font: inherit; }
-dd.authors > p { margin: 0; }
+dl.docinfo pre.address {
+ font: inherit;
+ margin: 0.5em 0;
+}
+dl.docinfo > dd.authors > p { margin: 0; }
/* Option Lists */
-dl.option-list { margin-left: 40px; }
dl.option-list > dt { font-weight: normal; }
span.option { white-space: nowrap; }
/* Footnotes and Citations */
-dl.footnote.superscript > dd {margin-left: 1em; }
-dl.footnote.brackets > dd {margin-left: 2em; }
-dl > dt.label { font-weight: normal; }
+dl.footnote.superscript > dd { margin-left: 1em; }
+dl.footnote.brackets > dd { margin-left: 2em; }
+dl.footnote > dt { font-weight: normal; }
a.footnote-reference.brackets:before,
dt.label > span.brackets:before { content: "["; }
a.footnote-reference.brackets:after,
@@ -166,94 +151,74 @@ dt.label > span.brackets:after { content: "]"; }
a.footnote-reference.superscript,
dl.footnote.superscript > dt.label {
vertical-align: super;
- font-size: smaller;
+ font-size: small;
}
-dt.label > span.fn-backref { margin-left: 0.2em; }
-dt.label > span.fn-backref > a { font-style: italic; }
-
-/* Line Blocks */
-div.line-block { display: block; }
-div.line-block div.line-block {
- margin-top: 0;
- margin-bottom: 0;
- margin-left: 40px;
+dt.label > span.fn-backref {
+ margin-left: 0.2em;
+ font-weight: normal;
}
+dt.label > span.fn-backref > a { font-style: italic; }
-/* Figures, Images, and Tables */
-.figure.align-left,
-img.align-left,
-object.align-left,
-table.align-left {
- margin-right: auto;
-}
-.figure.align-center,
-img.align-center,
-object.align-center {
- margin-left: auto;
+/* Alignment */
+.align-left {
+ text-align: left;
margin-right: auto;
- display: block;
}
-table.align-center {
+.align-center {
+ clear: both;
+ text-align: center;
margin-left: auto;
margin-right: auto;
}
-.figure.align-right,
-img.align-right,
-object.align-right,
-table.align-right {
+.align-right {
+ text-align: right;
margin-left: auto;
}
-/* reset inner alignment in figures and tables */
-div.align-left, div.align-center, div.align-right,
-table.align-left, table.align-center, table.align-right
-{ text-align: inherit }
+.align-top { vertical-align: top; }
+.align-middle { vertical-align: middle; }
+.align-bottom { vertical-align: bottom; }
-/* Admonitions and System Messages */
-div.admonition,
-div.system-message,
-div.sidebar{
- margin: 40px;
- border: medium outset;
- padding-right: 1em;
- padding-left: 1em;
+/* reset inner alignment in figures and tables */
+figure.align-left, figure.align-right,
+table.align-left, table.align-center, table.align-right {
+ text-align: inherit;
}
-/* Sidebar */
-div.sidebar {
+/* Text Blocks */
+blockquote,
+div.topic,
+aside.topic {
+ margin: 1em 2em;
+}
+.sidebar,
+.admonition,
+.system-message {
+ border: thin solid;
+ margin: 1em 2em;
+ padding: 0.5em 1em;
+}
+.sidebar {
width: 30%;
max-width: 26em;
float: right;
clear: right;
}
+div.line-block { display: block; }
+div.line-block div.line-block, pre { margin-left: 2em; }
-/* Text Blocks */
-div.topic,
-pre.literal-block,
-pre.doctest-block,
-pre.math,
-pre.code {
- margin-right: 40px;
- margin-left: 40px;
+/* Code line numbers: dropped when copying text from the page */
+pre.code .ln { display: none; }
+pre.code code:before {
+ content: attr(data-lineno); /* …, none) fallback not supported by any browser */
+ color: gray;
}
-pre.code .ln { color: gray; } /* line numbers */
/* Tables */
-table.docutils { border-collapse: collapse; }
-table.docutils > td, table.docutils > th {
- border-style: solid;
- border-color: silver;
- padding: 0 1ex;
- border-width: thin;
-}
-table.docutils > td > p:first-child, table.docutils > th > p:first-child { margin-top: 0; }
-table.docutils > td > p, table.docutils > th > p { margin-bottom: 0; }
-table.docutils > caption {
- text-align: left;
- margin-bottom: 0.25em
-}
+td > p:first-child, th > p:first-child { margin-top: 0; }
+td > p, th > p { margin-bottom: 0; }
-table.borderless td, table.borderless th {
+.borderless td, .borderless th {
border: 0;
padding: 0;
padding-right: 0.5em /* separate table cells */
@@ -263,7 +228,7 @@ table.borderless td, table.borderless th {
/* Rules for easy reading and pre-defined style variants. */
/* */
/* :Author: Günter Milde, based on html4css1.css by David Goodger */
-/* :Id: $Id: plain.css 7952 2016-07-26 18:15:59Z milde $ */
+/* :Id: $Id: plain.css 8636 2021-03-19 00:23:33Z milde $ */
/* :Copyright: © 2015 Günter Milde. */
/* :License: Released under the terms of the `2-Clause BSD license`_, */
/* in short: */
@@ -281,10 +246,7 @@ table.borderless td, table.borderless th {
/* Document Structure */
/* ****************** */
-/* Sections */
-
/* Transitions */
-
hr.docutils {
width: 80%;
margin-top: 1em;
@@ -292,32 +254,19 @@ hr.docutils {
clear: both;
}
-/* Paragraphs */
-/* ========== */
-
-/* vertical space (parskip) */
-/*p, ol, ul, dl,*/
-/*div.line-block,*/
-/*table{*/
- /*margin-top: 0.5em;*/
- /*margin-bottom: 0.5em;*/
-/*}*/
-/*h1, h2, h3, h4, h5, h6, */
dl > dd {
margin-bottom: 0.5em;
}
-/* Lists */
-/* ========== */
-
-/* Definition Lists */
+/* Lists */
+/* ===== */
-dl > dd p:first-child { margin-top: 0; }
-/* :last-child is not part of CSS 2.1 (introduced in CSS 3) */
-/* dl > dd p:last-child { margin-bottom: 0; } */
+/* Separate list entries in compound lists */
+dl > dd, ol > li,
-/* lists nested in definition lists */
-/* :only-child is not part of CSS 2.1 (introduced in CSS 3) */
+/* Definition Lists */
+/* Indent lists nested in definition lists */
+/* (:only-child is new in CSS 3) */
dd > ul:only-child, dd > ol:only-child { padding-left: 1em; }
/* Description Lists */
@@ -358,31 +307,16 @@ div.dedication p.topic-title {
font-style: normal;
}
-/* Citations */
-dl.citation dt.label {
- font-weight: bold;
-}
-span.fn-backref {
- font-weight: normal;
-}
-
-/* Text Blocks */
-/* ============ */
+/* Text Blocks */
+/* =========== */
-/* Literal Blocks */
+/* Literal Blocks */
pre.literal-block, pre.doctest-block,
pre.math, pre.code {
- margin-left: 1.5em;
- margin-right: 1.5em
+ font-family: monospace;
}
-/* Block Quotes */
-
-blockquote,
-div.topic {
- margin-left: 1.5em;
- margin-right: 1.5em
-}
+/* Block Quotes */
blockquote > table,
div.topic > table {
margin-top: 0;
@@ -394,8 +328,8 @@ div.topic p.attribution {
margin-left: 20%;
}
-/* Tables */
-/* ====== */
+/* Tables */
+/* ====== */
/* th { vertical-align: bottom; } */
@@ -422,11 +356,11 @@ table.numbered > caption:before {
font-weight: bold;
}
-/* Explicit Markup Blocks */
-/* ====================== */
+/* Explicit Markup Blocks */
+/* ====================== */
-/* Footnotes and Citations */
-/* ----------------------- */
+/* Footnotes and Citations */
+/* ----------------------- */
/* line on the left */
dl.footnote {
@@ -435,40 +369,56 @@ dl.footnote {
border-left-width: thin;
}
-/* Directives */
-/* ---------- */
+/* Directives */
+/* ---------- */
-/* Body Elements */
-/* ~~~~~~~~~~~~~ */
+/* Body Elements */
+/* ~~~~~~~~~~~~~ */
/* Images and Figures */
/* let content flow to the side of aligned images and figures */
-.figure.align-left,
+figure.align-left,
img.align-left,
+video.align-left,
object.align-left {
- display: block;
clear: left;
float: left;
- margin-right: 1em
+ margin-right: 1em;
}
-.figure.align-right,
+figure.align-right,
img.align-right,
+video.align-right,
object.align-right {
- display: block;
clear: right;
float: right;
- margin-left: 1em
+ margin-left: 1em;
}
-/* Sidebar */
+/* Numbered figures */
+figure.numbered > figcaption > p:before {
+ counter-increment: figure;
+ content: "Figure " counter(figure) ": ";
+ font-weight: bold;
+}
-/* Move into the margin. In a layout with fixed margins, */
-/* it can be moved into the margin completely. */
-div.sidebar {
+/* Admonitions and System Messages */
+.caution p.admonition-title,
+.attention p.admonition-title,
+.danger p.admonition-title,
+.error p.admonition-title,
+.warning p.admonition-title,
+div.error {
+ color: red;
+}
+
+/* Sidebar */
+/* Move right. In a layout with fixed margins, */
+/* it can be moved into the margin. */
+aside.sidebar {
width: 30%;
max-width: 26em;
margin-left: 1em;
- margin-right: -5.5%;
- background-color: #ffffee ;
+ margin-right: -2%;
+ background-color: #ffffee;
}
diff --git a/nikola/data/themes/base/messages/messages_ca.py b/nikola/data/themes/base/messages/messages_ca.py
index 0143a85..c5d8de8 100644
--- a/nikola/data/themes/base/messages/messages_ca.py
+++ b/nikola/data/themes/base/messages/messages_ca.py
@@ -2,7 +2,7 @@
"""Autogenerated file, do not edit. Submit translations on Transifex."""
MESSAGES = {
- "%d min remaining to read": "% min restants per a llegir",
+ "%d min remaining to read": "%d min restants per a llegir",
"(active)": "(actiu)",
"Also available in:": "També disponible en:",
"Archive": "Arxiu",
@@ -45,5 +45,5 @@ MESSAGES = {
"Write your post here.": "Escriviu la vostra entrada aquí.",
"old posts, page %d": "entrades antigues, pàgina %d",
"page %d": "pàgina %d",
- "updated": "",
+ "updated": "actualitzat",
}
diff --git a/nikola/data/themes/base/messages/messages_mi.py b/nikola/data/themes/base/messages/messages_mi.py
index 21f9739..853744a 100644
--- a/nikola/data/themes/base/messages/messages_mi.py
+++ b/nikola/data/themes/base/messages/messages_mi.py
@@ -2,48 +2,48 @@
"""Autogenerated file, do not edit. Submit translations on Transifex."""
MESSAGES = {
- "%d min remaining to read": "",
+ "%d min remaining to read": "%d meneti ka toe ki te korero",
"(active)": "(mātātoa)",
- "Also available in:": "",
+ "Also available in:": "Kei te wātea ano hoki",
"Archive": "Pūranga",
- "Atom feed": "",
+ "Atom feed": "Atom whangai",
"Authors": "Kaituhi",
"Categories": "Kāwai",
- "Comments": "Kōrerohia",
+ "Comments": "Nga korero",
"LANGUAGE": " Māori",
"Languages:": "Reo",
- "More posts about %s": "",
- "Newer posts": "",
- "Next post": "",
+ "More posts about %s": "Ētahi atu pou e pā ana ki %s",
+ "Newer posts": "Nga pou hou",
+ "Next post": "Pou muri",
"Next": "Panuku",
- "No posts found.": "",
+ "No posts found.": "Kāore i kitea he korero.",
"Nothing found.": "Kīhai i kitea",
- "Older posts": "",
- "Original site": "",
- "Posted:": "",
- "Posts about %s": "",
- "Posts by %s": "",
- "Posts for year %s": "",
- "Posts for {month_day_year}": "",
- "Posts for {month_year}": "",
- "Previous post": "",
+ "Older posts": "Nga pou tawhito",
+ "Original site": "Pae tukutuku",
+ "Posted:": "Tukua",
+ "Posts about %s": "Tuhinga e pā ana ki %s",
+ "Posts by %s": "Tuhinga na %s",
+ "Posts for year %s": "Tuhinga mo te tau %s",
+ "Posts for {month_day_year}": "Tuhinga mo {month_day_year}",
+ "Posts for {month_year}": "Tuhinga mo {month_year}",
+ "Previous post": "Tuhinga o mua",
"Previous": "Whakamuri",
- "Publication date": "",
+ "Publication date": "Pukapuka tuhi",
"RSS feed": "Whāngai RSS",
- "Read in English": "",
- "Read more": "",
- "Skip to main content": "",
+ "Read in English": "Pānuihia i te Maori",
+ "Read more": "Pānuihia atu",
+ "Skip to main content": "Haere ki te ihirangi matua",
"Source": "Matapuna",
- "Subcategories:": "",
+ "Subcategories:": "Ngā kōpaki",
"Tags and Categories": "Tūtohu me nga kāwai",
"Tags": "Tūtohu",
- "Toggle navigation": "",
- "Uncategorized": "",
+ "Toggle navigation": "Takahuri whakatere",
+ "Uncategorized": "Korekorekore",
"Up": "Ki runga",
"Updates": "Whakahou",
- "Write your page here.": "",
- "Write your post here.": "",
- "old posts, page %d": "",
+ "Write your page here.": "Tuhia taau whārangi ki konei.",
+ "Write your post here.": "Tuhia to pou i konei.",
+ "old posts, page %d": "nga pou tawhito, whārangi %d",
"page %d": "whārangi %d",
"updated": "whakahoutia",
}
diff --git a/nikola/data/themes/base/messages/messages_oc.py b/nikola/data/themes/base/messages/messages_oc.py
new file mode 100644
index 0000000..a51a9f3
--- /dev/null
+++ b/nikola/data/themes/base/messages/messages_oc.py
@@ -0,0 +1,49 @@
+# -*- encoding:utf-8 -*-
+"""Autogenerated file, do not edit. Submit translations on Transifex."""
+
+MESSAGES = {
+ "%d min remaining to read": "%d min demorantas de lectura",
+ "(active)": "(actiu)",
+ "Also available in:": "Tanben disponibla en :",
+ "Archive": "Archius",
+ "Atom feed": "Flux Atom",
+ "Authors": "Autors",
+ "Categories": "Categorias",
+ "Comments": "Comentaris",
+ "LANGUAGE": "Occitan",
+ "Languages:": "Lengas :",
+ "More posts about %s": "Mai de publicacion sus %s",
+ "Newer posts": "Publicacions mai recentas",
+ "Next post": "Publicacion seguenta",
+ "Next": "Seguent",
+ "No posts found.": "Cap de publicacion pas trobada.",
+ "Nothing found.": "Res pas trobat.",
+ "Older posts": "Publicacions mai ancianas",
+ "Original site": "Site original",
+ "Posted:": "Publicada lo :",
+ "Posts about %s": "Publicacions tocant %s",
+ "Posts by %s": "Publicat per %s",
+ "Posts for year %s": "Publicacions per annada %s",
+ "Posts for {month_day_year}": "Publicacions per {month_day_year}",
+ "Posts for {month_year}": "Publicacions per {month_year} ",
+ "Previous post": "Publicacion precedenta",
+ "Previous": "Precedent",
+ "Publication date": "Data de publicacion",
+ "RSS feed": "Flux RSS",
+ "Read in English": "Legir en occitan",
+ "Read more": "Ne legir mai",
+ "Skip to main content": "Passar al contengut màger",
+ "Source": "Font",
+ "Subcategories:": "Jos-categorias :",
+ "Tags and Categories": "Etiquetas e categorias",
+ "Tags": "Etiquetas",
+ "Toggle navigation": "Alternar la navigacion",
+ "Uncategorized": "Sens categoria",
+ "Up": "Amont",
+ "Updates": "Actualizacions",
+ "Write your page here.": "Escrivètz vòstra pagina aquí.",
+ "Write your post here.": "Escrivètz vòstra publicacion aquí.",
+ "old posts, page %d": "publicacions ancianas, pagina %d",
+ "page %d": "pagina %d",
+ "updated": "actualizada",
+}
diff --git a/nikola/data/themes/base/messages/messages_tzm.py b/nikola/data/themes/base/messages/messages_tzm.py
new file mode 100644
index 0000000..e9ea75b
--- /dev/null
+++ b/nikola/data/themes/base/messages/messages_tzm.py
@@ -0,0 +1,49 @@
+# -*- encoding:utf-8 -*-
+"""Autogenerated file, do not edit. Submit translations on Transifex."""
+
+MESSAGES = {
+ "%d min remaining to read": "",
+ "(active)": "",
+ "Also available in:": "",
+ "Archive": "",
+ "Atom feed": "",
+ "Authors": "",
+ "Categories": "",
+ "Comments": "Ixfawalen",
+ "LANGUAGE": "Tamaziɣt",
+ "Languages:": "",
+ "More posts about %s": "",
+ "Newer posts": "",
+ "Next post": "",
+ "Next": "",
+ "No posts found.": "",
+ "Nothing found.": "",
+ "Older posts": "",
+ "Original site": "",
+ "Posted:": "",
+ "Posts about %s": "",
+ "Posts by %s": "",
+ "Posts for year %s": "",
+ "Posts for {month_day_year}": "",
+ "Posts for {month_year}": "",
+ "Previous post": "",
+ "Previous": "",
+ "Publication date": "",
+ "RSS feed": "",
+ "Read in English": "Ɣer s tneglizt",
+ "Read more": "Ɣer uggar",
+ "Skip to main content": "",
+ "Source": "Asagem",
+ "Subcategories:": "",
+ "Tags and Categories": "",
+ "Tags": "",
+ "Toggle navigation": "",
+ "Uncategorized": "",
+ "Up": "",
+ "Updates": "",
+ "Write your page here.": "",
+ "Write your post here.": "",
+ "old posts, page %d": "",
+ "page %d": "",
+ "updated": "",
+}
diff --git a/nikola/data/themes/base/templates/base_helper.tmpl b/nikola/data/themes/base/templates/base_helper.tmpl
index 18801ed..684165d 100644
--- a/nikola/data/themes/base/templates/base_helper.tmpl
+++ b/nikola/data/themes/base/templates/base_helper.tmpl
@@ -82,7 +82,7 @@ lang="${lang}">
<script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.${luxon_locales[lang]}"></script>
% endif
% if use_cdn:
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js" integrity="sha256-OVk2fwTRcXYlVFxr/ECXsakqelJbOg5WCj1dXSIb+nU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.28.0/build/global/luxon.min.js" integrity="sha256-l1u7Y5ze+ENf/T9ORPa3E642/uMgHUFa1KnqzFCcWEY=" crossorigin="anonymous"></script>
% else:
<script src="/assets/js/luxon.min.js"></script>
% endif
diff --git a/nikola/data/themes/base/templates/comments_helper.tmpl b/nikola/data/themes/base/templates/comments_helper.tmpl
index 002499e..cfd52f2 100644
--- a/nikola/data/themes/base/templates/comments_helper.tmpl
+++ b/nikola/data/themes/base/templates/comments_helper.tmpl
@@ -1,63 +1,15 @@
## -*- coding: utf-8 -*-
-<%namespace name="disqus" file="comments_helper_disqus.tmpl"/>
-<%namespace name="intensedebate" file="comments_helper_intensedebate.tmpl"/>
-<%namespace name="muut" file="comments_helper_muut.tmpl"/>
-<%namespace name="facebook" file="comments_helper_facebook.tmpl"/>
-<%namespace name="isso" file="comments_helper_isso.tmpl"/>
-<%namespace name="commento" file="comments_helper_commento.tmpl"/>
-<%namespace name="utterances" file="comments_helper_utterances.tmpl"/>
+<%namespace name="comments_helper_impl" file="comments_helper_${context['comment_system']}.tmpl"/>
<%def name="comment_form(url, title, identifier)">
- %if comment_system == 'disqus':
- ${disqus.comment_form(url, title, identifier)}
- % elif comment_system == 'intensedebate':
- ${intensedebate.comment_form(url, title, identifier)}
- % elif comment_system == 'muut':
- ${muut.comment_form(url, title, identifier)}
- % elif comment_system == 'facebook':
- ${facebook.comment_form(url, title, identifier)}
- % elif comment_system == 'isso':
- ${isso.comment_form(url, title, identifier)}
- % elif comment_system == 'commento':
- ${commento.comment_form(url, title, identifier)}
- % elif comment_system == 'utterances':
- ${utterances.comment_form(url, title, identifier)}
- %endif
+ ${comments_helper_impl.comment_form(url, title, identifier)}
</%def>
<%def name="comment_link(link, identifier)">
- %if comment_system == 'disqus':
- ${disqus.comment_link(link, identifier)}
- % elif comment_system == 'intensedebate':
- ${intensedebate.comment_link(link, identifier)}
- % elif comment_system == 'muut':
- ${muut.comment_link(link, identifier)}
- % elif comment_system == 'facebook':
- ${facebook.comment_link(link, identifier)}
- % elif comment_system == 'isso':
- ${isso.comment_link(link, identifier)}
- % elif comment_system == 'commento':
- ${commento.comment_link(link, identifier)}
- % elif comment_system == 'utterances':
- ${utterances.comment_link(link, identifier)}
- %endif
+ ${comments_helper_impl.comment_link(link, identifier)}
</%def>
<%def name="comment_link_script()">
- %if comment_system == 'disqus':
- ${disqus.comment_link_script()}
- % elif comment_system == 'intensedebate':
- ${intensedebate.comment_link_script()}
- % elif comment_system == 'muut':
- ${muut.comment_link_script()}
- % elif comment_system == 'facebook':
- ${facebook.comment_link_script()}
- % elif comment_system == 'isso':
- ${isso.comment_link_script()}
- % elif comment_system == 'commento':
- ${commento.comment_link_script()}
- % elif comment_system == 'utterances':
- ${utterances.comment_link_script()}
- %endif
+ ${comments_helper_impl.comment_link_script()}
</%def>
diff --git a/nikola/data/themes/base/templates/comments_helper_dummy.tmpl b/nikola/data/themes/base/templates/comments_helper_dummy.tmpl
new file mode 100644
index 0000000..f31a2e0
--- /dev/null
+++ b/nikola/data/themes/base/templates/comments_helper_dummy.tmpl
@@ -0,0 +1,10 @@
+## -*- coding: utf-8 -*-
+
+<%def name="comment_form(url, title, identifier)">
+</%def>
+
+<%def name="comment_link(link, identifier)">
+</%def>
+
+<%def name="comment_link_script()">
+</%def>
diff --git a/nikola/data/themes/bootblog4-jinja/templates/base_helper.tmpl b/nikola/data/themes/bootblog4-jinja/templates/base_helper.tmpl
index 7f1bcc8..b35c8d2 100644
--- a/nikola/data/themes/bootblog4-jinja/templates/base_helper.tmpl
+++ b/nikola/data/themes/bootblog4-jinja/templates/base_helper.tmpl
@@ -64,9 +64,9 @@ lang="{{ lang }}">
{% macro late_load_js() %}
{% if use_cdn %}
- <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.js" integrity="sha256-ULQV01VS9LCI2ePpLsmka+W0mawFpEA0rtxnezUj4A4=" crossorigin="anonymous"></script>
{% endif %}
{% if use_bundles and use_cdn %}
@@ -86,7 +86,7 @@ lang="{{ lang }}">
<script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.{{ luxon_locales[lang] }}"></script>
{% endif %}
{% if use_cdn %}
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js" integrity="sha256-OVk2fwTRcXYlVFxr/ECXsakqelJbOg5WCj1dXSIb+nU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.28.0/build/global/luxon.min.js" integrity="sha256-l1u7Y5ze+ENf/T9ORPa3E642/uMgHUFa1KnqzFCcWEY=" crossorigin="anonymous"></script>
{% else %}
<script src="/assets/js/luxon.min.js"></script>
{% endif %}
@@ -100,7 +100,7 @@ lang="{{ lang }}">
{% macro html_stylesheets() %}
{% if use_cdn %}
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.css" integrity="sha256-cLMYWYYutHkt+KpNqjg7NVkYSQ+E2VbrXsEvOqU7mL0=" crossorigin="anonymous">
{% endif %}
{% if use_bundles and use_cdn %}
diff --git a/nikola/data/themes/bootblog4/templates/base_helper.tmpl b/nikola/data/themes/bootblog4/templates/base_helper.tmpl
index 2259d4d..33414d8 100644
--- a/nikola/data/themes/bootblog4/templates/base_helper.tmpl
+++ b/nikola/data/themes/bootblog4/templates/base_helper.tmpl
@@ -64,9 +64,9 @@ lang="${lang}">
<%def name="late_load_js()">
%if use_cdn:
- <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.js" integrity="sha256-ULQV01VS9LCI2ePpLsmka+W0mawFpEA0rtxnezUj4A4=" crossorigin="anonymous"></script>
% endif
%if use_bundles and use_cdn:
@@ -86,7 +86,7 @@ lang="${lang}">
<script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.${luxon_locales[lang]}"></script>
%endif
%if use_cdn:
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js" integrity="sha256-OVk2fwTRcXYlVFxr/ECXsakqelJbOg5WCj1dXSIb+nU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.28.0/build/global/luxon.min.js" integrity="sha256-l1u7Y5ze+ENf/T9ORPa3E642/uMgHUFa1KnqzFCcWEY=" crossorigin="anonymous"></script>
%else:
<script src="/assets/js/luxon.min.js"></script>
%endif
@@ -100,7 +100,7 @@ lang="${lang}">
<%def name="html_stylesheets()">
% if use_cdn:
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.css" integrity="sha256-cLMYWYYutHkt+KpNqjg7NVkYSQ+E2VbrXsEvOqU7mL0=" crossorigin="anonymous">
% endif
%if use_bundles and use_cdn:
diff --git a/nikola/data/themes/bootstrap4-jinja/templates/base_helper.tmpl b/nikola/data/themes/bootstrap4-jinja/templates/base_helper.tmpl
index 2d82147..ff1bfa2 100644
--- a/nikola/data/themes/bootstrap4-jinja/templates/base_helper.tmpl
+++ b/nikola/data/themes/bootstrap4-jinja/templates/base_helper.tmpl
@@ -64,9 +64,9 @@ lang="{{ lang }}">
{% macro late_load_js() %}
{% if use_cdn %}
- <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.js" integrity="sha256-ULQV01VS9LCI2ePpLsmka+W0mawFpEA0rtxnezUj4A4=" crossorigin="anonymous"></script>
{% endif %}
{% if use_bundles and use_cdn %}
@@ -86,7 +86,7 @@ lang="{{ lang }}">
<script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.{{ luxon_locales[lang] }}"></script>
{% endif %}
{% if use_cdn %}
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js" integrity="sha256-OVk2fwTRcXYlVFxr/ECXsakqelJbOg5WCj1dXSIb+nU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.28.0/build/global/luxon.min.js" integrity="sha256-l1u7Y5ze+ENf/T9ORPa3E642/uMgHUFa1KnqzFCcWEY=" crossorigin="anonymous"></script>
{% else %}
<script src="/assets/js/luxon.min.js"></script>
{% endif %}
@@ -100,7 +100,7 @@ lang="{{ lang }}">
{% macro html_stylesheets() %}
{% if use_cdn %}
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.css" integrity="sha256-cLMYWYYutHkt+KpNqjg7NVkYSQ+E2VbrXsEvOqU7mL0=" crossorigin="anonymous">
{% endif %}
{% if use_bundles and use_cdn %}
diff --git a/nikola/data/themes/bootstrap4/templates/base_helper.tmpl b/nikola/data/themes/bootstrap4/templates/base_helper.tmpl
index 80dd8f9..32ca42b 100644
--- a/nikola/data/themes/bootstrap4/templates/base_helper.tmpl
+++ b/nikola/data/themes/bootstrap4/templates/base_helper.tmpl
@@ -64,9 +64,9 @@ lang="${lang}">
<%def name="late_load_js()">
%if use_cdn:
- <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.js" integrity="sha256-ULQV01VS9LCI2ePpLsmka+W0mawFpEA0rtxnezUj4A4=" crossorigin="anonymous"></script>
% endif
%if use_bundles and use_cdn:
@@ -86,7 +86,7 @@ lang="${lang}">
<script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.${luxon_locales[lang]}"></script>
%endif
%if use_cdn:
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js" integrity="sha256-OVk2fwTRcXYlVFxr/ECXsakqelJbOg5WCj1dXSIb+nU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.28.0/build/global/luxon.min.js" integrity="sha256-l1u7Y5ze+ENf/T9ORPa3E642/uMgHUFa1KnqzFCcWEY=" crossorigin="anonymous"></script>
%else:
<script src="/assets/js/luxon.min.js"></script>
%endif
@@ -100,7 +100,7 @@ lang="${lang}">
<%def name="html_stylesheets()">
%if use_cdn:
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.css" integrity="sha256-cLMYWYYutHkt+KpNqjg7NVkYSQ+E2VbrXsEvOqU7mL0=" crossorigin="anonymous">
% endif
%if use_bundles and use_cdn:
diff --git a/nikola/filters.py b/nikola/filters.py
index 5e7ca5e..c2b10e2 100644
--- a/nikola/filters.py
+++ b/nikola/filters.py
@@ -268,8 +268,11 @@ def minify_lines(data):
def _run_typogrify(data, typogrify_filters, ignore_tags=None):
"""Run typogrify with ignore support."""
+ default_ignore_tags = ["title", ".math"]
if ignore_tags is None:
- ignore_tags = ["title"]
+ ignore_tags = default_ignore_tags
+ else:
+ ignore_tags = ignore_tags + default_ignore_tags
data = _normalize_html(data)
@@ -328,11 +331,13 @@ def typogrify_sans_widont(data):
@apply_to_text_file
-def typogrify_custom(data, typogrify_filters, ignore_tags=None):
- """Run typogrify with a custom list of fliter functions."""
+def typogrify_custom(data, typogrify_filters=None, ignore_tags=None):
+ """Run typogrify with a custom list of filter functions."""
if typo is None:
req_missing(['typogrify'], 'use the typogrify filter', optional=True)
return data
+ if typogrify_filters is None:
+ typogrify_filters = [typo.amp, typo.widont, typo.smartypants, typo.caps, typo.initial_quotes]
return _run_typogrify(data, typogrify_filters, ignore_tags)
diff --git a/nikola/image_processing.py b/nikola/image_processing.py
index b1d58c2..4ac6d93 100644
--- a/nikola/image_processing.py
+++ b/nikola/image_processing.py
@@ -142,7 +142,7 @@ class ImageProcessor(object):
if w > max_size or h > max_size:
size = max_size, max_size
# Panoramas get larger thumbnails because they look *awful*
- if bigger_panoramas and w > 2 * h:
+ if bigger_panoramas and w > 3 * h:
size = min(w, max_size * 4), min(w, max_size * 4)
try:
im.thumbnail(size, Image.ANTIALIAS)
@@ -189,7 +189,7 @@ class ImageProcessor(object):
# calculate new size preserving aspect ratio.
ratio = float(w) / h
# Panoramas get larger thumbnails because they look *awful*
- if bigger_panoramas and w > 2 * h:
+ if bigger_panoramas and w > 3 * h:
max_size = max_size * 4
if w > h:
w = max_size
diff --git a/nikola/nikola.py b/nikola/nikola.py
index 2ec8f2d..ca8291b 100644
--- a/nikola/nikola.py
+++ b/nikola/nikola.py
@@ -66,6 +66,7 @@ from .plugin_categories import (
TemplateSystem,
SignalHandler,
ConfigPlugin,
+ CommentSystem,
PostScanner,
Taxonomy,
)
@@ -133,10 +134,12 @@ LEGAL_VALUES = {
('ja', '!jp'): 'Japanese',
'ko': 'Korean',
'lt': 'Lithuanian',
+ 'mi': 'Maori',
'ml': 'Malayalam',
'mr': 'Marathi',
'nb': 'Norwegian (Bokmål)',
'nl': 'Dutch',
+ 'oc': 'Occitan',
'pa': 'Punjabi',
'pl': 'Polish',
'pt': 'Portuguese',
@@ -203,10 +206,12 @@ LEGAL_VALUES = {
'ja': 'ja',
'ko': 'ko',
'lt': 'lt',
+ 'mi': 'mi',
'ml': 'ml',
'mr': 'mr',
'nb': 'nb',
'nl': 'nl',
+ 'oc': 'oc',
'pa': 'pa',
'pl': 'pl',
'pt': 'pt',
@@ -681,6 +686,10 @@ class Nikola(object):
'FEED_READ_MORE_LINK',
'INDEXES_TITLE',
'CATEGORY_DESTPATH_NAMES',
+ 'CATEGORY_TITLES',
+ 'CATEGORY_DESCRIPTIONS',
+ 'TAG_TITLES',
+ 'TAG_DESCRIPTIONS',
'INDEXES_PAGES',
'INDEXES_PRETTY_PAGE_URL',
'THEME_CONFIG',
@@ -727,6 +736,8 @@ class Nikola(object):
'rss_path',
'rss_filename_base',
'atom_filename_base',
+ 'index_read_more_link',
+ 'feed_read_more_link',
)
# WARNING: navigation_(alt_)links SHOULD NOT be added to the list above.
# Themes ask for [lang] there and we should provide it.
@@ -1029,6 +1040,7 @@ class Nikola(object):
"ShortcodePlugin": ShortcodePlugin,
"SignalHandler": SignalHandler,
"ConfigPlugin": ConfigPlugin,
+ "CommentSystem": CommentSystem,
"PostScanner": PostScanner,
"Taxonomy": Taxonomy,
})
@@ -1172,7 +1184,8 @@ class Nikola(object):
self.compilers[plugin_info.name] = \
plugin_info.plugin_object
- # Load config plugins and register templated shortcodes
+ # Load comment systems, config plugins and register templated shortcodes
+ self._activate_plugins_of_category("CommentSystem")
self._activate_plugins_of_category("ConfigPlugin")
self._register_templated_shortcodes()
@@ -1237,7 +1250,7 @@ class Nikola(object):
self._GLOBAL_CONTEXT['translations'] = self.config.get('TRANSLATIONS')
self._GLOBAL_CONTEXT['license'] = self.config.get('LICENSE')
self._GLOBAL_CONTEXT['search_form'] = self.config.get('SEARCH_FORM')
- self._GLOBAL_CONTEXT['comment_system'] = self.config.get('COMMENT_SYSTEM')
+ self._GLOBAL_CONTEXT['comment_system'] = self.config.get('COMMENT_SYSTEM') or 'dummy'
self._GLOBAL_CONTEXT['comment_system_id'] = self.config.get('COMMENT_SYSTEM_ID')
self._GLOBAL_CONTEXT['site_has_comments'] = bool(self.config.get('COMMENT_SYSTEM'))
self._GLOBAL_CONTEXT['mathjax_config'] = self.config.get(
@@ -1309,6 +1322,8 @@ class Nikola(object):
self.ALL_PAGE_DEPS['slug_author_path'] = self.config.get('SLUG_AUTHOR_PATH')
self.ALL_PAGE_DEPS['slug_tag_path'] = self.config.get('SLUG_TAG_PATH')
self.ALL_PAGE_DEPS['locale'] = self.config.get('LOCALE')
+ self.ALL_PAGE_DEPS['index_read_more_link'] = self.config.get('INDEX_READ_MORE_LINK')
+ self.ALL_PAGE_DEPS['feed_read_more_link'] = self.config.get('FEED_READ_MORE_LINK')
def _activate_plugins_of_category(self, category):
"""Activate all the plugins of a given category and return them."""
@@ -1668,7 +1683,7 @@ class Nikola(object):
context[k] = context[k](context['lang'])
output = self.template_system.render_template_to_string(t_data, context)
if fname is not None:
- dependencies = [fname] + self.template_system.get_deps(fname)
+ dependencies = [fname] + self.template_system.get_deps(fname, context)
else:
dependencies = []
return output, dependencies
@@ -1709,7 +1724,7 @@ class Nikola(object):
for k in self._GLOBAL_CONTEXT_TRANSLATABLE:
context[k] = context[k](context['lang'])
output = self.template_system.render_template_to_string(t_data, context)
- dependencies = self.template_system.get_string_deps(t_data)
+ dependencies = self.template_system.get_string_deps(t_data, context)
return output, dependencies
def register_shortcode(self, name, f):
@@ -2264,8 +2279,10 @@ class Nikola(object):
"""
utils.LocaleBorg().set_locale(lang)
+ template_dep_context = context.copy()
+ template_dep_context.update(self.GLOBAL_CONTEXT)
file_deps = copy(file_deps) if file_deps else []
- file_deps += self.template_system.template_deps(template_name)
+ file_deps += self.template_system.template_deps(template_name, template_dep_context)
file_deps = sorted(list(filter(None, file_deps)))
context = copy(context) if context else {}
diff --git a/nikola/plugin_categories.py b/nikola/plugin_categories.py
index 722e672..0ba5991 100644
--- a/nikola/plugin_categories.py
+++ b/nikola/plugin_categories.py
@@ -94,7 +94,7 @@ class BasePlugin(IPlugin):
"""Add 'dependency' to the target task's task_deps."""
self.site.injected_deps[target].append(dependency)
- def get_deps(self, filename):
+ def get_deps(self, filename, context=None):
"""Find the dependencies for a file."""
return []
@@ -222,15 +222,15 @@ class TemplateSystem(BasePlugin):
"""Set the list of folders where templates are located and cache."""
raise NotImplementedError()
- def template_deps(self, template_name: str):
+ def template_deps(self, template_name: str, context=None):
"""Return filenames which are dependencies for a template."""
raise NotImplementedError()
- def get_deps(self, filename: str):
+ def get_deps(self, filename: str, context=None):
"""Return paths to dependencies for the template loaded from filename."""
raise NotImplementedError()
- def get_string_deps(self, text: str):
+ def get_string_deps(self, text: str, context=None):
"""Find dependencies for a template string."""
raise NotImplementedError()
@@ -475,6 +475,12 @@ class ConfigPlugin(BasePlugin):
name = "dummy_config_plugin"
+class CommentSystem(BasePlugin):
+ """A plugn that offers a new comment system."""
+
+ name = "dummy_comment_system"
+
+
class ShortcodePlugin(BasePlugin):
"""A plugin that adds a shortcode."""
diff --git a/nikola/plugins/command/auto/__init__.py b/nikola/plugins/command/auto/__init__.py
index 9de5622..2c6d0e7 100644
--- a/nikola/plugins/command/auto/__init__.py
+++ b/nikola/plugins/command/auto/__init__.py
@@ -37,6 +37,7 @@ import sys
import typing
import webbrowser
+import blinker
import pkg_resources
from nikola.plugin_categories import Command
@@ -122,7 +123,8 @@ class CommandAuto(Command):
'long': 'process',
'default': 0,
'type': int,
- 'help': 'Number of subprocesses (nikola build argument)'
+ 'help': 'Number of subprocesses',
+ 'section': 'Arguments passed to `nikola build`'
},
{
'name': 'parallel-type',
@@ -130,8 +132,25 @@ class CommandAuto(Command):
'long': 'parallel-type',
'default': 'process',
'type': str,
- 'help': "Parallelization mode ('process' or 'thread', nikola build argument)"
+ 'help': "Parallelization mode ('process' or 'thread')",
+ 'section': 'Arguments passed to `nikola build`'
},
+ {
+ 'name': 'db-file',
+ 'long': 'db-file',
+ 'default': '.doit.db',
+ 'type': str,
+ 'help': 'Database file',
+ 'section': 'Arguments passed to `nikola build`'
+ },
+ {
+ 'name': 'backend',
+ 'long': 'backend',
+ 'default': 'dbm',
+ 'type': str,
+ 'help': "Database backend ('dbm', 'json', 'sqlite3')",
+ 'section': 'Arguments passed to `nikola build`'
+ }
]
def _execute(self, options, args):
@@ -149,6 +168,8 @@ class CommandAuto(Command):
elif Observer is None:
req_missing(['watchdog'], 'use the "auto" command')
+ blinker.signal('auto_command_starting').send(self.site)
+
if sys.argv[0].endswith('__main__.py'):
self.nikola_cmd = [sys.executable, '-m', 'nikola', 'build']
else:
@@ -161,6 +182,10 @@ class CommandAuto(Command):
self.nikola_cmd += ['--process={}'.format(options['process']),
'--parallel-type={}'.format(options['parallel-type'])]
+ if options:
+ self.nikola_cmd += ['--db-file={}'.format(options['db-file']),
+ '--backend={}'.format(options['backend'])]
+
port = options and options.get('port')
self.snippet = '''<script>document.write('<script src="http://'
+ (location.host || 'localhost').split(':')[0]
diff --git a/nikola/plugins/command/import_wordpress.py b/nikola/plugins/command/import_wordpress.py
index 06e00a1..f513e1c 100644
--- a/nikola/plugins/command/import_wordpress.py
+++ b/nikola/plugins/command/import_wordpress.py
@@ -582,6 +582,11 @@ to
def add(our_key, wp_key, is_int=False, ignore_zero=False, is_float=False):
if wp_key in image_meta:
value = image_meta[wp_key]
+ if value in ("", b"") and (is_int or is_float):
+ if ignore_zero:
+ return
+ else:
+ dst_meta[our_key] = 0
if is_int:
value = int(value)
if ignore_zero and value == 0:
diff --git a/nikola/plugins/shortcode/post_list.py b/nikola/plugins/shortcode/post_list.py
index 0206cf0..2d8d170 100644
--- a/nikola/plugins/shortcode/post_list.py
+++ b/nikola/plugins/shortcode/post_list.py
@@ -219,7 +219,7 @@ class PostListShortcode(ShortcodePlugin):
posts += [post]
- template_deps = site.template_system.template_deps(template)
+ template_deps = site.template_system.template_deps(template, site.GLOBAL_CONTEXT)
if state:
# Register template as a dependency (Issue #2391)
for d in template_deps:
diff --git a/nikola/plugins/task/categories.py b/nikola/plugins/task/categories.py
index 3c0ea6b..b140101 100644
--- a/nikola/plugins/task/categories.py
+++ b/nikola/plugins/task/categories.py
@@ -186,6 +186,8 @@ link://category_rss/dogs => /categories/dogs.xml""",
"title": self.site.MESSAGES[lang]["Categories"],
"description": self.site.MESSAGES[lang]["Categories"],
"pagekind": ["list", "tags_page"],
+ "category_descriptions": self.site.config['CATEGORY_DESCRIPTIONS'](lang),
+ "category_titles": self.site.config['CATEGORY_TITLES'](lang),
}
kw.update(context)
return context, kw
@@ -209,8 +211,8 @@ link://category_rss/dogs => /categories/dogs.xml""",
subcats = [(child.name, self.site.link(self.classification_name, child.classification_name, lang)) for child in children]
friendly_name = self.get_classification_friendly_name(classification, lang)
context = {
- "title": self.site.config['CATEGORY_TITLES'].get(lang, {}).get(classification, self.site.MESSAGES[lang]["Posts about %s"] % friendly_name),
- "description": self.site.config['CATEGORY_DESCRIPTIONS'].get(lang, {}).get(classification),
+ "title": self.site.config['CATEGORY_TITLES'](lang).get(classification, self.site.MESSAGES[lang]["Posts about %s"] % friendly_name),
+ "description": self.site.config['CATEGORY_DESCRIPTIONS'](lang).get(classification),
"pagekind": ["tag_page", "index" if self.show_list_as_index else "list"],
"tag": friendly_name,
"category": classification,
diff --git a/nikola/plugins/task/galleries.py b/nikola/plugins/task/galleries.py
index 1c53cbd..c9b1915 100644
--- a/nikola/plugins/task/galleries.py
+++ b/nikola/plugins/task/galleries.py
@@ -307,10 +307,13 @@ class Galleries(Task, ImageProcessor):
context['post'] = post
else:
context['post'] = None
+
+ template_dep_context = context.copy()
+ template_dep_context.update(self.site.GLOBAL_CONTEXT)
file_dep = self.site.template_system.template_deps(
- template_name) + image_list + thumbs
+ template_name, template_dep_context) + image_list + thumbs
file_dep_dest = self.site.template_system.template_deps(
- template_name) + dest_img_list + thumbs
+ template_name, template_dep_context) + dest_img_list + thumbs
if post:
file_dep += [post.translated_base_path(l) for l in self.kw['translations']]
file_dep_dest += [post.translated_base_path(l) for l in self.kw['translations']]
diff --git a/nikola/plugins/task/listings.py b/nikola/plugins/task/listings.py
index 5f4fca9..d52ddb2 100644
--- a/nikola/plugins/task/listings.py
+++ b/nikola/plugins/task/listings.py
@@ -179,7 +179,7 @@ class Listings(Task):
yield self.group_task()
- template_deps = self.site.template_system.template_deps('listing.tmpl')
+ template_deps = self.site.template_system.template_deps('listing.tmpl', self.site.GLOBAL_CONTEXT)
for input_folder, output_folder in self.kw['listings_folders'].items():
for root, dirs, files in os.walk(input_folder, followlinks=True):
diff --git a/nikola/plugins/task/tags.py b/nikola/plugins/task/tags.py
index a1a6b77..cc2ced8 100644
--- a/nikola/plugins/task/tags.py
+++ b/nikola/plugins/task/tags.py
@@ -128,6 +128,8 @@ link://tag_rss/cats => /tags/cats.xml""",
"title": self.site.MESSAGES[lang]["Tags"],
"description": self.site.MESSAGES[lang]["Tags"],
"pagekind": ["list", "tags_page"],
+ "tag_descriptions": self.site.config['TAG_DESCRIPTIONS'](lang),
+ "tag_titles": self.site.config['TAG_TITLES'](lang),
}
kw.update(context)
return context, kw
@@ -143,8 +145,8 @@ link://tag_rss/cats => /tags/cats.xml""",
"tag_titles": self.site.config['TAG_TITLES'],
}
context = {
- "title": self.site.config['TAG_TITLES'].get(lang, {}).get(classification, self.site.MESSAGES[lang]["Posts about %s"] % classification),
- "description": self.site.config['TAG_DESCRIPTIONS'].get(lang, {}).get(classification),
+ "title": self.site.config['TAG_TITLES'](lang).get(classification, self.site.MESSAGES[lang]["Posts about %s"] % classification),
+ "description": self.site.config['TAG_DESCRIPTIONS'](lang).get(classification),
"pagekind": ["tag_page", "index" if self.show_list_as_index else "list"],
"tag": classification,
}
diff --git a/nikola/plugins/template/jinja.py b/nikola/plugins/template/jinja.py
index 845f4d5..aec6063 100644
--- a/nikola/plugins/template/jinja.py
+++ b/nikola/plugins/template/jinja.py
@@ -31,10 +31,11 @@ import json
import os
from nikola.plugin_categories import TemplateSystem
-from nikola.utils import makedirs, req_missing, sort_posts, _smartjoin_filter
+from nikola.utils import makedirs, req_missing, slugify, sort_posts, _smartjoin_filter
try:
import jinja2
+ import jinja2.nodes
from jinja2 import meta
except ImportError:
jinja2 = None
@@ -66,6 +67,7 @@ class JinjaTemplates(TemplateSystem):
self.lookup.filters['tojson'] = json.dumps
self.lookup.filters['sort_posts'] = sort_posts
self.lookup.filters['smartjoin'] = _smartjoin_filter
+ self.lookup.filters['slugify'] = slugify
self.lookup.globals['enumerate'] = enumerate
self.lookup.globals['isinstance'] = isinstance
self.lookup.globals['tuple'] = tuple
@@ -104,29 +106,35 @@ class JinjaTemplates(TemplateSystem):
"""Render template to a string using context."""
return self.lookup.from_string(template).render(**context)
- def get_string_deps(self, text):
+ def get_string_deps(self, text, context=None):
"""Find dependencies for a template string."""
deps = set([])
ast = self.lookup.parse(text)
- dep_names = [d for d in meta.find_referenced_templates(ast) if d]
+ simple_dep_names = [d for d in meta.find_referenced_templates(ast) if d]
+ formatted_dep_names = [
+ imp.template.left.value % (context[imp.template.right.name],)
+ for imp in ast.find_all(jinja2.nodes.Import)
+ if isinstance(imp.template, jinja2.nodes.Mod)
+ ]
+ dep_names = simple_dep_names + formatted_dep_names
for dep_name in dep_names:
filename = self.lookup.loader.get_source(self.lookup, dep_name)[1]
- sub_deps = [filename] + self.get_deps(filename)
+ sub_deps = [filename] + self.get_deps(filename, context)
self.dependency_cache[dep_name] = sub_deps
deps |= set(sub_deps)
return list(deps)
- def get_deps(self, filename):
+ def get_deps(self, filename, context=None):
"""Return paths to dependencies for the template loaded from filename."""
with io.open(filename, 'r', encoding='utf-8-sig') as fd:
text = fd.read()
- return self.get_string_deps(text)
+ return self.get_string_deps(text, context)
- def template_deps(self, template_name):
+ def template_deps(self, template_name, context=None):
"""Generate list of dependencies for a template."""
if self.dependency_cache.get(template_name) is None:
filename = self.lookup.loader.get_source(self.lookup, template_name)[1]
- self.dependency_cache[template_name] = [filename] + self.get_deps(filename)
+ self.dependency_cache[template_name] = [filename] + self.get_deps(filename, context)
return self.dependency_cache[template_name]
def get_template_path(self, template_name):
diff --git a/nikola/plugins/template/mako.py b/nikola/plugins/template/mako.py
index 8066b96..8197518 100644
--- a/nikola/plugins/template/mako.py
+++ b/nikola/plugins/template/mako.py
@@ -28,6 +28,7 @@
import io
import os
+import re
import shutil
from mako import exceptions, util, lexer, parsetree
@@ -52,7 +53,7 @@ class MakoTemplates(TemplateSystem):
directories = []
cache_dir = None
- def get_string_deps(self, text, filename=None):
+ def get_string_deps(self, text, context=None, *, filename=None):
"""Find dependencies for a template string."""
lex = lexer.Lexer(text=text, filename=filename, input_encoding='utf-8')
lex.parse()
@@ -61,7 +62,11 @@ class MakoTemplates(TemplateSystem):
for n in lex.template.nodes:
keyword = getattr(n, 'keyword', None)
if keyword in ["inherit", "namespace"] or isinstance(n, parsetree.IncludeTag):
- deps.append(n.attributes['file'])
+ filename = n.attributes["file"]
+ if '${' in filename:
+ # Support for comment helper inclusions
+ filename = re.sub(r'''\${context\[['"](.*?)['"]]}''', lambda m: context[m.group(1)], filename)
+ deps.append(filename)
# Some templates will include "foo.tmpl" and we need paths, so normalize them
# using the template lookup
for i, d in enumerate(deps):
@@ -73,10 +78,10 @@ class MakoTemplates(TemplateSystem):
d, filename)
return deps
- def get_deps(self, filename):
+ def get_deps(self, filename, context=None):
"""Get paths to dependencies for a template."""
text = util.read_file(filename)
- return self.get_string_deps(text, filename)
+ return self.get_string_deps(text, context, filename=filename)
def set_directories(self, directories, cache_folder):
"""Create a new template lookup with set directories."""
@@ -122,17 +127,17 @@ class MakoTemplates(TemplateSystem):
context.update(self.filters)
return Template(template, lookup=self.lookup).render(**context)
- def template_deps(self, template_name):
+ def template_deps(self, template_name, context=None):
"""Generate list of dependencies for a template."""
# We can cache here because dependencies should
# not change between runs
if self.cache.get(template_name, None) is None:
template = self.lookup.get_template(template_name)
- dep_filenames = self.get_deps(template.filename)
+ dep_filenames = self.get_deps(template.filename, context)
deps = [template.filename]
for fname in dep_filenames:
# yes, it uses forward slashes on Windows
- deps += self.template_deps(fname.split('/')[-1])
+ deps += self.template_deps(fname.split('/')[-1], context)
self.cache[template_name] = list(set(deps))
return self.cache[template_name]
diff --git a/nikola/post.py b/nikola/post.py
index 795f9d6..06de222 100644
--- a/nikola/post.py
+++ b/nikola/post.py
@@ -253,7 +253,7 @@ class Post(object):
self.post_name = os.path.splitext(source_path)[0] # posts/blah
_relpath = os.path.relpath(self.post_name)
if _relpath != self.post_name:
- self.post_name = _relpath.replace('..' + os.sep, '_..' + os.sep)
+ self.post_name = _relpath.replace('..' + os.sep, '__dotdot__' + os.sep)
# cache[\/]posts[\/]blah.html
self.base_path = os.path.join(self.config['CACHE_FOLDER'], self.post_name + ".html")
# cache/posts/blah.html
@@ -910,10 +910,7 @@ class Post(object):
if self.hyphenate:
hyphenate(document, real_lang)
- try:
- data = lxml.html.tostring(document.body, encoding='unicode')
- except Exception:
- data = lxml.html.tostring(document, encoding='unicode')
+ data = utils.html_tostring_fragment(document)
if teaser_only:
teaser_regexp = self.config.get('TEASER_REGEXP', TEASER_REGEXP)
@@ -936,10 +933,7 @@ class Post(object):
post_title=self.title(lang))
# This closes all open tags and sanitizes the broken HTML
document = lxml.html.fromstring(teaser)
- try:
- data = lxml.html.tostring(document.body, encoding='unicode')
- except IndexError:
- data = lxml.html.tostring(document, encoding='unicode')
+ data = utils.html_tostring_fragment(document)
if data and strip_html:
try:
@@ -952,11 +946,11 @@ class Post(object):
if self.demote_headers:
# see above
try:
- document = lxml.html.fromstring(data)
+ document = lxml.html.fragment_fromstring(data, "body")
demote_headers(document, self.demote_headers)
- data = lxml.html.tostring(document.body, encoding='unicode')
+ data = utils.html_tostring_fragment(document)
except (lxml.etree.ParserError, IndexError):
- data = lxml.html.tostring(document, encoding='unicode')
+ pass
return data
diff --git a/nikola/utils.py b/nikola/utils.py
index 54cd36f..363ab40 100644
--- a/nikola/utils.py
+++ b/nikola/utils.py
@@ -30,6 +30,7 @@ import configparser
import datetime
import hashlib
import io
+import lxml.html
import operator
import os
import re
@@ -656,6 +657,25 @@ def get_theme_chain(theme, themes_dirs):
return themes
+def html_tostring_fragment(document):
+ """Convert a HTML snippet to a fragment, ready for insertion elsewhere."""
+ try:
+ doc = lxml.html.tostring(document.body, encoding='unicode').strip()
+ except Exception:
+ doc = lxml.html.tostring(document, encoding='unicode').strip()
+ start_fragments = ["<html>", "<body>"]
+ end_fragments = ["</body>", "</html>"]
+ for start in start_fragments:
+ if doc.startswith(start):
+ doc = doc[len(start):].strip()
+ print(repr(doc))
+ for end in end_fragments:
+ if doc.endswith(end):
+ doc = doc[:-len(end)].strip()
+ print(repr(doc))
+ return doc
+
+
INCOMPLETE_LANGUAGES_WARNED = set()