1
0
Fork 0
forked from github/pelican

Allow directories in EXTRA_PATH_METADATA

Metadata applied to a directory will apply to all files under
it. In case of conflicts, child paths beat parent paths, so metadata
applied to `dir/subdir/file.md` will take precedence over that applied
to `dir/subdir`, which will take precedence over just `dir`.
This commit is contained in:
Andrew Vant 2017-07-16 17:17:51 -04:00
commit ce9f3d55a3
3 changed files with 48 additions and 3 deletions

View file

@ -783,7 +783,8 @@ Metadata
Extra metadata dictionaries keyed by relative path. Relative paths require
correct OS-specific directory separators (i.e. / in UNIX and \\ in Windows)
unlike some other Pelican file settings.
unlike some other Pelican file settings. Paths to a directory apply to all
files under it. The most-specific path wins conflicts.
Not all metadata needs to be :ref:`embedded in source file itself
<internal_metadata>`. For example, blog posts are often named following a

View file

@ -698,8 +698,20 @@ def path_metadata(full_path, source_path, settings=None):
if settings.get('DEFAULT_DATE', None) == 'fs':
metadata['date'] = SafeDatetime.fromtimestamp(
os.stat(full_path).st_mtime)
metadata.update(settings.get('EXTRA_PATH_METADATA', {}).get(
source_path, {}))
# Apply EXTRA_PATH_METADATA for the source path and the paths of any
# parent directories. Sorting EPM first ensures that the most specific
# path wins conflicts.
epm = settings.get('EXTRA_PATH_METADATA', {})
for path, meta in sorted(epm.items()):
# Enforce a trailing slash when checking for parent directories.
# This prevents false positives when one file or directory's name
# is a prefix of another's.
dirpath = os.path.join(path, '')
if source_path == path or source_path.startswith(dirpath):
metadata.update(meta)
return metadata

View file

@ -273,6 +273,38 @@ class RstReaderTest(ReaderTest):
}
self.assertDictHasSubset(page.metadata, expected)
def test_article_extra_path_metadata_recurse(self):
parent = "TestCategory"
notparent = "TestCategory/article"
path = "TestCategory/article_without_category.rst"
epm = {
parent: {'epmr_inherit': parent,
'epmr_override': parent, },
notparent: {'epmr_bogus': notparent},
path: {'epmr_override': path, },
}
expected_metadata = {
'epmr_inherit': parent,
'epmr_override': path,
}
page = self.read_file(path=path, EXTRA_PATH_METADATA=epm)
self.assertDictHasSubset(page.metadata, expected_metadata)
# Make sure vars aren't getting "inherited" by mistake...
path = "article.rst"
page = self.read_file(path=path, EXTRA_PATH_METADATA=epm)
for k in expected_metadata.keys():
self.assertNotIn(k, page.metadata)
# Same, but for edge cases where one file's name is a prefix of
# another.
path = "TestCategory/article_without_category.rst"
page = self.read_file(path=path, EXTRA_PATH_METADATA=epm)
for k in epm[notparent].keys():
self.assertNotIn(k, page.metadata)
def test_typogrify(self):
# if nothing is specified in the settings, the content should be
# unmodified