forked from github/pelican
commit
400a11d4c9
5 changed files with 171 additions and 18 deletions
|
|
@ -218,19 +218,14 @@ Note that, aside from the title, none of this metadata is mandatory: if the date
|
|||
is not specified and DEFAULT_DATE is 'fs', Pelican will rely on the file's
|
||||
"mtime" timestamp, and the category can be determined by the directory in which
|
||||
the file resides. For example, a file located at ``python/foobar/myfoobar.rst``
|
||||
will have a category of ``foobar``.
|
||||
will have a category of ``foobar``. If you would like to organize your files in
|
||||
other ways where the name of the subfolder would not be a good category name,
|
||||
you can set the setting ``USE_FOLDER_AS_CATEGORY`` to ``False``.
|
||||
|
||||
Note that, aside from the title and date, none of this metadata is mandatory.
|
||||
If the date is not specified and you have ``DEFAULT_DATE`` set, Pelican will
|
||||
use that instead, making the ``date`` metadata attribute optional. The category
|
||||
can be determined by the directory in which the file resides. For example, a
|
||||
file located at ``python/foobar/myfoobar.rst`` will have a category of
|
||||
``foobar``. If you would like to organize your files in other ways where the
|
||||
name of the subfolder would not be a good category name, you can set the
|
||||
setting ``USE_FOLDER_AS_CATEGORY`` to ``False``. If there is no summary
|
||||
metadata for a given post, the ``SUMMARY_MAX_LENGTH`` setting can be used to
|
||||
specify how many words from the beginning of an article are used as the
|
||||
summary.
|
||||
If there is no summary metadata for a given post, the ``SUMMARY_MAX_LENGTH``
|
||||
setting can be used to specify how many words from the beginning of an article
|
||||
are used as the summary. Summaries can also be specified inline with the body
|
||||
using the :ref:`Summary Plugin <plugin-summary>`.
|
||||
|
||||
You can also extract any metadata from the filename through a regular
|
||||
expression to be set in the ``FILENAME_METADATA`` setting.
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ The following plugins are currently included with Pelican:
|
|||
* `HTML tags for reStructuredText`_ ``pelican.plugins.html_rst_directive``
|
||||
* `Related posts`_ ``pelican.plugins.related_posts``
|
||||
* `Sitemap`_ ``pelican.plugins.sitemap``
|
||||
* `Summary`_ ``pelican.plugins.summary``
|
||||
|
||||
Ideas for plugins that haven't been written yet:
|
||||
|
||||
|
|
@ -371,3 +372,34 @@ Here is an example configuration (it's also the default settings):
|
|||
'pages': 'monthly'
|
||||
}
|
||||
}
|
||||
|
||||
.. _plugin-summary:
|
||||
|
||||
Summary
|
||||
-------------
|
||||
|
||||
This plugin allows easy, variable length summaries directly embedded into the
|
||||
body of your articles. It introduces two new settings: ``SUMMARY_BEGIN_MARKER``
|
||||
and ``SUMMARY_END_MARKER``: strings which can be placed directly into an article
|
||||
to mark the beginning and end of a summary. When found, the standard
|
||||
``SUMMARY_MAX_LENGTH`` setting will be ignored. The markers themselves will also
|
||||
be removed from your articles before they are published. The default values
|
||||
are ``<!-- PELICAN_BEGIN_SUMMARY -->`` and ``<!-- PELICAN_END_SUMMARY -->``.
|
||||
For example::
|
||||
|
||||
Title: My super title
|
||||
Date: 2010-12-03 10:20
|
||||
Tags: thats, awesome
|
||||
Category: yeah
|
||||
Slug: my-super-post
|
||||
Author: Alexis Metaireau
|
||||
|
||||
This is the content of my super blog post.
|
||||
<!-- PELICAN_END_SUMMARY -->
|
||||
and this content occurs after the summary.
|
||||
|
||||
Here, the summary is taken to be the first line of the post. Because no
|
||||
beginning marker was found, it starts at the top of the body. It is possible
|
||||
to leave out the end marker instead, in which case the summary will start at the
|
||||
beginning marker and continue to the end of the body.
|
||||
|
||||
|
|
|
|||
|
|
@ -201,11 +201,11 @@ class Page(object):
|
|||
if it is set, else truncate the content."""
|
||||
if hasattr(self, '_summary'):
|
||||
return self._summary
|
||||
else:
|
||||
if self.settings['SUMMARY_MAX_LENGTH']:
|
||||
return truncate_html_words(self.content,
|
||||
self.settings['SUMMARY_MAX_LENGTH'])
|
||||
return self.content
|
||||
|
||||
if self.settings['SUMMARY_MAX_LENGTH']:
|
||||
return truncate_html_words(self.content,
|
||||
self.settings['SUMMARY_MAX_LENGTH'])
|
||||
return self.content
|
||||
|
||||
def _set_summary(self, summary):
|
||||
"""Dummy function"""
|
||||
|
|
|
|||
62
pelican/plugins/summary.py
Normal file
62
pelican/plugins/summary.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import types
|
||||
|
||||
from pelican import signals
|
||||
|
||||
def initialized(pelican):
|
||||
from pelican.settings import _DEFAULT_CONFIG
|
||||
_DEFAULT_CONFIG.setdefault('SUMMARY_BEGIN_MARKER',
|
||||
'<!-- PELICAN_BEGIN_SUMMARY -->')
|
||||
_DEFAULT_CONFIG.setdefault('SUMMARY_END_MARKER',
|
||||
'<!-- PELICAN_END_SUMMARY -->')
|
||||
if pelican:
|
||||
pelican.settings.setdefault('SUMMARY_BEGIN_MARKER',
|
||||
'<!-- PELICAN_BEGIN_SUMMARY -->')
|
||||
pelican.settings.setdefault('SUMMARY_END_MARKER',
|
||||
'<!-- PELICAN_END_SUMMARY -->')
|
||||
|
||||
def content_object_init(PageClass, instance):
|
||||
# if summary is already specified, use it
|
||||
if 'summary' in instance.metadata:
|
||||
return
|
||||
|
||||
try:
|
||||
content = instance.content
|
||||
except:
|
||||
# in some tests, this fails because a context has not been set
|
||||
return
|
||||
|
||||
# monkey patch a new function around get_content that removes summary
|
||||
# markers
|
||||
prev_get_content = instance.get_content
|
||||
def get_content(self, siteurl):
|
||||
content = prev_get_content(siteurl)
|
||||
self.settings['SUMMARY_BEGIN_MARKER'] = '<!-- PELICAN_BEGIN_SUMMARY -->'
|
||||
self.settings['SUMMARY_END_MARKER'] = '<!-- PELICAN_END_SUMMARY -->'
|
||||
if self.settings['SUMMARY_BEGIN_MARKER']:
|
||||
content = content.replace(
|
||||
self.settings['SUMMARY_BEGIN_MARKER'], '', 1)
|
||||
if self.settings['SUMMARY_END_MARKER']:
|
||||
content = content.replace(
|
||||
self.settings['SUMMARY_END_MARKER'], '', 1)
|
||||
return content
|
||||
instance.get_content = types.MethodType(get_content, instance)
|
||||
|
||||
# extract out our summary
|
||||
begin_summary = -1
|
||||
end_summary = -1
|
||||
if instance.settings['SUMMARY_BEGIN_MARKER']:
|
||||
begin_summary = content.find(instance.settings['SUMMARY_BEGIN_MARKER'])
|
||||
if instance.settings['SUMMARY_END_MARKER']:
|
||||
end_summary = content.find(instance.settings['SUMMARY_END_MARKER'])
|
||||
if begin_summary != -1 or end_summary != -1:
|
||||
# the beginning position has to take into account the length
|
||||
# of the marker
|
||||
begin_summary = (begin_summary +
|
||||
len(instance.settings['SUMMARY_BEGIN_MARKER'])
|
||||
if begin_summary != -1 else 0)
|
||||
end_summary = end_summary if end_summary != -1 else None
|
||||
instance._summary = content[begin_summary:end_summary]
|
||||
|
||||
def register():
|
||||
signals.initialized.connect(initialized)
|
||||
signals.content_object_init.connect(content_object_init)
|
||||
|
|
@ -4,8 +4,10 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
from pelican.contents import Page
|
||||
from pelican.plugins import gzip_cache
|
||||
|
||||
from .test_contents import TEST_CONTENT, TEST_SUMMARY
|
||||
from .support import unittest, temporary_folder
|
||||
|
||||
class TestGzipCache(unittest.TestCase):
|
||||
|
|
@ -34,3 +36,65 @@ class TestGzipCache(unittest.TestCase):
|
|||
gzip_cache.create_gzip_file(a_html_filename)
|
||||
self.assertTrue(os.path.exists(a_html_filename + '.gz'))
|
||||
|
||||
class TestSummary(unittest.TestCase):
|
||||
def setUp(self):
|
||||
super(TestSummary, self).setUp()
|
||||
|
||||
from pelican.plugins import summary
|
||||
|
||||
summary.register()
|
||||
summary.initialized(None)
|
||||
self.page_kwargs = {
|
||||
'content': TEST_CONTENT,
|
||||
'context': {
|
||||
'localsiteurl': '',
|
||||
},
|
||||
'metadata': {
|
||||
'summary': TEST_SUMMARY,
|
||||
'title': 'foo bar',
|
||||
'author': 'Blogger',
|
||||
},
|
||||
}
|
||||
|
||||
def _copy_page_kwargs(self):
|
||||
# make a deep copy of page_kwargs
|
||||
page_kwargs = dict([(key, self.page_kwargs[key]) for key in
|
||||
self.page_kwargs])
|
||||
for key in page_kwargs:
|
||||
if not isinstance(page_kwargs[key], dict):
|
||||
break
|
||||
page_kwargs[key] = dict([(subkey, page_kwargs[key][subkey])
|
||||
for subkey in page_kwargs[key]])
|
||||
|
||||
return page_kwargs
|
||||
|
||||
def test_end_summary(self):
|
||||
page_kwargs = self._copy_page_kwargs()
|
||||
del page_kwargs['metadata']['summary']
|
||||
page_kwargs['content'] = (
|
||||
TEST_SUMMARY + '<!-- PELICAN_END_SUMMARY -->' + TEST_CONTENT)
|
||||
page = Page(**page_kwargs)
|
||||
# test both the summary and the marker removal
|
||||
self.assertEqual(page.summary, TEST_SUMMARY)
|
||||
self.assertEqual(page.content, TEST_SUMMARY + TEST_CONTENT)
|
||||
|
||||
def test_begin_summary(self):
|
||||
page_kwargs = self._copy_page_kwargs()
|
||||
del page_kwargs['metadata']['summary']
|
||||
page_kwargs['content'] = (
|
||||
'FOOBAR<!-- PELICAN_BEGIN_SUMMARY -->' + TEST_CONTENT)
|
||||
page = Page(**page_kwargs)
|
||||
# test both the summary and the marker removal
|
||||
self.assertEqual(page.summary, TEST_CONTENT)
|
||||
self.assertEqual(page.content, 'FOOBAR' + TEST_CONTENT)
|
||||
|
||||
def test_begin_end_summary(self):
|
||||
page_kwargs = self._copy_page_kwargs()
|
||||
del page_kwargs['metadata']['summary']
|
||||
page_kwargs['content'] = (
|
||||
'FOOBAR<!-- PELICAN_BEGIN_SUMMARY -->' + TEST_SUMMARY +
|
||||
'<!-- PELICAN_END_SUMMARY -->' + TEST_CONTENT)
|
||||
page = Page(**page_kwargs)
|
||||
# test both the summary and the marker removal
|
||||
self.assertEqual(page.summary, TEST_SUMMARY)
|
||||
self.assertEqual(page.content, 'FOOBAR' + TEST_SUMMARY + TEST_CONTENT)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue