Skip to content

Commit 5adbaaf

Browse files
authored
Feature: add per-feed custom titles and abstracts (#295)
This pull request allows an RSS feed to override the MkDocs default `site_name:` and/or `site_description:` settings to allow feed-specific titles and descriptions. This is useful when multiple instances of the plugin are used (for example, one for blog posts and another for doc updates), as it will allow RSS feed subscribers to know which feed is which. It's also useful even with a single instance of the plugin, since sometimes the site title or description is SEO-optimized, while the RSS feed might want shorter or alternate versions. To use this capability, add a `feed_title:` and/or `feed_description:` setting to the RSS feed plugin settings. If either of these keys is not included, the previous behavior of using the site-wide versions is used. This feature does not change any behavior of any existing configs. A minimal example: ``` yaml site_name: My awesome website site_description: Obviously the best website that exists, because MkDocs is awesome! plugins: - search - rss: match_path: blog/posts/.* feed_title: My awesome blog feed feed_description: The best blog from the best site - rss: match_path: guide/.* feed_title: Doc updates from the best site feed_description: Provides updates to documentation on this great site ``` I have updated the documentation, and also added tests. (Comment updated to reflect latest changes to the PR)
2 parents 8859787 + 1c17192 commit 5adbaaf

File tree

11 files changed

+106
-23
lines changed

11 files changed

+106
-23
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,13 @@ plugins:
5454
default_time: "09:30"
5555
default_timezone: Europe/Paris
5656
enabled: true
57+
feed_description: "My custom feed description" # MkDocs site_description: will be used if this key is not present
5758
feeds_filenames:
5859
json_created: feed_json_created.json
5960
json_updated: feed_json_updated.json
6061
rss_created: feed_rss_created.xml
6162
rss_updated: feed_rss_updated.xml
63+
feed_title: "My custom feed title" # MkDocs site_name: will be used if this key is not present
6264
feed_ttl: 1440
6365
image: https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Feed-icon.svg/128px-Feed-icon.svg.png
6466
json_feed_enabled: true

docs/configuration.md

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -367,28 +367,39 @@ At the end, into the RSS you will get:
367367

368368
----
369369

370-
### :material-alphabet-latin: `feeds_filenames`: customize the output feed URL { #feeds_filenames }
370+
### :material-subtitles: `feed_description`: override site description { #description }
371371

372-
> Since version 1.13.0.
372+
This option allows you to override the default MkDocs site description for the description tag in this feed.
373+
This is useful if you have multiple instances of this plugin for multiple feeds. (For example, one feed
374+
for the blog, and a second for documentation updates.)
373375

374-
Customize every feed filenames generated by the plugin:
376+
This setting is optional. If you do not include it, the default site description will be used.
375377

376-
```yaml title="mkdocs.yml with custom RSS and JSON feeds names."
378+
```yaml
377379
plugins:
378380
- rss:
379-
feeds_filenames:
380-
json_created: feed.json
381-
json_updated: feed-updated.json
382-
rss_created: rss.xml
383-
rss_updated: rss-updated.xml
381+
feed_description: The best blog from the best site
384382
```
385383
386-
Default:
384+
Default: Use the default MkDocs `site_description:`.
387385

388-
- JSON feed for **created** items: `feed_json_created.json`
389-
- JSON feed for **updated** items: `feed_json_updated.json`
390-
- RSS feed for **created** items: `feed_rss_created.json`
391-
- RSS feed for **updated** items: `feed_rss_updated.json`
386+
----
387+
388+
### :material-format-title: `feed_title`: override site title { #title }
389+
390+
This option allows you to override the default MkDocs site name for the title tag in this feed.
391+
This is useful if you have multiple instances of this plugin for multiple feeds. (For example, one feed
392+
for the blog, and a second for documentation updates.)
393+
394+
This setting is optional. If you do not include it, the default site name will be used.
395+
396+
```yaml
397+
plugins:
398+
- rss:
399+
feed_title: My awesome blog feed
400+
```
401+
402+
Default: Use the default MkDocs `site_name:`.
392403

393404
----
394405

@@ -406,6 +417,31 @@ Output:
406417

407418
----
408419

420+
### :material-alphabet-latin: `feeds_filenames`: customize the output feed URL { #feeds_filenames }
421+
422+
> Since version 1.13.0.
423+
424+
Customize every feed filenames generated by the plugin:
425+
426+
```yaml title="mkdocs.yml with custom RSS and JSON feeds names."
427+
plugins:
428+
- rss:
429+
feeds_filenames:
430+
json_created: feed.json
431+
json_updated: feed-updated.json
432+
rss_created: rss.xml
433+
rss_updated: rss-updated.xml
434+
```
435+
436+
Default:
437+
438+
- JSON feed for **created** items: `feed_json_created.json`
439+
- JSON feed for **updated** items: `feed_json_updated.json`
440+
- RSS feed for **created** items: `feed_rss_created.json`
441+
- RSS feed for **updated** items: `feed_rss_updated.json`
442+
443+
----
444+
409445
### :material-image-outline: `image`: set the channel image { #image }
410446

411447
`image`: URL to image to use as feed illustration.

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ plugins:
5454
5555
## Example
5656
57-
As examples, here come the feeds generated for this documentation:
57+
As examples, here are the feeds generated for this documentation:
5858
5959
- [feed_rss_created.xml](feed_rss_created.xml) and [feed_json_created.json](feed_json_created.json) for latest **created** pages: [W3C validator](https://validator.w3.org/feed/check.cgi?url=https%3A//guts.github.io/mkdocs-rss-plugin/feed_rss_created.xml)
6060
- [feed_rss_updated.xml](feed_rss_updated.xml) and [feed_json_updated.json](feed_json_updated.json) for latest **updated** pages: [W3C validator](https://validator.w3.org/feed/check.cgi?url=https%3A//guts.github.io/mkdocs-rss-plugin/feed_rss_updated.xml)

mkdocs_rss_plugin/config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ class RssPluginConfig(Config):
4545
comments_path = config_options.Optional(config_options.Type(str))
4646
date_from_meta = config_options.SubConfig(_DateFromMeta)
4747
enabled = config_options.Type(bool, default=True)
48-
feed_ttl = config_options.Type(int, default=1440)
4948
feeds_filenames = config_options.SubConfig(_FeedsFilenamesConfig)
49+
feed_description = config_options.Optional(config_options.Type(str))
50+
feed_title = config_options.Optional(config_options.Type(str))
51+
feed_ttl = config_options.Type(int, default=1440)
5052
image = config_options.Optional(config_options.Type(str))
5153
json_feed_enabled = config_options.Type(bool, default=True)
5254
length = config_options.Type(int, default=20)

mkdocs_rss_plugin/integrations/theme_material_social_plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class IntegrationMaterialSocialCards:
4444
CARDS_MANIFEST: dict | None = None
4545

4646
def __init__(self, mkdocs_config: MkDocsConfig, switch_force: bool = True) -> None:
47-
"""Integration instanciation.
47+
"""Integration instantiation.
4848
4949
Args:
5050
mkdocs_config (MkDocsConfig): Mkdocs website configuration object.

mkdocs_rss_plugin/plugin.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class GitRssPlugin(BasePlugin[RssPluginConfig]):
5656
supports_multiple_instances = True
5757

5858
def __init__(self):
59-
"""Instanciation."""
59+
"""Instantiation."""
6060
# pages storage
6161
self.pages_to_filter: list = []
6262
# prepare output feeds
@@ -98,7 +98,7 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig:
9898
switch_force=self.config.use_material_social_cards,
9999
)
100100

101-
# instanciate plugin tooling
101+
# instantiate plugin tooling
102102
self.util = Util(
103103
use_git=self.config.use_git,
104104
integration_material_social_cards=self.integration_material_social_cards,
@@ -115,14 +115,20 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig:
115115
"author": config.site_author or None,
116116
"buildDate": formatdate(get_build_timestamp()),
117117
"copyright": config.copyright,
118-
"description": config.site_description,
118+
"description": (
119+
self.config.feed_description
120+
if self.config.feed_description
121+
else config.site_description
122+
),
119123
"entries": [],
120124
"generator": f"{__title__} - v{__version__}",
121125
"html_url": self.util.get_site_url(mkdocs_config=config),
122126
"language": self.util.guess_locale(mkdocs_config=config),
123127
"pubDate": formatdate(get_build_timestamp()),
124128
"repo_url": config.repo_url,
125-
"title": config.site_name,
129+
"title": (
130+
self.config.feed_title if self.config.feed_title else config.site_name
131+
),
126132
"ttl": self.config.feed_ttl,
127133
}
128134

mkdocs_rss_plugin/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ def get_site_url(mkdocs_config: MkDocsConfig) -> str | None:
669669
:rtype: str or None
670670
"""
671671
# this method exists because the following line returns an empty string instead of \
672-
# None (because the key alwayus exists)
672+
# None (because the key always exists)
673673
defined_site_url = mkdocs_config.site_url
674674

675675
# cases

tests/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def get_plugin_config_from_mkdocs(
4545
not enabled into the mkdocs.yml.
4646
:rtype: Config
4747
"""
48-
# instanciate plugin
48+
# instantiate plugin
4949
cfg_mkdocs = load_config(str(mkdocs_yml_filepath.resolve()))
5050

5151
plugins = cfg_mkdocs.plugins
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
site_name: Test RSS Plugin with custom titles and descriptions
2+
site_description: Test RSS Plugin with customized descriptions
3+
site_url: https://guts.github.io/mkdocs-rss-plugin
4+
5+
plugins:
6+
- rss:
7+
feed_title: My custom RSS title
8+
feed_description: My custom RSS description
9+
10+
theme:
11+
name: mkdocs

tests/test_build.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,28 @@ def test_simple_build_pretty_print_disabled(self):
657657
with Path(Path(tmpdirname) / OUTPUT_RSS_FEED_UPDATED).open("r") as f:
658658
self.assertEqual(len(f.readlines()), 1)
659659

660+
def test_simple_build_custom_title_description(self):
661+
"""Test simple build with custom description and title."""
662+
with tempfile.TemporaryDirectory() as tmpdirname:
663+
cli_result = self.build_docs_setup(
664+
testproject_path="docs",
665+
mkdocs_yml_filepath=Path(
666+
"tests/fixtures/mkdocs_custom_title_description.yml"
667+
),
668+
output_path=tmpdirname,
669+
)
670+
if cli_result.exception is not None:
671+
e = cli_result.exception
672+
logger.debug(format_exception(type(e), e, e.__traceback__))
673+
674+
self.assertEqual(cli_result.exit_code, 0)
675+
self.assertIsNone(cli_result.exception)
676+
677+
# created items
678+
feed_parsed = feedparser.parse(Path(tmpdirname) / OUTPUT_RSS_FEED_CREATED)
679+
self.assertEqual(feed_parsed.feed.title, "My custom RSS title")
680+
self.assertEqual(feed_parsed.feed.description, "My custom RSS description")
681+
660682
def test_rss_feed_validation(self):
661683
with tempfile.TemporaryDirectory() as tmpdirname:
662684
cli_result = self.build_docs_setup(

0 commit comments

Comments
 (0)