Jekyll - generating JSON files alongside the HTML files

前端 未结 3 627
天涯浪人
天涯浪人 2020-12-14 12:00

I\'d like to make Jekyll create an HTML file and a JSON file for each page and post. This is to offer a JSON API of my Jekyll blog - e.g. a post can be accessed either at

相关标签:
3条回答
  • 2020-12-14 12:36

    Take a look at JekyllBot and the following 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
    

    Both should do exactly what you want.

    0 讨论(0)
  • 2020-12-14 12:38

    I was looking for something like this too, so I learned a bit of ruby and made a script that generates JSON representations of Jekyll blog posts. I’m still working on it, but most of it is there.

    I put this together with Gruntjs, Sass, Backbonejs, Requirejs and Coffeescript. If you like, you can take a look at 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
    
    0 讨论(0)
  • 2020-12-14 12:44

    There are two ways you can accomplish this, depending on your needs. If you want to use a layout to accomplish the task, then you want to use a Generator. You would loop through each page of your site and generate a new .json version of the page. You could optionally make which pages get generated conditional upon the site.config or the presence of a variable in the YAML front matter of the pages. Jekyll uses a generator to handle slicing blog posts up into indices with a given number of posts per page.

    The second way is to use a Converter (same link, scroll down). The converter will allow you to execute arbitrary code on your content to translate it to a different format. For an example of how this works, check out the markdown converter that comes with Jekyll.

    I think this is a cool idea!

    0 讨论(0)
提交回复
热议问题