【问题标题】:Jekyll extension calling an external scriptJekyll 扩展调用外部脚本
【发布时间】:2012-12-25 03:17:02
【问题描述】:

我编写了一个简单的 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 构建期间不起作用。

【问题讨论】:

    标签: ruby api twitter jekyll


    【解决方案1】:

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

    在您的情况下,当您需要 ~/.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"))
    

    【讨论】:

    • 太好了,感谢您的解释。如您所知,我不是 Ruby 程序员。我只是出于必要才破解它。这就像一个魅力。并且以标准数据格式而不是另一个 ruby​​ 脚本存储凭据要优雅得多。谢谢!
    猜你喜欢
    • 2016-05-11
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 2013-09-10
    • 2018-11-24
    • 1970-01-01
    相关资源
    最近更新 更多