Skip to content
Merged
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ Image: https://www.example.com/article-image.jpg

Based on [Open Graph protocol](https://ogp.me), the SEO plugin implements required properties and some aditionnals ones:

```
<meta property="og:site_name" content=":sitename:" />
```
`:sitename:`: The `SITENAME` from the Pelican settings.

```
<meta property="og:url" content=":fileurl:" />
```
Expand All @@ -293,6 +298,7 @@ og_image: https://www.example.com/og-image.jpg
```

If these metadata are not declared, `:title:`, `:description:`, `:image:` will be filled by the default `Title`, `Description` (Pelican metadata) and `Image` (plugin metadata) if they exist.
If `Description` is not defined, a plain text version of `Summary` will be used instead.

```
<meta property="og:locale" content=":language:">
Expand Down
17 changes: 16 additions & 1 deletion pelican/plugins/seo/seo_enhancer/html_enhancer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""HTML Enhancer : get instances of HTML enhancements."""

from bs4 import BeautifulSoup

from pelican.contents import Article, Page

from .article_schema_creator import ArticleSchemaCreator
Expand All @@ -9,6 +11,17 @@
from .twitter_cards import TwitterCards


def _get_plain_text_summary(metadata):
"""Get content from summary, without HTML tags."""

soup = BeautifulSoup(
metadata.get("summary", ""),
"html.parser",
)
text_summary = soup.get_text().strip()
return text_summary


class HTMLEnhancer:
"""HTML Enhancer : get instances of HTML enhancements."""

Expand Down Expand Up @@ -63,12 +76,14 @@ def __init__(self, file, output_path, path, open_graph=False, twitter_cards=Fals

if open_graph:
self.open_graph = OpenGraph(
sitename=_settings.get("SITENAME"),
siteurl=_settings.get("SITEURL"),
fileurl=_fileurl,
file_type=_file_type,
title=_metadata.get("og_title") or _title,
description=_metadata.get("og_description")
or _metadata.get("description"),
or _metadata.get("description")
or _get_plain_text_summary(_metadata),
image=_metadata.get("og_image") or _image,
locale=_settings.get("LOCALE"),
)
Expand Down
6 changes: 5 additions & 1 deletion pelican/plugins/seo/seo_enhancer/html_enhancer/open_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ class OpenGraph:
"""

def __init__(
self, siteurl, fileurl, file_type, title, description, image, locale
self, sitename, siteurl, fileurl, file_type, title, description, image, locale
) -> None:
self.sitename = sitename
self.siteurl = siteurl
self.fileurl = fileurl
self.type = file_type
Expand Down Expand Up @@ -57,6 +58,9 @@ def create_tags(self) -> dict:
"""
open_graph_tags = {}

if self.sitename:
open_graph_tags["site_name"] = self.sitename

open_graph_tags["url"] = self._create_absolute_fileurl()
open_graph_tags["type"] = self.type

Expand Down
4 changes: 3 additions & 1 deletion pelican/plugins/seo/seo_report/seo_analyzer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ class SEOAnalyzer:

def __init__(self, article):
self._title = getattr(article, "title", None)
self._description = getattr(article, "description", None)
self._description = getattr(article, "description", None) or getattr(
article, "summary", None
)
self._content = getattr(article, "content", None)
self._settings = getattr(article, "settings", None)

Expand Down
1 change: 1 addition & 0 deletions pelican/plugins/seo/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def fake_article():
"og_description": "OG Description",
"og_image": "https://www.fakesite.com/og-image.jpg",
"tw_account": "@TestTWCards",
"summary": "Fake summary",
}
title = "Fake Title"
description = "Fake description"
Expand Down
7 changes: 7 additions & 0 deletions pelican/plugins/seo/tests/test_open_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def test_create_absolute_fileurl(self, fake_article):
"""

og = OpenGraph(
sitename=None,
siteurl=fake_article.settings["SITEURL"],
fileurl=fake_article.url,
file_type=None,
Expand All @@ -39,6 +40,7 @@ def test_create_absolute_fileurl_with_site_url_with_path(self, site_url, file_ur
slash and a file URL with or without a leading slash properly.
"""
og = OpenGraph(
sitename=None,
siteurl=site_url,
fileurl=file_url,
file_type=None,
Expand Down Expand Up @@ -67,6 +69,7 @@ def test_get_locale(self, locale, expected_result):
"""

og = OpenGraph(
sitename=None,
siteurl=None,
fileurl=None,
file_type=None,
Expand All @@ -86,6 +89,7 @@ def test_create_tags(self, fake_article):
"""

og = OpenGraph(
sitename=fake_article.settings["SITENAME"],
siteurl=fake_article.settings["SITEURL"],
fileurl=fake_article.url,
file_type="article",
Expand All @@ -97,6 +101,7 @@ def test_create_tags(self, fake_article):

og_tags = og.create_tags()

assert og_tags["site_name"] == "Fake Site Name"
assert og_tags["url"] == "https://www.fakesite.com/fake-title.html"
assert og_tags["type"] == "article"
assert og_tags["title"] == "OG Title"
Expand All @@ -111,6 +116,7 @@ def test_create_tags_missing_elements(self, fake_article_missing_elements):
"""

og = OpenGraph(
sitename=fake_article_missing_elements.settings["SITENAME"],
siteurl=fake_article_missing_elements.settings["SITEURL"],
fileurl=fake_article_missing_elements.url,
file_type="article",
Expand All @@ -122,6 +128,7 @@ def test_create_tags_missing_elements(self, fake_article_missing_elements):

og_tags = og.create_tags()

assert "site_name" not in og_tags
assert "title" not in og_tags
assert "description" not in og_tags
assert "image" not in og_tags
66 changes: 66 additions & 0 deletions pelican/plugins/seo/tests/test_seo_enhancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,77 @@ def test_add_html_enhancements_to_file_with_open_graph(
<link href="https://www.fakesite.com/fake-title.html" rel="canonical"/>
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Fake Site Name", "item": "https://www.fakesite.com"}, {"@type": "ListItem", "position": 2, "name": "Fake_file", "item": "https://www.fakesite.com/fake_file.html"}]}</script>
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "Article", "author": {"@type": "Person", "name": "Fake author"}, "publisher": {"@type": "Organization", "name": "Fake Site Name", "logo": {"@type": "ImageObject", "url": "https://www.fakesite.com/fake-logo.jpg"}}, "headline": "Fake Title", "about": "Fake category", "datePublished": "2019-04-03 23:49"}</script>
<meta content="Fake Site Name" property="og:site_name"/>
<meta content="https://www.fakesite.com/fake-title.html" property="og:url"/>
<meta content="website" property="og:type"/>
<meta content="OG Title" property="og:title"/>
<meta content="OG Description" property="og:description"/>
<meta content="https://www.fakesite.com/og-image.jpg" property="og:image"/>
<meta content="fr_FR" property="og:locale"/>
</head>
<body>
<h1>Fake content title</h1>
<p>Fake content 🙃</p>
<a href="https://www.fakesite.com">Fake internal link</a>
<p>Fake content with <code>inline code</code></p>
<p>Fake content with "<a href="https://www.fakesite.com">Fake inline internal link</a>"</p>
</body>
</html>"""
)

def test_add_html_enhancements_to_file_with_open_graph_using_summary_for_description(
self, fake_article, fake_seo_enhancer
):
"""
Test if add_html_to_file with open_graph setting
adds Open Graph tags to HTML files.
"""

# Remove higher priority values for the og:description tag to force the use of
# the summary from article description.
del fake_article.metadata["og_description"]
del fake_article.description

path = "fake_output/fake_file.html"
fake_html_enhancements = fake_seo_enhancer.launch_html_enhancer(
file=fake_article,
output_path="fake_output",
path=path,
open_graph=True,
)

with patch(
"seo.seo_enhancer.open", mock_open(read_data=fake_article.content)
) as mocked_open:
mocked_file_handle = mocked_open.return_value

fake_seo_enhancer.add_html_to_file(
enhancements=fake_html_enhancements, path=path
)
assert len(mocked_open.call_args_list) == 2
mocked_file_handle.read.assert_called_once()
mocked_file_handle.write.assert_called_once()

write_args, _ = mocked_file_handle.write.call_args_list[0]
fake_html_content = write_args[0]

# The og:description tag should now contain "Fake summary".
assert (
fake_html_content
== """<html>
<head>
<title>Fake Title</title>
<meta content="Fake description" name="description"/>
<link href="https://www.fakesite.com/fake-title.html" rel="canonical"/>
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Fake Site Name", "item": "https://www.fakesite.com"}, {"@type": "ListItem", "position": 2, "name": "Fake_file", "item": "https://www.fakesite.com/fake_file.html"}]}</script>
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "Article", "author": {"@type": "Person", "name": "Fake author"}, "publisher": {"@type": "Organization", "name": "Fake Site Name", "logo": {"@type": "ImageObject", "url": "https://www.fakesite.com/fake-logo.jpg"}}, "headline": "Fake Title", "about": "Fake category", "datePublished": "2019-04-03 23:49"}</script>
<meta content="Fake Site Name" property="og:site_name"/>
<meta content="https://www.fakesite.com/fake-title.html" property="og:url"/>
<meta content="website" property="og:type"/>
<meta content="OG Title" property="og:title"/>
<meta content="Fake summary" property="og:description"/>
<meta content="https://www.fakesite.com/og-image.jpg" property="og:image"/>
<meta content="fr_FR" property="og:locale"/>
</head>
<body>
<h1>Fake content title</h1>
Expand Down Expand Up @@ -295,6 +360,7 @@ def test_add_html_enhancements_to_file_with_twitter_cards(
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "Article", "author": {"@type": "Person", "name": "Fake author"}, "publisher": {"@type": "Organization", "name": "Fake Site Name", "logo": {"@type": "ImageObject", "url": "https://www.fakesite.com/fake-logo.jpg"}}, "headline": "Fake Title", "about": "Fake category", "datePublished": "2019-04-03 23:49"}</script>
<meta content="summary" name="twitter:card"/>
<meta content="@TestTWCards" name="twitter:site"/>
<meta content="Fake Site Name" property="og:site_name"/>
<meta content="https://www.fakesite.com/fake-title.html" property="og:url"/>
<meta content="website" property="og:type"/>
<meta content="OG Title" property="og:title"/>
Expand Down