fix: Don't link to missing category pages

When `CATEGORY_SAVE_AS` is disabled but `CATEGORIES_SAVE_AS` is not,
the category index page was still generated, and its links pointed to
category pages that don't exist. This change shows category names
without links in the Simple and NotMyIdea themes in such cases and also
documents that both settings must be disabled to remove all
category-related output.
This commit is contained in:
Justin Mayer 2026-10-11 19:52:32 +02:00
commit 4e2ff4c229
4 changed files with 32 additions and 27 deletions

View file

@ -596,6 +596,9 @@ This would save your articles into something like
The location to save a category. The default is ``"category/{slug}.html"``.
Set this to ``""`` to disable category pages. Articles still keep their
categories, which can be used in URL patterns such as ``ARTICLE_SAVE_AS``.
To disable all category output, also set ``CATEGORIES_SAVE_AS = None``
and ``CATEGORY_FEED_ATOM = None`` (as well as ``CATEGORY_FEED_RSS``, if
you have enabled it).
.. data:: TAG_URL

View file

@ -184,31 +184,33 @@ class TestTemplateInheritance(LoggedTestCase):
try:
for theme in ("simple", "notmyidea"):
with self.subTest(theme=theme):
settings = read_settings(
path=None,
override={
"THEME": theme,
"PATH": content_dir,
"OUTPUT_PATH": self.temp_output,
"CACHE_PATH": self.temp_cache,
"SITEURL": "http://example.com",
"ARTICLE_SAVE_AS": "{category}/{slug}.html",
"CATEGORY_SAVE_AS": False,
"CATEGORIES_SAVE_AS": False,
},
)
for category_save_as in ("", None, False):
with self.subTest(theme=theme, CATEGORY_SAVE_AS=category_save_as):
settings = read_settings(
path=None,
override={
"THEME": theme,
"PATH": content_dir,
"OUTPUT_PATH": self.temp_output,
"CACHE_PATH": self.temp_cache,
"SITEURL": "http://example.com",
"ARTICLE_SAVE_AS": "{category}/{slug}.html",
"CATEGORY_SAVE_AS": category_save_as,
},
)
pelican = Pelican(settings=settings)
mute(True)(pelican.run)()
pelican = Pelican(settings=settings)
mute(True)(pelican.run)()
with open(
os.path.join(self.temp_output, "blog", "in-blog.html")
) as f:
content = f.read()
for page in ("blog/in-blog.html", "categories.html"):
with open(os.path.join(self.temp_output, page)) as f:
content = f.read()
self.assertIn("blog", content)
self.assertNotIn("/category/", content)
self.assertIn("blog", content)
self.assertNotIn("/category/", content)
self.assertFalse(
os.path.exists(os.path.join(self.temp_output, "category"))
)
finally:
rmtree(content_dir)

View file

@ -8,7 +8,7 @@
<h1>Categories for {{ SITENAME }}</h1>
<ul>
{% for category, articles in categories|sort %}
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a> ({{ articles|count }})</li>
<li>{% if CATEGORY_SAVE_AS %}<a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a>{% else %}{{ category }}{% endif %} ({{ articles|count }})</li>
{% endfor %}
</ul>
</section>

View file

@ -6,7 +6,7 @@
<h2>Categories on {{ SITENAME }}</h2>
<ul>
{% for category, articles in categories|sort %}
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a> ({{ articles|count }})</li>
<li>{% if CATEGORY_SAVE_AS %}<a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a>{% else %}{{ category }}{% endif %} ({{ articles|count }})</li>
{% endfor %}
</ul>
{% endblock %}