aboutsummaryrefslogtreecommitdiffstats
path: root/nikola/plugins/task
diff options
context:
space:
mode:
Diffstat (limited to 'nikola/plugins/task')
-rw-r--r--nikola/plugins/task/__init__.py2
-rw-r--r--nikola/plugins/task/archive.py2
-rw-r--r--nikola/plugins/task/authors.py32
-rw-r--r--nikola/plugins/task/bundles.py2
-rw-r--r--nikola/plugins/task/copy_assets.py2
-rw-r--r--nikola/plugins/task/copy_files.py2
-rw-r--r--nikola/plugins/task/galleries.py58
-rw-r--r--nikola/plugins/task/gzip.py2
-rw-r--r--nikola/plugins/task/indexes.py72
-rw-r--r--nikola/plugins/task/listings.py62
-rw-r--r--nikola/plugins/task/pages.py4
-rw-r--r--nikola/plugins/task/posts.py2
-rw-r--r--nikola/plugins/task/py3_switch.py4
-rw-r--r--nikola/plugins/task/redirect.py4
-rw-r--r--nikola/plugins/task/robots.py2
-rw-r--r--nikola/plugins/task/rss.py5
-rw-r--r--nikola/plugins/task/scale_images.py8
-rw-r--r--nikola/plugins/task/sitemap/__init__.py6
-rw-r--r--nikola/plugins/task/sources.py2
-rw-r--r--nikola/plugins/task/tags.py196
20 files changed, 288 insertions, 181 deletions
diff --git a/nikola/plugins/task/__init__.py b/nikola/plugins/task/__init__.py
index fd9a48f..4eeae62 100644
--- a/nikola/plugins/task/__init__.py
+++ b/nikola/plugins/task/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/archive.py b/nikola/plugins/task/archive.py
index 3cdd33b..303d349 100644
--- a/nikola/plugins/task/archive.py
+++ b/nikola/plugins/task/archive.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/authors.py b/nikola/plugins/task/authors.py
index 081d21d..ec61800 100644
--- a/nikola/plugins/task/authors.py
+++ b/nikola/plugins/task/authors.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2015 Juanjo Conti.
+# Copyright © 2015-2016 Juanjo Conti and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -35,6 +35,8 @@ except ImportError:
from urllib.parse import urljoin # NOQA
from collections import defaultdict
+from blinker import signal
+
from nikola.plugin_categories import Task
from nikola import utils
@@ -47,13 +49,20 @@ class RenderAuthors(Task):
def set_site(self, site):
"""Set Nikola site."""
+ self.generate_author_pages = False
if site.config["ENABLE_AUTHOR_PAGES"]:
site.register_path_handler('author_index', self.author_index_path)
site.register_path_handler('author', self.author_path)
site.register_path_handler('author_atom', self.author_atom_path)
site.register_path_handler('author_rss', self.author_rss_path)
+ signal('scanned').connect(self.posts_scanned)
return super(RenderAuthors, self).set_site(site)
+ def posts_scanned(self, event):
+ """Called after posts are scanned via signal."""
+ self.generate_author_pages = self.site.config["ENABLE_AUTHOR_PAGES"] and len(self._posts_per_author()) > 1
+ self.site.GLOBAL_CONTEXT["author_pages_generated"] = self.generate_author_pages
+
def gen_tasks(self):
"""Render the author pages and feeds."""
kw = {
@@ -78,12 +87,10 @@ class RenderAuthors(Task):
"index_file": self.site.config['INDEX_FILE'],
}
- yield self.group_task()
self.site.scan_posts()
+ yield self.group_task()
- generate_author_pages = self.site.config["ENABLE_AUTHOR_PAGES"] and len(self._posts_per_author()) > 1
- self.site.GLOBAL_CONTEXT["author_pages_generated"] = generate_author_pages
- if generate_author_pages:
+ if self.generate_author_pages:
yield self.list_authors_page(kw)
if not self._posts_per_author(): # this may be self.site.posts_per_author
@@ -244,10 +251,13 @@ class RenderAuthors(Task):
}
return utils.apply_filters(task, kw['filters'])
- def slugify_author_name(self, name):
+ def slugify_author_name(self, name, lang=None):
"""Slugify an author name."""
+ if lang is None: # TODO: remove in v8
+ utils.LOGGER.warn("RenderAuthors.slugify_author_name() called without language!")
+ lang = ''
if self.site.config['SLUG_AUTHOR_PATH']:
- name = utils.slugify(name)
+ name = utils.slugify(name, lang)
return name
def author_index_path(self, name, lang):
@@ -272,13 +282,13 @@ class RenderAuthors(Task):
return [_f for _f in [
self.site.config['TRANSLATIONS'][lang],
self.site.config['AUTHOR_PATH'],
- self.slugify_author_name(name),
+ self.slugify_author_name(name, lang),
self.site.config['INDEX_FILE']] if _f]
else:
return [_f for _f in [
self.site.config['TRANSLATIONS'][lang],
self.site.config['AUTHOR_PATH'],
- self.slugify_author_name(name) + ".html"] if _f]
+ self.slugify_author_name(name, lang) + ".html"] if _f]
def author_atom_path(self, name, lang):
"""Link to an author's Atom feed.
@@ -288,7 +298,7 @@ class RenderAuthors(Task):
link://author_atom/joe => /authors/joe.atom
"""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
- self.site.config['AUTHOR_PATH'], self.slugify_author_name(name) + ".atom"] if
+ self.site.config['AUTHOR_PATH'], self.slugify_author_name(name, lang) + ".atom"] if
_f]
def author_rss_path(self, name, lang):
@@ -299,7 +309,7 @@ class RenderAuthors(Task):
link://author_rss/joe => /authors/joe.rss
"""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
- self.site.config['AUTHOR_PATH'], self.slugify_author_name(name) + ".xml"] if
+ self.site.config['AUTHOR_PATH'], self.slugify_author_name(name, lang) + ".xml"] if
_f]
def _add_extension(self, path, extension):
diff --git a/nikola/plugins/task/bundles.py b/nikola/plugins/task/bundles.py
index e709133..b33d8e0 100644
--- a/nikola/plugins/task/bundles.py
+++ b/nikola/plugins/task/bundles.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/copy_assets.py b/nikola/plugins/task/copy_assets.py
index 2cab71a..4ed7414 100644
--- a/nikola/plugins/task/copy_assets.py
+++ b/nikola/plugins/task/copy_assets.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/copy_files.py b/nikola/plugins/task/copy_files.py
index 0488011..6f6cfb8 100644
--- a/nikola/plugins/task/copy_files.py
+++ b/nikola/plugins/task/copy_files.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/galleries.py b/nikola/plugins/task/galleries.py
index d3f1db7..edfd33d 100644
--- a/nikola/plugins/task/galleries.py
+++ b/nikola/plugins/task/galleries.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -33,7 +33,6 @@ import io
import json
import mimetypes
import os
-import sys
try:
from urlparse import urljoin
except ImportError:
@@ -86,6 +85,8 @@ class Galleries(Task, ImageProcessor):
'tzinfo': site.tzinfo,
'comments_in_galleries': site.config['COMMENTS_IN_GALLERIES'],
'generate_rss': site.config['GENERATE_RSS'],
+ 'preserve_exif_data': site.config['PRESERVE_EXIF_DATA'],
+ 'exif_whitelist': site.config['EXIF_WHITELIST'],
}
# Verify that no folder in GALLERY_FOLDERS appears twice
@@ -93,8 +94,8 @@ class Galleries(Task, ImageProcessor):
for source, dest in self.kw['gallery_folders'].items():
if source in appearing_paths or dest in appearing_paths:
problem = source if source in appearing_paths else dest
- utils.LOGGER.error("The gallery input or output folder '{0}' appears in more than one entry in GALLERY_FOLDERS, exiting.".format(problem))
- sys.exit(1)
+ utils.LOGGER.error("The gallery input or output folder '{0}' appears in more than one entry in GALLERY_FOLDERS, ignoring.".format(problem))
+ continue
appearing_paths.add(source)
appearing_paths.add(dest)
@@ -115,10 +116,11 @@ class Galleries(Task, ImageProcessor):
if len(candidates) == 1:
return candidates[0]
self.logger.error("Gallery name '{0}' is not unique! Possible output paths: {1}".format(name, candidates))
+ raise RuntimeError("Gallery name '{0}' is not unique! Possible output paths: {1}".format(name, candidates))
else:
self.logger.error("Unknown gallery '{0}'!".format(name))
self.logger.info("Known galleries: " + str(list(self.proper_gallery_links.keys())))
- sys.exit(1)
+ raise RuntimeError("Unknown gallery '{0}'!".format(name))
def gallery_path(self, name, lang):
"""Link to an image gallery's path.
@@ -173,6 +175,7 @@ class Galleries(Task, ImageProcessor):
for k, v in self.site.GLOBAL_CONTEXT['template_hooks'].items():
self.kw['||template_hooks|{0}||'.format(k)] = v._items
+ self.site.scan_posts()
yield self.group_task()
template_name = "gallery.tmpl"
@@ -194,13 +197,6 @@ class Galleries(Task, ImageProcessor):
# Create image list, filter exclusions
image_list = self.get_image_list(gallery)
- # Sort as needed
- # Sort by date
- if self.kw['sort_by_date']:
- image_list.sort(key=lambda a: self.image_date(a))
- else: # Sort by name
- image_list.sort()
-
# Create thumbnails and large images in destination
for image in image_list:
for task in self.create_target_images(image, input_folder):
@@ -211,8 +207,6 @@ class Galleries(Task, ImageProcessor):
for task in self.remove_excluded_image(image, input_folder):
yield task
- crumbs = utils.get_crumbs(gallery, index_folder=self)
-
for lang in self.kw['translations']:
# save navigation links as dependencies
self.kw['navigation_links|{0}'.format(lang)] = self.kw['global_context']['navigation_links'](lang)
@@ -242,7 +236,7 @@ class Galleries(Task, ImageProcessor):
img_titles = []
for fn in image_name_list:
name_without_ext = os.path.splitext(os.path.basename(fn))[0]
- img_titles.append(utils.unslugify(name_without_ext))
+ img_titles.append(utils.unslugify(name_without_ext, lang))
else:
img_titles = [''] * len(image_name_list)
@@ -266,7 +260,7 @@ class Galleries(Task, ImageProcessor):
context["folders"] = natsort.natsorted(
folders, alg=natsort.ns.F | natsort.ns.IC)
- context["crumbs"] = crumbs
+ context["crumbs"] = utils.get_crumbs(gallery, index_folder=self, lang=lang)
context["permalink"] = self.site.link("gallery", gallery, lang)
context["enable_comments"] = self.kw['comments_in_galleries']
context["thumbnail_size"] = self.kw["thumbnail_size"]
@@ -423,6 +417,8 @@ class Galleries(Task, ImageProcessor):
# may break)
if post.title == 'index':
post.title = os.path.split(gallery)[1]
+ # Register the post (via #2417)
+ self.site.post_per_input_file[index_path] = post
else:
post = None
return post
@@ -482,7 +478,8 @@ class Galleries(Task, ImageProcessor):
'targets': [thumb_path],
'actions': [
(self.resize_image,
- (img, thumb_path, self.kw['thumbnail_size']))
+ (img, thumb_path, self.kw['thumbnail_size'], False, self.kw['preserve_exif_data'],
+ self.kw['exif_whitelist']))
],
'clean': True,
'uptodate': [utils.config_changed({
@@ -497,7 +494,8 @@ class Galleries(Task, ImageProcessor):
'targets': [orig_dest_path],
'actions': [
(self.resize_image,
- (img, orig_dest_path, self.kw['max_image_size']))
+ (img, orig_dest_path, self.kw['max_image_size'], False, self.kw['preserve_exif_data'],
+ self.kw['exif_whitelist']))
],
'clean': True,
'uptodate': [utils.config_changed({
@@ -558,6 +556,18 @@ class Galleries(Task, ImageProcessor):
url = '/'.join(os.path.relpath(p, os.path.dirname(output_name) + os.sep).split(os.sep))
return url
+ all_data = list(zip(img_list, thumbs, img_titles))
+
+ if self.kw['sort_by_date']:
+ all_data.sort(key=lambda a: self.image_date(a[0]))
+ else: # Sort by name
+ all_data.sort(key=lambda a: a[0])
+
+ if all_data:
+ img_list, thumbs, img_titles = zip(*all_data)
+ else:
+ img_list, thumbs, img_titles = [], [], []
+
photo_array = []
for img, thumb, title in zip(img_list, thumbs, img_titles):
w, h = _image_size_cache.get(thumb, (None, None))
@@ -591,6 +601,18 @@ class Galleries(Task, ImageProcessor):
def make_url(url):
return urljoin(self.site.config['BASE_URL'], url.lstrip('/'))
+ all_data = list(zip(img_list, dest_img_list, img_titles))
+
+ if self.kw['sort_by_date']:
+ all_data.sort(key=lambda a: self.image_date(a[0]))
+ else: # Sort by name
+ all_data.sort(key=lambda a: a[0])
+
+ if all_data:
+ img_list, dest_img_list, img_titles = zip(*all_data)
+ else:
+ img_list, dest_img_list, img_titles = [], [], []
+
items = []
for img, srcimg, title in list(zip(dest_img_list, img_list, img_titles))[:self.kw["feed_length"]]:
img_size = os.stat(
diff --git a/nikola/plugins/task/gzip.py b/nikola/plugins/task/gzip.py
index aaa213d..79a11dc 100644
--- a/nikola/plugins/task/gzip.py
+++ b/nikola/plugins/task/gzip.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/indexes.py b/nikola/plugins/task/indexes.py
index 2ab97fa..8ecd1de 100644
--- a/nikola/plugins/task/indexes.py
+++ b/nikola/plugins/task/indexes.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -36,6 +36,7 @@ except ImportError:
from nikola.plugin_categories import Task
from nikola import utils
+from nikola.nikola import _enclosure
class Indexes(Task):
@@ -51,6 +52,7 @@ class Indexes(Task):
site.register_path_handler('index_atom', self.index_atom_path)
site.register_path_handler('section_index', self.index_section_path)
site.register_path_handler('section_index_atom', self.index_section_atom_path)
+ site.register_path_handler('section_index_rss', self.index_section_rss_path)
return super(Indexes, self).set_site(site)
def _get_filtered_posts(self, lang, show_untranslated_posts):
@@ -77,6 +79,10 @@ class Indexes(Task):
"translations": self.site.config['TRANSLATIONS'],
"messages": self.site.MESSAGES,
"output_folder": self.site.config['OUTPUT_FOLDER'],
+ "feed_length": self.site.config['FEED_LENGTH'],
+ "feed_links_append_query": self.site.config["FEED_LINKS_APPEND_QUERY"],
+ "feed_teasers": self.site.config["FEED_TEASERS"],
+ "feed_plain": self.site.config["FEED_PLAIN"],
"filters": self.site.config['FILTERS'],
"index_file": self.site.config['INDEX_FILE'],
"show_untranslated_posts": self.site.config['SHOW_UNTRANSLATED_POSTS'],
@@ -85,6 +91,7 @@ class Indexes(Task):
"strip_indexes": self.site.config['STRIP_INDEXES'],
"blog_title": self.site.config["BLOG_TITLE"],
"generate_atom": self.site.config["GENERATE_ATOM"],
+ "site_url": self.site.config["SITE_URL"],
}
template_name = "index.tmpl"
@@ -110,8 +117,6 @@ class Indexes(Task):
yield self.site.generic_index_renderer(lang, filtered_posts, indexes_title, template_name, context, kw, 'render_indexes', page_link, page_path)
if self.site.config['POSTS_SECTIONS']:
-
- kw["posts_section_are_indexes"] = self.site.config['POSTS_SECTION_ARE_INDEXES']
index_len = len(kw['index_file'])
groups = defaultdict(list)
@@ -145,16 +150,16 @@ class Indexes(Task):
context["pagekind"] = ["section_page"]
context["description"] = self.site.config['POSTS_SECTION_DESCRIPTIONS'](lang)[section_slug] if section_slug in self.site.config['POSTS_SECTION_DESCRIPTIONS'](lang) else ""
- if kw["posts_section_are_indexes"]:
+ if self.site.config["POSTS_SECTION_ARE_INDEXES"]:
context["pagekind"].append("index")
- kw["posts_section_title"] = self.site.config['POSTS_SECTION_TITLE'](lang)
+ posts_section_title = self.site.config['POSTS_SECTION_TITLE'](lang)
section_title = None
- if type(kw["posts_section_title"]) is dict:
- if section_slug in kw["posts_section_title"]:
- section_title = kw["posts_section_title"][section_slug]
- elif type(kw["posts_section_title"]) is str:
- section_title = kw["posts_section_title"]
+ if type(posts_section_title) is dict:
+ if section_slug in posts_section_title:
+ section_title = posts_section_title[section_slug]
+ elif type(posts_section_title) is str:
+ section_title = posts_section_title
if not section_title:
section_title = post_list[0].section_name(lang)
section_title = section_title.format(name=post_list[0].section_name(lang))
@@ -168,7 +173,37 @@ class Indexes(Task):
task['basename'] = self.name
yield task
- if not self.site.config["STORY_INDEX"]:
+ # RSS feed for section
+ deps = []
+ deps_uptodate = []
+ if kw["show_untranslated_posts"]:
+ posts = post_list[:kw['feed_length']]
+ else:
+ posts = [x for x in post_list if x.is_translation_available(lang)][:kw['feed_length']]
+ for post in posts:
+ deps += post.deps(lang)
+ deps_uptodate += post.deps_uptodate(lang)
+
+ feed_url = urljoin(self.site.config['BASE_URL'], self.site.link('section_index_rss', section_slug, lang).lstrip('/'))
+ output_name = os.path.join(kw['output_folder'], self.site.path('section_index_rss', section_slug, lang).lstrip(os.sep))
+ task = {
+ 'basename': self.name,
+ 'name': os.path.normpath(output_name),
+ 'file_dep': deps,
+ 'targets': [output_name],
+ 'actions': [(utils.generic_rss_renderer,
+ (lang, kw["blog_title"](lang), kw["site_url"],
+ context["description"], posts, output_name,
+ kw["feed_teasers"], kw["feed_plain"], kw['feed_length'], feed_url,
+ _enclosure, kw["feed_links_append_query"]))],
+
+ 'task_dep': ['render_posts'],
+ 'clean': True,
+ 'uptodate': [utils.config_changed(kw, 'nikola.plugins.indexes')] + deps_uptodate,
+ }
+ yield task
+
+ if not self.site.config["PAGE_INDEX"]:
return
kw = {
"translations": self.site.config['TRANSLATIONS'],
@@ -207,7 +242,7 @@ class Indexes(Task):
for post in post_list:
# If there is an index.html pending to be created from
- # a story, do not generate the STORY_INDEX
+ # a page, do not generate the PAGE_INDEX
if post.destination_path(lang) == short_destination:
should_render = False
else:
@@ -252,7 +287,7 @@ class Indexes(Task):
self.site,
extension=extension)
- def index_section_path(self, name, lang, is_feed=False):
+ def index_section_path(self, name, lang, is_feed=False, is_rss=False):
"""Link to the index for a section.
Example:
@@ -264,6 +299,8 @@ class Indexes(Task):
if is_feed:
extension = ".atom"
index_file = os.path.splitext(self.site.config['INDEX_FILE'])[0] + extension
+ elif is_rss:
+ index_file = 'rss.xml'
else:
index_file = self.site.config['INDEX_FILE']
if name in self.number_of_pages_section[lang]:
@@ -298,3 +335,12 @@ class Indexes(Task):
link://section_index_atom/cars => /cars/index.atom
"""
return self.index_section_path(name, lang, is_feed=True)
+
+ def index_section_rss_path(self, name, lang):
+ """Link to the RSS feed for a section.
+
+ Example:
+
+ link://section_index_rss/cars => /cars/rss.xml
+ """
+ return self.index_section_path(name, lang, is_rss=True)
diff --git a/nikola/plugins/task/listings.py b/nikola/plugins/task/listings.py
index 891f361..e694aa5 100644
--- a/nikola/plugins/task/listings.py
+++ b/nikola/plugins/task/listings.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -29,12 +29,11 @@
from __future__ import unicode_literals, print_function
from collections import defaultdict
-import sys
import os
import lxml.html
from pygments import highlight
-from pygments.lexers import get_lexer_for_filename, TextLexer
+from pygments.lexers import get_lexer_for_filename, guess_lexer, TextLexer
import natsort
from nikola.plugin_categories import Task
@@ -55,6 +54,7 @@ class Listings(Task):
def set_site(self, site):
"""Set Nikola site."""
site.register_path_handler('listing', self.listing_path)
+ site.register_path_handler('listing_source', self.listing_source_path)
# We need to prepare some things for the listings path handler to work.
@@ -73,7 +73,7 @@ class Listings(Task):
if source in appearing_paths or dest in appearing_paths:
problem = source if source in appearing_paths else dest
utils.LOGGER.error("The listings input or output folder '{0}' appears in more than one entry in LISTINGS_FOLDERS, exiting.".format(problem))
- sys.exit(1)
+ continue
appearing_paths.add(source)
appearing_paths.add(dest)
@@ -127,7 +127,11 @@ class Listings(Task):
try:
lexer = get_lexer_for_filename(in_name)
except:
- lexer = TextLexer()
+ try:
+ lexer = guess_lexer(fd.read())
+ except:
+ lexer = TextLexer()
+ fd.seek(0)
code = highlight(fd.read(), lexer, utils.NikolaPygmentsHTML(in_name))
title = os.path.basename(in_name)
else:
@@ -145,7 +149,7 @@ class Listings(Task):
os.path.join(
self.kw['output_folder'],
output_folder))))
- if self.site.config['COPY_SOURCES'] and in_name:
+ if in_name:
source_link = permalink[:-5] # remove '.html'
else:
source_link = None
@@ -238,19 +242,35 @@ class Listings(Task):
'uptodate': [utils.config_changed(uptodate, 'nikola.plugins.task.listings:source')],
'clean': True,
}, self.kw["filters"])
- if self.site.config['COPY_SOURCES']:
- rel_name = os.path.join(rel_path, f)
- rel_output_name = os.path.join(output_folder, rel_path, f)
- self.register_output_name(input_folder, rel_name, rel_output_name)
- out_name = os.path.join(self.kw['output_folder'], rel_output_name)
- yield utils.apply_filters({
- 'basename': self.name,
- 'name': out_name,
- 'file_dep': [in_name],
- 'targets': [out_name],
- 'actions': [(utils.copy_file, [in_name, out_name])],
- 'clean': True,
- }, self.kw["filters"])
+
+ rel_name = os.path.join(rel_path, f)
+ rel_output_name = os.path.join(output_folder, rel_path, f)
+ self.register_output_name(input_folder, rel_name, rel_output_name)
+ out_name = os.path.join(self.kw['output_folder'], rel_output_name)
+ yield utils.apply_filters({
+ 'basename': self.name,
+ 'name': out_name,
+ 'file_dep': [in_name],
+ 'targets': [out_name],
+ 'actions': [(utils.copy_file, [in_name, out_name])],
+ 'clean': True,
+ }, self.kw["filters"])
+
+ def listing_source_path(self, name, lang):
+ """A link to the source code for a listing.
+
+ It will try to use the file name if it's not ambiguous, or the file path.
+
+ Example:
+
+ link://listing_source/hello.py => /listings/tutorial/hello.py
+
+ link://listing_source/tutorial/hello.py => /listings/tutorial/hello.py
+ """
+ result = self.listing_path(name, lang)
+ if result[-1].endswith('.html'):
+ result[-1] = result[-1][:-5]
+ return result
def listing_path(self, namep, lang):
"""A link to a listing.
@@ -275,14 +295,14 @@ class Listings(Task):
# ambiguities.
if len(self.improper_input_file_mapping[name]) > 1:
utils.LOGGER.error("Using non-unique listing name '{0}', which maps to more than one listing name ({1})!".format(name, str(self.improper_input_file_mapping[name])))
- sys.exit(1)
+ return ["ERROR"]
if len(self.site.config['LISTINGS_FOLDERS']) > 1:
utils.LOGGER.notice("Using listings names in site.link() without input directory prefix while configuration's LISTINGS_FOLDERS has more than one entry.")
name = list(self.improper_input_file_mapping[name])[0]
break
else:
utils.LOGGER.error("Unknown listing name {0}!".format(namep))
- sys.exit(1)
+ return ["ERROR"]
if not name.endswith(os.sep + self.site.config["INDEX_FILE"]):
name += '.html'
path_parts = name.split(os.sep)
diff --git a/nikola/plugins/task/pages.py b/nikola/plugins/task/pages.py
index 8d41035..7d8287b 100644
--- a/nikola/plugins/task/pages.py
+++ b/nikola/plugins/task/pages.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -54,7 +54,7 @@ class RenderPages(Task):
if post.is_post:
context = {'pagekind': ['post_page']}
else:
- context = {'pagekind': ['story_page']}
+ context = {'pagekind': ['story_page', 'page_page']}
for task in self.site.generic_page_renderer(lang, post, kw["filters"], context):
task['uptodate'] = task['uptodate'] + [config_changed(kw, 'nikola.plugins.task.pages')]
task['basename'] = self.name
diff --git a/nikola/plugins/task/posts.py b/nikola/plugins/task/posts.py
index 8735beb..fe10c5f 100644
--- a/nikola/plugins/task/posts.py
+++ b/nikola/plugins/task/posts.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/py3_switch.py b/nikola/plugins/task/py3_switch.py
index 930c593..2ff4e2d 100644
--- a/nikola/plugins/task/py3_switch.py
+++ b/nikola/plugins/task/py3_switch.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -51,7 +51,7 @@ PY2_BARBS = [
"Python 2 is the safety blanket of languages. Be a big kid and switch to Python 3",
"Python 2 is old and busted. Python 3 is the new hotness.",
"Nice unicode you have there, would be a shame something happened to it.. switch to python 3!.",
- "Don’t get in the way of progress! Upgrade to Python 3 and save a developer’s mind today!",
+ "Don't get in the way of progress! Upgrade to Python 3 and save a developer's mind today!",
"Winners don't use Python 2 -- Signed: The FBI",
"Python 2? What year is it?",
"I just wanna tell you how I'm feeling\n"
diff --git a/nikola/plugins/task/redirect.py b/nikola/plugins/task/redirect.py
index 2d4eba4..b170b81 100644
--- a/nikola/plugins/task/redirect.py
+++ b/nikola/plugins/task/redirect.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -50,7 +50,7 @@ class Redirect(Task):
yield self.group_task()
if kw['redirections']:
for src, dst in kw["redirections"]:
- src_path = os.path.join(kw["output_folder"], src)
+ src_path = os.path.join(kw["output_folder"], src.lstrip('/'))
yield utils.apply_filters({
'basename': self.name,
'name': src_path,
diff --git a/nikola/plugins/task/robots.py b/nikola/plugins/task/robots.py
index 7c7f5df..8537fc8 100644
--- a/nikola/plugins/task/robots.py
+++ b/nikola/plugins/task/robots.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/rss.py b/nikola/plugins/task/rss.py
index be57f5c..780559b 100644
--- a/nikola/plugins/task/rss.py
+++ b/nikola/plugins/task/rss.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -34,6 +34,7 @@ except ImportError:
from urllib.parse import urljoin # NOQA
from nikola import utils
+from nikola.nikola import _enclosure
from nikola.plugin_categories import Task
@@ -97,7 +98,7 @@ class GenerateRSS(Task):
(lang, kw["blog_title"](lang), kw["site_url"],
kw["blog_description"](lang), posts, output_name,
kw["feed_teasers"], kw["feed_plain"], kw['feed_length'], feed_url,
- None, kw["feed_links_append_query"]))],
+ _enclosure, kw["feed_links_append_query"]))],
'task_dep': ['render_posts'],
'clean': True,
diff --git a/nikola/plugins/task/scale_images.py b/nikola/plugins/task/scale_images.py
index e55dc6c..2b483ae 100644
--- a/nikola/plugins/task/scale_images.py
+++ b/nikola/plugins/task/scale_images.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2014-2015 Pelle Nilsson and others.
+# Copyright © 2014-2016 Pelle Nilsson and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -71,8 +71,8 @@ class ScaleImage(Task, ImageProcessor):
def process_image(self, src, dst, thumb):
"""Resize an image."""
- self.resize_image(src, dst, self.kw['max_image_size'], False)
- self.resize_image(src, thumb, self.kw['image_thumbnail_size'], False)
+ self.resize_image(src, dst, self.kw['max_image_size'], False, preserve_exif_data=self.kw['preserve_exif_data'], exif_whitelist=self.kw['exif_whitelist'])
+ self.resize_image(src, thumb, self.kw['image_thumbnail_size'], False, preserve_exif_data=self.kw['preserve_exif_data'], exif_whitelist=self.kw['exif_whitelist'])
def gen_tasks(self):
"""Copy static files into the output folder."""
@@ -82,6 +82,8 @@ class ScaleImage(Task, ImageProcessor):
'image_folders': self.site.config['IMAGE_FOLDERS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
'filters': self.site.config['FILTERS'],
+ 'preserve_exif_data': self.site.config['PRESERVE_EXIF_DATA'],
+ 'exif_whitelist': self.site.config['EXIF_WHITELIST'],
}
self.image_ext_list = self.image_ext_list_builtin
diff --git a/nikola/plugins/task/sitemap/__init__.py b/nikola/plugins/task/sitemap/__init__.py
index 90acdd3..64fcb45 100644
--- a/nikola/plugins/task/sitemap/__init__.py
+++ b/nikola/plugins/task/sitemap/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -158,7 +158,7 @@ class Sitemap(LateTask):
continue
alternates = []
if post:
- for lang in kw['translations']:
+ for lang in post.translated_to:
alt_url = post.permalink(lang=lang, absolute=True)
if encodelink(loc) == alt_url:
continue
@@ -215,7 +215,7 @@ class Sitemap(LateTask):
loc = urljoin(base_url, base_path + path)
alternates = []
if post:
- for lang in kw['translations']:
+ for lang in post.translated_to:
alt_url = post.permalink(lang=lang, absolute=True)
if encodelink(loc) == alt_url:
continue
diff --git a/nikola/plugins/task/sources.py b/nikola/plugins/task/sources.py
index f782ad4..0d77aba 100644
--- a/nikola/plugins/task/sources.py
+++ b/nikola/plugins/task/sources.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
diff --git a/nikola/plugins/task/tags.py b/nikola/plugins/task/tags.py
index 6d9d495..8b4683e 100644
--- a/nikola/plugins/task/tags.py
+++ b/nikola/plugins/task/tags.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2015 Roberto Alsina and others.
+# Copyright © 2012-2016 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -29,7 +29,6 @@
from __future__ import unicode_literals
import json
import os
-import sys
import natsort
try:
from urlparse import urljoin
@@ -38,6 +37,7 @@ except ImportError:
from nikola.plugin_categories import Task
from nikola import utils
+from nikola.nikola import _enclosure
class RenderTags(Task):
@@ -97,31 +97,31 @@ class RenderTags(Task):
if not self.site.posts_per_tag and not self.site.posts_per_category:
return
- if kw['category_path'] == kw['tag_path']:
- tags = {self.slugify_tag_name(tag): tag for tag in self.site.posts_per_tag.keys()}
- cats = {tuple(self.slugify_category_name(category)): category for category in self.site.posts_per_category.keys()}
- categories = {k[0]: v for k, v in cats.items() if len(k) == 1}
- intersect = set(tags.keys()) & set(categories.keys())
- if len(intersect) > 0:
- for slug in intersect:
- utils.LOGGER.error("Category '{0}' and tag '{1}' both have the same slug '{2}'!".format('/'.join(categories[slug]), tags[slug], slug))
- sys.exit(1)
-
- # Test for category slug clashes
- categories = {}
- for category in self.site.posts_per_category.keys():
- slug = tuple(self.slugify_category_name(category))
- for part in slug:
- if len(part) == 0:
- utils.LOGGER.error("Category '{0}' yields invalid slug '{1}'!".format(category, '/'.join(slug)))
- sys.exit(1)
- if slug in categories:
- other_category = categories[slug]
- utils.LOGGER.error('You have categories that are too similar: {0} and {1}'.format(category, other_category))
- utils.LOGGER.error('Category {0} is used in: {1}'.format(category, ', '.join([p.source_path for p in self.site.posts_per_category[category]])))
- utils.LOGGER.error('Category {0} is used in: {1}'.format(other_category, ', '.join([p.source_path for p in self.site.posts_per_category[other_category]])))
- sys.exit(1)
- categories[slug] = category
+ for lang in kw["translations"]:
+ if kw['category_path'][lang] == kw['tag_path'][lang]:
+ tags = {self.slugify_tag_name(tag, lang): tag for tag in self.site.tags_per_language[lang]}
+ cats = {tuple(self.slugify_category_name(category, lang)): category for category in self.site.posts_per_category.keys()}
+ categories = {k[0]: v for k, v in cats.items() if len(k) == 1}
+ intersect = set(tags.keys()) & set(categories.keys())
+ if len(intersect) > 0:
+ for slug in intersect:
+ utils.LOGGER.error("Category '{0}' and tag '{1}' both have the same slug '{2}' for language {3}!".format('/'.join(categories[slug]), tags[slug], slug, lang))
+
+ # Test for category slug clashes
+ categories = {}
+ for category in self.site.posts_per_category.keys():
+ slug = tuple(self.slugify_category_name(category, lang))
+ for part in slug:
+ if len(part) == 0:
+ utils.LOGGER.error("Category '{0}' yields invalid slug '{1}'!".format(category, '/'.join(slug)))
+ raise RuntimeError("Category '{0}' yields invalid slug '{1}'!".format(category, '/'.join(slug)))
+ if slug in categories:
+ other_category = categories[slug]
+ utils.LOGGER.error('You have categories that are too similar: {0} and {1} (language {2})'.format(category, other_category, lang))
+ utils.LOGGER.error('Category {0} is used in: {1}'.format(category, ', '.join([p.source_path for p in self.site.posts_per_category[category]])))
+ utils.LOGGER.error('Category {0} is used in: {1}'.format(other_category, ', '.join([p.source_path for p in self.site.posts_per_category[other_category]])))
+ raise RuntimeError("Category '{0}' yields invalid slug '{1}'!".format(category, '/'.join(slug)))
+ categories[slug] = category
tag_list = list(self.site.posts_per_tag.items())
cat_list = list(self.site.posts_per_category.items())
@@ -185,7 +185,7 @@ class RenderTags(Task):
task['clean'] = True
yield utils.apply_filters(task, kw['filters'])
- def _create_tags_page(self, kw, include_tags=True, include_categories=True):
+ def _create_tags_page(self, kw, lang, include_tags=True, include_categories=True):
"""Create a global "all your tags/categories" page for each language."""
categories = [cat.category_name for cat in self.site.category_hierarchy]
has_categories = (categories != []) and include_categories
@@ -193,59 +193,59 @@ class RenderTags(Task):
kw = kw.copy()
if include_categories:
kw['categories'] = categories
- for lang in kw["translations"]:
- tags = natsort.natsorted([tag for tag in self.site.tags_per_language[lang]
- if len(self.site.posts_per_tag[tag]) >= kw["taglist_minimum_post_count"]],
- alg=natsort.ns.F | natsort.ns.IC)
- has_tags = (tags != []) and include_tags
- if include_tags:
- kw['tags'] = tags
- output_name = os.path.join(
- kw['output_folder'], self.site.path('tag_index' if has_tags else 'category_index', None, lang))
- context = {}
- if has_categories and has_tags:
- context["title"] = kw["messages"][lang]["Tags and Categories"]
- elif has_categories:
- context["title"] = kw["messages"][lang]["Categories"]
- else:
- context["title"] = kw["messages"][lang]["Tags"]
- if has_tags:
- context["items"] = [(tag, self.site.link("tag", tag, lang)) for tag
- in tags]
- else:
- context["items"] = None
- if has_categories:
- context["cat_items"] = [(tag, self.site.link("category", tag, lang)) for tag
- in categories]
- context['cat_hierarchy'] = [(node.name, node.category_name, node.category_path,
- self.site.link("category", node.category_name),
- node.indent_levels, node.indent_change_before,
- node.indent_change_after)
- for node in self.site.category_hierarchy]
- else:
- context["cat_items"] = None
- context["permalink"] = self.site.link("tag_index" if has_tags else "category_index", None, lang)
- context["description"] = context["title"]
- context["pagekind"] = ["list", "tags_page"]
- task = self.site.generic_post_list_renderer(
- lang,
- [],
- output_name,
- template_name,
- kw['filters'],
- context,
- )
- task['uptodate'] = task['uptodate'] + [utils.config_changed(kw, 'nikola.plugins.task.tags:page')]
- task['basename'] = str(self.name)
- yield task
+ tags = natsort.natsorted([tag for tag in self.site.tags_per_language[lang]
+ if len(self.site.posts_per_tag[tag]) >= kw["taglist_minimum_post_count"]],
+ alg=natsort.ns.F | natsort.ns.IC)
+ has_tags = (tags != []) and include_tags
+ if include_tags:
+ kw['tags'] = tags
+ output_name = os.path.join(
+ kw['output_folder'], self.site.path('tag_index' if has_tags else 'category_index', None, lang))
+ context = {}
+ if has_categories and has_tags:
+ context["title"] = kw["messages"][lang]["Tags and Categories"]
+ elif has_categories:
+ context["title"] = kw["messages"][lang]["Categories"]
+ else:
+ context["title"] = kw["messages"][lang]["Tags"]
+ if has_tags:
+ context["items"] = [(tag, self.site.link("tag", tag, lang)) for tag
+ in tags]
+ else:
+ context["items"] = None
+ if has_categories:
+ context["cat_items"] = [(tag, self.site.link("category", tag, lang)) for tag
+ in categories]
+ context['cat_hierarchy'] = [(node.name, node.category_name, node.category_path,
+ self.site.link("category", node.category_name),
+ node.indent_levels, node.indent_change_before,
+ node.indent_change_after)
+ for node in self.site.category_hierarchy]
+ else:
+ context["cat_items"] = None
+ context["permalink"] = self.site.link("tag_index" if has_tags else "category_index", None, lang)
+ context["description"] = context["title"]
+ context["pagekind"] = ["list", "tags_page"]
+ task = self.site.generic_post_list_renderer(
+ lang,
+ [],
+ output_name,
+ template_name,
+ kw['filters'],
+ context,
+ )
+ task['uptodate'] = task['uptodate'] + [utils.config_changed(kw, 'nikola.plugins.task.tags:page')]
+ task['basename'] = str(self.name)
+ yield task
def list_tags_page(self, kw):
"""Create a global "all your tags/categories" page for each language."""
- if self.site.config['TAG_PATH'] == self.site.config['CATEGORY_PATH']:
- yield self._create_tags_page(kw, True, True)
- else:
- yield self._create_tags_page(kw, False, True)
- yield self._create_tags_page(kw, True, False)
+ for lang in kw["translations"]:
+ if self.site.config['TAG_PATH'][lang] == self.site.config['CATEGORY_PATH'][lang]:
+ yield self._create_tags_page(kw, lang, True, True)
+ else:
+ yield self._create_tags_page(kw, lang, False, True)
+ yield self._create_tags_page(kw, lang, True, False)
def _get_title(self, tag, is_category):
if is_category:
@@ -253,9 +253,9 @@ class RenderTags(Task):
else:
return tag
- def _get_indexes_title(self, tag, is_category, lang, messages):
+ def _get_indexes_title(self, tag, nice_tag, is_category, lang, messages):
titles = self.site.config['CATEGORY_PAGES_TITLES'] if is_category else self.site.config['TAG_PAGES_TITLES']
- return titles[lang][tag] if lang in titles and tag in titles[lang] else messages[lang]["Posts about %s"] % tag
+ return titles[lang][tag] if lang in titles and tag in titles[lang] else messages[lang]["Posts about %s"] % nice_tag
def _get_description(self, tag, is_category, lang):
descriptions = self.site.config['CATEGORY_PAGES_DESCRIPTIONS'] if is_category else self.site.config['TAG_PAGES_DESCRIPTIONS']
@@ -290,7 +290,7 @@ class RenderTags(Task):
context_source["category"] = tag
context_source["category_path"] = self.site.parse_category_name(tag)
context_source["tag"] = title
- indexes_title = self._get_indexes_title(title, is_category, lang, kw["messages"])
+ indexes_title = self._get_indexes_title(tag, title, is_category, lang, kw["messages"])
context_source["description"] = self._get_description(tag, is_category, lang)
if is_category:
context_source["subcategories"] = self._get_subcategories(tag)
@@ -312,7 +312,7 @@ class RenderTags(Task):
context["category"] = tag
context["category_path"] = self.site.parse_category_name(tag)
context["tag"] = title
- context["title"] = self._get_indexes_title(title, is_category, lang, kw["messages"])
+ context["title"] = self._get_indexes_title(tag, title, is_category, lang, kw["messages"])
context["posts"] = post_list
context["permalink"] = self.site.link(kind, tag, lang)
context["kind"] = kind
@@ -379,17 +379,20 @@ class RenderTags(Task):
(lang, "{0} ({1})".format(kw["blog_title"](lang), self._get_title(tag, is_category)),
kw["site_url"], None, post_list,
output_name, kw["feed_teasers"], kw["feed_plain"], kw['feed_length'],
- feed_url, None, kw["feed_link_append_query"]))],
+ feed_url, _enclosure, kw["feed_link_append_query"]))],
'clean': True,
'uptodate': [utils.config_changed(kw, 'nikola.plugins.task.tags:rss')] + deps_uptodate,
'task_dep': ['render_posts'],
}
return utils.apply_filters(task, kw['filters'])
- def slugify_tag_name(self, name):
+ def slugify_tag_name(self, name, lang):
"""Slugify a tag name."""
+ if lang is None: # TODO: remove in v8
+ utils.LOGGER.warn("RenderTags.slugify_tag_name() called without language!")
+ lang = ''
if self.site.config['SLUG_TAG_PATH']:
- name = utils.slugify(name)
+ name = utils.slugify(name, lang)
return name
def tag_index_path(self, name, lang):
@@ -430,13 +433,13 @@ class RenderTags(Task):
return [_f for _f in [
self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'][lang],
- self.slugify_tag_name(name),
+ self.slugify_tag_name(name, lang),
self.site.config['INDEX_FILE']] if _f]
else:
return [_f for _f in [
self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'][lang],
- self.slugify_tag_name(name) + ".html"] if _f]
+ self.slugify_tag_name(name, lang) + ".html"] if _f]
def tag_atom_path(self, name, lang):
"""A link to a tag's Atom feed.
@@ -446,7 +449,7 @@ class RenderTags(Task):
link://tag_atom/cats => /tags/cats.atom
"""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
- self.site.config['TAG_PATH'][lang], self.slugify_tag_name(name) + ".atom"] if
+ self.site.config['TAG_PATH'][lang], self.slugify_tag_name(name, lang) + ".atom"] if
_f]
def tag_rss_path(self, name, lang):
@@ -457,15 +460,18 @@ class RenderTags(Task):
link://tag_rss/cats => /tags/cats.xml
"""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
- self.site.config['TAG_PATH'][lang], self.slugify_tag_name(name) + ".xml"] if
+ self.site.config['TAG_PATH'][lang], self.slugify_tag_name(name, lang) + ".xml"] if
_f]
- def slugify_category_name(self, name):
+ def slugify_category_name(self, name, lang):
"""Slugify a category name."""
+ if lang is None: # TODO: remove in v8
+ utils.LOGGER.warn("RenderTags.slugify_category_name() called without language!")
+ lang = ''
path = self.site.parse_category_name(name)
if self.site.config['CATEGORY_OUTPUT_FLAT_HIERARCHY']:
path = path[-1:] # only the leaf
- result = [self.slugify_tag_name(part) for part in path]
+ result = [self.slugify_tag_name(part, lang) for part in path]
result[0] = self.site.config['CATEGORY_PREFIX'] + result[0]
if not self.site.config['PRETTY_URLS']:
result = ['-'.join(result)]
@@ -485,11 +491,11 @@ class RenderTags(Task):
if self.site.config['PRETTY_URLS']:
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH'][lang]] if
- _f] + self.slugify_category_name(name) + [self.site.config['INDEX_FILE']]
+ _f] + self.slugify_category_name(name, lang) + [self.site.config['INDEX_FILE']]
else:
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH'][lang]] if
- _f] + self._add_extension(self.slugify_category_name(name), ".html")
+ _f] + self._add_extension(self.slugify_category_name(name, lang), ".html")
def category_atom_path(self, name, lang):
"""A link to a category's Atom feed.
@@ -500,7 +506,7 @@ class RenderTags(Task):
"""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH'][lang]] if
- _f] + self._add_extension(self.slugify_category_name(name), ".atom")
+ _f] + self._add_extension(self.slugify_category_name(name, lang), ".atom")
def category_rss_path(self, name, lang):
"""A link to a category's RSS feed.
@@ -511,4 +517,4 @@ class RenderTags(Task):
"""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH'][lang]] if
- _f] + self._add_extension(self.slugify_category_name(name), ".xml")
+ _f] + self._add_extension(self.slugify_category_name(name, lang), ".xml")