python-frontmatter
python-frontmatter copied to clipboard
Feature request: preserve order of YAML front matter when writing content back to file
It looks like the frontmatter is alphabetically sorted when it is written back out. It would be great if it could preserve the order of existing items, while adding new items to the end.
I am using the following handler to preserve order:
import re
import frontmatter as fm
import oyaml
class OYAMLHandler(fm.default_handlers.BaseHandler):
"""
Load and export YAML metadata using oyaml [1].
[1]: https://github.com/wimglenn/oyaml
"""
FM_BOUNDARY = re.compile(r"^-{3,}\s*$", re.MULTILINE)
START_DELIMITER = END_DELIMITER = "---"
def load(self, fm: str, **kwargs: object) -> Any:
"""
Parse YAML front matter. This uses oyaml.SafeLoader by default.
"""
kwargs.setdefault("Loader", oyaml.SafeLoader)
return oyaml.load(fm, **kwargs) # type: ignore[arg-type]
def export(self, metadata: dict[str, object], **kwargs: object) -> str:
"""
Export metadata as YAML. This uses oyaml.SafeDumper by default.
"""
kwargs.setdefault("Dumper", oyaml.SafeDumper)
kwargs.setdefault("default_flow_style", False)
kwargs.setdefault("allow_unicode", True)
metadata_str = oyaml.dump(metadata, **kwargs).strip() # type: ignore[call-overload]
return fm.util.u(metadata_str) # ensure unicode
Example usage:
with open(filename) as f:
note = fm.load(f, handler=OYAMLHandler())
# ...
with open(filename, 'wb') as f:
fm.dump(note, f, handler=OYAMLHandler())
I came here searching for this same problem.
sort_keys=False worked for me.
The thread about it is here: https://github.com/eyeseast/python-frontmatter/issues/26#issuecomment-799024484