mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
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
|
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
|
"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``
|
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 there is no summary metadata for a given post, the ``SUMMARY_MAX_LENGTH``
|
||||||
If the date is not specified and you have ``DEFAULT_DATE`` set, Pelican will
|
setting can be used to specify how many words from the beginning of an article
|
||||||
use that instead, making the ``date`` metadata attribute optional. The category
|
are used as the summary. Summaries can also be specified inline with the body
|
||||||
can be determined by the directory in which the file resides. For example, a
|
using the :ref:`Summary Plugin <plugin-summary>`.
|
||||||
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.
|
|
||||||
|
|
||||||
You can also extract any metadata from the filename through a regular
|
You can also extract any metadata from the filename through a regular
|
||||||
expression to be set in the ``FILENAME_METADATA`` setting.
|
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``
|
* `HTML tags for reStructuredText`_ ``pelican.plugins.html_rst_directive``
|
||||||
* `Related posts`_ ``pelican.plugins.related_posts``
|
* `Related posts`_ ``pelican.plugins.related_posts``
|
||||||
* `Sitemap`_ ``pelican.plugins.sitemap``
|
* `Sitemap`_ ``pelican.plugins.sitemap``
|
||||||
|
* `Summary`_ ``pelican.plugins.summary``
|
||||||
|
|
||||||
Ideas for plugins that haven't been written yet:
|
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'
|
'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 it is set, else truncate the content."""
|
||||||
if hasattr(self, '_summary'):
|
if hasattr(self, '_summary'):
|
||||||
return self._summary
|
return self._summary
|
||||||
else:
|
|
||||||
if self.settings['SUMMARY_MAX_LENGTH']:
|
if self.settings['SUMMARY_MAX_LENGTH']:
|
||||||
return truncate_html_words(self.content,
|
return truncate_html_words(self.content,
|
||||||
self.settings['SUMMARY_MAX_LENGTH'])
|
self.settings['SUMMARY_MAX_LENGTH'])
|
||||||
return self.content
|
return self.content
|
||||||
|
|
||||||
def _set_summary(self, summary):
|
def _set_summary(self, summary):
|
||||||
"""Dummy function"""
|
"""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 os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from pelican.contents import Page
|
||||||
from pelican.plugins import gzip_cache
|
from pelican.plugins import gzip_cache
|
||||||
|
|
||||||
|
from .test_contents import TEST_CONTENT, TEST_SUMMARY
|
||||||
from .support import unittest, temporary_folder
|
from .support import unittest, temporary_folder
|
||||||
|
|
||||||
class TestGzipCache(unittest.TestCase):
|
class TestGzipCache(unittest.TestCase):
|
||||||
|
|
@ -34,3 +36,65 @@ class TestGzipCache(unittest.TestCase):
|
||||||
gzip_cache.create_gzip_file(a_html_filename)
|
gzip_cache.create_gzip_file(a_html_filename)
|
||||||
self.assertTrue(os.path.exists(a_html_filename + '.gz'))
|
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