diff --git a/pelican/contents.py b/pelican/contents.py
index b453f61b..dbc33716 100644
--- a/pelican/contents.py
+++ b/pelican/contents.py
@@ -10,6 +10,11 @@ import os
import re
import sys
+try:
+ from urlparse import urlparse, urlunparse
+except ImportError:
+ from urllib.parse import urlparse, urlunparse
+
from datetime import datetime
@@ -194,34 +199,36 @@ class Content(object):
def replacer(m):
what = m.group('what')
- value = m.group('value')
+ value = urlparse(m.group('value'))
+ path = value.path
origin = m.group('path')
- # we support only filename for now. the plan is to support
- # categories, tags, etc. in the future, but let's keep things
- # simple for now.
-
# XXX Put this in a different location.
if what == 'filename':
- if value.startswith('/'):
- value = value[1:]
+ if path.startswith('/'):
+ path = path[1:]
else:
# relative to the source path of this content
- value = self.get_relative_source_path(
- os.path.join(self.relative_dir, value)
+ path = self.get_relative_source_path(
+ os.path.join(self.relative_dir, path)
)
- if value in self._context['filenames']:
+ if path in self._context['filenames']:
origin = '/'.join((siteurl,
- self._context['filenames'][value].url))
- origin = origin.replace('\\', '/') # Fow windows paths.
+ self._context['filenames'][path].url))
+ origin = origin.replace('\\', '/') # for Windows paths.
else:
logger.warning("Unable to find {fn}, skipping url"
- " replacement".format(fn=value))
+ " replacement".format(fn=path))
elif what == 'category':
- origin = Category(value, self.settings).url
+ origin = Category(path, self.settings).url
elif what == 'tag':
- origin = Tag(value, self.settings).url
+ origin = Tag(path, self.settings).url
+
+ # keep all other parts, such as query, fragment, etc.
+ parts = list(value)
+ parts[2] = origin
+ origin = urlunparse(parts)
return ''.join((m.group('markup'), m.group('quote'), origin,
m.group('quote')))
diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py
index 936903c1..437d0228 100644
--- a/pelican/tests/test_contents.py
+++ b/pelican/tests/test_contents.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+import six
from datetime import datetime
from sys import platform
@@ -204,6 +205,69 @@ class TestPage(unittest.TestCase):
('A simple test, with a '
'link'))
+ def test_intrasite_link(self):
+ # type does not take unicode in PY2 and bytes in PY3, which in
+ # combination with unicode literals leads to following insane line:
+ cls_name = '_DummyArticle' if six.PY3 else b'_DummyArticle'
+ article = type(cls_name, (object,), {'url': 'article.html'})
+
+ args = self.page_kwargs.copy()
+ args['settings'] = get_settings()
+ args['source_path'] = 'content'
+ args['context']['filenames'] = {'article.rst': article}
+
+ # Classic intrasite link via filename
+ args['content'] = (
+ 'A simple test, with a '
+ 'link'
+ )
+ content = Page(**args).get_content('http://notmyidea.org')
+ self.assertEquals(
+ content,
+ 'A simple test, with a '
+ 'link'
+ )
+
+ # fragment
+ args['content'] = (
+ 'A simple test, with a '
+ 'link'
+ )
+ content = Page(**args).get_content('http://notmyidea.org')
+ self.assertEquals(
+ content,
+ 'A simple test, with a '
+ 'link'
+ )
+
+ # query
+ args['content'] = (
+ 'A simple test, with a '
+ 'link'
+ )
+ content = Page(**args).get_content('http://notmyidea.org')
+ self.assertEquals(
+ content,
+ 'A simple test, with a '
+ 'link'
+ )
+
+ # combination
+ args['content'] = (
+ 'A simple test, with a '
+ 'link'
+ )
+ content = Page(**args).get_content('http://notmyidea.org')
+ self.assertEquals(
+ content,
+ 'A simple test, with a '
+ 'link'
+ )
+
class TestArticle(TestPage):
def test_template(self):