Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BlogPlugin: handling of generated blog posts #7583

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 38 additions & 33 deletions material/plugins/blog/structure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,40 +52,45 @@ class Post(Page):
def __init__(self, file: File, config: MkDocsConfig):
super().__init__(None, file, config)

# Resolve path relative to docs directory
docs = os.path.relpath(config.docs_dir)
path = os.path.relpath(file.abs_src_path, docs)
if file.generated_by is None:
# Resolve path relative to docs directory
docs = os.path.relpath(config.docs_dir)
path = os.path.relpath(file.abs_src_path, docs)
file_origin = f" in '{docs}'"
else:
# Path for generated posts
path = file.src_path
file_origin = f" generated by '{file.generated_by}'"

# Read contents and metadata immediately
with open(file.abs_src_path, encoding = "utf-8-sig") as f:
self.markdown = f.read()

# Sadly, MkDocs swallows any exceptions that occur during parsing.
# Since we want to provide the best possible user experience, we
# need to catch errors early and display them nicely. We decided to
# drop support for MkDocs' MultiMarkdown syntax, because it is not
# correctly implemented anyway. When using MultiMarkdown syntax, all
# date formats are returned as strings and list are not properly
# supported. Thus, we just use the relevants parts of `get_data`.
match: Match = YAML_RE.match(self.markdown)
if not match:
raise PluginError(
f"Error reading metadata of post '{path}' in '{docs}':\n"
f"Expected metadata to be defined but found nothing"
)

# Extract metadata and parse as YAML
try:
self.meta = yaml.load(match.group(1), SafeLoader) or {}
self.markdown = self.markdown[match.end():].lstrip("\n")

# The post's metadata could not be parsed because of a syntax error,
# which we display to the author with a nice error message
except Exception as e:
raise PluginError(
f"Error reading metadata of post '{path}' in '{docs}':\n"
f"{e}"
)
self.markdown = file.content_string

# Sadly, MkDocs swallows any exceptions that occur during parsing.
# Since we want to provide the best possible user experience, we
# need to catch errors early and display them nicely. We decided to
# drop support for MkDocs' MultiMarkdown syntax, because it is not
# correctly implemented anyway. When using MultiMarkdown syntax, all
# date formats are returned as strings and list are not properly
# supported. Thus, we just use the relevants parts of `get_data`.
match: Match = YAML_RE.match(self.markdown)
if not match:
raise PluginError(
f"Error reading metadata of post '{path}' {file_origin}:\n"
f"Expected metadata to be defined but found nothing"
)

# Extract metadata and parse as YAML
try:
self.meta = yaml.load(match.group(1), SafeLoader) or {}
self.markdown = self.markdown[match.end():].lstrip("\n")

# The post's metadata could not be parsed because of a syntax error,
# which we display to the author with a nice error message
except Exception as e:
raise PluginError(
f"Error reading metadata of post '{path}' {file_origin}:\n"
f"{e}"
)

# Initialize post configuration, but remove all keys that this plugin
# doesn't care about, or they will be reported as invalid configuration
Expand All @@ -103,7 +108,7 @@ def __init__(self, file: File, config: MkDocsConfig):
log.warning(w)
for k, e in errors:
raise PluginError(
f"Error reading metadata '{k}' of post '{path}' in '{docs}':\n"
f"Error reading metadata '{k}' of post '{path}' {file_origin}:\n"
f"{e}"
)

Expand Down
71 changes: 38 additions & 33 deletions src/plugins/blog/structure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,40 +52,45 @@ class Post(Page):
def __init__(self, file: File, config: MkDocsConfig):
super().__init__(None, file, config)

# Resolve path relative to docs directory
docs = os.path.relpath(config.docs_dir)
path = os.path.relpath(file.abs_src_path, docs)
if file.generated_by is None:
# Resolve path relative to docs directory
docs = os.path.relpath(config.docs_dir)
path = os.path.relpath(file.abs_src_path, docs)
file_origin = f" in '{docs}'"
else:
# Path for generated posts
path = file.src_path
file_origin = f" generated by '{file.generated_by}'"

# Read contents and metadata immediately
with open(file.abs_src_path, encoding = "utf-8-sig") as f:
self.markdown = f.read()

# Sadly, MkDocs swallows any exceptions that occur during parsing.
# Since we want to provide the best possible user experience, we
# need to catch errors early and display them nicely. We decided to
# drop support for MkDocs' MultiMarkdown syntax, because it is not
# correctly implemented anyway. When using MultiMarkdown syntax, all
# date formats are returned as strings and list are not properly
# supported. Thus, we just use the relevants parts of `get_data`.
match: Match = YAML_RE.match(self.markdown)
if not match:
raise PluginError(
f"Error reading metadata of post '{path}' in '{docs}':\n"
f"Expected metadata to be defined but found nothing"
)

# Extract metadata and parse as YAML
try:
self.meta = yaml.load(match.group(1), SafeLoader) or {}
self.markdown = self.markdown[match.end():].lstrip("\n")

# The post's metadata could not be parsed because of a syntax error,
# which we display to the author with a nice error message
except Exception as e:
raise PluginError(
f"Error reading metadata of post '{path}' in '{docs}':\n"
f"{e}"
)
self.markdown = file.content_string

# Sadly, MkDocs swallows any exceptions that occur during parsing.
# Since we want to provide the best possible user experience, we
# need to catch errors early and display them nicely. We decided to
# drop support for MkDocs' MultiMarkdown syntax, because it is not
# correctly implemented anyway. When using MultiMarkdown syntax, all
# date formats are returned as strings and list are not properly
# supported. Thus, we just use the relevants parts of `get_data`.
match: Match = YAML_RE.match(self.markdown)
if not match:
raise PluginError(
f"Error reading metadata of post '{path}' {file_origin}:\n"
f"Expected metadata to be defined but found nothing"
)

# Extract metadata and parse as YAML
try:
self.meta = yaml.load(match.group(1), SafeLoader) or {}
self.markdown = self.markdown[match.end():].lstrip("\n")

# The post's metadata could not be parsed because of a syntax error,
# which we display to the author with a nice error message
except Exception as e:
raise PluginError(
f"Error reading metadata of post '{path}' {file_origin}:\n"
f"{e}"
)

# Initialize post configuration, but remove all keys that this plugin
# doesn't care about, or they will be reported as invalid configuration
Expand All @@ -103,7 +108,7 @@ def __init__(self, file: File, config: MkDocsConfig):
log.warning(w)
for k, e in errors:
raise PluginError(
f"Error reading metadata '{k}' of post '{path}' in '{docs}':\n"
f"Error reading metadata '{k}' of post '{path}' {file_origin}:\n"
f"{e}"
)

Expand Down