forked from github/pelican
parent
bb0ed26fdd
commit
4201256a5b
6 changed files with 56 additions and 7 deletions
|
|
@ -89,7 +89,7 @@ contains a list of reserved metadata keywords:
|
||||||
``summary`` Brief description of content for index pages
|
``summary`` Brief description of content for index pages
|
||||||
``lang`` Content language ID (``en``, ``fr``, etc.)
|
``lang`` Content language ID (``en``, ``fr``, etc.)
|
||||||
``translation`` If content is a translation of another (``true`` or ``false``)
|
``translation`` If content is a translation of another (``true`` or ``false``)
|
||||||
``status`` Content status: ``draft``, ``hidden``, or ``published``
|
``status`` Content status: ``draft``, ``hidden``, ``skip``, or ``published``
|
||||||
``template`` Name of template to use to generate content (without extension)
|
``template`` Name of template to use to generate content (without extension)
|
||||||
``save_as`` Save content to this relative file path
|
``save_as`` Save content to this relative file path
|
||||||
``url`` URL to use for this article/page
|
``url`` URL to use for this article/page
|
||||||
|
|
@ -633,6 +633,13 @@ attribute. Hidden posts will be output to ``ARTICLE_SAVE_AS`` as expected, but
|
||||||
are not included by default in tag, category, and author indexes, nor in the
|
are not included by default in tag, category, and author indexes, nor in the
|
||||||
main article feed. This has the effect of creating an "unlisted" post.
|
main article feed. This has the effect of creating an "unlisted" post.
|
||||||
|
|
||||||
|
Skip Posts
|
||||||
|
==========
|
||||||
|
|
||||||
|
Posts marked with ``skip`` status are ignored entirely. They are not processed
|
||||||
|
nor output to the ``ARTICLE_SAVE_AS`` path. Such posts will similarly not be
|
||||||
|
included in indexes or feeds.
|
||||||
|
|
||||||
.. _W3C ISO 8601: https://www.w3.org/TR/NOTE-datetime
|
.. _W3C ISO 8601: https://www.w3.org/TR/NOTE-datetime
|
||||||
.. _AsciiDoc: https://asciidoc.org
|
.. _AsciiDoc: https://asciidoc.org
|
||||||
.. _Pelican Plugins: https://github.com/pelican-plugins
|
.. _Pelican Plugins: https://github.com/pelican-plugins
|
||||||
|
|
|
||||||
|
|
@ -547,9 +547,29 @@ class Content:
|
||||||
self._summary = self.metadata["summary"]
|
self._summary = self.metadata["summary"]
|
||||||
|
|
||||||
|
|
||||||
|
class SkipStub(Content):
|
||||||
|
"""Stub class representing content that should not be processed in any way."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, content, metadata=None, settings=None, source_path=None, context=None
|
||||||
|
):
|
||||||
|
self.source_path = source_path
|
||||||
|
|
||||||
|
def is_valid(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def content(self):
|
||||||
|
raise NotImplementedError("Stub content should not be read")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def save_as(self):
|
||||||
|
raise NotImplementedError("Stub content cannot be saved")
|
||||||
|
|
||||||
|
|
||||||
class Page(Content):
|
class Page(Content):
|
||||||
mandatory_properties = ("title",)
|
mandatory_properties = ("title",)
|
||||||
allowed_statuses = ("published", "hidden", "draft")
|
allowed_statuses = ("published", "hidden", "draft", "skip")
|
||||||
default_status = "published"
|
default_status = "published"
|
||||||
default_template = "page"
|
default_template = "page"
|
||||||
|
|
||||||
|
|
@ -560,7 +580,7 @@ class Page(Content):
|
||||||
|
|
||||||
class Article(Content):
|
class Article(Content):
|
||||||
mandatory_properties = ("title", "date", "category")
|
mandatory_properties = ("title", "date", "category")
|
||||||
allowed_statuses = ("published", "hidden", "draft")
|
allowed_statuses = ("published", "hidden", "draft", "skip")
|
||||||
default_status = "published"
|
default_status = "published"
|
||||||
default_template = "article"
|
default_template = "article"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ from jinja2 import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from pelican.cache import FileStampDataCacher
|
from pelican.cache import FileStampDataCacher
|
||||||
from pelican.contents import Article, Page, Static
|
from pelican.contents import Article, Page, SkipStub, Static
|
||||||
from pelican.plugins import signals
|
from pelican.plugins import signals
|
||||||
from pelican.plugins._utils import plugin_enabled
|
from pelican.plugins._utils import plugin_enabled
|
||||||
from pelican.readers import Readers
|
from pelican.readers import Readers
|
||||||
|
|
@ -690,6 +690,10 @@ class ArticlesGenerator(CachingGenerator):
|
||||||
self._add_failed_source_path(f)
|
self._add_failed_source_path(f)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if isinstance(article, SkipStub):
|
||||||
|
logger.debug("Safely skipping %s", f)
|
||||||
|
continue
|
||||||
|
|
||||||
if not article.is_valid():
|
if not article.is_valid():
|
||||||
self._add_failed_source_path(f)
|
self._add_failed_source_path(f)
|
||||||
continue
|
continue
|
||||||
|
|
@ -702,6 +706,8 @@ class ArticlesGenerator(CachingGenerator):
|
||||||
all_drafts.append(article)
|
all_drafts.append(article)
|
||||||
elif article.status == "hidden":
|
elif article.status == "hidden":
|
||||||
hidden_articles.append(article)
|
hidden_articles.append(article)
|
||||||
|
elif article.status == "skip":
|
||||||
|
raise AssertionError("Documents with 'skip' status should be skipped")
|
||||||
|
|
||||||
self.add_source_path(article)
|
self.add_source_path(article)
|
||||||
self.add_static_links(article)
|
self.add_static_links(article)
|
||||||
|
|
@ -899,6 +905,10 @@ class PagesGenerator(CachingGenerator):
|
||||||
self._add_failed_source_path(f)
|
self._add_failed_source_path(f)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if isinstance(page, SkipStub):
|
||||||
|
logger.debug("Safely skipping %s", f)
|
||||||
|
continue
|
||||||
|
|
||||||
if not page.is_valid():
|
if not page.is_valid():
|
||||||
self._add_failed_source_path(f)
|
self._add_failed_source_path(f)
|
||||||
continue
|
continue
|
||||||
|
|
@ -911,6 +921,9 @@ class PagesGenerator(CachingGenerator):
|
||||||
hidden_pages.append(page)
|
hidden_pages.append(page)
|
||||||
elif page.status == "draft":
|
elif page.status == "draft":
|
||||||
draft_pages.append(page)
|
draft_pages.append(page)
|
||||||
|
elif page.status == "skip":
|
||||||
|
raise AssertionError("Documents with 'skip' status should be skipped")
|
||||||
|
|
||||||
self.add_source_path(page)
|
self.add_source_path(page)
|
||||||
self.add_static_links(page)
|
self.add_static_links(page)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ from docutils.writers.html4css1 import HTMLTranslator, Writer
|
||||||
|
|
||||||
from pelican import rstdirectives # NOQA
|
from pelican import rstdirectives # NOQA
|
||||||
from pelican.cache import FileStampDataCacher
|
from pelican.cache import FileStampDataCacher
|
||||||
from pelican.contents import Author, Category, Page, Tag
|
from pelican.contents import Author, Category, Page, SkipStub, Tag
|
||||||
from pelican.plugins import signals
|
from pelican.plugins import signals
|
||||||
from pelican.utils import file_suffix, get_date, pelican_open, posixize_path
|
from pelican.utils import file_suffix, get_date, pelican_open, posixize_path
|
||||||
|
|
||||||
|
|
@ -669,6 +669,9 @@ class Readers(FileStampDataCacher):
|
||||||
)
|
)
|
||||||
context_signal.send(context_sender, metadata=metadata)
|
context_signal.send(context_sender, metadata=metadata)
|
||||||
|
|
||||||
|
if metadata.get("status") == "skip":
|
||||||
|
content_class = SkipStub
|
||||||
|
|
||||||
return content_class(
|
return content_class(
|
||||||
content=content,
|
content=content,
|
||||||
metadata=metadata,
|
metadata=metadata,
|
||||||
|
|
|
||||||
5
pelican/tests/content/article_skip.md
vendored
Normal file
5
pelican/tests/content/article_skip.md
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Title: Skipped article
|
||||||
|
Date: 2024-06-30
|
||||||
|
Status: skip
|
||||||
|
|
||||||
|
This content will not be rendered.
|
||||||
|
|
@ -183,15 +183,16 @@ class TestCache(unittest.TestCase):
|
||||||
generator.readers.read_file = MagicMock()
|
generator.readers.read_file = MagicMock()
|
||||||
generator.generate_context()
|
generator.generate_context()
|
||||||
"""
|
"""
|
||||||
6 files don't get cached because they were not valid
|
7 files don't get cached because they were not valid
|
||||||
- article_with_attributes_containing_double_quotes.html
|
- article_with_attributes_containing_double_quotes.html
|
||||||
- article_with_comments.html
|
- article_with_comments.html
|
||||||
- article_with_null_attributes.html
|
- article_with_null_attributes.html
|
||||||
- 2012-11-30_md_w_filename_meta#foo-bar.md
|
- 2012-11-30_md_w_filename_meta#foo-bar.md
|
||||||
- empty.md
|
- empty.md
|
||||||
- empty_with_bom.md
|
- empty_with_bom.md
|
||||||
|
- article_skip.md
|
||||||
"""
|
"""
|
||||||
self.assertEqual(generator.readers.read_file.call_count, 6)
|
self.assertEqual(generator.readers.read_file.call_count, 7)
|
||||||
|
|
||||||
def test_article_reader_content_caching(self):
|
def test_article_reader_content_caching(self):
|
||||||
"""Test raw article content caching at the reader level"""
|
"""Test raw article content caching at the reader level"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue