1
0
Fork 0
forked from github/pelican

Merge pull request #2371 from oulenz/draft_pages

Allow pages to have draft status, like articles
This commit is contained in:
Justin Mayer 2018-07-04 18:20:57 +02:00 committed by GitHub
commit ec1914d3bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 17 deletions

View file

@ -533,9 +533,9 @@ your settings file.
Publishing drafts Publishing drafts
================= =================
If you want to publish an article as a draft (for friends to review before If you want to publish an article or a page as a draft (for friends to review
publishing, for example), you can add a ``Status: draft`` attribute to its before publishing, for example), you can add a ``Status: draft`` attribute to
metadata. That article will then be output to the ``drafts`` folder and not its metadata. That article will then be output to the ``drafts`` folder and not
listed on the index page nor on any category or tag page. listed on the index page nor on any category or tag page.
If your articles should be automatically published as a draft (to not accidentally If your articles should be automatically published as a draft (to not accidentally

View file

@ -445,6 +445,24 @@ respectively.
The location we will save the page which doesn't use the default language. The location we will save the page which doesn't use the default language.
.. data:: DRAFT_PAGE_URL = 'drafts/pages/{slug}.html'
The URL used to link to a page draft.
.. data:: DRAFT_PAGE_SAVE_AS = 'drafts/pages/{slug}.html'
The actual location a page draft is saved at.
.. data:: DRAFT_PAGE_LANG_URL = 'drafts/pages/{slug}-{lang}.html'
The URL used to link to a page draft which doesn't use the default
language.
.. data:: DRAFT_PAGE_LANG_SAVE_AS = 'drafts/pages/{slug}-{lang}.html'
The actual location a page draft which doesn't use the default language is
saved at.
.. data:: CATEGORY_URL = 'category/{slug}.html' .. data:: CATEGORY_URL = 'category/{slug}.html'
The URL to use for a category. The URL to use for a category.

View file

@ -86,6 +86,7 @@ categories A list of (category, articles) tuples, containing
all the categories and corresponding articles (values) all the categories and corresponding articles (values)
pages The list of pages pages The list of pages
hidden_pages The list of hidden pages hidden_pages The list of hidden pages
draft_pages The list of draft pages
============= =================================================== ============= ===================================================
@ -423,7 +424,7 @@ metadata Page header metadata `dict`.
save_as Location to save the page. save_as Location to save the page.
slug Page slug. slug Page slug.
source_path Full system path of the page source file. source_path Full system path of the page source file.
status The page status, can be any of 'published' or status The page status, can be any of 'published', 'hidden' or
'draft'. 'draft'.
summary Rendered summary content. summary Rendered summary content.
tags List of :ref:`Tag <object-author_cat_tag>` tags List of :ref:`Tag <object-author_cat_tag>`

View file

@ -212,13 +212,20 @@ class Pelican(object):
len(pages_generator.hidden_translations)), len(pages_generator.hidden_translations)),
'hidden page', 'hidden page',
'hidden pages') 'hidden pages')
pluralized_draft_pages = maybe_pluralize(
(len(pages_generator.draft_pages) +
len(pages_generator.draft_translations)),
'draft page',
'draft pages')
print('Done: Processed {}, {}, {} and {} in {:.2f} seconds.'.format( print('Done: Processed {}, {}, {}, {} and {} in {:.2f} seconds.'
pluralized_articles, .format(
pluralized_drafts, pluralized_articles,
pluralized_pages, pluralized_drafts,
pluralized_hidden_pages, pluralized_pages,
time.time() - start_time)) pluralized_hidden_pages,
pluralized_draft_pages,
time.time() - start_time))
def get_generator_classes(self): def get_generator_classes(self):
generators = [ArticlesGenerator, PagesGenerator] generators = [ArticlesGenerator, PagesGenerator]

View file

@ -444,10 +444,14 @@ class Content(object):
class Page(Content): class Page(Content):
mandatory_properties = ('title',) mandatory_properties = ('title',)
allowed_statuses = ('published', 'hidden') allowed_statuses = ('published', 'hidden', 'draft')
default_status = 'published' default_status = 'published'
default_template = 'page' default_template = 'page'
def _expand_settings(self, key):
klass = 'draft_page' if self.status == 'draft' else None
return super(Page, self)._expand_settings(key, klass)
class Article(Content): class Article(Content):
mandatory_properties = ('title', 'date', 'category') mandatory_properties = ('title', 'date', 'category')
@ -472,7 +476,7 @@ class Article(Content):
self.date = SafeDatetime.max self.date = SafeDatetime.max
def _expand_settings(self, key): def _expand_settings(self, key):
klass = 'article' if self.status == 'published' else 'draft' klass = 'draft' if self.status == 'draft' else 'article'
return super(Article, self)._expand_settings(key, klass) return super(Article, self)._expand_settings(key, klass)

View file

@ -656,14 +656,18 @@ class PagesGenerator(CachingGenerator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.pages = [] self.pages = []
self.translations = []
self.hidden_pages = [] self.hidden_pages = []
self.hidden_translations = [] self.hidden_translations = []
self.draft_pages = []
self.draft_translations = []
super(PagesGenerator, self).__init__(*args, **kwargs) super(PagesGenerator, self).__init__(*args, **kwargs)
signals.page_generator_init.send(self) signals.page_generator_init.send(self)
def generate_context(self): def generate_context(self):
all_pages = [] all_pages = []
hidden_pages = [] hidden_pages = []
draft_pages = []
for f in self.get_files( for f in self.get_files(
self.settings['PAGE_PATHS'], self.settings['PAGE_PATHS'],
exclude=self.settings['PAGE_EXCLUDES']): exclude=self.settings['PAGE_EXCLUDES']):
@ -694,14 +698,18 @@ class PagesGenerator(CachingGenerator):
all_pages.append(page) all_pages.append(page)
elif page.status == "hidden": elif page.status == "hidden":
hidden_pages.append(page) hidden_pages.append(page)
elif page.status == "draft":
draft_pages.append(page)
self.add_source_path(page) self.add_source_path(page)
self.pages, self.translations = process_translations(all_pages) self.pages, self.translations = process_translations(all_pages)
self.pages = order_content(self.pages, self.settings['PAGE_ORDER_BY']) self.pages = order_content(self.pages, self.settings['PAGE_ORDER_BY'])
self.hidden_pages, self.hidden_translations = \ self.hidden_pages, self.hidden_translations = \
process_translations(hidden_pages) process_translations(hidden_pages)
self.draft_pages, self.draft_translations = \
process_translations(draft_pages)
self._update_context(('pages', 'hidden_pages')) self._update_context(('pages', 'hidden_pages', 'draft_pages'))
self.save_cache() self.save_cache()
self.readers.save_cache() self.readers.save_cache()
@ -709,7 +717,8 @@ class PagesGenerator(CachingGenerator):
def generate_output(self, writer): def generate_output(self, writer):
for page in chain(self.translations, self.pages, for page in chain(self.translations, self.pages,
self.hidden_translations, self.hidden_pages): self.hidden_translations, self.hidden_pages,
self.draft_translations, self.draft_pages):
signals.page_generator_write_page.send(self, content=page) signals.page_generator_write_page.send(self, content=page)
writer.write_file( writer.write_file(
page.save_as, self.get_template(page.template), page.save_as, self.get_template(page.template),
@ -722,7 +731,9 @@ class PagesGenerator(CachingGenerator):
def refresh_metadata_intersite_links(self): def refresh_metadata_intersite_links(self):
for e in chain(self.pages, for e in chain(self.pages,
self.hidden_pages, self.hidden_pages,
self.hidden_translations): self.hidden_translations,
self.draft_pages,
self.draft_translations):
if hasattr(e, 'refresh_metadata_intersite_links'): if hasattr(e, 'refresh_metadata_intersite_links'):
e.refresh_metadata_intersite_links() e.refresh_metadata_intersite_links()

View file

@ -80,6 +80,11 @@ DEFAULT_CONFIG = {
'PAGE_ORDER_BY': 'basename', 'PAGE_ORDER_BY': 'basename',
'PAGE_LANG_URL': 'pages/{slug}-{lang}.html', 'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
'PAGE_LANG_SAVE_AS': posix_join('pages', '{slug}-{lang}.html'), 'PAGE_LANG_SAVE_AS': posix_join('pages', '{slug}-{lang}.html'),
'DRAFT_PAGE_URL': 'drafts/pages/{slug}.html',
'DRAFT_PAGE_SAVE_AS': posix_join('drafts', 'pages', '{slug}.html'),
'DRAFT_PAGE_LANG_URL': 'drafts/pages/{slug}-{lang}.html',
'DRAFT_PAGE_LANG_SAVE_AS': posix_join('drafts', 'pages',
'{slug}-{lang}.html'),
'STATIC_URL': '{path}', 'STATIC_URL': '{path}',
'STATIC_SAVE_AS': '{path}', 'STATIC_SAVE_AS': '{path}',
'STATIC_CREATE_LINKS': False, 'STATIC_CREATE_LINKS': False,

View file

@ -0,0 +1,8 @@
This is a test draft page
##########################
:status: draft
The quick brown fox .
This page is a draft.

View file

@ -0,0 +1,12 @@
title: This is a markdown test draft page
status: draft
Test Markdown File Header
=========================
Used for pelican test
---------------------
The quick brown fox .
This page is a draft

View file

@ -0,0 +1,11 @@
This is a test draft page with a custom template
#################################################
:status: draft
:template: custom
The quick brown fox .
This page is a draft
This page has a custom template to be called when rendered

View file

@ -71,6 +71,7 @@ class TestCache(unittest.TestCase):
generator.generate_context() generator.generate_context()
uncached_pages = sorted_titles(generator.pages) uncached_pages = sorted_titles(generator.pages)
uncached_hidden_pages = sorted_titles(generator.hidden_pages) uncached_hidden_pages = sorted_titles(generator.hidden_pages)
uncached_draft_pages = sorted_titles(generator.draft_pages)
generator = PagesGenerator( generator = PagesGenerator(
context=settings.copy(), settings=settings, context=settings.copy(), settings=settings,
@ -78,9 +79,11 @@ class TestCache(unittest.TestCase):
generator.generate_context() generator.generate_context()
cached_pages = sorted_titles(generator.pages) cached_pages = sorted_titles(generator.pages)
cached_hidden_pages = sorted_titles(generator.hidden_pages) cached_hidden_pages = sorted_titles(generator.hidden_pages)
cached_draft_pages = sorted_titles(generator.draft_pages)
self.assertEqual(uncached_pages, cached_pages) self.assertEqual(uncached_pages, cached_pages)
self.assertEqual(uncached_hidden_pages, cached_hidden_pages) self.assertEqual(uncached_hidden_pages, cached_hidden_pages)
self.assertEqual(uncached_draft_pages, cached_draft_pages)
def test_reader_caching(self): def test_reader_caching(self):
"""Test that cached and uncached content is same in reader level""" """Test that cached and uncached content is same in reader level"""

View file

@ -601,6 +601,7 @@ class TestPageGenerator(unittest.TestCase):
generator.generate_context() generator.generate_context()
pages = self.distill_pages(generator.pages) pages = self.distill_pages(generator.pages)
hidden_pages = self.distill_pages(generator.hidden_pages) hidden_pages = self.distill_pages(generator.hidden_pages)
draft_pages = self.distill_pages(generator.draft_pages)
pages_expected = [ pages_expected = [
['This is a test page', 'published', 'page'], ['This is a test page', 'published', 'page'],
@ -614,7 +615,13 @@ class TestPageGenerator(unittest.TestCase):
['This is a test hidden page', 'hidden', 'page'], ['This is a test hidden page', 'hidden', 'page'],
['This is a markdown test hidden page', 'hidden', 'page'], ['This is a markdown test hidden page', 'hidden', 'page'],
['This is a test hidden page with a custom template', 'hidden', ['This is a test hidden page with a custom template', 'hidden',
'custom'] 'custom'],
]
draft_pages_expected = [
['This is a test draft page', 'draft', 'page'],
['This is a markdown test draft page', 'draft', 'page'],
['This is a test draft page with a custom template', 'draft',
'custom'],
] ]
self.assertEqual(sorted(pages_expected), sorted(pages)) self.assertEqual(sorted(pages_expected), sorted(pages))
@ -622,9 +629,13 @@ class TestPageGenerator(unittest.TestCase):
sorted(pages_expected), sorted(pages_expected),
sorted(self.distill_pages(generator.context['pages']))) sorted(self.distill_pages(generator.context['pages'])))
self.assertEqual(sorted(hidden_pages_expected), sorted(hidden_pages)) self.assertEqual(sorted(hidden_pages_expected), sorted(hidden_pages))
self.assertEqual(sorted(draft_pages_expected), sorted(draft_pages))
self.assertEqual( self.assertEqual(
sorted(hidden_pages_expected), sorted(hidden_pages_expected),
sorted(self.distill_pages(generator.context['hidden_pages']))) sorted(self.distill_pages(generator.context['hidden_pages'])))
self.assertEqual(
sorted(draft_pages_expected),
sorted(self.distill_pages(generator.context['draft_pages'])))
def test_generate_sorted(self): def test_generate_sorted(self):
settings = get_settings(filenames={}) settings = get_settings(filenames={})