mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Merge pull request #262 from justinmayer/feeddomain
Allow for serving feeds from a separate domain.
This commit is contained in:
commit
38b5b94617
6 changed files with 106 additions and 34 deletions
|
|
@ -62,10 +62,13 @@ Setting name (default value) What does it do?
|
|||
`RELATIVE_URLS` (``True``) Defines whether Pelican should use relative URLs or
|
||||
not.
|
||||
`SITENAME` (``'A Pelican Blog'``) Your site name
|
||||
`SITEURL` Base URL of your website. Note that this is
|
||||
not a way to tell Pelican whether to use relative URLs
|
||||
or static ones. You should instead use the
|
||||
`RELATIVE_URL` setting for that purpose.
|
||||
`SITEURL` Base URL of your website. Not defined by default,
|
||||
which means the base URL is assumed to be "/" with a
|
||||
root-relative URL structure. If `SITEURL` is specified
|
||||
explicitly, URLs will be generated with an absolute
|
||||
URL structure (including the domain). If you want to
|
||||
use relative URLs instead of root-relative or absolute
|
||||
URLs, you should instead use the `RELATIVE_URL` setting.
|
||||
`STATIC_PATHS` (``['images']``) The static paths you want to have accessible
|
||||
on the output path "static". By default,
|
||||
Pelican will copy the 'images' folder to the
|
||||
|
|
@ -86,10 +89,10 @@ Setting name (default value) What does it do?
|
|||
URL settings
|
||||
------------
|
||||
|
||||
You can customize the URL's and locations where files will be saved. The URL's and
|
||||
SAVE_AS variables use python's format strings. These variables allow you to place
|
||||
your articles in a location such as '{slug}/index.html' and link to then as
|
||||
'{slug}' for clean urls. These settings give you the flexibility to place your
|
||||
You can customize the URLs and locations where files will be saved. The URLs and
|
||||
SAVE_AS variables use Python's format strings. These variables allow you to place
|
||||
your articles in a location such as '{slug}/index.html' and link to them as
|
||||
'{slug}' for clean URLs. These settings give you the flexibility to place your
|
||||
articles and pages anywhere you want.
|
||||
|
||||
Note: If you specify a datetime directive, it will be substituted using the
|
||||
|
|
@ -216,15 +219,26 @@ the ``TAG_FEED`` and ``TAG_FEED_RSS`` settings:
|
|||
================================================ =====================================================
|
||||
Setting name (default value) What does it do?
|
||||
================================================ =====================================================
|
||||
`CATEGORY_FEED` ('feeds/%s.atom.xml'[2]_) Where to put the category Atom feeds.
|
||||
`CATEGORY_FEED_RSS` (``None``, i.e. no RSS) Where to put the category RSS feeds.
|
||||
`FEED_DOMAIN` (``None``, i.e. base URL is "/") The domain prepended to feed URLs. Since feed URLs
|
||||
should always be absolute, it is highly recommended
|
||||
to define this (e.g., "http://feeds.example.com"). If
|
||||
you have already explicitly defined SITEURL (see
|
||||
above) and want to use the same domain for your
|
||||
feeds, you can just set: `FEED_DOMAIN = SITEURL`
|
||||
`FEED` (``'feeds/all.atom.xml'``) Relative URL to output the Atom feed.
|
||||
`FEED_RSS` (``None``, i.e. no RSS) Relative URL to output the RSS feed.
|
||||
`TAG_FEED` (``None``, ie no tag feed) Relative URL to output the tag Atom feed. It should
|
||||
`CATEGORY_FEED` ('feeds/%s.atom.xml'[2]_) Where to put the category Atom feeds.
|
||||
`CATEGORY_FEED_RSS` (``None``, i.e. no RSS) Where to put the category RSS feeds.
|
||||
`TAG_FEED` (``None``, i.e. no tag feed) Relative URL to output the tag Atom feed. It should
|
||||
be defined using a "%s" match in the tag name.
|
||||
`TAG_FEED_RSS` (``None``, ie no RSS tag feed) Relative URL to output the tag RSS feed
|
||||
`FEED_MAX_ITEMS` Maximum number of items allowed in a feed. Feed item
|
||||
quantity is unrestricted by default.
|
||||
`FEED_MAIN_URL` (``'feeds/all.atom.xml'``) URL appended to domain for the main Atom feed and
|
||||
used to populate its `<link>` in the base template.
|
||||
Useful when you want the feed link to differ from the
|
||||
filesystem path, such as when using web server
|
||||
aliases/rewrites or FeedBurner (see below).
|
||||
================================================ =====================================================
|
||||
|
||||
If you don't want to generate some of these feeds, set ``None`` to the
|
||||
|
|
@ -232,6 +246,25 @@ variables above.
|
|||
|
||||
.. [2] %s is the name of the category.
|
||||
|
||||
FeedBurner
|
||||
----------
|
||||
|
||||
If you want to use FeedBurner for your primary Atom feed, there are two
|
||||
primary fields to configure in the `FeedBurner
|
||||
<http://feedburner.google.com>`_ interface: "Original Feed" and "Feed Address".
|
||||
If using the default Pelican `FEED` attribute and assuming your feeds
|
||||
are served from the `www.example.com` domain, you would enter
|
||||
`http://www.example.com/feeds/all.atom.xml` in the "Original Feed" field in
|
||||
FeedBurner.
|
||||
|
||||
For the "Feed Address" field in the FeedBurner interface, you may choose
|
||||
whatever suffix you prefer. In your Pelican settings, assign this suffix to
|
||||
the `FEED_MAIN_URL` setting. So if your FeedBurner feed address is set to
|
||||
`http://feeds.feedburner.com/myblogfeed`, in your Pelican settings you would
|
||||
set: `FEED_MAIN_URL = "myblogfeed"`. Then set the `FEED_DOMAIN` setting to
|
||||
`http://feeds.feedburner.com`, or `http://feeds.example.com` if you are using
|
||||
a CNAME on your own domain (i.e., FeedBurner's "MyBrand" feature).
|
||||
|
||||
Pagination
|
||||
==========
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ _DEFAULT_CONFIG = {'PATH': None,
|
|||
'STATIC_PATHS': ['images', ],
|
||||
'THEME_STATIC_PATHS': ['static', ],
|
||||
'FEED': 'feeds/all.atom.xml',
|
||||
'FEED_MAIN_URL': 'feeds/all.atom.xml',
|
||||
'CATEGORY_FEED': 'feeds/%s.atom.xml',
|
||||
'TRANSLATION_FEED': 'feeds/all-%s.atom.xml',
|
||||
'FEED_MAX_ITEMS': '',
|
||||
|
|
@ -71,26 +72,45 @@ _DEFAULT_CONFIG = {'PATH': None,
|
|||
|
||||
|
||||
def read_settings(filename=None):
|
||||
if filename:
|
||||
local_settings = get_settings_from_file(filename)
|
||||
else:
|
||||
local_settings = _DEFAULT_CONFIG
|
||||
configured_settings = configure_settings(local_settings, None, filename)
|
||||
return configured_settings
|
||||
|
||||
|
||||
def get_settings_from_file(filename, default_settings=None):
|
||||
"""Load a Python file into a dictionary.
|
||||
"""
|
||||
context = _DEFAULT_CONFIG.copy()
|
||||
if default_settings == None:
|
||||
default_settings = _DEFAULT_CONFIG
|
||||
context = default_settings.copy()
|
||||
if filename:
|
||||
tempdict = {}
|
||||
execfile(filename, tempdict)
|
||||
for key in tempdict:
|
||||
if key.isupper():
|
||||
context[key] = tempdict[key]
|
||||
return context
|
||||
|
||||
# Make the paths relative to the settings file
|
||||
|
||||
def configure_settings(settings, default_settings=None, filename=None):
|
||||
"""Provide optimizations, error checking, and warnings for loaded settings"""
|
||||
if default_settings is None:
|
||||
default_settings = _DEFAULT_CONFIG
|
||||
|
||||
# Make the paths relative to the settings file
|
||||
if filename:
|
||||
for path in ['PATH', 'OUTPUT_PATH']:
|
||||
if path in context:
|
||||
if context[path] is not None and not isabs(context[path]):
|
||||
context[path] = os.path.abspath(os.path.normpath(
|
||||
os.path.join(os.path.dirname(filename), context[path]))
|
||||
if path in settings:
|
||||
if settings[path] is not None and not isabs(settings[path]):
|
||||
settings[path] = os.path.abspath(os.path.normpath(
|
||||
os.path.join(os.path.dirname(filename), settings[path]))
|
||||
)
|
||||
|
||||
# if locales is not a list, make it one
|
||||
locales = context['LOCALE']
|
||||
locales = settings['LOCALE']
|
||||
|
||||
if isinstance(locales, basestring):
|
||||
locales = [locales]
|
||||
|
|
@ -108,11 +128,20 @@ def read_settings(filename=None):
|
|||
else:
|
||||
logger.warn("LOCALE option doesn't contain a correct value")
|
||||
|
||||
if not 'TIMEZONE' in context:
|
||||
# If SITEURL is defined but FEED_DOMAIN isn't, set FEED_DOMAIN = SITEURL
|
||||
if ('SITEURL' in settings) and (not 'FEED_DOMAIN' in settings):
|
||||
settings['FEED_DOMAIN'] = settings['SITEURL']
|
||||
|
||||
# Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined
|
||||
if (('FEED' in settings) or ('FEED_RSS' in settings)) and (not 'FEED_DOMAIN' in settings):
|
||||
logger.warn("Since feed URLs should always be absolute, you should specify "
|
||||
"FEED_DOMAIN in your settings. (e.g., 'FEED_DOMAIN = "
|
||||
"http://www.example.com')")
|
||||
|
||||
if not 'TIMEZONE' in settings:
|
||||
logger.warn("No timezone information specified in the settings. Assuming"
|
||||
" your timezone is UTC for feed generation. Check "
|
||||
"http://docs.notmyidea.org/alexis/pelican/settings.html#timezone "
|
||||
"for more information")
|
||||
|
||||
# set the locale
|
||||
return context
|
||||
return settings
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ body {
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Headings */
|
||||
h1 {font-size: 2em }
|
||||
h2 {font-size: 1.571em} /* 22px */
|
||||
|
|
@ -304,7 +302,7 @@ img.left, figure.left {float: right; margin: 0 0 2em 2em;}
|
|||
.social a[href*='digg.com'] {background-image: url('../images/icons/digg.png');}
|
||||
.social a[href*='facebook.com'] {background-image: url('../images/icons/facebook.png');}
|
||||
.social a[href*='last.fm'], .social a[href*='lastfm.'] {background-image: url('../images/icons/lastfm.png');}
|
||||
.social a[href*='atom.xml'] {background-image: url('../images/icons/rss.png');}
|
||||
.social a[type$='atom+xml'], .social a[type$='rss+xml'] {background-image: url('../images/icons/rss.png');}
|
||||
.social a[href*='twitter.com'] {background-image: url('../images/icons/twitter.png');}
|
||||
.social a[href*='linkedin.com'] {background-image: url('../images/icons/linkedin.png');}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
<title>{% block title %}{{ SITENAME }}{%endblock%}</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="{{ SITEURL }}/theme/css/{{ CSS_FILE }}" type="text/css" />
|
||||
<link href="{{ SITEURL }}/{{ FEED }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} ATOM Feed" />
|
||||
<link href="{{ FEED_DOMAIN }}/{{ FEED_MAIN_URL }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
|
||||
{% if FEED_RSS %}
|
||||
<link href="{{ SITEURL }}/{{ FEED_RSS }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
|
||||
<link href="{{ FEED_DOMAIN }}/{{ FEED_RSS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
|
||||
{% endif %}
|
||||
|
||||
<!--[if IE]>
|
||||
|
|
@ -56,9 +56,9 @@
|
|||
<div class="social">
|
||||
<h2>social</h2>
|
||||
<ul>
|
||||
<li><a href="{{ SITEURL }}/{{ FEED }}" rel="alternate">atom feed</a></li>
|
||||
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_MAIN_URL }}" type="application/atom+xml" rel="alternate">atom feed</a></li>
|
||||
{% if FEED_RSS %}
|
||||
<li><a href="{{ SITEURL }}/{{ FEED_RSS }}" rel="alternate">rss feed</a></li>
|
||||
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_RSS }}" type="application/rss+xml" rel="alternate">rss feed</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% for name, link in SOCIAL %}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ SOCIAL = (('twitter', 'http://twitter.com/ametaireau'),
|
|||
DEFAULT_METADATA = (('yeah', 'it is'),)
|
||||
|
||||
# static paths will be copied under the same name
|
||||
STATIC_PATHS = ["pictures",]
|
||||
STATIC_PATHS = ["pictures", ]
|
||||
|
||||
# A list of files to copy from the source to the destination
|
||||
FILES_TO_COPY = (('extra/robots.txt', 'robots.txt'),)
|
||||
|
|
@ -37,4 +37,3 @@ FILES_TO_COPY = (('extra/robots.txt', 'robots.txt'),)
|
|||
# foobar will not be used, because it's not in caps. All configuration keys
|
||||
# have to be in caps
|
||||
foobar = "barbaz"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
from os.path import dirname, abspath, join
|
||||
|
||||
from pelican.settings import read_settings, _DEFAULT_CONFIG
|
||||
from pelican.settings import read_settings, configure_settings, _DEFAULT_CONFIG
|
||||
from .support import unittest
|
||||
|
||||
|
||||
class TestSettingsFromFile(unittest.TestCase):
|
||||
"""Providing a file, it should read it, replace the default values and
|
||||
append new values to the settings, if any
|
||||
class TestSettingsConfiguration(unittest.TestCase):
|
||||
"""Provided a file, it should read it, replace the default values,
|
||||
append new values to the settings (if any), and apply basic settings
|
||||
optimizations.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.PATH = abspath(dirname(__file__))
|
||||
|
|
@ -31,3 +32,15 @@ class TestSettingsFromFile(unittest.TestCase):
|
|||
"""providing no file should return the default values."""
|
||||
settings = read_settings(None)
|
||||
self.assertDictEqual(settings, _DEFAULT_CONFIG)
|
||||
|
||||
def test_configure_settings(self):
|
||||
"""Manipulations to settings should be applied correctly."""
|
||||
|
||||
# FEED_DOMAIN, if undefined, should default to SITEURL
|
||||
settings = {'SITEURL': 'http://blog.notmyidea.org', 'LOCALE': ''}
|
||||
configure_settings(settings)
|
||||
self.assertEqual(settings['FEED_DOMAIN'], 'http://blog.notmyidea.org')
|
||||
|
||||
settings = {'FEED_DOMAIN': 'http://feeds.example.com', 'LOCALE': ''}
|
||||
configure_settings(settings)
|
||||
self.assertEqual(settings['FEED_DOMAIN'], 'http://feeds.example.com')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue