1
0
Fork 0
forked from github/pelican

Merge pull request #716 from mankyd/summary-cutoff

Summary Cutoff
This commit is contained in:
Bruno Binet 2013-02-20 22:02:42 -08:00
commit 400a11d4c9
5 changed files with 171 additions and 18 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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"""

View 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)

View file

@ -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)