【问题标题】:Jekyll - generating JSON files alongside the HTML filesJekyll - 在 HTML 文件旁边生成 JSON 文件
【发布时间】:2013-01-23 11:12:06
【问题描述】:

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

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

【问题讨论】:

  • 为什么要创建 JSON 版本?所以有人只能访问原始内容?
  • 为什么重要?以多种格式公开您的内容非常有用,而 JSON 是 API 的标准。我的想法是使用 Backbone.js 之类的东西编写一些前端 JavaScript 来动态提取内容。这可能有助于使用 Cache Manifest 使博客离线可用。
  • 我问是因为很难从人们的问题中判断他们的能力水平。有些人要求东西,因为他们不知道自己想做什么。可以想象有人想将 HTML 放入他们的 JSON 中,认为这将是一件有用的事情。很难说你想要什么,所以我问了。
  • @theTinMan 很酷。是的。我知道很多 JavaScript 和一些 Ruby,但真的不知道从哪里开始扩展 Jekyll 来做这样的事情,或者是否有可能。
  • 无论如何,这里的挑战在于不输出 JSON,这只是一个模板格式问题——或者最坏的情况是 markdown parsing one。我不知道该怎么做是让 Jekyll 从同一页面的多个模板输出。默认情况下,它将使用前面指定的layout 中的单个模板。默认情况下,我想根据两个不同的模板将一页解析到两个不同的位置。这可能吗?

标签: ruby json api jekyll


【解决方案1】:

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

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

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

【讨论】:

  • 太棒了。发电机看起来像那种东西。有机会我会调查一下,如果我得到它的工作,请接受你的回答。
  • 转换器无法正常工作的原因是,当转换器插件运行时,markdown 文件已经消失,取而代之的是 html 文件。
【解决方案2】:

看看JekyllBotfollowing code

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

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

【讨论】:

    【解决方案3】:

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

    我将它与 Gruntjs、Sass、Backbonejs、Requirejs 和 Coffeescript 放在一起。喜欢的可以关注my jekyll-backbone project on Github

    # 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多