Skip to content

Commit

Permalink
Merge pull request #3504 from getnikola/fix-3503-pretty-url-yaml-toml
Browse files Browse the repository at this point in the history
Fix #3503 — fix per-post pretty_url with YAML/TOML booleans
  • Loading branch information
Kwpolska committed Jan 19, 2021
2 parents f93ed6c + 26645b3 commit 52ae5fb
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Features
* Add ``BasePlugin.register_auto_watched_folder()``
* Allow different ``PANDOC_OPTIONS`` values based on input extensions
by specifying a dict of ``{".extension": [options]}`` (Issue #3492)
* Allow boolean/integer ``pretty_url`` post meta values in YAML/TOML
(Issue #3503)

Bugfixes
--------
Expand Down
18 changes: 10 additions & 8 deletions nikola/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
to_datetime,
demote_headers,
get_translation_candidate,
map_metadata
map_metadata,
bool_from_meta,
)

try:
Expand Down Expand Up @@ -427,13 +428,14 @@ def __repr__(self):

def has_pretty_url(self, lang):
"""Check if this page has a pretty URL."""
m = self.meta[lang].get('pretty_url', '')
if m:
# match is a non-empty string, overides anything
return m.lower() == 'true' or m.lower() == 'yes'
else:
meta_value = bool_from_meta(self.meta[lang], 'pretty_url')

if meta_value is None:
# use PRETTY_URLS, unless the slug is 'index'
return self.pretty_urls and self.meta[lang]['slug'] != 'index'
else:
# override with meta value
return meta_value

def _has_pretty_url(self, lang):
"""Check if this page has a pretty URL."""
Expand All @@ -450,13 +452,13 @@ def has_math(self):
return True
lang = nikola.utils.LocaleBorg().current_lang
if self.is_translation_available(lang):
if self.meta[lang].get('has_math') in ('true', 'True', 'yes', '1', 1, True):
if bool_from_meta(self.meta[lang], 'has_math'):
return True
if self.config['USE_TAG_METADATA']:
return 'mathjax' in self.tags_for_language(lang)
# If it has math in ANY other language, enable it. Better inefficient than broken.
for lang in self.translated_to:
if self.meta[lang].get('has_math') in ('true', 'True', 'yes', '1', 1, True):
if bool_from_meta(self.meta[lang], 'has_math'):
return True
if self.config['USE_TAG_METADATA']:
return 'mathjax' in self.alltags
Expand Down
20 changes: 19 additions & 1 deletion nikola/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
'adjust_name_for_index_path', 'adjust_name_for_index_link',
'NikolaPygmentsHTML', 'create_redirect', 'clean_before_deployment',
'sort_posts', 'smartjoin', 'indent', 'load_data', 'html_unescape',
'rss_writer', 'map_metadata', 'req_missing',
'rss_writer', 'map_metadata', 'req_missing', 'bool_from_meta',
# Deprecated, moved to hierarchy_utils:
'TreeNode', 'clone_treenode', 'flatten_tree_structure',
'sort_classifications', 'join_hierarchical_category_path',
Expand Down Expand Up @@ -1497,6 +1497,24 @@ def write_metadata(data, metadata_format=None, comment_wrap=False, site=None, co
return DEFAULT_EXTRACTOR.write_metadata(data, comment_wrap)


def bool_from_meta(meta, key, fallback=False, blank=None):
"""Convert a boolean-ish meta value to a boolean."""
value = meta.get(key)
if isinstance(value, str):
value_lowercase = value.lower().strip()
if value_lowercase in {"true", "yes", "1"}:
return True
elif value_lowercase in {"false", "no", "0"}:
return False
elif not value_lowercase:
return blank
elif isinstance(value, int):
return bool(value)
elif value is None:
return blank
return fallback


def ask(query, default=None):
"""Ask a question."""
if default:
Expand Down
30 changes: 30 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
get_theme_chain,
get_translation_candidate,
write_metadata,
bool_from_meta,
)


Expand Down Expand Up @@ -573,6 +574,35 @@ def test_write_metadata_fallbacks(post, arg):
assert write_metadata(data, arg) == ".. title: xx\n\n"


@pytest.mark.parametrize("value, expected", [
("true", True),
("True", True),
("TRUE", True),
("yes", True),
("Yes", True),
("YES", True),
("false", False),
("False", False),
("FALSE", False),
("no", False),
("No", False),
("NO", False),
("1", True),
(1, True),
("0", False),
(0, False),
("0", False),
(True, True),
(False, False),
("unknown", "F"),
(None, "B"),
("", "B"),
])
def test_bool_from_meta(value, expected):
meta = {"key": value}
assert bool_from_meta(meta, "key", "F", "B") == expected


@pytest.fixture
def post():
return FakePost()
Expand Down

0 comments on commit 52ae5fb

Please sign in to comment.