From cecb0b65ae6a0db31fd8a2cc7e83f3d72198e532 Mon Sep 17 00:00:00 2001 From: Patrick Fournier Date: Mon, 17 Nov 2025 21:07:33 -0500 Subject: [PATCH 1/3] Improve SEO content rewriting - Preserve whitespace from original file. - Add line break after each added tag. --- pelican/plugins/seo/seo_enhancer/__init__.py | 27 +++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/pelican/plugins/seo/seo_enhancer/__init__.py b/pelican/plugins/seo/seo_enhancer/__init__.py index 87e3c28..3d6edde 100644 --- a/pelican/plugins/seo/seo_enhancer/__init__.py +++ b/pelican/plugins/seo/seo_enhancer/__init__.py @@ -4,7 +4,7 @@ import logging import os -from bs4 import BeautifulSoup +from bs4 import BeautifulSoup, NavigableString from .html_enhancer import HTMLEnhancer from .robots_file_creator import RobotsFileCreator @@ -83,17 +83,27 @@ def generate_robots(self, rules, output_path, sitemap_url=None): logger.info("SEO plugin - SEO Enhancement: robots.txt file created") + @staticmethod + def _add_meta_tag(soup, attr_name, prefix, name, content): + tag = soup.new_tag( + name="meta", + attrs={attr_name: prefix + ":" + name, "content": content}, + ) + soup.head.append(tag) + soup.head.append(NavigableString("\n")) + def add_html_to_file(self, enhancements, path): """Open HTML file, add enhancements with bs4 and create the new HTML files.""" with open(path, encoding="utf8") as html_file: html_content = html_file.read() - soup = BeautifulSoup(html_content, features="html.parser") + soup = BeautifulSoup(html_content, features="html.parser", preserve_whitespace_tags={"html"}) canonical_tag = soup.new_tag( "link", rel="canonical", href=enhancements.get("canonical_tag") ) soup.head.append(canonical_tag) + soup.head.append(NavigableString("\n")) schemas = [e for e in enhancements if e.endswith("_schema")] for schema in schemas: @@ -102,23 +112,16 @@ def add_html_to_file(self, enhancements, path): # Google valids schema only with double quotes schema_script.append(json.dumps(enhancements[schema], ensure_ascii=False)) soup.head.append(schema_script) + soup.head.append(NavigableString("\n")) # Let's add first Twitter Cards tags in the HTML if feature is enabled if "twitter_cards" in enhancements: for tw_property, tw_content in enhancements["twitter_cards"].items(): - twitter_cards_tag = soup.new_tag( - name="meta", - attrs={"name": "twitter:" + tw_property, "content": tw_content}, - ) - soup.head.append(twitter_cards_tag) + self._add_meta_tag(soup, "name", "twitter", tw_property, tw_content) if "open_graph" in enhancements: for og_property, og_content in enhancements["open_graph"].items(): - open_graph_tag = soup.new_tag( - name="meta", - attrs={"property": "og:" + og_property, "content": og_content}, - ) - soup.head.append(open_graph_tag) + self._add_meta_tag(soup, "property", "og", og_property, og_content) with open(path, "w", encoding="utf8") as html_file: html_file.write(str(soup)) From 36f78eca8a2f87171df35ca8b93c6ab703576f83 Mon Sep 17 00:00:00 2001 From: Patrick Fournier Date: Mon, 17 Nov 2025 21:33:17 -0500 Subject: [PATCH 2/3] Update tests --- .../plugins/seo/tests/test_seo_enhancer.py | 124 ++++++++---------- 1 file changed, 56 insertions(+), 68 deletions(-) diff --git a/pelican/plugins/seo/tests/test_seo_enhancer.py b/pelican/plugins/seo/tests/test_seo_enhancer.py index 21f8dda..c05af56 100644 --- a/pelican/plugins/seo/tests/test_seo_enhancer.py +++ b/pelican/plugins/seo/tests/test_seo_enhancer.py @@ -117,25 +117,21 @@ def test_add_html_enhancements_to_file(self, fake_article, fake_seo_enhancer): assert ( fake_html_content == """ - -Fake Title - -\ -\ -\ + + Fake Title + + + + - -

Fake content title

-

Fake content 🙃

-Fake internal link -

Fake content with inline code

-

Fake content with "Fake inline internal link"

- -""" + +

Fake content title

+

Fake content 🙃

+ Fake internal link +

Fake content with inline code

+

Fake content with "Fake inline internal link"

+ + """ ) @pytest.mark.parametrize( @@ -231,31 +227,27 @@ def test_add_html_enhancements_to_file_with_open_graph( assert ( fake_html_content == """ - -Fake Title - -\ -\ -\ -\ -\ -\ -\ -\ -\ + + Fake Title + + + + + + + + + + - -

Fake content title

-

Fake content 🙃

-Fake internal link -

Fake content with inline code

-

Fake content with "Fake inline internal link"

- -""" + +

Fake content title

+

Fake content 🙃

+ Fake internal link +

Fake content with inline code

+

Fake content with "Fake inline internal link"

+ + """ ) def test_add_html_enhancements_to_file_with_twitter_cards( @@ -295,31 +287,27 @@ def test_add_html_enhancements_to_file_with_twitter_cards( assert ( fake_html_content == """ - -Fake Title - -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ + + Fake Title + + + + + + + + + + + + - -

Fake content title

-

Fake content 🙃

-Fake internal link -

Fake content with inline code

-

Fake content with "Fake inline internal link"

- -""" + +

Fake content title

+

Fake content 🙃

+ Fake internal link +

Fake content with inline code

+

Fake content with "Fake inline internal link"

+ + """ ) From 9e3ccdda5ac7bf571f60c7df172246c7ddbad70a Mon Sep 17 00:00:00 2001 From: Patrick Fournier Date: Mon, 17 Nov 2025 21:36:37 -0500 Subject: [PATCH 3/3] Run format tool --- pelican/plugins/seo/seo_enhancer/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pelican/plugins/seo/seo_enhancer/__init__.py b/pelican/plugins/seo/seo_enhancer/__init__.py index 3d6edde..8f9baba 100644 --- a/pelican/plugins/seo/seo_enhancer/__init__.py +++ b/pelican/plugins/seo/seo_enhancer/__init__.py @@ -97,7 +97,9 @@ def add_html_to_file(self, enhancements, path): with open(path, encoding="utf8") as html_file: html_content = html_file.read() - soup = BeautifulSoup(html_content, features="html.parser", preserve_whitespace_tags={"html"}) + soup = BeautifulSoup( + html_content, features="html.parser", preserve_whitespace_tags={"html"} + ) canonical_tag = soup.new_tag( "link", rel="canonical", href=enhancements.get("canonical_tag")