Skip to content
Permalink
Browse files

New plug-in: Recent posts as JSON

  • Loading branch information
da2x committed May 8, 2015
1 parent accf184 commit 52053066a2687bba01b4efe053df2c7438b8f24c
@@ -0,0 +1,22 @@
This plug-in generates a /index.json file containing the same posts
as /index.html. Intended to be used in JavaScripts. For example to
promote the most recent posts at the bottom of older posts.

By default, the JSON file will include:
{
<JS Date object>: {
"title": <post-title>,
"iri": <relative-link-to-post>
},
}

Optionally, it can be expanded to include thumbnails or descriptions:
{ <JS Date object>: {
"title": <post-title>, "iri": <post-relative-link>,
"desc": <post-meta-description>,
"img": <post-meta-thumbnail>
}, }

Posts are sorted by their post.meta.date as JavaScript dates.

Pro tip: Set a sensible cache header for the JSON file.
@@ -0,0 +1,11 @@
# Generates a /index.json with the most recent posts from /index.html.
# Can be expanded with these options:

# Number of posts to include, defaults to INDEX_DISPLAY_POST_COUNT (10)
RECENT_POSTS_JSON_LENGTH = 5

# Include {"desc": post.description}, defaults to False
RECENT_POSTS_JSON_DESCRIPTION = False

# Include {"img": post.meta.previewimage}, defaults to False
RECENT_POSTS_JSON_PREVIEWIMAGE = False
@@ -0,0 +1,10 @@
[Core]
Name = recent_posts_json
Module = recent_posts_json

[Documentation]
Author = Daniel Aleksandersen
Version = 0.9.0
Website = https://www.aeyoun.com
Description = Generate JSON with recent posts.

@@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-

# Copyright © 2012-2015 Roberto Alsina and others.

# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
# documentation files (the "Software"), to deal in the
# Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice
# shall be included in all copies or substantial portions of
# the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from __future__ import unicode_literals, print_function
import os
import io
import json
import time
try:
from urlparse import urljoin
except ImportError:
from urllib.parse import urljoin # NOQA

from nikola import utils
from nikola.plugin_categories import Task


class RecentPostsJon(Task):
"""Generate JSON with recent posts."""

name = "recent_posts_json"

def set_site(self, site):
site.register_path_handler("recent_posts_json", self.json_path)
return super(RecentPostsJon, self).set_site(site)

def gen_tasks(self):
"""Generate RSS feeds."""
kw = {
"output_folder": self.site.config["OUTPUT_FOLDER"],
"filters": self.site.config["FILTERS"],
"index_file": self.site.config["INDEX_FILE"],
"translations": self.site.config["TRANSLATIONS"],
"show_untranslated_posts": self.site.config["SHOW_UNTRANSLATED_POSTS"],
"site_url": self.site.config["SITE_URL"],
"base_url": self.site.config["BASE_URL"],
"json_posts_length": self.site.config["RECENT_POSTS_JSON_LENGTH"] if "RECENT_POSTS_JSON_LENGTH" in self.site.config else self.site.config["INDEX_DISPLAY_POST_COUNT"],
"json_descriptions": self.site.config["RECENT_POSTS_JSON_DESCRIPTION"] if "RECENT_POSTS_JSON_DESCRIPTION" in self.site.config else False,
"json_previewimage": self.site.conf["RECENT_POSTS_JSON_PREVIEWIMAGE"] if "RECENT_POSTS_JSON_PREVIEWIMAGE" in self.site.config else False,
}
self.site.scan_posts()
yield self.group_task()
for lang in kw["translations"]:
output_path = os.path.join(kw["output_folder"],
self.site.path("recent_posts_json", None, lang))
deps = []
deps_uptodate = []
if kw["show_untranslated_posts"]:
posts = self.site.posts[:kw["json_posts_length"]]
else:
posts = [x for x in self.site.posts if x.is_translation_available(lang)][:kw["json_posts_length"]]
for post in posts:
deps += post.deps(lang)
deps_uptodate += post.deps_uptodate(lang)
task = {
"basename": "recent_posts_json",
"name": os.path.normpath(output_path),
"file_dep": deps,
"targets": [output_path],
"actions": [(self.make_json,
(posts, kw["json_descriptions"], kw["json_previewimage"], output_path))],
"task_dep": ["render_posts"],
"clean": True,
"uptodate": [utils.config_changed(kw, "nikola.plugins.task.recent_pots_json")] + deps_uptodate,
}
yield utils.apply_filters(task, kw["filters"])

def make_json(self, posts, descriptions, previewimage, output_path):
recent_posts = {}
for post in posts:
date = int(time.mktime(post.date.timetuple()) * 1000) # JavaScript Date
link = post.permalink(absolute=False)
title = post.title()
recent_posts[date] = {"title": title,
"iri": link}
if descriptions:
recent_posts[date]["desc"] = post.description()
if previewimage:
recent_posts[date]["img"] = post.previewimage()
data = json.dumps(recent_posts, indent=2)
utils.LOGGER.warn(data)
with io.open(output_path, "w+", encoding="utf8") as outf:
outf.write(data)

def json_path(self, name, lang):
return [_f for _f in [self.site.config["TRANSLATIONS"][lang],
os.path.splitext(self.site.config["INDEX_FILE"])[0] + ".json"] if _f]

0 comments on commit 5205306

Please sign in to comment.