Skip to content

Commit

Permalink
feat: Add options for checking the length of meta descriptions (#182)
Browse files Browse the repository at this point in the history
* doc: Add options for checking the length of meta descriptions

* feat: Update config_scheme

* clean: Avoid defining default config values more than once

* feat: Implement core functionality

* clean: Rename option check_length to enable_checks

This makes the option name more future proof in case the plugin will
perform more validations besides checking the length at some point.

* test: Add minimal safeguard mkdocs configuration file

* clean: Review warning messages copy

* clean: Add warning for missing meta descriptions

* test: Add tests for enable_checks

* doc: Update CHANGELOG.md for v2.1.0
  • Loading branch information
Paulo Ribeiro authored Oct 1, 2022
1 parent bcc5ff5 commit 9ed7df1
Show file tree
Hide file tree
Showing 17 changed files with 178 additions and 6 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ This file lists all updates to the [mkdocs-meta-descriptions plugin](https://git

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v2.1.0](https://www.github.com/prcr/mkdocs-meta-descriptions-plugin/compare/v2.0.0...v2.1.0) (2022-10-01)

### Added

- New option [`enable_checks`](https://github.com/prcr/mkdocs-meta-descriptions-plugin#enable_checks) to validate if all pages have meta descriptions and if each meta description has the recommended length.

## [v2.0.0](https://www.github.com/prcr/mkdocs-meta-descriptions-plugin/compare/v1.0.2...v2.0.0) (2022-07-23)

### Removed
Expand All @@ -13,7 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Added

- Added support for Python 3.10.
- Option `quiet` to stop info messages from being displayed on the console when running MkDocs.
- New option [`quiet`](https://github.com/prcr/mkdocs-meta-descriptions-plugin#quiet) to stop info messages from being displayed on the console when running MkDocs.
- New debug messages to log which meta description the plugin used on each page, available by running MkDocs with the `--verbose` flag.

### Changed
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ plugins:
- meta-descriptions:
export_csv: false
quiet: false
enable_checks: false
min_length: 50
max_length: 160
```
### `export_csv`
Expand All @@ -68,7 +71,25 @@ This is useful to review and keep track of all the meta descriptions in your pag

If `true`, the plugin logs messages of level `INFO` using the level `DEBUG` instead. The default is `false`.

Use this option to have a cleaner MkDocs console output. You can still see all logs by running MkDocs with the `--verbose` flag.
Enable this option to have a cleaner MkDocs console output. You can still see all logs by running MkDocs with the `--verbose` flag.

### `enable_checks`

If `true`, the plugin outputs a warning for each page that will have an empty or default meta description, as well as for each meta description shorter than `min_length` or longer than `max_length`. The default is `false`.

Enable this option if you want to make sure that all pages have a meta description and that each meta description follows general SEO best practices.

### `min_length`

Minimum number of characters that each meta description should have. The default is 50 characters, based on [these general recommendations](https://moz.com/learn/seo/meta-description).

Make sure that you set `enable_checks: true` for this option to have an effect.

### `max_length`

Maximum number of characters that each meta description should have. The default is 160 characters, based on [these general recommendations](https://moz.com/learn/seo/meta-description).

Make sure that you set `enable_checks: true` for this option to have an effect.

## See also

Expand Down
50 changes: 50 additions & 0 deletions mkdocs_meta_descriptions_plugin/checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from string import Template

from .common import logger


class Checker:
"""Checks meta descriptions against general SEO recommendations."""
_initialized = False
_check = False
_min_length = 50
_max_length = 160
_template_warning_missing = Template(
"Meta description not found: $page")
_template_warning_length = Template(
"Meta description $character_count character$plural $comparative than $limit: $page")

def _check_length(self, page):
length = len(page.meta.get("description", ""))
if length == 0:
logger.write(logger.Warning, self._template_warning_missing.substitute(page=page.file.src_path))
return # Skip length check
elif length < self._min_length:
diff = self._min_length - length
logger.write(logger.Warning, self._template_warning_length.substitute(character_count=diff,
plural="s"[:diff != 1],
comparative="shorter",
limit=self._min_length,
page=page.file.src_path))
elif length > self._max_length:
diff = length - self._max_length
logger.write(logger.Warning, self._template_warning_length.substitute(character_count=diff,
plural="s"[:diff != 1],
comparative="longer",
limit=self._max_length,
page=page.file.src_path))

def initialize(self, config):
self._check = config.get("enable_checks")
self._min_length = config.get("min_length")
self._max_length = config.get("max_length")
self._initialized = True

def check(self, page):
if not self._initialized:
logger.write(logger.Warning, "'LengthChecker' object not initialized yet, using default configurations")
if self._check:
self._check_length(page)


checker = Checker()
2 changes: 1 addition & 1 deletion mkdocs_meta_descriptions_plugin/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Logger:
Debug, Info, Warning, Error = range(0, 4)

def initialize(self, config):
self._quiet = config.get("quiet", False)
self._quiet = config.get("quiet")
self._initialized = True

def write(self, log_level, message):
Expand Down
10 changes: 8 additions & 2 deletions mkdocs_meta_descriptions_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

from .common import logger
from .export import Export
from .checker import checker


class MetaDescription(BasePlugin):

config_scheme = (
("export_csv", config_options.Type(bool, default=False)),
("quiet", config_options.Type(bool, default=False)),
("enable_checks", config_options.Type(bool, default=False)),
("min_length", config_options.Type(int, default=50)),
("max_length", config_options.Type(int, default=160)),
)

def __init__(self):
Expand All @@ -37,6 +41,7 @@ def _get_first_paragraph_text(self, html):

def on_config(self, config):
logger.initialize(self.config)
checker.initialize(self.config)
return config

def on_page_content(self, html, page, config, files):
Expand All @@ -57,16 +62,17 @@ def on_page_content(self, html, page, config, files):
return html

def on_post_page(self, output, page, config):
if self.config.get("export_csv", False):
if self.config.get("export_csv"):
# Collect pages to export meta descriptions to CSV file
self._pages.append(page)
checker.check(page)
return output

def on_post_build(self, config):
count_meta = self._count_meta + self._count_first_paragraph
count_total = count_meta + self._count_empty
logger.write(logger.Info, f"Added meta descriptions to {count_meta} of {count_total} pages, "
f"{self._count_first_paragraph} using the first paragraph")
if self.config.get("export_csv", False):
if self.config.get("export_csv"):
# Export meta descriptions to CSV file
Export(self._pages, config).write_csv()
7 changes: 7 additions & 0 deletions tests/docs/warning-long.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
description: Long meta description, long meta description.
---

# Heading 1

First paragraph.
5 changes: 5 additions & 0 deletions tests/docs/warning-not-found.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Heading 1

## Heading 2

Page without meta description.
7 changes: 7 additions & 0 deletions tests/docs/warning-short.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
description: Short meta description.
---

# Heading 1

First paragraph.
3 changes: 3 additions & 0 deletions tests/meta-descriptions-no-directory-urls.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-intro.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-paragraph.html,Value of site_description on mkdocs.yml
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph.html,First paragraph.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/front-matter-description.html,Value of meta description on front-matter-description.md
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-long.html,"Long meta description, long meta description."
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-not-found.html,Value of site_description on mkdocs.yml
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-short.html,Short meta description.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/index.html,For full documentation visit mkdocs.org.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/first-paragraph.html,First paragraph.
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-intro.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-paragraph.html,
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph.html,First paragraph.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/front-matter-description.html,Value of meta description on front-matter-description.md
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-long.html,"Long meta description, long meta description."
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-not-found.html,
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-short.html,Short meta description.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/index.html,For full documentation visit mkdocs.org.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/first-paragraph.html,First paragraph.
3 changes: 3 additions & 0 deletions tests/meta-descriptions-no-site-description.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-intro/
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-paragraph/,
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph/,First paragraph.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/front-matter-description/,Value of meta description on front-matter-description.md
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-long/,"Long meta description, long meta description."
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-not-found/,
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-short/,Short meta description.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/,For full documentation visit mkdocs.org.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/first-paragraph/,First paragraph.
3 changes: 3 additions & 0 deletions tests/meta-descriptions-no-site-url-no-directory-urls.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ first-paragraph-no-intro.html,Value of site_description on mkdocs.yml
first-paragraph-no-paragraph.html,Value of site_description on mkdocs.yml
first-paragraph.html,First paragraph.
front-matter-description.html,Value of meta description on front-matter-description.md
warning-long.html,"Long meta description, long meta description."
warning-not-found.html,Value of site_description on mkdocs.yml
warning-short.html,Short meta description.
subdirectory/index.html,For full documentation visit mkdocs.org.
subdirectory/first-paragraph.html,First paragraph.
3 changes: 3 additions & 0 deletions tests/meta-descriptions-no-site-url.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ first-paragraph-no-intro/,Value of site_description on mkdocs.yml
first-paragraph-no-paragraph/,Value of site_description on mkdocs.yml
first-paragraph/,First paragraph.
front-matter-description/,Value of meta description on front-matter-description.md
warning-long/,"Long meta description, long meta description."
warning-not-found/,Value of site_description on mkdocs.yml
warning-short/,Short meta description.
subdirectory/,For full documentation visit mkdocs.org.
subdirectory/first-paragraph/,First paragraph.
3 changes: 3 additions & 0 deletions tests/meta-descriptions.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-intro/
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph-no-paragraph/,Value of site_description on mkdocs.yml
https://prcr.github.io/mkdocs-meta-descriptions-plugin/first-paragraph/,First paragraph.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/front-matter-description/,Value of meta description on front-matter-description.md
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-long/,"Long meta description, long meta description."
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-not-found/,Value of site_description on mkdocs.yml
https://prcr.github.io/mkdocs-meta-descriptions-plugin/warning-short/,Short meta description.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/,For full documentation visit mkdocs.org.
https://prcr.github.io/mkdocs-meta-descriptions-plugin/subdirectory/first-paragraph/,First paragraph.
14 changes: 14 additions & 0 deletions tests/mkdocs-enable-checks-no-site-description.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
site_name: Test mkdocs-meta-descriptions-plugin

theme:
name: material

plugins:
- search
- meta-descriptions:
enable_checks: true
min_length: 25
max_length: 35

markdown_extensions:
- admonition
15 changes: 15 additions & 0 deletions tests/mkdocs-enable-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
site_name: Test mkdocs-meta-descriptions-plugin
site_description: "Value of site_description on mkdocs.yml"

theme:
name: material

plugins:
- search
- meta-descriptions:
enable_checks: true
min_length: 25
max_length: 35

markdown_extensions:
- admonition
25 changes: 24 additions & 1 deletion tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def use_directory_urls(request):
def build(request, use_directory_urls):
mkdocs_yml = request.param
with tempfile.TemporaryDirectory() as tempdir:
result = CliRunner().invoke(
result = CliRunner(mix_stderr=False).invoke(
build_command,
["--config-file", mkdocs_yml, "--site-dir", tempdir, use_directory_urls[0]],
)
Expand Down Expand Up @@ -161,3 +161,26 @@ def test_export_csv_output_no_site_url(self, build):
"tests/meta-descriptions-no-site-url-no-directory-urls.csv",
csv_path,
)


class TestChecker:
def test_checker_long(self, build):
result, _, mkdocs_yml, _ = build
if "enable-checks" in mkdocs_yml:
expected = f"WARNING - \x1b[0m[meta-descriptions] Meta description 10 characters longer than 35: " \
f"warning-long.md"
assert expected in result.stderr

def test_checker_short(self, build):
result, _, mkdocs_yml, _ = build
if "enable-checks" in mkdocs_yml:
expected = f"WARNING - \x1b[0m[meta-descriptions] Meta description 2 characters shorter than 25: " \
f"warning-short.md"
assert expected in result.stderr

def test_checker_not_found(self, build):
result, _, mkdocs_yml, _ = build
if "enable-checks" in mkdocs_yml:
expected = f"WARNING - \x1b[0m[meta-descriptions] Meta description not found: " \
f"warning-not-found.md"
assert expected in result.stderr

0 comments on commit 9ed7df1

Please sign in to comment.