diff --git a/pelican/contents.py b/pelican/contents.py
index f29783eebd..e5e9e30913 100644
--- a/pelican/contents.py
+++ b/pelican/contents.py
@@ -11,7 +11,7 @@
import pytz
import six
-from six.moves.urllib.parse import urlparse, urlunparse
+from six.moves.urllib.parse import urljoin, urlparse, urlunparse
from pelican import signals
from pelican.settings import DEFAULT_CONFIG
@@ -210,6 +210,12 @@ def _link_replacer(self, siteurl, m):
path = value.path
origin = m.group('path')
+ # In order to stay compatible with behavior of Pelican 3.7.1, where
+ # having empty SITEURL would still produce proper absolute links
+ # starting with /, I'm adding a trailing slash to it so urljoin does
+ # the right thing.
+ if not siteurl.endswith('/'): siteurl += '/'
+
# XXX Put this in a different location.
if what in {'filename', 'attach'}:
if path.startswith('/'):
@@ -236,7 +242,7 @@ def _link_replacer(self, siteurl, m):
"%s used {attach} link syntax on a "
"non-static file. Use {filename} instead.",
self.get_relative_source_path())
- origin = '/'.join((siteurl, linked_content.url))
+ origin = urljoin(siteurl, linked_content.url)
origin = origin.replace('\\', '/') # for Windows paths.
else:
logger.warning(
@@ -245,13 +251,13 @@ def _link_replacer(self, siteurl, m):
'limit_msg': ("Other resources were not found "
"and their urls not replaced")})
elif what == 'category':
- origin = '/'.join((siteurl, Category(path, self.settings).url))
+ origin = urljoin(siteurl, Category(path, self.settings).url)
elif what == 'tag':
- origin = '/'.join((siteurl, Tag(path, self.settings).url))
+ origin = urljoin(siteurl, Tag(path, self.settings).url)
elif what == 'index':
- origin = '/'.join((siteurl, self.settings['INDEX_SAVE_AS']))
+ origin = urljoin(siteurl, self.settings['INDEX_SAVE_AS'])
elif what == 'author':
- origin = '/'.join((siteurl, Author(path, self.settings).url))
+ origin = urljoin(siteurl, Author(path, self.settings).url)
else:
logger.warning(
"Replacement Indicator '%s' not recognized, "
diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py
index 56928b812f..31e8f1c1af 100644
--- a/pelican/tests/test_contents.py
+++ b/pelican/tests/test_contents.py
@@ -10,6 +10,7 @@
from jinja2.utils import generate_lorem_ipsum
import six
+from six.moves.urllib.parse import urljoin
from pelican.contents import Article, Author, Category, Page, Static, Tag
from pelican.settings import DEFAULT_CONFIG
@@ -395,6 +396,54 @@ def test_intrasite_link_more(self):
''
)
+ def test_intrasite_link_absolute(self):
+ """Test that absolute URLs are merged properly."""
+
+ args = self.page_kwargs.copy()
+ args['settings'] = get_settings(
+ STATIC_URL='http://static.cool.site/{path}',
+ ARTICLE_URL='http://blog.cool.site/{slug}.html')
+ args['source_path'] = 'content'
+ args['context']['filenames'] = {
+ 'images/poster.jpg': Static('',
+ settings=args['settings'],
+ source_path='images/poster.jpg'),
+ 'article.rst': Article('',
+ settings=args['settings'],
+ metadata={'slug': 'article',
+ 'title': 'Article'})
+ }
+
+ # Article link will go to blog
+ args['content'] = (
+ 'Article'
+ )
+ content = Page(**args).get_content('http://cool.site')
+ self.assertEqual(
+ content,
+ 'Article'
+ )
+
+ # Page link will go to the main site
+ args['content'] = (
+ 'Index'
+ )
+ content = Page(**args).get_content('http://cool.site')
+ self.assertEqual(
+ content,
+ 'Index'
+ )
+
+ # Image link will go to static
+ args['content'] = (
+ ''
+ )
+ content = Page(**args).get_content('http://cool.site')
+ self.assertEqual(
+ content,
+ ''
+ )
+
def test_intrasite_link_markdown_spaces(self):
# Markdown introduces %20 instead of spaces, this tests that
# we support markdown doing this.
@@ -734,8 +783,8 @@ def test_index_link_syntax(self):
self.assertNotEqual(content, html)
expected_html = ('link')
self.assertEqual(content, expected_html)
@@ -788,7 +837,7 @@ def test_index_link_syntax_with_spaces(self):
self.assertNotEqual(content, html)
expected_html = ('link')
self.assertEqual(content, expected_html)