Repository: getnikola/nikola

Issue:
post-list shortcode not working very well
`{{% post-list slugs='one' all %}}`
results in:

```
TaskError - taskid:render_posts:cache/stories/one.html
PythonAction Error
Traceback (most recent call last):
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/doit/action.py", line 383, in execute
    returned_value = self.py_callable(*self.args, **kwargs)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/post.py", line 493, in compile
    self.is_two_file),
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/plugins/compile/markdown/__init__.py", line 79, in compile_html
    output = apply_shortcodes(output, self.site.shortcode_registry, self.site, source)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/shortcodes.py", line 313, in apply_shortcodes
    res = registry[name](*args, **kw)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/plugins/compile/rest/post_list.py", line 234, in _do_post_list
    for post in filtered_timeline[start:stop:step]:
TypeError: slice indices must be integers or None or have an __index__ method
```

while
`{{% post-list start=0 stop=2 slugs='one' all %}}`
results in:

```
TaskError - taskid:render_posts:cache/stories/one.html
PythonAction Error
Traceback (most recent call last):
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/doit/action.py", line 383, in execute
    returned_value = self.py_callable(*self.args, **kwargs)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/post.py", line 493, in compile
    self.is_two_file),
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/plugins/compile/markdown/__init__.py", line 79, in compile_html
    output = apply_shortcodes(output, self.site.shortcode_registry, self.site, source)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/shortcodes.py", line 313, in apply_shortcodes
    res = registry[name](*args, **kw)
TypeError: _do_post_list() got multiple values for argument 'start'
```

post-list shortcode not working very well
`{{% post-list slugs='one' all %}}`
results in:

```
TaskError - taskid:render_posts:cache/stories/one.html
PythonAction Error
Traceback (most recent call last):
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/doit/action.py", line 383, in execute
    returned_value = self.py_callable(*self.args, **kwargs)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/post.py", line 493, in compile
    self.is_two_file),
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/plugins/compile/markdown/__init__.py", line 79, in compile_html
    output = apply_shortcodes(output, self.site.shortcode_registry, self.site, source)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/shortcodes.py", line 313, in apply_shortcodes
    res = registry[name](*args, **kw)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/plugins/compile/rest/post_list.py", line 234, in _do_post_list
    for post in filtered_timeline[start:stop:step]:
TypeError: slice indices must be integers or None or have an __index__ method
```

while
`{{% post-list start=0 stop=2 slugs='one' all %}}`
results in:

```
TaskError - taskid:render_posts:cache/stories/one.html
PythonAction Error
Traceback (most recent call last):
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/doit/action.py", line 383, in execute
    returned_value = self.py_callable(*self.args, **kwargs)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/post.py", line 493, in compile
    self.is_two_file),
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/plugins/compile/markdown/__init__.py", line 79, in compile_html
    output = apply_shortcodes(output, self.site.shortcode_registry, self.site, source)
  File "/Users/fuzzy76/repos/nikola/lib/python3.5/site-packages/nikola/shortcodes.py", line 313, in apply_shortcodes
    res = registry[name](*args, **kw)
TypeError: _do_post_list() got multiple values for argument 'start'
```



Discussion:
I guess #1707 isn't quite done yet, but thought you'd like a separate issue for this.

It also seems that we’d need to move the logic (eg. for categories and sections) out of PostList.run() and into `_do_post_list()`

@Kwpolska yep. I am not that familiar with post-list, so feel free to take over, I have not looked at it much yet.

I guess #1707 isn't quite done yet, but thought you'd like a separate issue for this.

It also seems that we’d need to move the logic (eg. for categories and sections) out of PostList.run() and into `_do_post_list()`

@Kwpolska yep. I am not that familiar with post-list, so feel free to take over, I have not looked at it much yet.


Resolving patch:
diff --git a/nikola/plugins/compile/rest/post_list.py b/nikola/plugins/compile/rest/post_list.py
--- a/nikola/plugins/compile/rest/post_list.py
+++ b/nikola/plugins/compile/rest/post_list.py
@@ -116,13 +116,13 @@ class PostList(Directive):
         Filter posts to show only posts having at least one of the ``slugs``.
         Defaults to None.
 
-    ``post_type`` : string
+    ``post_type`` (or ``type``) : string
         Show only ``posts``, ``pages`` or ``all``.
         Replaces ``all``. Defaults to ``posts``.
 
     ``all`` : flag
-        Shows all posts and pages in the post list.
-        Defaults to show only posts with set *use_in_feeds*.
+        (deprecated, use ``post_type`` instead)
+        Shows all posts and pages in the post list.  Defaults to show only posts.
 
     ``lang`` : string
         The language of post *titles* and *links*.
@@ -147,6 +147,7 @@ class PostList(Directive):
         'sections': directives.unchanged,
         'slugs': directives.unchanged,
         'post_type': directives.unchanged,
+        'type': directives.unchanged,
         'all': directives.flag,
         'lang': directives.unchanged,
         'template': directives.path,
@@ -160,22 +161,19 @@ def run(self):
         stop = self.options.get('stop')
         reverse = self.options.get('reverse', False)
         tags = self.options.get('tags')
-        tags = [t.strip().lower() for t in tags.split(',')] if tags else []
         categories = self.options.get('categories')
-        categories = [c.strip().lower() for c in categories.split(',')] if categories else []
         sections = self.options.get('sections')
-        sections = [s.strip().lower() for s in sections.split(',')] if sections else []
         slugs = self.options.get('slugs')
-        slugs = [s.strip() for s in slugs.split(',')] if slugs else []
         post_type = self.options.get('post_type')
-        show_all = self.options.get('all', False)
+        type = self.options.get('type', False)
+        all = self.options.get('all', False)
         lang = self.options.get('lang', utils.LocaleBorg().current_lang)
         template = self.options.get('template', 'post_list_directive.tmpl')
         sort = self.options.get('sort')
         date = self.options.get('date')
 
-        output = _do_post_list(start, stop, reverse, tags, categories, sections, slugs, post_type,
-                               show_all, lang, template, sort, state=self.state, site=self.site, date=date)
+        output = _do_post_list(start, stop, reverse, tags, categories, sections, slugs, post_type, type,
+                               all, lang, template, sort, state=self.state, site=self.site, date=date)
         self.state.document.settings.record_dependencies.add("####MAGIC####TIMELINE")
         if output:
             return [nodes.raw('', output, format='html')]
@@ -184,7 +182,7 @@ def run(self):
 
 
 def _do_post_list(start=None, stop=None, reverse=False, tags=None, categories=None,
-                  sections=None, slugs=None, post_type='post', show_all=False,
+                  sections=None, slugs=None, post_type='post', type=False, all=False,
                   lang=None, template='post_list_directive.tmpl', sort=None,
                   id=None, data=None, state=None, site=None, date=None):
     if lang is None:
@@ -194,12 +192,27 @@ def _do_post_list(start=None, stop=None, reverse=False, tags=None, categories=No
     else:
         post_list_id = id or 'post_list_' + uuid.uuid4().hex
 
+    # If we get strings for start/stop, make them integers
+    if start is not None:
+        start = int(start)
+    if stop is not None:
+        stop = int(stop)
+
+    # Parse tags/categories/sections/slugs (input is strings)
+    tags = [t.strip().lower() for t in tags.split(',')] if tags else []
+    categories = [c.strip().lower() for c in categories.split(',')] if categories else []
+    sections = [s.strip().lower() for s in sections.split(',')] if sections else []
+    slugs = [s.strip() for s in slugs.split(',')] if slugs else []
+
     filtered_timeline = []
     posts = []
     step = -1 if reverse is None else None
 
+    if type is not False:
+        post_type = type
+
     # TODO: remove in v8
-    if show_all is None:
+    if all is not False:
         timeline = [p for p in site.timeline]
     elif post_type == 'page':
         timeline = [p for p in site.timeline if not p.use_in_feeds]
@@ -208,7 +221,7 @@ def _do_post_list(start=None, stop=None, reverse=False, tags=None, categories=No
     else:  # post
         timeline = [p for p in site.timeline if p.use_in_feeds]
 
-    # TODO: replaces show_all, uncomment in v8
+    # TODO: replaces all, uncomment in v8
     # if post_type == 'page':
     #    timeline = [p for p in site.timeline if not p.use_in_feeds]
     # elif post_type == 'all':
@@ -258,11 +271,12 @@ def _do_post_list(start=None, stop=None, reverse=False, tags=None, categories=No
         posts += [post]
 
     if not posts:
-        return []
+        return ''
 
-    # Register template as a dependency (Issue #2391)
-    state.document.settings.record_dependencies.add(
-        site.template_system.get_template_path(template))
+    if state:
+        # Register template as a dependency (Issue #2391)
+        state.document.settings.record_dependencies.add(
+            site.template_system.get_template_path(template))
 
     template_data = {
         'lang': lang,


Test patch: