add better metadata handling
This commit is contained in:
parent
71982435f3
commit
73215df2e8
3 changed files with 75 additions and 10 deletions
|
@ -3,18 +3,38 @@ from zona import markdown as zmd
|
|||
from zona import util
|
||||
from pathlib import Path
|
||||
import frontmatter
|
||||
from dacite import from_dict
|
||||
from dacite import Config, from_dict, DaciteError
|
||||
from datetime import date
|
||||
from yaml import YAMLError
|
||||
|
||||
|
||||
def split_metadata(path: Path) -> tuple[Metadata, str]:
|
||||
post = frontmatter.load(str(path))
|
||||
# TODO: handle missing metadata
|
||||
meta = post.metadata
|
||||
# TODO: handle malformed metadata
|
||||
metadata = from_dict(
|
||||
data_class=Metadata,
|
||||
data=meta,
|
||||
)
|
||||
"""
|
||||
Parses a file and returns parsed Metadata and its content. Defaults
|
||||
are applied for missing fields. If there is no metadata, a Metadata
|
||||
with default values is returned.
|
||||
|
||||
Raises:
|
||||
ValueError: If the metadata block is malformed in any way.
|
||||
"""
|
||||
try:
|
||||
post = frontmatter.load(str(path))
|
||||
except YAMLError as e:
|
||||
raise ValueError(f"YAML frontmatter error in {path}: {e}")
|
||||
raw_meta = post.metadata or {}
|
||||
defaults = {
|
||||
"title": util.filename_to_title(path),
|
||||
"date": date.fromtimestamp(path.stat().st_mtime),
|
||||
}
|
||||
meta = {**defaults, **raw_meta}
|
||||
try:
|
||||
metadata = from_dict(
|
||||
data_class=Metadata,
|
||||
data=meta,
|
||||
config=Config(check_types=True, strict=True),
|
||||
)
|
||||
except DaciteError as e:
|
||||
raise ValueError(f"Malformed metadata in {path}: {e}")
|
||||
return metadata, post.content
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from typing import Literal
|
|||
class Metadata:
|
||||
title: str
|
||||
date: date
|
||||
description: str
|
||||
description: str | None
|
||||
# add more options later...
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import pytest
|
||||
from datetime import date
|
||||
from zona.models import Metadata
|
||||
from zona.builder import split_metadata, discover, build
|
||||
|
@ -24,6 +25,50 @@ description: This is a test.
|
|||
assert content == "# Hello World"
|
||||
|
||||
|
||||
def test_no_metadata(tmp_path: Path):
|
||||
content = "# Hello World"
|
||||
test_file = tmp_path / "hello-world.md"
|
||||
test_file.write_text(content)
|
||||
meta, content = split_metadata(test_file)
|
||||
|
||||
assert isinstance(meta, Metadata)
|
||||
assert meta.title == "Hello World"
|
||||
assert meta.description is None
|
||||
assert meta.date == date.today()
|
||||
assert content == "# Hello World"
|
||||
|
||||
|
||||
def test_malformed_metadata(tmp_path: Path):
|
||||
with pytest.raises(ValueError):
|
||||
tests = {
|
||||
"""
|
||||
---
|
||||
title: Test Post
|
||||
date: not a date!!!
|
||||
description: This is a test.
|
||||
---
|
||||
""",
|
||||
"""
|
||||
---
|
||||
title: Test Post
|
||||
foobar:
|
||||
something: what???
|
||||
description: This is a test.
|
||||
---
|
||||
""",
|
||||
"""
|
||||
---
|
||||
title Test Post
|
||||
description: This is a test.
|
||||
---
|
||||
""",
|
||||
}
|
||||
for i, content in enumerate(tests):
|
||||
test_file = tmp_path / str(i)
|
||||
test_file.write_text(content)
|
||||
split_metadata(test_file)
|
||||
|
||||
|
||||
def test_discover(tmp_path: Path):
|
||||
contentd = tmp_path / "content"
|
||||
staticd = contentd / "static"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue