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 zona import util
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import frontmatter
|
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]:
|
def split_metadata(path: Path) -> tuple[Metadata, str]:
|
||||||
|
"""
|
||||||
|
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))
|
post = frontmatter.load(str(path))
|
||||||
# TODO: handle missing metadata
|
except YAMLError as e:
|
||||||
meta = post.metadata
|
raise ValueError(f"YAML frontmatter error in {path}: {e}")
|
||||||
# TODO: handle malformed metadata
|
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(
|
metadata = from_dict(
|
||||||
data_class=Metadata,
|
data_class=Metadata,
|
||||||
data=meta,
|
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
|
return metadata, post.content
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from typing import Literal
|
||||||
class Metadata:
|
class Metadata:
|
||||||
title: str
|
title: str
|
||||||
date: date
|
date: date
|
||||||
description: str
|
description: str | None
|
||||||
# add more options later...
|
# add more options later...
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pytest
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from zona.models import Metadata
|
from zona.models import Metadata
|
||||||
from zona.builder import split_metadata, discover, build
|
from zona.builder import split_metadata, discover, build
|
||||||
|
@ -24,6 +25,50 @@ description: This is a test.
|
||||||
assert content == "# Hello World"
|
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):
|
def test_discover(tmp_path: Path):
|
||||||
contentd = tmp_path / "content"
|
contentd = tmp_path / "content"
|
||||||
staticd = contentd / "static"
|
staticd = contentd / "static"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue