避免在 Jekyll Ruby 插件中重复调用 API [英] Avoid repeated calls to an API in Jekyll Ruby plugin

查看:28
本文介绍了避免在 Jekyll Ruby 插件中重复调用 API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个 Jekyll 插件,通过使用 garb gem 调用 Google Analytics API 来显示页面上的综合浏览量.我的方法唯一的问题是它为每个页面调用 API,减慢了构建时间,并且还可能达到 API 上的用户调用限制.

I have written a Jekyll plugin to display the number of pageviews on a page by calling the Google Analytics API using the garb gem. The only trouble with my approach is that it makes a call to the API for each page, slowing down build time and also potentially hitting the user call limits on the API.

可以在一次调用中返回所有数据并将其存储在本地,然后查看每个页面的浏览量计数,但我的 Jekyll/Ruby-fu 不符合标准.我不知道如何编写插件运行一次以获取所有数据并将其存储在本地,然后我的当前函数可以访问它,而不是逐页调用 API.

It would be possible to return all the data in a single call and store it locally, and then look up the pageview count from each page, but my Jekyll/Ruby-fu isn't up to scratch. I do not know how to write the plugin to run once to get all the data and store it locally where my current function could then access it, rather than calling the API page by page.

基本上我的代码被写成一个可以放入我的页面布局的液体块:

Basically my code is written as a liquid block that can be put into my page layout:

 class GoogleAnalytics < Liquid::Block
    def initialize(tag_name, markup, tokens)
      super # options that appear in block (between tag and endtag)
      @options = markup # optional optionss passed in by opening tag
    end
    def render(context)
      path = super
      # Read in credentials and authenticate 
      cred = YAML.load_file("/home/cboettig/.garb_auth.yaml")
      Garb::Session.api_key = cred[:api_key]
      token = Garb::Session.login(cred[:username], cred[:password])
      profile = Garb::Management::Profile.all.detect {|p| p.web_property_id == cred[:ua]}

      # place query, customize to modify results
      data = Exits.results(profile, 
                           :filters => {:page_path.eql => path}, 
                           :start_date => Chronic.parse("2011-01-01"))

      data.first.pageviews
    end

我的插件的完整版本在这里

如何将所有对 API 的调用移动到其他一些函数,并确保 jekyll 在开始时运行一次,然后调整上面的标签以读取本地数据?

How can I move all the calls to the API to some other function and make sure jekyll runs that once at the start, and then adjust the tag above to read that local data?

EDIT 看起来这可以通过生成器完成并将数据写入文件.请参阅此分支上的示例现在我只需要弄清楚如何对结果进行子集化:https://github.com/Sija/装束/问题/22

EDIT Looks like this can be done with a Generator and writing the data to a file. See example on this branch Now I just need to figure out how to subset the results: https://github.com/Sija/garb/issues/22

推荐答案

为了存储数据,我不得不:

To store the data, I had to:

  1. 编写一个 Generator 类(参见 Jekyll wiki 插件)来调用应用程序接口.

  1. Write a Generator class (see Jekyll wiki plugins) to call the API.

将数据转换为散列(为了方便按路径查找,请参见 5):

Convert data to a hash (for easy lookup by path, see 5):

result = Hash[data.collect{|row| [row.page_path, [row.exits, row.pageviews]]}]

  • 将数据哈希写入 JSON 文件.

  • Write the data hash to a JSON file.

    从我现有 Liquid 块类中的文件中读取数据.

    Read in the data from the file in my existing Liquid block class.

    注意块标签在 _includes 目录下工作,而生成器在根目录下工作.

    Note that the block tag works from the _includes dir, while the generator works from the root directory.

    匹配页面路径,一旦将数据转换为哈希就很容易:

    Match the page path, easy once the data is converted to a hash:

    result[path][1]
    

  • 完整插件的代码,展示如何在这里创建生成器和写入文件等

    感谢 GitHub 上的 Sija 在这方面的帮助.

    And thanks to Sija on GitHub for help on this.

    这篇关于避免在 Jekyll Ruby 插件中重复调用 API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆