12

我想让 Jekyll 为每个页面和帖子创建一个 HTML 文件和一个 JSON 文件。这是为了提供我的 Jekyll 博客的 JSON API - 例如可以在/posts/2012/01/01/my-post.html/posts/2012/01/01/my-post.json

有谁知道是否有 Jekyll 插件,或者我将如何开始编写这样的插件,以并排生成两组文件?

4

3 回答 3

12

我也在寻找类似的东西,所以我学习了一点 ruby​​ 并制作了一个脚本,可以生成 Jekyll 博客文章的 JSON 表示。我仍在努力,但大部分都在那里。

我将它与 Gruntjs、Sass、Backbonejs、Requirejs 和 Coffeescript 放在一起。如果你喜欢,你可以看看我在 Github 上的 jekyll-backbone 项目

# encoding: utf-8
#
# Title:
# ======
# Jekyll to JSON Generator
#
# Description:
# ============
# A plugin for generating JSON representations of your
# site content for easy use with JS MVC frameworks like Backbone.
#
# Author:
# ======
# Jezen Thomas
# jezenthomas@gmail.com
# http://jezenthomas.com

module Jekyll
  require 'json'

  class JSONGenerator < Generator
    safe true
    priority :low

    def generate(site)
      # Converter for .md > .html
      converter = site.getConverterImpl(Jekyll::Converters::Markdown)

      # Iterate over all posts
      site.posts.each do |post|

        # Encode the HTML to JSON
        hash = { "content" => converter.convert(post.content)}
        title = post.title.downcase.tr(' ', '-').delete("’!")

        # Start building the path
        path = "_site/dist/"

        # Add categories to path if they exist
        if (post.data['categories'].class == String)
          path << post.data['categories'].tr(' ', '/')
        elsif (post.data['categories'].class == Array)
          path <<  post.data['categories'].join('/')
        end

        # Add the sanitized post title to complete the path
        path << "/#{title}"

        # Create the directories from the path
        FileUtils.mkpath(path) unless File.exists?(path)

        # Create the JSON file and inject the data
        f = File.new("#{path}/raw.json", "w+")
        f.puts JSON.generate(hash)
      end

    end

  end

end
于 2013-09-11T09:29:14.443 回答
5

看看JekyllBot下面的代码

require 'json' 

module Jekyll

  class JSONPostGenerator < Generator
    safe true

    def generate(site)

      site.posts.each do |post|
        render_json(post,site)    
      end

      site.pages.each do |page|
        render_json(page,site)    
      end

    end

    def render_json(post, site)

      #add `json: false` to YAML to prevent JSONification
      if post.data.has_key? "json" and !post.data["json"]
        return
      end

      path = post.destination( site.source )

      #only act on post/pages index in /index.html
      return if /\/index\.html$/.match(path).nil?

      #change file path
      path['/index.html'] = '.json'

      #render post using no template(s)
      post.render( {}, site.site_payload)

      #prepare output for JSON
      post.data["related_posts"] = related_posts(post,site)
      output = post.to_liquid
      output["next"] = output["next"].id unless output["next"].nil?
      output["previous"] = output["previous"].id unless output["previous"].nil?

      #write
      #todo, figure out how to overwrite post.destination 
      #so we can just use post.write
      FileUtils.mkdir_p(File.dirname(path))
      File.open(path, 'w') do |f|
        f.write(output.to_json)
      end

    end

    def related_posts(post, site)

      related = []
      return related unless post.instance_of?(Post)

      post.related_posts(site.posts).each do |post|
        related.push :url => post.url, :id => post.id, :title => post.to_liquid["title"]
      end

      related

    end
  end
end

两者都应该完全按照您的意愿行事。

于 2013-03-22T14:00:28.937 回答
5

根据您的需要,有两种方法可以实现此目的。如果您想使用布局来完成任务,那么您需要使用Generator。您将遍历站点的每个页面并生成该页面的新 .json 版本。您可以选择根据 site.config 或页面的 YAML 前端内容中是否存在变量来生成哪些页面。Jekyll 使用生成器来处理将博客文章分割成索引,每页具有给定数量的文章。

第二种方法是使用转换器(相同的链接,向下滚动)。该转换器将允许您对内容执行任意代码,以将其转换为不同的格式。有关其工作原理的示例,请查看Jekyll 附带的降价转换器。

我认为这是一个很酷的主意!

于 2013-02-12T00:51:32.283 回答