2013-01-10 93 views
2

我已經寫了一個簡單的Jekyll插件來使用twitter gem(參見下文)拉我的推文。我想在開放的Github網站上保留插件的ruby腳本,但是在twitter API最近發生的變化之後,該gem現在需要身份驗證憑證。Jekyll擴展調用外部腳本

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構建過程中不起作用。

回答

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看起來像soemthing:

: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")) 
+0

太好了,謝謝你的解釋。你可以告訴我,我不是一個紅寶石程序員;我只是在必要的情況下破解它。這工作像一個魅力;並以一個標準的數據格式而不是另一個ruby腳本存儲憑證要優雅得多。謝謝! – cboettig