almost 6 years ago

這幾天在寫一個小玩具,因為要用到 Github 認證,於是採取了 OmniAuth + Devise 這組作法。因為適逢 OmniAuth 在十月底一舉從 v0.3 大改版,直衝到 v1.0。版號大躍進,整個架構與 API 也幾乎全都不一樣了,網路上的教學幾乎等於作廢,加上 Github 原本實作的 OAuth 2.0 本來就不太標準,吃了幾個小時苦頭,終於才把認證搞定。不過也拜這一晚的折騰,讓我把 OmniAuth 架構摸個更加透徹。

多方認證的需求

現在作網站,使用者的要求比以往的高。在過往,幾乎都是站方的姿態較高,使用者要試用一個網站前,無不是必須填一堆資料,勾完一堆囉哩八縮的選項,才能加入這個網站。

但隨著時代的改變,Facebook Connect 的普及,現在網路生態卻跟以前完全相反,如果你的網站不提供傳統帳號密碼以外的方案(諸如 Facebook Connect、Google ID …etc.)使用者二話不說,絕對馬上就閃人。反正網站那麼多,不差哪一個…

於是提供傳統帳號密碼以外的註冊方案,對一個新創網站就顯得格外重要。

實作上的困難

話雖如此,但是實作上是真的有很大的困難的。就拿 Rails 生態圈好了,傳統帳號密碼方案 有非常多套:Devise、Authlogic、Restful-authenication 等等。而實作第三方認證的功能也是相當多元的,你可以拿 Facebook API 的 gem 或者是 Google OAuth 的 gem 直接硬幹整合這些方案,也是做的出來。

理想的境界應該是一個網站最好只要提供一個 3rd Party 的認證,而且認證 Library 與 API 存取機制,不能要有太大的變化。

但這真的只是理想而已,現實上你會遇到三類大挑戰:

1. PM 亂開規格

PM 不會管你死活,硬是要你同時既提供 Facebook / OpenID / Yahoo Auth / Google OpenID。天知道這些網站認證和存取 API 的規格完全都不一樣。

硬是把這些方案一起塞到一個 controller 和同一個 model,瞬間就會無法維護。不…很可能是 code 亂到讓自己狂跌倒,直接作不出來

2. OAuth 版本規格間的問題

理想的境界應該是大家都走 OAuth 就能夠解決問題,但是 OAuth 1.0 推出時,鬧了一個大笑話:被發現有 security issue。於是 OAuth 推出了 1.0a 的修補方案,但這又衍生出另外一個問題:每一家解決 security issue 機制完全不一樣。

因為 service provider 的機制完全不一樣,就造成了已經上路使用 OAuth 的網站大囧。因為 1.0a 那步要變成客製。其實大家做的調整都差不多,但當時有一家是來亂的:Yahoo ….

因為 Yahoo 實在太特例,還造成當時 OAuth 這個 rubygem 的作者,拒絕支援 Yahoo(因為要做的修改不只是「小」修改而已)。

這件事實在是太囧了,於是 OAuth 在不久後,又提供了一個解決方案:直接提出 OAuth 2.0!

鬧劇到這裡就結束了嗎?

沒有。

因為 OAuth 2.0 不相容 1.0a 及 1.0 …

好吧,那算了,大家還是繼續裝死使用 1.0x …

還沒有結束喔!

原本完全不鳥 OAuth 的 Facebook 這時候宣布即將放棄自己的 Facebook Connect 架構,宣布未來直接擁抱 OAuth 2.0。

崩潰。一個專案上跑 n 種 OAuth library 是什麼鬼....

[** 如果你是沒什麼信念的 Web Developer,看到這裡我建議你可以轉行 **]

3. 大網站本身直接的 API 改版以及認證機制的改變

一個網站只要還沒倒,就不可能一直停滯不前。更尤有甚者如 Facebook,它的 API 更是三天一小改,五天一大改。而 FB 的 認證架構 和 API 一改,相對的 library wrapper 就一定會跟著改。

這就苦到那一些直接使用 library 接認證的開發者。

而 FB 改版就已經夠令人苦惱,其他網站不可能也像一攤死水,Google 也改很大....。從之前只是
OpenID + API 存取,改成直接走 OAuth ...

你也許會問,為何要使用 library 直接接認證呢?那是不用獨立 library 接認證有時候也不太行得通,因為每一家提供使用者資訊的「方式」和「資料格式」幾乎不一樣。有時候還要分好幾步才能拿到令人滿意的結果

理想的解決方案

當 Web Developer 實在太苦了,賣雞排真的比較輕鬆 :/

理想中 Developer 們需要的解決方案應該是這樣的:

  1. 開發者不需管最底層的傳統認證方案是哪一套 solution,甚至是不只局限於 Rails 這個框架
  2. 開發者不需管提供認證方使用的是哪一套協定
  3. 開發者拿到的使用者資料格式應該是接近一致的

這套方案存在嗎?

存在,它就是 OmniAuth

小結

前言歷史寫太長了,決定拆成幾篇寫完。下集待續。

 
almost 6 years ago

今天下班回家,看到 Mr. Jamie 寫了這一篇 魔球 (Moneyball):一個 Hack Everything 的棒球故事

電影《魔球 (Moneyball)》終於在台灣上映了,一樣的我也還沒去看。但我同樣的也要說,就算你沒有要進電影院看故事,我也推薦你一定要去買魔球這本書。

但我要推薦的理由跟 inside 的 fOxJamie 都不一樣。我推薦的原因是,它是一本告訴你「要成為產業贏家就必須搞清楚競賽重點」的書。

魔球是一本 2002 年出版的書,現在這個版本是因應電影上映重新出過的書。中文書第一版出的時候,我正念大二。

而閱讀這本書,從此改變了我對經營事業的看法。

不是 Hack ,而是抓住遊戲的重點

Billy Beane 的故事相信大家都耳熟能詳。Mr. Jamie 整理了五段摘要:

  • 一個老產業 + 一支窮球隊
  • 勝場數 = 營收
  • 最珍貴的資源: 27 Outs
  • 數字 > 天賦
  • 第二年

我就不重新寫了。

而 Billy Beane 的故事,讓我所領悟到很清楚的一件事是: Billy Beane 並不是個 Game Hacker,而他的成功,是因找到了這場金錢遊戲的本質。

(也許是我念數學系的關係,教授平常要求我們的不是去練各種技巧,而是去挖出問題本質,以自身累積出的理論與實力見題解題、見招拆招)

在大聯盟賺到很多錢的方法?

  • 如何賺大錢?勝場數 = 營收
  • 如何贏球?在 27 個出局數中得到最多分
  • 如何得到最多分?提高上壘率
  • 如何提高上壘率?找出厲害的球員
  • 沒那麼多錢買明星球員怎麼辦?找出上壘率高,但有其他缺陷導致薪水被嚴重低估的球員。

而 Billy 所作的也很單純,就是:「用一分錢實實在在的買下一分錢的勝利」。想辦法讓他的錢花的有價值。

而其他人的手段卻是「買明星」,而說穿了也是用「用十塊錢去賭賺一塊錢的機會。」

所有人都能靠賭博賺錢,但是真正賺到錢的機率很低,所以絕大多數的球隊也幾乎都是花了大錢,但票房勝場慘兮兮。

要從網路上賺錢,第一天就要作能有實質收入的生意

本來我也覺得大聯盟的砸錢遊戲,荒謬可笑。

直到我踏入了網路界才發現,原來這樣的劇本在各個領域內無時無刻都在上演。只是賭博遊戲變成了:

  • 如何在網路上賺錢?做出 PV 幾百萬的網站。
  • 網站如何長成 PV 幾百萬? => 做出很酷的網站 => 花大錢 Hire 明星團隊
  • 網站如何長成 PV 幾百萬? => 生出很棒的內容 => 花很多錢找人產生內容、經營社群
  • PV 沒有成長怎麼辦 => 改版增加更多更屌的實驗新 feature => RD 不夠 => Hire 更多的 RD
  • PV 沒有成長怎麼辦 => 砸錢養更多的編輯生更多的 content => 編輯不夠 => Hire 更多的編輯

一年半載下來。準備的幾千萬資本額不夠燒,就算有幾百萬 PV。等到你做到幾百萬 PV 的那一天,你才發現因為 PV 不能吃,轉換率太低,回收的利潤根本不夠龐大的人事費用,然後因為你的帳面太難看,又沒有 VC 想投你,最後就只能黯然收攤。

這不是在影射任何一家網路公司,而是幾乎所有倒掉的網路公司都是類似的劇本。只是誰的口袋比較淺,誰先死。

從網路上賺到錢的秘密:「charge for your products.」

37 Signals 的 DHH 曾經在 2008 的 Startup School 給過一場 Talk。這場 Talk 曾經震撼當時的矽谷,這個影片那時還在網路上傳來傳去好一陣子,蔚為風潮。

因為在這場 Talk 中,他講出 37signals 賺錢真正的秘方,這個秘方真的非常非常簡單:簡單到這個言論當時造成矽谷一陣騷動,那就是:「charge for your products.

想從網路上「賺錢」?很簡單,那就是先「收錢」啊!

很好笑對吧?沒想到大家都在作「慈善」,做到忘記其實公司成立的目的,其實就是要「賺錢」。

小結

更有趣的是,這分別是 2002 以及 2008 的兩個故事。至今你還可以在各行各業中看到,大家還是拼了命的在下大注賭博:拿自己的老底賭,去借大錢賭。

很多程式設計師總打趣,若寫程式賺不到錢,那就應該回家賣雞排。

若你打算開雞排店,就算你炸的雞排很難吃,你會有可能從開業第一天,就每天雞排都免費,送到有人開始覺得你炸的雞排很好吃,然後你才決定開始賣 40 塊嗎?

你不會,因為如果你這樣作,店開一個月就會倒了。

為什麼你覺得你在網路上這樣送免費雞排不會倒?

從雞排銷售數字分析廚師手藝?Hack 雞排香料祕方?

我想我從這些故事裡,領悟到的是:「你要靠賣雞排賺錢就不要免費;你要靠賣雞排賺大錢就應該努力去把雞排炸的很好吃,讓更多人主動衝來買; 而租個豪華大攤位,挖個五星級廚師、開發榴槤雞排口味,客人不一定會更多,但更有可能的是會讓你虧到死而已...」。

我不知道你會在魔球這本書這場 Talk 裡看到什麼。

希望有機會看到你想追求的答案。

 
almost 6 years ago

今天在 RGBA 跟 DK 嘴砲聊 Twitter 釋出的 BootStrap 這套 CSS Framework,才雄雄想起來我前幾週寫了一個小玩具,忘記拿出來講。

我曾經在 Asset Pipeline 的重大意義:Version Control Your Asset Package 提過 bootstrap-rails 這個 gem。

Rails 社群這群狂徒當然不會放棄把 Bootstrap 扔進 Gem 做 Asset Pipeline 的機會。事實上,Bootstrap 還是大家練習包 Asset Gem 的絕佳練習對象。你可以在網路上 Google 到一堆 bootstrap-rails 的 gem,幾乎都是在做同樣的事 XD

不過 Asset Gem 包好了,剩下來的問題就是… Helper。Bootstrap 是提供了樣式,但是這些被指定了 class 的 HTML呢?

有麵包屑、列表、警告訊息、表單,別跟我說你還是想要手寫啊?

Rails Developer 要有骨氣一點,要繼續秉持著懶的寫 HTML 的精神繼續寫 Ruby XD

所以我的練習作業跟人家不一樣,我是跑去寫 Rails Helper,我把原先的 Asset Gem fork 出來 一份,然後寫了幾乎所有可以拿來練的 HTML Helper …XD

寫一般 HTML Helper 還算簡單,基本上也是拿 前輩寫過的 Helper 改一改 DOM 結構扔進去包成 Gem。

但是寫 Form Helper 就很麻煩了。因為表單元件除了 text_field 與 text_area 這兩個選項外的,實在千奇百怪,什麼鬼 case 都有。本來之前也想秉著硬幹魂硬幹到底,折騰兩個小時以後就決定砍掉放棄了。

本來想說跑去看看其他 Form Gem 如何設計,自己也來寫一套 Form Helper。結果看完第一套 Gem simple_form 我就投降了。simple_form 考慮得很周全,幾乎什麼 case 都考慮到了

要重造一台精密坦克,即便是只有 clone 履帶也可能超過我能力。

我馬上放棄自己寫 Form Helper 的念頭。方向換成鑽研如何使用 simple_form 自動產生出來的表單,改成可以直接 bootstrap 樣式的 HTML。

本來最初的想法也是直接 override helper method,這樣最快。因為 simple form 自己產生出來的表單欄位,外面還是會產生出來一堆包覆用的 styling div。

後來看完 source 繞了一大圈才發現,README 上面就有說明,simple_form 提供直接「抽換」template 的選項。

也就是可以透過 override def input 這個 method,可以達到改變 styling div 的目的。

所以我做的事就變成重寫 form builder

module Bootstrap
  
  class CustomFormBuilder < SimpleForm::FormBuilder
    def input(attribute_name, options = {}, &block)
       "<div class='clearfix'>#{super}</div>".html_safe
    end

    def button(type, *args, &block)
      options = args.extract_options!
      options[:class] = "btn primary"
      args << options
      "<div class='actions'>
        #{super}
      </div>".html_safe
    end
  end
end

override input helper 再包進自己的 Helper Gem 內。

class CollectionInput < SimpleForm::Inputs::CollectionInput
  def input
    "<div class='input'>#{super}</div>".html_safe
  end
end

寫表單再也不需要辛苦的手包 div 調整 style。

可以維持用原先 simple_form 的這種標準寫法,卻產生出符合 bootstrap style 的 form。

<%= bootstrap_form_for :post, :url => posts_path do |f| %>
  <%= f.input :username, :disabled => true, :hint => "You cannot change your username." %>
  <%= f.button :submit %>
<% end %>

如此一來,以後我 bootstrap 任何 project 就可以直接引入自己寫的 xdite-bootstrap-rails 這個 gem,一次搞定 Form , HTML , CSS , JavaScript 的問題。

繼續懶惰下去。甚至可能乾脆寫成 rails template,因為也許 template 可能才 3 行而已?

寫完這個 gem,我突然間理解為什麼 simple_form 打遍天下無敵手,因為它本身就是一套 Form Framework。其他人實在沒有再造一套輪子的必要,透過 override template,你幾乎可以造出各式各樣的表單欄位....

 
almost 6 years ago

Github 內部自用的機器人 Hubot 一直是個神秘的產品,常常看到內部員工在投影片內炫耀 Hubot 多麼的屌:

Hubot1

Hubot2

但往往只是聞其聲,不見其蹤。

不過要是按照 Github 內部慣例,常常在員工投影片出現的東西,往往就是下一個 release 的標的。因此大家也都是迫不及待在等 Hubot 的釋出。按照大家的假想,Hubot 應該是某種 Perl 或 Ruby 的 client,而且 Ruby 的機率可能還大的多。

但 Github 官方 blog 貼的這篇公告文章讓大家下巴掉下來:HubotCoffeeScript 寫的.......XDDDDD

(註:以防你不知道什麼是 CoffeeScript,或者是它能帶來的好處,我曾經寫過這麼一篇文章 解釋原理以及用途 )

CoffeeScript meets NodeJS

更精確的來說,Hubot 是用 NodeJS 架構作出來的一套機器人框架,而 Github 並非直接撰寫 JavaScript,他們是直接使用 CoffeeScript。整個專案的原始碼都只有 .coffee 而已。

Support Campfire 與 IRC

目前 Hubot 支援兩種 chatroom,預設是 37signals 的產品 Campfire,也有提供 IRC 的 adapter。

Provide tons of hubot-scripts example

為了避免大家不知道怎樣擴展 Hubot 的功能,Github 在專案內提供了大概十支左右的 example,也另開了一個專案 hubot-scripts,讓大家交流和 contribute。

Hosted on Heroku

你會覺得,要跑起這樣一隻 bot,也許又要找一台機器把 bot 跑起來?

Well,這次你錯了…

Hubot 的架構被設計為可以透過 HerokuProcfile 架構掛起來,也就是可以把這一隻 Bot 養在雲端 XD ( Hubot 的文件有教你怎麼作 )

小結

昨天晚上在 Twitter 上看到幾個 Rails core team member 在講 hubot-scripts 時,才突然發現 Hubot 竟然已經釋出了。早上認真想玩時,發現整個架構竟然是 CoffeeScript + NodeJS 時,內心其實有小震撼…

目前看到的幾個是 feature project 的 network program 都是以這樣的方式誕生,如 Pow、Hubot。看來 network program 應該會越來越往 NodeJS 方向傾斜過去。

BTW,今天在玩 Hubot 時,有發現幾個比較值得注意的地方。

  1. 請使用 trunk 版。雖然官方請你直接下載有版本號的打包檔,不過大概是剛釋出,bug 有一點點多,但社群都積極的在修補,這些修補檔目前都還在 master branch 上,還沒被 tag 成 release 版本。所以跑 master 通常會比較沒問題。

  2. 扔上 Heroku 時,要記得寫 Procfile,不然是不會動的。Procfile 的 sample 在 src/templates 下。記得一定要寫,然後再開 heroku ps:scale app=1。完整 Heroku 教學放在 src/templates/README.md 下。

Good Luck!

 
almost 6 years ago

我不知道設計這個 feature 的是哪位。只是簡單講一下我覺得這個 feature 畫虎不成反類犬了。

在為網站實作 SEO 改善工程時,我們通常會使用一個技巧:在 permalink 裡面塞關鍵字

這樣的設計你可以在 T 客邦 看到,也可以在 PIXNET 看到。

  • T 客邦的設計是 /1234-seo-in-url
  • PIXNET 的設計是 /5678-SEO藏在網址裡

中文是否適合塞在網址裡面,還是個見仁見智的問題,畢竟每一家處理 URL ENCODE 的方法不一樣。但

Yahoo 的網址是這樣的: /SEO藏在網址裡-7890.html。

看的出設計者應該覺得這是個 獨樹一格 別出心裁 的設計。因為全世界幾乎沒有人這樣幹啊 =_=|||

螢幕快照 2011-10-25 下午5.25.23

螢幕快照 2011-10-25 下午5.26.29

這樣你應該看出問題了吧。

各家縮網址和 auto-link 的 library 不認得中文字。因此

  • /1234-seo-in-url => 不會有問題
  • /5678-SEO藏在網址裡 => 會被 parse 成 /5678 ,但因為是動態網頁,所以還是沒問題

  • /SEO藏在網址裡-7890.html => 被 parse 成 / ,就算輸入 /7890.html 還是連不到。

「將中文放在 URL 裡且是在數字之前」的設計,會造成在某些網站社群穿透力為 0,因為貼的連結會被自動 parse 成為根本不能動的連結。

不知道為什麼這個問題沒被測到,這應該在 beta 測試就要被檢驗出來了...

===

後續 update

網友 @fauzty 說:

Android 手機的內建瀏覽器和海豚瀏覽器,就因此看不到新版奇摩新聞。Opera Mini 倒是可以,應該是 url encode 問題
 
almost 6 years ago

先聲明,這一篇純粹是個人讀後感而已。不是什麼嚴肅的 Book Review。

今天 賈伯斯傳 上市了。身為一個蘋果愛用者,自然是蠻高興這件事的。因此就花了「一點時間」把這本書讀完了。

但是讀完之後,坦白說我真的算蠻失望的。若要我形容這本書的讀後感,我會說 -- 去把 2 L 悅氏礦泉水 一飲而盡,你就知道讀這本書的滋味了。

這麼好的題材,被這樣烹調實在很可惜。

沒有人說傳記「必須」要有趣,但我覺得「Jobs 傳」這本書平淡到過於異常。

怎麼說呢?也許你是 Jobs 的反對者,那麼你可能會覺得這本書 --- 很有趣。因為裡面不少八卦小故事,關於他詭異作風、負面人格描述,關於不屑別人的行為的大量描述。

但有營養的呢?我覺得很少。如果這是採訪一百多個親友、同事、仇敵得出來的樣貌,我真的非常失望。

人們最敬佩也想了解的是 Jobs 的熱情、Vision、和推動他持續創造出偉大產品背後的秘密。而 Steve Jobs 會希望作者幫他作傳,也是基於他想讓「他的孩子」們知道他「所做的一切」、還有「這一切背後的想法與意義」。

但是 Walter Isaacson,他真的不理解 Jobs,這也就是我認為可惜的地方。我在書中只見作者一直不斷的描述周遭人覺得他多詭異、多暴君,而雖然看得出來作者試圖為 Jobs 說話解套,但是一直失敗。He just doesn't get it.。

我想這也是 Jobs 這輩子始終為什麼認為別人為什麼愚蠢的原因:「He just doesn't get it.」

如果你曾新創過某個事業,並 fell in love with it。你就能從書中就會看見閃閃發光的 Jobs。他能夠夠持續偉大的原因很簡單 --- 那就是他熱愛自己的公司,熱愛持續打造偉大的成品。Willing to die for it,而他最後也作到了…

我想這也許是因為傳記作者始終是個作家。而不是個 some business founders。只要你是個 bussiness owner,曾經熱愛過某個事業,用盡了全力打造你深信的偉大的產品。你就能夠了解 Steve Jobs 的行為和心理模式。這是領人薪水,覺得別人家資金花不完的上班族很難領悟到的事:

It's simple,只要你覺得這是別人的事業。你就不會想要 -- 「做到最好」。反之亦然。

Steve 會有那麼大的動力打造產品,力求瘋狂的完美,講話時不時散發著令人攝服的現實扭曲場。這些都不是因為它是一個詭異瘋子,而是因為他真心相信且瘋狂熱愛它的事業。

用盡一切的氣力去熱愛作某一件事,去把產品打造到最好是很累的。有過這樣經驗的人,就會更敬佩 Steve Jobs,他真的夠厲害,遠遠不是熱情覺得讓人可敬而已。這也不只是熱情而已,當中還要有不動趨鞭自己進步的動力。

因為他走在世界最前端,這更加格外的辛苦。

We do want to see things behind these. 我們不是要看瘋子傳。

He just doesn't get it.

===

Reed Jobs 都可能比 Water Issacson 懂 Steve Jobs 在想什麼( according to some piece of this book )。真是可惜了,這麼好的材料,這麼平淡的一本八卦書….

 
almost 6 years ago

stickies 這個 plugin 是我在開發中常用的一個 plugin。用來實作注意/警告訊息的。

stickies 是一個非常古早的 plugin,在 2008 年前左右就問世了,當時的特效還是使用 rjs 。後來 ihower和多 時把這個 plugin 翻成 jQuery 版本。

這套 plugin 我自己還蠻喜歡用的。T 客邦內部也用了很多,不過因為內部有 Gem (認證系統)預設訊息就綁 stickies,每次開新專案裝完認證,就要手動 copy plugin 到 vendor/ 和手動 copy assets 到 public/,有夠麻煩...

今天進公司大概跟同事聊了一下昨天寫的用 Asset Pipeline 掛 Asset 的概念。

vincent 就覺得 stickies 應該要首先被拔出去,每次 copy asset 實在太麻煩了,將來最好還可以放在認證系統的 Gemfile dependency 上。於是剛剛我就接下來作了。

本來以為只是掛 asset 而已,小事一樁。不巧的我發現它還是 Rails 2.x 時代的 Rails Plugin。於是剛剛索性將架構作了一番重構。

(重寫 generator,用 Railtie / Engine 作 gem )

目前 stickies 已經被我包裝成 rubygems,並支援 Rails 3.0 / 3.1。
而且 3.1 版本可以直接用 asset pipeline 掛 assets。不需要再跑 copy tasks )

code 放在這裡:https://github.com/techbang/stickies

 
almost 6 years ago

Asset Pipeline 是 Rails 3.1 引入的重大 feature。

之前我曾經為文撰寫過背後設計的意義以及哲學。若你有興趣的話可以觀看這一系列的文章:

今天我要談的是 Assetp pipeline 帶來的另一個震撼:"Asset as rubygem"

Asset as rubygem

其實這個設計在 Rails 3.1 的蠻早期就有了,而且就藏在官方範例中。只是我初看時完全沒意識到這個設計背後的原理、哲學以及它的重大意義。而多數的鎂光燈也集中在 Asset Pipeline 可大幅獲益於 Compass 與 CoffeeScript 中,沒多少人提起這件事。

Rails 的 application.js 裡面有著這麼一段:

application.js
//= require jquery
//= require jquery_ujs

而這是由 Gemfile 中的這個 gem : jquery-rails 所提供的

Gemfile
gem "jquery-rails"

看得出來奧妙嗎?

結合 Rails Engine 提供 asset 掛載

yes。現在你可以透過結合 Rails Engine 把 gem 中的 asset 掛起來。所以 application.js 中

application.js
//= require jquery
//= require jquery_ujs

的 jquery 以及 jquery_ujs 都是 jquery-rails 這個 gem 中的 javascript。

Boost you project

還看不出來意義嗎?讓我再給你一個例子吧:bootstrap-rails

Bootstrap 是 Twitter 近期所推出的一個 CSS Framework opensource project,它能夠讓程式設計師,在做 project 的初期(設計師還沒把畫面設計好時),或者是在做小 project (不需要複雜 Style)時,很快的就把一些簡單的版面元素搞定,簡單大方。

但是在 Rails project 中 setup 還是小麻煩,因為你必須手動把 asset 搬到指定位址才行。

若是我跟你說,如果用這個 gem,你只要在 Gemfile 裡 require

Gemfile
gem 'anjlab-bootstrap-rails', :require => 'bootstrap-rails'

然後再到 application.css 中

application.css
//= require bootstrap

接著即刻就可以寫 HTML,Bootstrap 馬上就生效了呢?

另一個程式設計師最愛的 web-app-theme,在 Rails 3.1 後的版本,也可以用同樣的方法,把 CSS 直接掛起來,馬上寫!

而不是像之前的作法,掛上 gem 之後,還得用 generator 把當時版本的 asset copy (算是半自動)到目錄資料夾裡!

不僅是這兩個 CSS framework,將來只要是有組織的 asset 套件,如 CSS Framework / jQuery plugin,都有可能可以這樣搞。

這樣夠震撼你的心靈了嗎?

「萃取」 / 「打包」 / 「版本控制」core asset 的好處

在從前,若我們同時維護多個系列 project,都會有 asset 其實都長得差不多,但是會有只要一份發現要更新,其他份沒有同步更新,就會相當麻煩的痛處。但是作這些更新,都必須要手動去調整。而且 asset 的 version control log 會與專案程式的 version control log 混在一起。若沒有馬上一併處理更新,時日一久,當你要更新其他 project 時,就會忘記自己需要改哪裡。

使用 SCSS 並沒有改變: 「你還是要 copy 好幾份 SCSS 到多個 project 」的事實。

但是如果你的 core SCSS / core JavaScript plugin 是一份 Gem 呢?

** 維護的方式可以變成只需要維護 Gemfile 中的版本號,複雜度幾乎趨近於 0。**

Gemfile
gem "some-css-plugin", "0.0.2"
gem "some-js-plugin", "0.5.7"

你不需要再對「一包」檔案作版本控制,而是對「一個數字」作版本控制。

使用 git submodule 不行嗎?

當然你也會問,使用 git submodule 管理 asset 不行嗎? 這當然也是一種作法。但問題在於

  • git submodule 不管修改、刪除、更新都要特殊的步驟,否則就會弄爛你的 project
  • git submodule 是依 commit id
  • git submodule 沒有處理 dependency 問題

而且當你想把 asset revert 到某一版本時,可能就會讓你的耐性爆炸 ….

小結

因為今天在練習寫 Generator 還有 Rails Engine。寫著寫著就有鬼點子,不知道 Rails 3.1 之後,Rails Engine 支不支援掛 asset。當然也沒有一股就栽下去,當然先去找找有沒人已經作過這件事,想想 Bootstrap 最近很紅,應該會變成大家練習的對象。沒想到真的就有人寫出來....而且還有一堆。

看了別人有實作出來,就隨便找了一套 CSS 當練習包 Gem 的對象,熟悉一下結構。沒想到門檻也沒有說很高。既然 CSS 成功了,就開始繼續亂想 JavaScript 可不可以惡搞,這一想,才意識到 Rails 範例的

application.js
//= require jquery
//= require jquery_ujs

就是在講這件事啊 XDDDDDD。

為什麼我這麼豬頭,都沒想到過啊…繼續往下想,就 blow my mind 了。

因為既然這樣可以 work,那就表示以後只要是 asset,就可以打包。CSS framework 和 jQuery plugin 市面上滿山滿谷,那就表示將來一定會出現更多更變態的玩法。不禁讓人越來越期待接下來的發展了。

越來越覺得身為一個 Rails Developer 是相當幸福快樂的事啊!

 
almost 6 years ago

各位應該有注意到我的 theme 從 Octopress 換成了自定的 Theme 了。
LOGO 和背景色有做了一點小調整。

頭換成以前經典款的 LOGO,背景色改成藍色。hover LOGO 還會進行「Dell 跳」XD

不過這些都不是重點。

這次的改版比較特別的是,CSS 是 @evenwu 直接 fork 我的 blog 改的。
我只要收它的 pull request,merge 進來就可以 deploy 改版了。

為什麼我以前沒想過要跟設計師這樣合作呢?

 
almost 6 years ago

跟各位介紹我剛剛做好的這一個翻譯 project 「Learn Ruby The Hard Way」中文版

這是 Zed Shaw 2011 年 8 月新出版的書。其實也不算新了,它其實是「Learn Python The Hard Way」 的 Ruby 改編版。

Zed Shaw 目前正在積極出版 Learn Code The Hard Way,目前已經出了 Python、Ruby,下一本 C 正在撰寫中。

在 8 月時,看到這一本書剛推出,其實就很想翻,那時候也寫信取得 「Learn Python The Hard Way」中譯版的譯者授權,讓我可以將它的譯作也放到此書裡面( 畢竟大部分關於原理敘述的段落是相通的)。

但那一陣子畢竟太忙。我也只有趁一個假日草草大概先翻了 10 幾篇,接著就把它放著了。這陣子放長假,才有機會將它從箱子裡面翻出來整理。剛好用 Octopress 也蠻熟練的。就把它也架了起來。

希望對大家學習 Ruby 有任何助益。

另外改一下 LPTHW 中文版的譯序 為大家介紹這本書。


《 笨方法學 Ruby 》(Learn Ruby The Hard Way)是 Zed Shaw 編寫的一本Ruby 入門書籍。適合對電腦了解不多,沒有學過寫程式,但對寫程式感興趣的朋友學習使用。這本書以習題的方式引導讀者一步一步學習寫程式,從簡單的打印一直講到完整專案的實現。也許讀完這本書並不意味著你已經學會了寫程式,但至少你會對程式語言以及開發程式這個行業有一個初步的了解。

筆者認為本書區別於其它入門書籍的特點如下:

  • 注重實踐。本書提供了足夠的練習代碼,如果你完成了所有的練習(包括加分習題),那你已經寫了上萬行的代碼。要知道很多職業程式設計師一年也就寫幾萬行程式碼而已。
  • 注重能力培養。除了原序言提到的「讀和寫」、「注重細節」、以及「發現不同」這樣的基本能力以外,本書還培養了讀者自己鑽研問題和尋求答案的能力。
  • 注重好習慣的養成。本書詳細地講解了怎樣寫出好的代碼、好的註釋、好的項目。這會讓你在後續的學習中少走很多彎路。

本書結構非常簡單,其實就是52 個習題而已。其中26 個覆蓋了輸入輸出、變量、以及函式三個課題,另外 26 個覆蓋了一些比較進階的話題,如條件判斷、迴圈、類和物件、程式碼測試、以及專案的實現等。每一章節的格式基本都是一樣的,以程式碼練習題開始,讀者照著說明編寫程式碼(不允許複製貼上),運行並檢查結果,然後再做一下加分習題就可以了。當然如果你覺得加分習題對你來說有點難,你也可以暫時跳過,以後再完成也沒關係。

另外閱讀本書還需要你有一定的英文能力。其實學習寫程式不懂英語是很吃虧的,畢竟編程語言都是基於英語,而程式社群的主要交流方式也是英語。不會英語的人在程式界可能就只好當二等公民了。本書的翻譯盡量保留了所有的英文專業詞彙(可能會有中文說明),而且遵照 Zed 的建議,程式碼及答案部分沒有翻譯成中文,讀者看到不懂的地方,請自己查字典解決。

如果你對自己的英文能力比較有信心,譯者強烈推薦你直接去下載閱讀英文原版。這本書代碼較多,文字內容較少,因此英文原版的閱讀理解也比較容易。

LRTHW的風格和別的書差異很大。它沒有像一般的入門書籍一樣通過討好讀者以激發讀者興趣,而是直截了當地告訴你你需要做什麼,需要注意什麼。這種風格可能會讓人覺得枯燥乏味,讀者姑且把這也當做 Hard Way 的一部分吧。


LPTHW 簡體中文的翻譯者是 wangdingwei82@gmail.com,而他的 blog 是 http://ducktypist.com/

LRTHW 中文版是我基於 LPTHW 中文版的翻譯成果,改編成 Ruby 版,並修正當中繁簡以及不同程式( Python / Ruby 環境所造成的差異改譯而成。

如果你對 LRTHW 的翻譯有任何意見和建議,請在這個 project 的 Github issue 頁發 issue 給我,或者是直接 pull request 也行。

你也可以上 LRTHW 官網購買本書正版,這也是對 Zed Shaw 的支持。