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)