How to use Jekyll like a pro : build a JSON API for your static website
Throughout this tutorial we are going to learn how to build an API for static websites powered by Jekyll,so you can consume static data via any web/mobile application.
So first of all lets talk about the basics .If you just need to output some data as JSON you can easily do that using jsonify filter for example,if you have an array in your front matter such as :
--- myArray: - a1 - a2 - a3 - a4 ---
You can easily get myArray as JSON
var myArray = null;
After building/serving your website, the result will be as you may expect :
var myArray = ["a1","a2","a3","a4"];
All variables in the front matter of your page will be accessible via page variable so we took our YAML array page.myArray and convert it to JSON with jsonify liquid filter.
Now lets try with a more practical example.What if you want to get the JSON output of all your posts in some json file ,that's also not hard at all with Jekyll ,you can do it following these two steps:
First create the output file with a name,lets call it output.json.
Next open the file output.json and add the following code :
The limit meta in the front matter controls the number of posts to output as JSON. We have looped through all site.posts and created a JSON object with each post data separating the objects with a comma.After building your website,Jekyll will take of parsing the YAML and Liquid data and outputting output.json with your posts data in the JSON format.
Go ahead and test it with a Jekyll blog,serve it or build it then look inside of your _site folder for your output.json with posts data populated for you.Or just visit 127.0.0.1:4000/output.json to see the result.
gem install jekyll-paginate
Next under your _plugins folder create a new ruby file ,lets name it api.rb and add the following code to the file.
class Pagination < Generator safe true priority :lowest def generate(site) if Paginate::Pager.pagination_enabled?(site) site.categories.each do |category, posts| total = Paginate::Pager.calculate_pages(posts, site.config['paginate']) (1..total).each do |i| site.pages << JsonPage.new(site, category, i,site.categories[category]) end end total = Paginate::Pager.calculate_pages(site.posts, site.config['paginate']) (1..total).each do |i| site.pages << JsonPage.new(site, 'all', i,site.posts) end end end end class JsonPage < Page def initialize(site, category, num_page,posts) @site = site @base = site.source @total = posts.length() @current = num_page @previous = -1 @next = -1 @paginator = Paginate::Pager.new(site, num_page, posts) @length = @paginator.posts.length() if(@paginator.previous_page) @previous = @current - 1 end if(@paginator.next_page) @next = @current + 1 end category_dir = site.config['api_category_dir'] || 'api' @dir = File.join(category_dir,category) #@name = Paginate::Pager.paginate_path(site, num_page) #@name.concat '/' unless @name.end_with? '/' @name = num_page.to_s + '.json' self.process(@name) category_layout = site.config['api_layout'] || '_layouts/api.md' self.read_yaml(@base, category_layout) self.data.merge!( 'title' => category, 'category' => category, 'length' => @length, 'total' => @total, 'current' => @current, 'next' => @next, 'previous' => @previous, 'paginator' => @paginator ) end end end
end end apibycategory.rb
class Pagination < Generator safe true priority :lowest def generate(site) if Paginate::Pager.pagination_enabled?(site) site.categories.each do |category, posts| total = Paginate::Pager.calculate_pages(posts, site.config['paginate']) (1..total).each do |i| site.pages << JsonPage.new(site, category, i) end end end end end end
So lets highlight the important lines of our plugin code