2013年6月27日 星期四

利用formData來達成ajax上傳檔案

最近手邊有個案子用到canvas來做圖片的合成,並且要將輸出圖片存到facebook相簿中,一般來說這種要將圖片合成的功能都在server-side完成,這次用canvas除了為了省時以外,也想盡量減輕server-side的負擔。就這個專案的需求來說,操作canvas不是難事,但是以canvas.toDataURL輸出的dataURL要怎麼以file的形式post到fb呢?


首先,要把 dataURL轉成blob

下面這四點是我在stackoverflow上查到的四個步驟:
  1. Take a bytearray or any other data
  2. Convert it to base64
  3. Convert it to blob
  4. Send it as a normal file with Ajax/xhr/FormData using your favorite method
下面這段程式碼就是上述的1~3個步驟

function (dataURI) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs
    var byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    var blob = new Blob([ab]);
    return blob;
}

不要問我上面的code怎麼來的,我抄來的!(挺)
接下來我曾經好傻好天真的認為可以把blob塞進form的欄位中,然後把它submit出去,但最後發現是不可以的...


用Ajax將檔案post出去吧


查了一下發現最方便的方式是使用formData物件,只要只用他的append方法就能把blob或string append上去:
var fd = new FormData();
fd.append("source", blob);
接下來只要將他post出去就好囉:
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.send(fd);

2013年6月26日 星期三

Rails的db:seed小技巧

在開發Rails專案時,在db的sync上,常常會遇到下面兩個情況:

1. 開發環境與正式環境的初始資料
2. 多人開發時的local DB同步問題

第二個問題其實只要開一個遠端的伺服器來共用就解決了,但是在使用sqlite或是沒有網路的情況下,這麼做實在很麻煩,而且有時候我們也不希望別人的資料弄髒資料庫。這時候我們可以使用seed.rb來初始化資料庫中的資料,我們來看看怎麼做:
# seed.rb

areas = [
  {name:"台北"},
  {name:"高雄"}
]
Area.create areas
然後下rake db:seed這個指令就行了


進階需求


但是需要初始化的資料往往都是系統的固定選項(如縣市等不應被隨意增加、減少的資料),這時常常會有需要指定id的需求,這時我們就要稍微修改一下作法:
areas = [
  {id:1, name:"台北"},
  {id:2, name:"高雄"}
]
areas.each do |area|
  s = Area.new area
  s.id = area[:id]
  s.save
end

如果是確定此資料表中只會出現seed中所寫入的資料的話,我們可以加上delete_all來先清空資料表再做插入資料的動作:
Area.delete_all

使用csv匯入資料


在只有少量資料需要被處理時,直接將資料寫在seed.rb十分方便,但是當資料量很大時,我們希望能以報表的形式事先整理好再做匯入。而csv是一個格式簡單,也能被Excel, Numbers等報表軟體支援的檔案格式,因此我選擇它作為外部資料匯入的媒介。

但是在Excel中比較難去設定成我們想要的utf-8編碼,比較建議使用Apple的Numbers軟體,可以直接輸出成utf-8的csv檔。

來一段簡單的程式碼大家應該就能看懂了:
# seed.rb

require "csv"
SysSchool.delete_all
CSV.foreach("#{Rails.root}/db/school.csv") do |row|
 school = {
  id:row[0],
  name:row[1],
  sys_area_id:row[2]
 }
 s = SysSchool.new school
 s.id = school[:id]
 s.save
end

這段程式碼也是要貼在seed.rb中的,這樣一來在執行"rake db:seed"時,就會先刪除資料表中的資料,並將db/school.csv裡的資料一列一列插進資料表中。

2013年6月8日 星期六

Middleman 產生 sitemap 的方法

middleman除了前兩篇提到的好用功能外,當然也可以產生sitemap囉,我們來看看要麼做:

1. 安裝builder

首先在Gemfile中加入這一行:
gem "builder"
然後在config.rb中加入:
require "builder"
接著bundle install


2. 在根目錄下新增data/site.yml

內容:
url: <你的網址,ex. http://google.com>


3. 在source資料夾中新增sitemap.xml.builder

xml.instruct!
xml.urlset "xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9" do
  sitemap.resources.each do |resource|
    xml.url do
      xml.loc "http://dash.tw/#{resource.url}"
    end if resource.url !~ /\.(css|js|eot|svg|woff|ttf|png|jpg|psd)$/ 
  end
end

然後每次build的時候就會產出sitemap到build/sitemap.xml了

2013年6月1日 星期六

Middleman奇技淫巧大揭密

上一篇我們介紹到了middleman的基礎知識以及slim的安裝,這一篇我們會介紹更多好用的工具,我們先接續上一篇講到的slim:

使用slim作為project預設的template engine


上一篇教到的slim安裝方式其實不能算是很方便,因為安裝過後還必須手動將所有的erb附檔名換成slim,檔案內容也要改成slim的格式,並不是太親民,我們希望一開始產生project時裡面的頁面就全部是以slim的格式呈現的。
幸好middleman-slim這一款gem可以幫我們做到這件事。來,簡單兩步驟:
  1. gem install middleman-slim 
  2. middleman init PROJECT_NAME --template slim

ok,這樣就搞定了。


懶得按F5沒關係 - LiveReload幫你自動刷新瀏覽器頁面


LiveReload真的可以稱得上是究極懶人功能,目前市面上最有名的是這個:http://livereload.com/,但他是要花錢買的。現在使用middleman讓你不花半毛錢,而且幾乎零設定,一樣是簡單的三步驟:
  1. 在Gemfile中加入這行:gem "middleman-livereload"
  2. 在config.rb中加入這行:activate :livereload
  3. 在終端機輸入:bundle install,重啟伺服器
現在只要在檔案中做了任意修改並存檔後,瀏覽器的頁面就會自動刷新,搭配外接螢幕真的可以說是神兵利器啊~XD


高效率撰寫css - sass&compass


sass是一種可以被編譯成css的語言,他的出現是為了補足css的諸多限制,例如:無法使用變數、無法進行數學運算、沒有函式。習慣了sass之後,你可以更有效率的撰寫css,只是在寫完以後會需要多一個編譯的動作罷了,但幸好在middleman中,這些事情都會自動幫我們做好。
在開始教學之前,還要在講解一個東西,那就是compass。compass之於sass就好像jquery之於javascript,他提供了許多常用的函式及模組讓我們能更有效率的撰寫sass。
好,那我們就開始安裝sass及compass吧~
  1. 在Gemfile中加入這兩行:gem "sass"、gem "compass"
  2. bundle install
記得將附檔名.css改成.css.sass,還要注意一下縮排、分號、大括號喔。


用Lorem產生假文字、假日期、假圖片


middleman之所以好用,不只是因為可以整合上面提到的plugin,最大的原因就是他能嵌入ruby程式碼,幫你搞定許多routine work,例如:迴圈產生假的list、產生假文字。

在這裡我們就介紹一下如何使用ruby code來產生迴圈及假資料

Loop:

<% 5.times do%>
    <!-- HTML code -->
<% end %>

假文字:

<%= lorem.words 5 %>

假句子:

<%= lorem.sentence %>

假圖片:

<%= lorem.image("300x400", :background_color=>"333", :color=>"111", :text=>"YEAH") %>

<%= lorem.image("300x400", :random_color=>true %>


Middleman快速入手

之前就時常聽到Middleman這個東東,但是一直沒有機會去試他,因為其實自己在刻html上還沒遇到什麼太大的產能問題。今天為了教設計師怎麼迅速產生靜態網站,自己便下海來學了一下。

why middleman?

當然是因為他好吃好看又好玩
  1. 可以內嵌partial頁面
  2. 可以導入haml、slim加快layout速度
  3. 可以導入sass加快寫css的效率及管理
  4. 可以livereload,瀏覽器即時更新目前頁面


How to start?

首先,你得安裝ruby環境及gem,這部份不贅述。
安裝好ruby環境後,一行指令輕鬆安裝:
gem install middleman

好了,這樣就裝好了,接著我們來介紹三個實用指令:
  • middleman init [project_name]
  • middleman server 
  • middleman build


產生middleman project - middleman init


很簡單,在你要產生project的路徑下打這段指令即可:
middleman init [project_name]

這時middleman會幫你產生一些檔案:
source(資料夾)、
config.rb、
Gemfile、
Gemfile.lock、
.gitignore

我們主要要修改的html,css,javascript等檔案,都在source這個資料夾裡面。


啟動伺服器 - middleman server 


如果還要先安裝apache那也太累了,一樣在專案資料夾底下一行指令:
middleman server

輕鬆啟動你的服務~預設是跑在localhost:4567上


輸出你的專案 - middleman build


一樣在專案資料夾底下一行指令:
middleman build

就會在專案資料夾中產生build資料夾,裡面就是輸出後的靜態頁面了。
看到這裡你可能會很好奇,為什麼我還要多跑這道手續呢?
因為在middleman裡我們預設是使用erb來寫html,雖然跟html幾乎一模一樣,但是我們還是會多少使用到一些嵌程式碼或局部頁面的功能,而這樣的東西還是要經過compile成一般的html檔案,瀏覽器才看得懂。如果你是用sass來寫css,在這個步驟也會同時將scss檔轉成css檔案。


安裝其他套件讓你的專案建立更快速


在middleman中管理套件的方式跟rails是一樣的,只需要把需要安裝的gem加到Gemfile中即可,安裝時只要打這個指令:
bundle install

拿slim這個套件做舉例好了,slim是個跟haml和jade有著異曲同工之妙的html簡化工具,能讓你用更加簡潔的方式撰寫html,例如原本要寫:
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    
    <title>Welcome to Middleman</title>
    
  </head>
  
  <body class="index">
    <div class="welcome">
      <h1>Middleman is Watching</h1>
      <p class="doc">
        <a href="http://middlemanapp.com/">Read Online Documentation</a>
      </p><!-- .doc -->
    </div><!-- .welcome -->
  </body>
</html>

但用slim的話只要這樣寫就夠了,有夠簡單:
| <!doctype html>
html
  head
    meta charset="utf-8"
      title Welcome to Middleman
  body.index
    .welcome
      h1 Middleman is Watching
      p.doc
        a href="http://middlemanapp.com/"
      /! .doc
    /! .welcome

那要怎樣在middleman中使用這個簡潔的撰寫方法勒?只要簡單三步驟:

  1. 在Gemfile中加入gem "slim"
  2. 在config.rb中加入require "slim"
  3. 在終端機輸入:bundle install


OK,接著你就可以開始體驗這種簡潔快速的撰寫方式了!

更多關於middleman的奇技淫巧請看下一篇:Middleman奇技淫巧大揭密