Jekyll扩展调用外部脚本

时间:2013-01-10 16:44:32

标签: ruby api twitter jekyll

我写了一个简单的Jekyll插件来使用twitter gem来推送我的推文(见下文)。我想在我的开放Github网站上保留插件的ruby脚本,但是在最近对twitter API的更改之后,gem现在需要身份验证凭据。

require 'twitter'   # Twitter API
require 'redcarpet' # Formatting links

module Jekyll
  class TwitterFeed < Liquid::Tag
    def initialize(tag_name, text, tokens)
      super
      input = text.split(/, */ )
      @user = input[0]
      @count = input[1]
      if input[1] == nil
        @count = 3
      end
    end
    def render(context)
      # Initialize a redcarpet markdown renderer to autolink urls
      # Could use octokit instead to get GFM
      markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
                                                 :autolink => true, 
                                                 :space_after_headers => true)

      ## Attempt to load credentials externally here:
      require '~/.twitter_auth.rb'

      out = "<ul>"
      tweets = @client.user_timeline(@user)
      for i in 0 ... @count.to_i
      out = out + "<li>" + markdown.render(tweets[i].text) +
        " <a href=\"http://twitter.com/" + @user + "/statuses/" + 
        tweets[i].id.to_s + "\">"  + tweets[i].created_at.strftime("%I:%M %Y/%m/%d") + 
        "</a> " + "</li>"
      end
      out + "</ul>"
    end
  end
end
Liquid::Template.register_tag('twitter_feed', Jekyll::TwitterFeed)

如果我换行

      require '~/.twitter_auth.rb'

其中twitter_auth.rb包含以下内容:

require 'twitter'
@client = Twitter::Client.new(
:consumer_key => "CEoYXXXXXXXXXXX",
:consumer_secret => "apnHXXXXXXXXXXXXXXXXXXXXXXXX",
:oauth_token => "105XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
:oauth_token_secret => "BJ7AlXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
)

如果我将这些内容直接放在上面的脚本中,那么我的插件脚本就可以了。但是当我将它们移动到外部文件并尝试如图所示读取它们时,Jekyll无法进行身份验证。当我从irb调用它时,该函数似乎工作正常,所以我不确定为什么它在Jekyll构建期间不起作用。

1 个答案:

答案 0 :(得分:2)

我认为您可能会对require的工作方式感到困惑。当你调用require时,第一个Ruby会检查文件是否已被要求,如果是,它只是直接返回。如果没有,则运行该文件的内容,但不在require语句的范围内。换句话说,使用require 相同,而不是将require语句替换为文件的内容(例如,的方式) ,C的#include有效。

在您的情况下,当您需要~/.twitter_auth.rb文件时,正在创建@client实例变量,但作为顶级main对象的实例变量, not 作为TwitterFeed实例的实例变量,其中require被称为表单。

可以做一些事情,比如将Twitter::Client对象分配给一个常量,然后你可以从render方法中引用它:

MyClient = Twitter::Client.new{...

然后

require '~/twitter_auth.rb'
@client = MyClient
...

我只是建议用require作为对~/twitter_auth.rb发生的事情的解释,这不是一个好的技巧。

我认为,更好的选择是将您的凭据保存在主目录中的简单数据格式中,然后从脚本中读取它们并使用它们创建Twitter客户端。在这种情况下,Yaml可能会完成这项工作。

首先将~/twitter_auth.yaml替换为:consumer_key: "CEoYXXXXXXXXXXX" :consumer_secret: "apnHXXXXXXXXXXXXXXXXXXXXXXXX" :oauth_token: "105XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" :oauth_token_secret: "BJ7AlXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ,其外观类似于:

requre "~/twitter_auth.rb"

然后在您的班级中require 'yaml',请替换为此文件(您还需要文件顶部的@client = Twitter::Client.new(YAML.load_file("~/twitter_auth.yaml")) ):

{{1}}