aboutsummaryrefslogtreecommitdiffstats
path: root/nikola/plugins/task/indexes.py
diff options
context:
space:
mode:
authorLibravatarDererk <dererk@satellogic.com>2016-11-15 14:18:53 -0300
committerLibravatarDererk <dererk@satellogic.com>2016-11-15 14:18:53 -0300
commit1ad5102b7ddd181bb9c632b124d3ea4c7db28be6 (patch)
tree73dda18465d0f4b8eb52d4482282a387c9f67c95 /nikola/plugins/task/indexes.py
parentb67294f76809a681ff73f209ed691a3e3f00563d (diff)
parentffb671c61a24a9086343b54bad080e145ff33fc5 (diff)
Merge tag 'upstream/7.8.1'
Upstream version 7.8.1 # gpg: Firmado el mar 15 nov 2016 14:18:48 ART # gpg: usando RSA clave A6C7B88B9583046A11C5403E0B00FB6CEBE2D002 # gpg: Firma correcta de "Ulises Vitulli <dererk@debian.org>" [absoluta] # gpg: alias "Dererk <dererk@torproject.org>" [absoluta] # gpg: alias "Ulises Vitulli <uvitulli@fi.uba.ar>" [absoluta] # gpg: alias "Ulises Vitulli <dererk@satellogic.com>" [absoluta]
Diffstat (limited to 'nikola/plugins/task/indexes.py')
-rw-r--r--nikola/plugins/task/indexes.py210
1 files changed, 194 insertions, 16 deletions
diff --git a/nikola/plugins/task/indexes.py b/nikola/plugins/task/indexes.py
index c02818e..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
@@ -29,23 +29,47 @@
from __future__ import unicode_literals
from collections import defaultdict
import os
+try:
+ from urlparse import urljoin
+except ImportError:
+ from urllib.parse import urljoin # NOQA
from nikola.plugin_categories import Task
from nikola import utils
+from nikola.nikola import _enclosure
class Indexes(Task):
-
"""Render the blog indexes."""
name = "render_indexes"
def set_site(self, site):
"""Set Nikola site."""
+ self.number_of_pages = dict()
+ self.number_of_pages_section = {lang: dict() for lang in site.config['TRANSLATIONS']}
site.register_path_handler('index', self.index_path)
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):
+ """Return a filtered list of all posts for the given language.
+
+ If show_untranslated_posts is True, will only include posts which
+ are translated to the given language. Otherwise, returns all posts.
+ """
+ if show_untranslated_posts:
+ return self.site.posts
+ else:
+ return [x for x in self.site.posts if x.is_translation_available(lang)]
+
+ def _compute_number_of_pages(self, filtered_posts, posts_count):
+ """Given a list of posts and the maximal number of posts per page, computes the number of pages needed."""
+ return min(1, (len(filtered_posts) + posts_count - 1) // posts_count)
+
def gen_tasks(self):
"""Render the blog indexes."""
self.site.scan_posts()
@@ -55,17 +79,22 @@ 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'],
"index_display_post_count": self.site.config['INDEX_DISPLAY_POST_COUNT'],
"indexes_title": self.site.config['INDEXES_TITLE'],
+ "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"
- posts = self.site.posts
- self.number_of_pages = dict()
for lang in kw["translations"]:
def page_link(i, displayed_i, num_pages, force_addition, extension=None):
feed = "_atom" if extension == ".atom" else ""
@@ -77,20 +106,104 @@ class Indexes(Task):
return utils.adjust_name_for_index_path(self.site.path("index" + feed, None, lang), i, displayed_i,
lang, self.site, force_addition, extension)
- if kw["show_untranslated_posts"]:
- filtered_posts = posts
- else:
- filtered_posts = [x for x in posts if x.is_translation_available(lang)]
+ filtered_posts = self._get_filtered_posts(lang, kw["show_untranslated_posts"])
indexes_title = kw['indexes_title'](lang) or kw['blog_title'](lang)
- self.number_of_pages[lang] = (len(filtered_posts) + kw['index_display_post_count'] - 1) // kw['index_display_post_count']
+ self.number_of_pages[lang] = self._compute_number_of_pages(filtered_posts, kw['index_display_post_count'])
context = {}
- context["pagekind"] = ["index"]
+ context["pagekind"] = ["main_index", "index"]
yield self.site.generic_index_renderer(lang, filtered_posts, indexes_title, template_name, context, kw, 'render_indexes', page_link, page_path)
- if not self.site.config["STORY_INDEX"]:
+ if self.site.config['POSTS_SECTIONS']:
+ index_len = len(kw['index_file'])
+
+ groups = defaultdict(list)
+ for p in filtered_posts:
+ groups[p.section_slug(lang)].append(p)
+
+ # don't build sections when there is only one, aka. default setups
+ if not len(groups.items()) > 1:
+ continue
+
+ for section_slug, post_list in groups.items():
+ self.number_of_pages_section[lang][section_slug] = self._compute_number_of_pages(post_list, kw['index_display_post_count'])
+
+ def cat_link(i, displayed_i, num_pages, force_addition, extension=None):
+ feed = "_atom" if extension == ".atom" else ""
+ return utils.adjust_name_for_index_link(self.site.link("section_index" + feed, section_slug, lang), i, displayed_i,
+ lang, self.site, force_addition, extension)
+
+ def cat_path(i, displayed_i, num_pages, force_addition, extension=None):
+ feed = "_atom" if extension == ".atom" else ""
+ return utils.adjust_name_for_index_path(self.site.path("section_index" + feed, section_slug, lang), i, displayed_i,
+ lang, self.site, force_addition, extension)
+
+ context = {}
+
+ short_destination = os.path.join(section_slug, kw['index_file'])
+ link = short_destination.replace('\\', '/')
+ if kw['strip_indexes'] and link[-(1 + index_len):] == '/' + kw['index_file']:
+ link = link[:-index_len]
+ context["permalink"] = link
+ 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 self.site.config["POSTS_SECTION_ARE_INDEXES"]:
+ context["pagekind"].append("index")
+ posts_section_title = self.site.config['POSTS_SECTION_TITLE'](lang)
+
+ section_title = None
+ 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))
+
+ task = self.site.generic_index_renderer(lang, post_list, section_title, "sectionindex.tmpl", context, kw, self.name, cat_link, cat_path)
+ else:
+ context["pagekind"].append("list")
+ output_name = os.path.join(kw['output_folder'], section_slug, kw['index_file'])
+ task = self.site.generic_post_list_renderer(lang, post_list, output_name, "list.tmpl", kw['filters'], context)
+ task['uptodate'] = [utils.config_changed(kw, 'nikola.plugins.task.indexes')]
+ task['basename'] = self.name
+ yield task
+
+ # 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'],
@@ -129,12 +242,13 @@ 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:
context["items"].append((post.title(lang),
- post.permalink(lang)))
+ post.permalink(lang),
+ None))
if should_render:
task = self.site.generic_post_list_renderer(lang, post_list,
@@ -147,22 +261,86 @@ class Indexes(Task):
yield task
def index_path(self, name, lang, is_feed=False):
- """Return path to an index."""
+ """Link to a numbered index.
+
+ Example:
+
+ link://index/3 => /index-3.html
+ """
extension = None
if is_feed:
extension = ".atom"
index_file = os.path.splitext(self.site.config['INDEX_FILE'])[0] + extension
else:
index_file = self.site.config['INDEX_FILE']
+ if lang in self.number_of_pages:
+ number_of_pages = self.number_of_pages[lang]
+ else:
+ number_of_pages = self._compute_number_of_pages(self._get_filtered_posts(lang, self.site.config['SHOW_UNTRANSLATED_POSTS']), self.site.config['INDEX_DISPLAY_POST_COUNT'])
+ self.number_of_pages[lang] = number_of_pages
return utils.adjust_name_for_index_path_list([_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['INDEX_PATH'],
index_file] if _f],
name,
- utils.get_displayed_page_number(name, self.number_of_pages[lang], self.site),
+ utils.get_displayed_page_number(name, number_of_pages, self.site),
+ lang,
+ self.site,
+ extension=extension)
+
+ def index_section_path(self, name, lang, is_feed=False, is_rss=False):
+ """Link to the index for a section.
+
+ Example:
+
+ link://section_index/cars => /cars/index.html
+ """
+ extension = None
+
+ 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]:
+ number_of_pages = self.number_of_pages_section[lang][name]
+ else:
+ posts = [post for post in self._get_filtered_posts(lang, self.site.config['SHOW_UNTRANSLATED_POSTS']) if post.section_slug(lang) == name]
+ number_of_pages = self._compute_number_of_pages(posts, self.site.config['INDEX_DISPLAY_POST_COUNT'])
+ self.number_of_pages_section[lang][name] = number_of_pages
+ return utils.adjust_name_for_index_path_list([_f for _f in [self.site.config['TRANSLATIONS'][lang],
+ name,
+ index_file] if _f],
+ None,
+ utils.get_displayed_page_number(None, number_of_pages, self.site),
lang,
self.site,
extension=extension)
def index_atom_path(self, name, lang):
- """Return path to an Atom index."""
+ """Link to a numbered Atom index.
+
+ Example:
+
+ link://index_atom/3 => /index-3.atom
+ """
return self.index_path(name, lang, is_feed=True)
+
+ def index_section_atom_path(self, name, lang):
+ """Link to the Atom index for a section.
+
+ Example:
+
+ 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)