summaryrefslogtreecommitdiffstats
path: root/nikola/nikola.py
diff options
context:
space:
mode:
Diffstat (limited to 'nikola/nikola.py')
-rw-r--r--nikola/nikola.py53
1 files changed, 37 insertions, 16 deletions
diff --git a/nikola/nikola.py b/nikola/nikola.py
index 59e1b97..6a3fc0d 100644
--- a/nikola/nikola.py
+++ b/nikola/nikola.py
@@ -25,7 +25,7 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from __future__ import print_function, unicode_literals
-import codecs
+import io
from collections import defaultdict
from copy import copy
from pkg_resources import resource_filename
@@ -34,6 +34,7 @@ import glob
import locale
import os
import sys
+import mimetypes
try:
from urlparse import urlparse, urlsplit, urljoin
except ImportError:
@@ -133,7 +134,7 @@ LEGAL_VALUES = {
'pt': 'pt_br',
'zh': 'zh_cn'
},
- 'RTL_LANGUAGES': ('fa', 'ur'),
+ 'RTL_LANGUAGES': ('ar', 'fa', 'ur'),
'COLORBOX_LOCALES': defaultdict(
str,
bg='bg',
@@ -163,6 +164,16 @@ LEGAL_VALUES = {
}
+def _enclosure(post, lang):
+ '''Default implementation of enclosures'''
+ enclosure = post.meta('enclosure', lang)
+ if enclosure:
+ length = 0
+ url = enclosure
+ mime = mimetypes.guess_type(url)[0]
+ return url, length, mime
+
+
class Nikola(object):
"""Class that handles site generation.
@@ -319,6 +330,7 @@ class Nikola(object):
'USE_CDN': False,
'USE_FILENAME_AS_TITLE': True,
'USE_OPEN_GRAPH': True,
+ 'USE_SLUGIFY': True,
'TIMEZONE': 'UTC',
'DEPLOY_DRAFTS': True,
'DEPLOY_FUTURE': False,
@@ -389,6 +401,9 @@ class Nikola(object):
# We provide the arguments to format in CONTENT_FOOTER_FORMATS.
self.config['CONTENT_FOOTER'].langformat(self.config['CONTENT_FOOTER_FORMATS'])
+ # propagate USE_SLUGIFY
+ utils.USE_SLUGIFY = self.config['USE_SLUGIFY']
+
# Make sure we have pyphen installed if we are using it
if self.config.get('HYPHENATE') and pyphen is None:
utils.LOGGER.warn('To use the hyphenation, you have to install '
@@ -635,6 +650,7 @@ class Nikola(object):
'SHOW_SOURCELINK')
self._GLOBAL_CONTEXT['extra_head_data'] = self.config.get('EXTRA_HEAD_DATA')
self._GLOBAL_CONTEXT['colorbox_locales'] = LEGAL_VALUES['COLORBOX_LOCALES']
+ self._GLOBAL_CONTEXT['url_replacer'] = self.url_replacer
self._GLOBAL_CONTEXT.update(self.config.get('GLOBAL_CONTEXT', {}))
@@ -866,6 +882,10 @@ class Nikola(object):
if not result:
result = "."
+ # Don't forget the query part of the link
+ if parsed_dst.query:
+ result += "?" + parsed_dst.query
+
# Don't forget the fragment (anchor) part of the link
if parsed_dst.fragment:
result += "#" + parsed_dst.fragment
@@ -875,7 +895,7 @@ class Nikola(object):
return result
def generic_rss_renderer(self, lang, title, link, description, timeline, output_path,
- rss_teasers, rss_plain, feed_length=10, feed_url=None, enclosure=None):
+ rss_teasers, rss_plain, feed_length=10, feed_url=None, enclosure=_enclosure):
"""Takes all necessary data, and renders a RSS feed in output_path."""
rss_obj = rss.RSS2(
@@ -929,14 +949,11 @@ class Nikola(object):
rss_obj.rss_attrs["xmlns:dc"] = "http://purl.org/dc/elements/1.1/"
""" Enclosure callback must returns tuple """
- if enclosure:
- download_link, download_size, download_type = enclosure(post=post, lang=lang)
-
- args['enclosure'] = rss.Enclosure(
- download_link,
- download_size,
- download_type,
- )
+ # enclosure callback returns None if post has no enclosure, or a
+ # 3-tuple of (url, length (0 is valid), mimetype)
+ enclosure_details = enclosure(post=post, lang=lang)
+ if enclosure_details is not None:
+ args['enclosure'] = rss.Enclosure(*enclosure_details)
items.append(utils.ExtendedItem(**args))
@@ -944,7 +961,7 @@ class Nikola(object):
dst_dir = os.path.dirname(output_path)
utils.makedirs(dst_dir)
- with codecs.open(output_path, "wb+", "utf-8") as rss_file:
+ with io.open(output_path, "w+", encoding="utf-8") as rss_file:
data = rss_obj.to_xml(encoding='utf-8')
if isinstance(data, utils.bytes_str):
data = data.decode('utf-8')
@@ -1199,16 +1216,17 @@ class Nikola(object):
self.posts_per_month[
'{0}/{1:02d}'.format(post.date.year, post.date.month)].append(post)
for tag in post.alltags:
- if utils.slugify(tag) in slugged_tags:
+ _tag_slugified = utils.slugify(tag)
+ if _tag_slugified in slugged_tags:
if tag not in self.posts_per_tag:
# Tags that differ only in case
- other_tag = [k for k in self.posts_per_tag.keys() if k.lower() == tag.lower()][0]
+ other_tag = [existing for existing in self.posts_per_tag.keys() if utils.slugify(existing) == _tag_slugified][0]
utils.LOGGER.error('You have tags that are too similar: {0} and {1}'.format(tag, other_tag))
utils.LOGGER.error('Tag {0} is used in: {1}'.format(tag, post.source_path))
utils.LOGGER.error('Tag {0} is used in: {1}'.format(other_tag, ', '.join([p.source_path for p in self.posts_per_tag[other_tag]])))
quit = True
else:
- slugged_tags.add(utils.slugify(tag))
+ slugged_tags.add(utils.slugify(tag, force=True))
self.posts_per_tag[tag].append(post)
self.posts_per_category[post.meta('category')].append(post)
else:
@@ -1249,7 +1267,6 @@ class Nikola(object):
context['title'] = post.title(lang)
context['description'] = post.description(lang)
context['permalink'] = post.permalink(lang)
- context['page_list'] = self.pages
if post.use_in_feeds:
context['enable_comments'] = True
else:
@@ -1274,6 +1291,8 @@ class Nikola(object):
for k in self._GLOBAL_CONTEXT_TRANSLATABLE:
deps_dict[k] = deps_dict['global'][k](lang)
+ deps_dict['navigation_links'] = deps_dict['global']['navigation_links'](lang)
+
if post:
deps_dict['post_translations'] = post.translated_to
@@ -1315,6 +1334,8 @@ class Nikola(object):
for k in self._GLOBAL_CONTEXT_TRANSLATABLE:
deps_context[k] = deps_context['global'][k](lang)
+ deps_context['navigation_links'] = deps_context['global']['navigation_links'](lang)
+
task = {
'name': os.path.normpath(output_name),
'targets': [output_name],