2

我已经编写了一个简单的 Jekyll 插件来使用 twitter gem 来拉入我的推文(见下文)。我想将插件的 ruby​​ 脚本保留在我打开的 Github 站点上,但是随着最近对 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 构建期间不起作用。

4

1 回答 1

2

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

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

可以执行一些操作,例如将Twitter::Client对象分配给一个常量,然后您可以从render方法中引用该常量:

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

接着

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

我仅建议将此作为对 发生的事情的解释require,这并不是一个真正的好技术。

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

首先~/twitter_auth.rb用一个~/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"))
于 2013-01-12T23:33:34.210 回答