<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Jokry]]></title>
  <link href="http://jokry.com/atom.xml" rel="self"/>
  <link href="http://jokry.com/"/>
  <updated>2012-05-12T12:07:24+08:00</updated>
  <id>http://jokry.com/</id>
  <author>
    <name><![CDATA[Jokry]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[在Rails中使用Redis]]></title>
    <link href="http://jokry.com/blog/2012/05/09/using-redis-with-ruby-on-rails/"/>
    <updated>2012-05-09T22:21:00+08:00</updated>
    <id>http://jokry.com/blog/2012/05/09/using-redis-with-ruby-on-rails</id>
    <content type="html"><![CDATA[<p><a href="http://redis.io">Redis</a> 是一个高性能的key-value数据库，支持strings, sets, sorted sets, lists and hashes 中数据类型。它和<a href="http://memcached.org/">Memcache</a>一样，Redis所有的数据运行在内存中。但不同的是，Redis可以将数据持久化到磁盘中。</p>

<h2>Redis 数据类型</h2>

<p>以下是对Redis支持的数据类型的概括：</p>

<p><code>String</code>    字符串是最基本的类型，可以用作计数器（通过<code>incr</code>, <code>incrby</code>, <code>decr</code>, <code>decrby</code>命令）</p>

<p><code>Set</code>   无序无重复的集合</p>

<p><code>Sorted Set</code>    有序无重复的集合</p>

<p><code>List</code>  有序集合的数组，和Ruby中的Array一样。可以通过<code>pop</code>, <code>push</code>实现队列操作</p>

<p><code>Hash</code>  键值对的哈希类型</p>

<p>Redis的命令可以参考《<a href="http://redis.io/commands">Redis commands</a>》，使用场景可以参考《<a href="http://blog.nosqlfan.com/html/2925.html">redis 适用场景与实现</a>》。</p>

<!--more-->


<h2>安装Redis</h2>

<p>安装非常简单，</p>

<pre><code>curl -O http://redis.googlecode.com/files/redis-2.2.2.tar.gz
tar xzf redis-2.2.2.tar.gz
cd redis-2.2.2
make
cp src/redis-server src/redis-cli /usr/bin
</code></pre>

<h2>启动Redis服务</h2>

<p>如果在本地环境使用<code>redis-server</code>，可以通过以下命令来启动，该命令使用默认的配置。</p>

<pre><code>redis-server
</code></pre>

<p>如果希望使用自己的配置文件，可以加入path</p>

<pre><code>redis-server /path/to/redis.conf
</code></pre>

<h2>Redis 和 Rails</h2>

<p>使用<a href="http://brainspl.at/">Ezra Zygmuntowicz</a>开发的gem——<a href="https://github.com/ezmobius/redis-rb">redis-rb</a>。</p>

<p>第一步，在<code>Gemfile</code>中加入redis-rb</p>

<pre><code>gem 'redis', '2.1.1'
</code></pre>

<p>通过Bundler安装</p>

<pre><code>bundle install
</code></pre>

<p>最后，创建<code>config/initializers/redis.rb</code>进行以下配置</p>

<pre><code>$redis = Redis.new(:host =&gt; 'localhost', :port =&gt; 6379)
</code></pre>

<p>该命令将使用默认的端口6379实例化redis，并设定全局变量 <code>$redis</code>。</p>

<p>让我们检查一下是否一切顺利，启动<code>rails console</code></p>

<pre><code>&gt; $redis
=&gt; #&lt;Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.2.2)&gt; 
&gt; $redis.set('chunky', 'bacon')
=&gt; "OK" 
&gt; $redis.get('chunky')
=&gt; "bacon"
</code></pre>

<h2>和Rails结合的例子</h2>

<p>用户关系（User Friendships）</p>

<p>下面介绍使用<code>ActiveRecord</code>和<code>Redis</code>结合管理用户关系。采用<code>sets</code>来存储关系数据。</p>

<p><code>User</code> Model</p>

<pre><code>class User &lt; ActiveRecord::Base
  # follow a user 关注某个用户
  def follow!(user)
    $redis.multi do
      $redis.sadd(self.redis_key(:following), user.id)
      $redis.sadd(user.redis_key(:followers), self.id)
    end
  end

  # unfollow a user 取消关注某个用户
  def unfollow!(user)
    $redis.multi do
      $redis.srem(self.redis_key(:following), user.id)
      $redis.srem(user.redis_key(:followers), self.id)
    end
  end

  # users that self follows 我的粉丝
  def followers
    user_ids = $redis.smembers(self.redis_key(:followers))
    User.where(:id =&gt; user_ids)
  end

  # users that follow self 我的关注
  def following
    user_ids = $redis.smembers(self.redis_key(:following))
    User.where(:id =&gt; user_ids)
  end

  # users who follow and are being followed by self 互相关注
  def friends
    user_ids = $redis.sinter(self.redis_key(:following), self.redis_key(:followers))
    User.where(:id =&gt; user_ids)
  end

  # does the user follow self 是否是我的粉丝
  def followed_by?(user)
    $redis.sismember(self.redis_key(:followers), user.id)
  end

  # does self follow user 是否关注某个用户
  def following?(user)
    $redis.sismember(self.redis_key(:following), user.id)
  end

  # number of followers 关注总数
  def followers_count
    $redis.scard(self.redis_key(:followers))
  end

  # number of users being followed 粉丝总数
  def following_count
    $redis.scard(self.redis_key(:following))
  end

  # helper method to generate redis keys
  def redis_key(str)
    "user:#{self.id}:#{str}"
  end
end
</code></pre>

<p>使用例子：</p>

<pre><code>&gt; %w[Alfred Bob].each{|name| User.create(:name =&gt; name)}
=&gt; ['Alfred', 'Bob']
&gt; a, b = User.all
=&gt; [#&lt;User id: 1, name: "Alfred"&gt;, #&lt;User id: 2, name: "Bob"&gt;] 
&gt; a.follow!(b)
=&gt; [1, 1] 
&gt; a.following?(b)
=&gt; true 
&gt; b.followed_by?(a)
=&gt; true 
&gt; a.following
=&gt; [#&lt;User id: 2, name: "Bob"&gt;] 
&gt; b.followers
=&gt; [#&lt;User id: 1, name: "Alfred"&gt;]
&gt; a.friends
=&gt; [] 
&gt; b.follow!(a)
=&gt; [1, 1] 
&gt; a.friends
=&gt; [#&lt;User id: 2, name: "Bob"&gt;] 
&gt; b.friends
=&gt; [#&lt;User id: 1, name: "Alfred"&gt;]
</code></pre>

<p>Redis使用起来非常简单。在管理用户关系的中，共使用了<code>sadd</code>, <code>scem</code>, <code>smembers</code>, &#8216;sinter&#8217;, <code>scard</code>, <code>sismember</code>, <code>mutil</code>，简单说明如下：</p>

<p><code>sadd</code>  将一个或多个member元素加入到集合key当中，已经存在于集合的member元素将被忽略。</p>

<p><code>srem</code>  移除集合key中的一个或多个member元素，不存在的member元素会被忽略。</p>

<p><code>smembers</code> 返回集合key中的所有成员。</p>

<p><code>sinter</code>  返回一个集合的全部成员，该集合是所有给定集合的交集。</p>

<p><code>scard</code>   返回集合key的基数(集合中元素的数量)。</p>

<p><code>sismember</code>   判断member元素是否是集合key的成员。</p>

<p><code>mutil</code>   事务管理，使多条指令成为原子操作</p>

<h2>排行榜（hign score table）</h2>

<p>我们可以通过Redis的<a href="http://redis.io/commands#sorted_set">sorted sets</a>构建一个排行榜。</p>

<pre><code>class User &lt; ActiveRecord::Base
  # log high score
  def scored(score)
    if score &gt; self.high_score
      $redis.zadd("highscores", score, self.id)
    end
  end

  # table rank
  def rank
    $redis.zrevrank("highscores", self.id) + 1
  end

  # high score
  def high_score
    $redis.zscore("highscores", self.id).to_i
  end

  # load top 3 users
  def self.top_3
    $redis.zrevrange("highscores", 0, 2).map{|id| User.find(id)}
  end
end
</code></pre>

<p>使用例子如下：</p>

<pre><code>&gt; a, b, c, d = User.limit(4)
=&gt; [#&lt;User id: 1, name: "Alfred"&gt;, #&lt;User id: 2, name: "Bob"&gt;, #&lt;User id: 3, name: "Charlie"&gt;, #&lt;User id: 4, name: "Derek""&gt;] 
&gt; a.scored 100
=&gt; true 
&gt; b.scored 500
=&gt; true 
&gt; c.scored 25
=&gt; true 
&gt; d.scored 10000
 =&gt; true 
&gt; d.high_score
 =&gt; 10000 
&gt; d.rank
=&gt; 1 
&gt; c.rank
=&gt; 4 
&gt; c.scored 5000000
=&gt; false 
&gt; c.high_score
=&gt; 5000000 
&gt; c.rank
=&gt; 1 
&gt; User.top_3
=&gt; [#&lt;User id: 3, name: "Charlie"&gt;, #&lt;User id: 4, name: "Derek"&gt;, #&lt;User id: 2, name: "Bob"&gt;] 
</code></pre>

<p>我们通过<code>zadd</code>, <code>zrevrank</code>, <code>zrevrange</code>, <code>zscore</code>构建了排行榜，简单说明如下：</p>

<p><code>zadd</code>  将一个或多个member元素及其score值加入到有序集key当中。</p>

<p><code>zrevrank</code>  返回有序集key中成员member的排名。其中有序集成员按score值递减(从大到小)排序。</p>

<p><code>zrevrange</code>   返回有序集key中，指定区间内的成员。</p>

<p><code>zscore</code>  返回有序集key中，成员member的score值。</p>

<h3>更多的例子</h3>

<ul>
<li><a href="http://www.paperplanes.de/2010/2/16/a_collection_of_redis_use_cases.html">A Collection Of Redis Use Cases</a></li>
<li><a href="http://nosql.mypopescu.com/post/836086276/presentation-redis-persistence-power-or-redis-use">Presentation: Redis - Persistence Power or Redis Use Cases</a></li>
</ul>


<h2>将Redis作为Rails的缓存存储</h2>

<p>通过Luca Guidi的<a href="https://github.com/rtomayko/rack-cache">Redis Store</a>，可方便的将Redis作为缓存储存。Redis store为Rails框架提供了Rack::Session, Rack::Cache, I18n 和Redis缓存。它可以用来缓存存储、Session存储，且与Rack::Cache集成的很好。</p>

<pre><code>https://github.com/jodosha/redis-store
</code></pre>

<p>在<code>Gemfile</code>中加入redis-store</p>

<pre><code>gem 'redis-store', '1.0.0.beta4'
</code></pre>

<p>然后，通过Bundler安装</p>

<pre><code>bundle install
</code></pre>

<p>接着在<code>config/environments/production.rb</code>更新配置：</p>

<pre><code>config.cache_store = :redis_store
</code></pre>

<p>就这样，Rails应用将使用Redis作为缓存存储</p>

<h2>监控Redis</h2>

<p>如果在自己的服务器上使用Redis，且在<code>redis.conf</code>中设置了<code>daemonize</code>为<code>yes</code>，且需要对其进行监控。下方是使用<a href="http://mmonit.com/monit/">Monit</a>和<a href="http://godrb.com/">God</a>的例子：</p>

<h3>Monit</h3>

<pre><code>check process redis
  start program = "/usr/bin/redis-server /etc/redis/redis.conf"
  stop program = "/usr/bin/redis-cli -p 6379 shutdown"
  with pidfile /var/run/redis.pid
  group redis
</code></pre>

<h3>God</h3>

<pre><code>%w{6379}.each do |port|
  God.watch do |w| 
    w.name = "redis" 
    w.interval = 30.seconds 

    w.start = "/usr/bin/redis-server /etc/redis/redis.conf" 
    w.stop = "/usr/bin/redis-cli -p 6379 shutdown" 
    w.restart = "#{w.stop} &amp;&amp; #{w.start}" 

    w.start_grace = 10.seconds 
    w.restart_grace = 10.seconds 

    w.start_if do |start| 
      start.condition(:process_running) do |c| 
        c.interval = 5.seconds 
        c.running = false 
      end 
    end 
  end
end
</code></pre>

<h2>Redis和Unix Sockets</h2>

<p>Redis 2.2起引入和unix sockets通信的机制。要使用该功能，就要在<code>redis.conf</code>里将下面的配置取消注释：</p>

<pre><code>unixsocket /tmp/redis.sock
</code></pre>

<p>修改<code>config/initializers/redis.rb</code>以链接到应用中的Redis：</p>

<pre><code>$redis = Redis.new(:path =&gt; "/tmp/redis.sock")
</code></pre>

<h2>Redis相关Gems</h2>

<h3>Redis Objects</h3>

<p><a href="https://github.com/nateware/redis-objects">Redis objects</a>可以将redis数据类型映射为Ruby object，是ORMs非常的替代品。</p>

<h3>Resque</h3>

<p><a href="https://github.com/defunkt/resque">Resque</a>是基于Redis的管理后台任务，它可以建立多个队列并设置优先级。在Github使用并开源，可以通过<a href="https://github.com/blog/542-introducing-resque">这篇介绍</a>了解Resque。</p>

<h3>Vanity</h3>

<p><a href="https://github.com/assaf/vanity">Vanity</a>是试验驱动的开发框架，它为Rails程序提供了A/B测试的功能，并通过<a href="https://github.com/vigetlabs/garb">Grab</a>与Google Analytics集成。</p>

<h3>Ohm</h3>

<p><a href="https://github.com/soveran/ohm">Ohm</a>将Redis作为数据存储，它提供验证扩展，并有很好的性能。</p>

<h3>Rollout</h3>

<p><a href="https://github.com/jamesgolick/rollout">Rollout</a>基于Redis，用户产品小流量测试或灰度发布。</p>

<h3>Soulmate</h3>

<p><a href="https://github.com/seatgeek/soulmate">Soulmate</a>提供了自动完成（Autocomplete）的通用解决方案。它基于Redis的sorted set，可根据输入的部分单词索引出最相符的选项。</p>

<p>英文原文：<a href="http://jimneath.org/2011/03/24/using-redis-with-ruby-on-rails.html#redis_and_rails">http://jimneath.org/2011/03/24/using-redis-with-ruby-on-rails.html</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Devise多角色的Sign out path]]></title>
    <link href="http://jokry.com/blog/2012/05/08/sign-out-path-with-many-roles-in-devise/"/>
    <updated>2012-05-08T21:47:00+08:00</updated>
    <id>http://jokry.com/blog/2012/05/08/sign-out-path-with-many-roles-in-devise</id>
    <content type="html"><![CDATA[<p>在<a href="https://github.com/plataformatec/devise">Devise</a>中可以添加多个用户角色，比如<code>User</code>与<code>Admin</code>。</p>

<p>在用户进行登录与退出，Devise都提供了回调方法，在它的<a href="https://github.com/plataformatec/devise/wiki/How-To:-Change-the-redirect-path-after-destroying-a-session-i.e.-signing-out">wiki</a>中有详细介绍。</p>

<p>在<strong>app/controllers/application_controller.rb</strong>中添加如下方法：</p>

<pre><code>class ApplicationController &lt; ActionController::Base
   private

   # Overwriting the sign_out redirect path method
   def after_sign_out_path_for(resource_or_scope)
     root_path
   end
end
</code></pre>

<p>如果有多个用户角色，只要在<code>after_sign_out_path_for</code>中进行判断即可，如</p>

<pre><code>def after_sign_out_path_for(resource_or_scope)
  if resource_name == :admin
    new_administrator_session_path  #返回到登录页面
  else
    new_user_session_path #返回到登录页面
  end
end
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[译]从竞品中学习]]></title>
    <link href="http://jokry.com/blog/2012/03/13/learning-from-competition-by-marco/"/>
    <updated>2012-03-13T23:38:00+08:00</updated>
    <id>http://jokry.com/blog/2012/03/13/learning-from-competition-by-marco</id>
    <content type="html"><![CDATA[<p><a href="http://www.marco.org/">Marco</a>是<a href="http://www.instapaper.com/">Instapaper</a>的创始人，由于错失最先推出自定义字体功能，而学会重视竞品，并进行经验总结——<a href="http://www.marco.org/2012/03/08/learning-from-competition">Learning from competition</a>。这边文章在<a href="http://pinboard.in">pinboard</a>上也是热门收藏的文章。<a href="http://jokry.com">我</a>将其翻译如下，仓促发布，若有不正确的请大家指出。</p>

<p>去年我尝试在Instapaper中添加自定义字体的功能，但我的努力最终却成了泡影。在iOS 5之前，在iOS系统的UIWebView控件中进行自定义字体的渲染，是非常慢的。当我向字体授权方申请授权时，几乎没有任何回应。所以，即使我想要的这些字体非常棒，但也不能合法的使用这些字体。于是，我搁置了自定义字体的想法。</p>

<p>但我搁置的时间太长了。当<a href="http://www.readability.com">Readability</a>在上周发布他们的<a href="http://itunes.apple.com/app/id460156587">竞品</a>，其中的自定义字体功能备受好评。在对比之下，Instapaper显得毫无吸引力。</p>

<!--more-->


<p>我可以进行防御型地推托：“万能的Georgia和Verdana字体是非常优秀的高可读性字体。我没有必要也添加自定义字体的功能。
新字体未必更好。这些元老级的字体，拥有新字体不具备的优势，等等“。</p>

<p>但这些辩解，让我显得固执而不可理喻。我错失了解新字体更受用户欢迎的原因，也错过了最先自定义字体功能的机会。</p>

<p>这次的失策犹如当头棒喝：我错失了一次为产品增加长期竞争力的机会。所以，我花了一整周的时间进行大量字体的测试，并从我尊重的设计师那收集反馈，最终精选出部分与字体授权商进行谈判，希望能加入下一个版本的Instapaper。测试的结果令人满意。我多希望当时能有人将我从自满踢回到现实。</p>

<p>对这次竞争，让我明白对自己的产品需要进行批判性的分析，发现其不足。需要彻底地、无偏见地分析竞品的优势。</p>

<p>用户并不是狂热粉丝。他们并不会被市场洗脑。如果你的产品不具备竞争优势，那么竞品的用户不会转移到你的产品上来。</p>

<p>他们有充分的理由选择竞品，并会下意识的否认你产品优势，并认为你的产品不会超过他们正在使用的产品。</p>

<p>一个好例子就是苹果公司，它能在如此多的市场处于支配地位，是由于它的竞品们大多是采用防御性推托。</p>

<p>Windows Phone 7 和 Windows8之所以能获得肯定，是因为在多年的市场否认后，微软不得不承认苹果有很多创新性设计与产品，必须认真的对待它们。</p>

<p>我不确定Google是否认可Apple的创新设计。至少在公共场合，Google一直认为Android在任何方面都是最棒的，它必定将处于支配地位。这令我好奇的是，Google的高层没有意识到Android的不足吗？</p>

<p>这就是如今微软越值得关注的原因：当Google认为他们不必做出任何调整，而Apple的消费者被市场洗脑的同时，Ballmer停止在公共场合谈论Apple，微软将进行彻底地改变。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Octopress介绍与安装]]></title>
    <link href="http://jokry.com/blog/2012/03/08/octopress/"/>
    <updated>2012-03-08T00:26:00+08:00</updated>
    <id>http://jokry.com/blog/2012/03/08/octopress</id>
    <content type="html"><![CDATA[<p>将自己的博客转向Octopress，利用Github托管并自定义域名。安装过程中也遇到一些问题，通过本篇文章记录下来，希望对要转向Octopress的朋友有帮助。</p>

<ol>
<li>什么是Octopress</li>
<li>安装与发布Octopress</li>
<li>安装中可能出现的问题</li>
<li>通过Markdown语法写文章</li>
<li>自定义域名</li>
<li>导出wordpress文章到Octopress</li>
</ol>


<h2>1. 什么是Octopress</h2>

<p>Octopress是使用Ruby语言编写的博客系统。相比wordpress，它拥有一些独特的特点：</p>

<ul>
<li>运行生成Html静态页面，无需数据库支持</li>
<li>默认使用markdown语法撰写文章</li>
<li>通过Git方便地进行博客版本控制</li>
<li>利用Github Pages托管Octopress，无需服务器支持</li>
<li>Mash up免费服务，如Disqus , Google analysis , Delicious…</li>
<li>Geek Style</li>
</ul>


<p>如果你想更具体的了解Octopress，可以阅读<a href="http://octopress.org/">官方介绍</a>或者xdite的<a href="http://blog.xdite.net/posts/2011/10/07/what-is-octopress/">Why Octopress?</a></p>

<!--more-->


<h2>2. 安装与发布Octopress</h2>

<p>如果你不了解Ruby以及Git，不建议急着上手安装Octopress。安装步骤你可以参考<a href="http://octopress.org/docs/setup/">官网文档</a>，也可以按照以下步骤来安装。</p>

<p>a. Octopress需要基于ruby 1.9.2版本环境，通过RVM切换</p>

<pre><code>rvm install 1.9.2 &amp;&amp; rvm use 1.9.2
</code></pre>

<p>b. 通过git clone获取octopress源代码</p>

<pre><code>git clone git://github.com/imathis/octopress.git octopress
</code></pre>

<p>c. 进入octopress文件夹，将Gemfile的source改用<a href="http://ruby.taobao.org">淘宝镜像</a></p>

<pre><code>source "http://ruby.taobao.org"
</code></pre>

<p>d. 运行命令进行安装</p>

<pre><code>bundle install
rake install
</code></pre>

<p>e. 建立github pages repo，假设你的用户名是username，则建立repo名为username.github.com。具体可参见<a href="http://pages.github.com/">github pages</a>。</p>

<p>f. 通过以下命令，自动建立github pages所需的配置</p>

<pre><code>rake setup_github_pages
</code></pre>

<p>当提示输入github url时，请输入<code>git@github.com:username/username.github.com.git</code>，当然需要替换username。</p>

<p>该命令将自动建立两个branch，分别是master和source。master用来发布octopress生成的静态内容，在<em>deploy文件夹里的静态文件。source用来发布除了</em>deploy之外的所有文件，既octopress程序本身。</p>

<p>g. 通过_config.yml配置octopress博客信息，请注意冒号之后需要空格，具体详见<a href="http://octopress.org/docs/configuring/">Octopress Configuring</a>。</p>

<p>h. 生成以及预览功能</p>

<pre><code>rake generate # generate your blog static pages content according to your input. 
rake preview # start a web server on "http://localhost:4000", you can preview your blog content.
</code></pre>

<p>第一条命令将生成静态页面到_deploy文件夹；第二条命令通过http://localhost:4000来预览生成的页面，这时候还没有写文章，先看看是否config信息是否正确。</p>

<p>i. 发布生成的静态内容到master branch</p>

<pre><code>rake deploy # push your static pages content to your github pages repo ("master" branch)
</code></pre>

<p>j. 发布程序本身发布到source branch</p>

<pre><code>git add .
git commit -m 'install'
git push origin source
</code></pre>

<p>通过以上步骤就完成了安装与发布，这时候github会发邮件给你，github pages服务需要一会才能生效。生效后，可通过username.github.com来访问你的octopress blog。</p>

<h2>3. 安装中可能出现的问题</h2>

<p>a. rake版本错误</p>

<pre><code>rake aborted!
You have already activated rake 0.9.2.2, but your Gemfile requires rake 0.9.2. U
sing bundle exec may solve this.
(See full trace by running task with --trace)
</code></pre>

<p>一种解决方案是将Gemfile里的改成<code>gem 'rake', '0.9.2.2'</code>，并重新执行bundle install；另一种方案可以执行<code>bundle exec rake</code>替代<code>rake</code>命令。</p>

<p>b. _config.yml配置中，冒号后面没有空格，语法错误。</p>

<pre><code>psych. Rb: 148: in ` parse ': peasants' t parse YAML at line 12 column 0 (Psych: : SyntaxError)
</code></pre>

<p>c. 解决中文编码问题</p>

<p>找到ruby环境下的<code>setup_environment.bat</code>文件，在文件最后加入2行代码</p>

<pre><code>set LC_ALL=en_US.UTF-8
set LANG=en_US.UTF-8
</code></pre>

<p>d. 还是中文编码的错误</p>

<pre><code>gems/ruby-1.9.2-p290/gems/jekyll-0.11.0/lib/jekyll/convertible.rb:32:in `read_yaml': invalid byte sequence in US-ASCII (ArgumentError)
</code></pre>

<p>解决方案：将convertible.rb文件的第29行</p>

<pre><code>self.content = File.read(File.join(base, name))
</code></pre>

<p>修改为：</p>

<pre><code>self.content = File.read(File.join(base, name), :encoding =&gt; "utf-8")
</code></pre>

<p>e. jekyll版本不兼容，请升级jekyll到0.11.2。（liquid > 2.3）</p>

<pre><code>uninitialized constant Jekyll::Layout::Convertible&lt;NameError&gt;
</code></pre>

<p>修改Gemfile如下，并重新进行<code>bundle install</code></p>

<pre><code>source "http://ruby.taobao.org"
group :development do
  gem 'rake', '0.9.2.2' 
  gem 'rack'
  gem 'jekyll', '0.11.2'
  gem 'rdiscount'
  gem 'pygments.rb'
  gem 'RedCloth'
  gem 'haml', '&gt;= 3.1'
  gem 'compass', '&gt;= 0.11'
  gem 'rubypants'
  gem 'rb-fsevent'
  gem 'stringex'
  gem 'liquid', '2.3'    # jekyll 0.11.2required liquid &gt;= 2.3
end
gem 'sinatra', '1.2.6'
</code></pre>

<h2>4. 通过Markdown语法写文章</h2>

<p><a href="http://daringfireball.net/projects/markdown/">Markdown</a>语法是一种轻量级的标记语言，只需要10min就能掌握。它将使你更专注与写作。</p>

<h3>4.1 Markdown编辑器</h3>

<p>Mac OS 推荐使用 <a href="http://mouapp.com/">mouapp</a>
Linux 推荐使用 VIM 或 <a href="http://www.sublimetext.com/">Sublime</a> 加上 <a href="http://lucifr.com/2012/02/20/sublime-text-2-markdown-%E9%A2%84%E8%A7%88%E6%8F%92%E4%BB%B6/#disqus_thread">Markdown-Preview</a>
Windows 推荐使用 Sublime 或 <a href="http://markdownpad.com/">MarkdownPad</a></p>

<h3>4.2 编写Octopress文章</h3>

<p>a. 新建文章</p>

<pre><code>cd octopress
rake new_post["The Title of Your Article"]
</code></pre>

<p>该命令将在<em>source/_posts</em>下生成<em>.markdown</em>文件，可通过上述的编辑器进行编辑。除了新建文章之后，也可以通过<code>rake new_page</code>来新建页面。</p>

<p>b. 编写文章</p>

<pre><code>---
layout: post
title: "The Title of Your Article"
date: 2012-03-08 2:59
comments: true
categories: 
---
#上方是配置信息，从在这里开始编写文章。
</code></pre>

<p>编写完成后，再次按照2.h步骤开始，进行生成、预览、发布等。具体你可以参考<a href="http://octopress.org/docs/blogging/">这里</a>。</p>

<h2>5. 自定义域名</h2>

<p>在项目里的<em>source</em>文件夹新建名为CNAME的文件，在CNAME里写上你的域名。也可通过命令外执行：</p>

<pre><code>$ echo 'yourdomain.com' &gt;&gt; source/CNAME
</code></pre>

<p>修改域名的解析：让<code>A Record</code>指向<code>207.97.227.245</code>，并让<code>WWW CNAME</code>指向<code>username.github.com</code>。</p>

<p>解析需要一定时间生效，不要太着急。更详细的信息可参考<a href="http://pages.github.com/">Github Pages</a></p>

<h2>6. 导出wordpress文章到Octopress</h2>

<p>通过这个<a href="https://gist.github.com/1796343">wordpress blog -> markdown</a>可以将wordpress的导出文件转化为对应的markdown文件。将生成的文件放在<code>_deploy</code>文件夹下，再次生成发布。</p>

<p>好吧，终于写完了，希望能够帮到建立Octopress的朋友，如果还有其他的疑问，可以留言。</p>
]]></content>
  </entry>
  
</feed>

