<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Roc's blog]]></title>
  <link href="http://rociiu.com/atom.xml" rel="self"/>
  <link href="http://rociiu.com/"/>
  <updated>2018-03-04T18:39:21+08:00</updated>
  <id>http://rociiu.com/</id>
  <author>
    <name><![CDATA[Roc Yu]]></name>
    <email><![CDATA[rociiu.yu@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Setup Bitcoin Development Environment]]></title>
    <link href="http://rociiu.com/blog/2018/03/04/setup-bitcoin-development-environment/"/>
    <updated>2018-03-04T18:16:09+08:00</updated>
    <id>http://rociiu.com/blog/2018/03/04/setup-bitcoin-development-environment</id>
    <content type="html"><![CDATA[<p>Bitcoin or blockchain is crazy hot on internet today, and I&rsquo;m curious what&rsquo;s the best way for a programmer to get start with it. After read some books, I found that you can setup a test bitcoin testnet and play with it, so in this post I will share how it works.</p>

<h3>Get a ubuntu server</h3>

<p>First of all, you need to get a server or in your local environment. I&rsquo;m running with latest ubuntu on a VPS server.</p>

<h3>Install docker-ce in ubuntu</h3>

<p>I&rsquo;m using docker-ce here. To install docker-ce in ubuntu, you can follow the steps:</p>

<h4>remove the old docker if exists</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ sudo apt-get remove docker docker-engine docker.io</span></code></pre></td></tr></table></div></figure>


<h4>Update apt repos.</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ sudo apt-get update
</span></code></pre></td></tr></table></div></figure>


<h4>Install dependencies packages</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
</span><span class='line'>$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
</span><span class='line'>$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
</span><span class='line'>$ sudo apt-get update</span></code></pre></td></tr></table></div></figure>


<h4>Install docker-ce</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ sudo apt-get install docker-ce</span></code></pre></td></tr></table></div></figure>


<h3>Install bitcoin-testnet-box</h3>

<h4>Get the docker image.</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker pull freewil/bitcoin-testnet-box
</span></code></pre></td></tr></table></div></figure>


<h4>Run bitcoin-testnet-box</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker run -t -i -p 19001:19001 -p 19011:19011 freewil/bitcoin-testnet-box</span></code></pre></td></tr></table></div></figure>


<h4>Then you will see something similar with:</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>tester@84074da951a2:~/bitcoin-testnet-box$</span></code></pre></td></tr></table></div></figure>


<h4>Check the info</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>make getinfo</span></code></pre></td></tr></table></div></figure>


<h3>Generate blocks</h3>

<p>Must generate 200 blocks to get balance</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>make generate BLOCKS=200</span></code></pre></td></tr></table></div></figure>


<h3>Install ruby</h3>

<p>I&rsquo;m using ruby to call the rpc-json server, so ruby have to be installed in server first.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>apt-get install ruby</span></code></pre></td></tr></table></div></figure>


<h3>Run ruby script to bitcoin rpc-json</h3>

<p>I got the code sample from bitcoin.it wiki, but replace the server with the username/password/post from the configuration in bitcoin-testnet-box. Save following code outside the docker instance as test.rb</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;net/http&#39;</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;uri&#39;</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;json&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">BitcoinRPC</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">service_url</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@uri</span> <span class="o">=</span> <span class="no">URI</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">service_url</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
</span><span class='line'>    <span class="n">post_body</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">&#39;method&#39;</span> <span class="o">=&gt;</span> <span class="nb">name</span><span class="p">,</span> <span class="s1">&#39;params&#39;</span> <span class="o">=&gt;</span> <span class="n">args</span><span class="p">,</span> <span class="s1">&#39;id&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;jsonrpc&#39;</span> <span class="p">}</span><span class="o">.</span><span class="n">to_json</span>
</span><span class='line'>    <span class="n">resp</span> <span class="o">=</span> <span class="no">JSON</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span> <span class="n">http_post_request</span><span class="p">(</span><span class="n">post_body</span><span class="p">)</span> <span class="p">)</span>
</span><span class='line'>    <span class="k">raise</span> <span class="no">JSONRPCError</span><span class="p">,</span> <span class="n">resp</span><span class="o">[</span><span class="s1">&#39;error&#39;</span><span class="o">]</span> <span class="k">if</span> <span class="n">resp</span><span class="o">[</span><span class="s1">&#39;error&#39;</span><span class="o">]</span>
</span><span class='line'>    <span class="n">resp</span><span class="o">[</span><span class="s1">&#39;result&#39;</span><span class="o">]</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">http_post_request</span><span class="p">(</span><span class="n">post_body</span><span class="p">)</span>
</span><span class='line'>    <span class="n">http</span>    <span class="o">=</span> <span class="ss">Net</span><span class="p">:</span><span class="ss">:HTTP</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="vi">@uri</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="vi">@uri</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>
</span><span class='line'>    <span class="n">request</span> <span class="o">=</span> <span class="ss">Net</span><span class="p">:</span><span class="ss">:HTTP</span><span class="o">::</span><span class="no">Post</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="vi">@uri</span><span class="o">.</span><span class="n">request_uri</span><span class="p">)</span>
</span><span class='line'>    <span class="n">request</span><span class="o">.</span><span class="n">basic_auth</span> <span class="vi">@uri</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="vi">@uri</span><span class="o">.</span><span class="n">password</span>
</span><span class='line'>    <span class="n">request</span><span class="o">.</span><span class="n">content_type</span> <span class="o">=</span> <span class="s1">&#39;application/json&#39;</span>
</span><span class='line'>    <span class="n">request</span><span class="o">.</span><span class="n">body</span> <span class="o">=</span> <span class="n">post_body</span>
</span><span class='line'>    <span class="n">http</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="n">request</span><span class="p">)</span><span class="o">.</span><span class="n">body</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">class</span> <span class="nc">JSONRPCError</span> <span class="o">&lt;</span> <span class="no">RuntimeError</span><span class="p">;</span> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="vg">$0</span> <span class="o">==</span> <span class="bp">__FILE__</span>
</span><span class='line'>  <span class="n">h</span> <span class="o">=</span> <span class="no">BitcoinRPC</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;http://admin1:123@127.0.0.1:19001&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="nb">p</span> <span class="n">h</span><span class="o">.</span><span class="n">getbalance</span>
</span><span class='line'>  <span class="nb">p</span> <span class="n">h</span><span class="o">.</span><span class="n">getinfo</span>
</span><span class='line'>  <span class="nb">p</span> <span class="n">h</span><span class="o">.</span><span class="n">getnewaddress</span>
</span><span class='line'>  <span class="nb">p</span> <span class="n">h</span><span class="o">.</span><span class="n">dumpprivkey</span><span class="p">(</span> <span class="n">h</span><span class="o">.</span><span class="n">getnewaddress</span> <span class="p">)</span>
</span><span class='line'>  <span class="c1"># also see: https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Run the code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">ruby</span> <span class="nb">test</span><span class="o">.</span><span class="n">rb</span>
</span></code></pre></td></tr></table></div></figure>


<p>You will see something like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="mi">5539</span><span class="o">.</span><span class="mi">9999616</span>
</span><span class='line'><span class="p">{</span><span class="s2">&quot;version&quot;</span><span class="o">=&gt;</span><span class="mi">130200</span><span class="p">,</span> <span class="s2">&quot;protocolversion&quot;</span><span class="o">=&gt;</span><span class="mi">70015</span><span class="p">,</span> <span class="s2">&quot;walletversion&quot;</span><span class="o">=&gt;</span><span class="mi">130000</span><span class="p">,</span> <span class="s2">&quot;balance&quot;</span><span class="o">=&gt;</span><span class="mi">5539</span><span class="o">.</span><span class="mi">9999616</span><span class="p">,</span> <span class="s2">&quot;blocks&quot;</span><span class="o">=&gt;</span><span class="mi">211</span><span class="p">,</span> <span class="s2">&quot;timeoffset&quot;</span><span class="o">=&gt;</span><span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;connections&quot;</span><span class="o">=&gt;</span><span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;proxy&quot;</span><span class="o">=&gt;</span><span class="s2">&quot;&quot;</span><span class="p">,</span><span class="s2">&quot;difficulty&quot;</span><span class="o">=&gt;</span><span class="mi">4</span><span class="o">.</span><span class="mi">656542373906925</span><span class="n">e</span><span class="o">-</span><span class="mi">10</span><span class="p">,</span> <span class="s2">&quot;testnet&quot;</span><span class="o">=&gt;</span><span class="kp">false</span><span class="p">,</span> <span class="s2">&quot;keypoololdest&quot;</span><span class="o">=&gt;</span><span class="mi">1520155323</span><span class="p">,</span> <span class="s2">&quot;keypoolsize&quot;</span><span class="o">=&gt;</span><span class="mi">100</span><span class="p">,</span> <span class="s2">&quot;paytxfee&quot;</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;relayfee&quot;</span><span class="o">=&gt;</span><span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mo">05</span><span class="p">,</span> <span class="s2">&quot;errors&quot;</span><span class="o">=&gt;</span><span class="s2">&quot;&quot;</span><span class="p">}</span>
</span><span class='line'><span class="s2">&quot;mve5QiJZmVQTGqeYNwi3xf78vrVp7eArJL&quot;</span>
</span><span class='line'><span class="s2">&quot;cRtYox2ALixpCuhL7rdx7LzCKMKaA6gCbogVkb3YgsxBAdTYZwK6&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>References</h3>

<ul>
<li><a href="https://github.com/freewil/bitcoin-testnet-box">https://github.com/freewil/bitcoin-testnet-box</a></li>
<li><a href="https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce-1">https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce-1</a></li>
<li><a href="https://en.bitcoin.it/wiki/API_reference_(JSON-RPC">https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)</a>)</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Import Csv Into Postgres With Copy Command]]></title>
    <link href="http://rociiu.com/blog/2015/02/06/import-csv-into-postgres-with-copy-command/"/>
    <updated>2015-02-06T11:30:35+08:00</updated>
    <id>http://rociiu.com/blog/2015/02/06/import-csv-into-postgres-with-copy-command</id>
    <content type="html"><![CDATA[<p>When deal with data related project, if often need to import data from csv or excel, you can write loop to import with active record model one by one or by transaction, you can also use database command to do the bulk import, in mongodb there&rsquo;s <a href="http://docs.mongodb.org/v2.2/reference/mongoimport/">mongoimport</a>, for postgresql you can use <a href="http://www.postgresql.org/docs/9.2/static/sql-copy.html">copy</a>.</p>

<p>Here I want to import crimes data (<a href="http://data.police.uk">http://data.police.uk</a>) into postgresql, I wrote follow sql command to import:</p>

<pre><code>sql = "copy crimes (crime_id, month, reported_by, falls_within, lon, lat, location, lsoa_code, lsoa_name, crime_type, last_outcome_category, context) from '/Users/rociiu/sandbox/ukpolice/uk-crimes/xx.csv' DELIMITERS ',' CSV HEADER;"

ActiveRecord::Base.connection.execute(sql) # run with active record connection
</code></pre>

<p>You can find more document with the link above, here I list column names following the table name to match the columns in csv, also specify the csv delimiters and tell the command that there&rsquo;s header in csv.</p>

<p>The full rake task for importing is here: <a href="https://github.com/rociiu/uk-crimes/blob/master/lib/tasks/import.rake">https://github.com/rociiu/uk-crimes/blob/master/lib/tasks/import.rake</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Create Ember App With Yeoman]]></title>
    <link href="http://rociiu.com/blog/2015/01/12/create-ember-app-with-yeoman/"/>
    <updated>2015-01-12T08:28:29+08:00</updated>
    <id>http://rociiu.com/blog/2015/01/12/create-ember-app-with-yeoman</id>
    <content type="html"><![CDATA[<h3>1. install dependencies</h3>

<p>Download and install from <a href="http://nodejs.org">nodejs</a>, it include NPM for node package manage</p>

<p>Install yeoman, grunt, bower.</p>

<pre><code>npm install -g yo grunt-cli bower
</code></pre>

<h3>2. install ember generator</h3>

<p>Run yo command, you will see options for execute yo commands:</p>

<pre><code>yo
</code></pre>

<p>Use your up/down keys to select different menu/command to execute, select install generator.</p>

<pre><code>❯ Install a generator
</code></pre>

<p>It will prompt:</p>

<pre><code>? Search npm for generators:
</code></pre>

<p>Enter ember to search emberjs related generator. after a while it will return search results for &lsquo;ember&rsquo;:</p>

<pre><code>? Here's what I found. Official generator → ෴
  Install one? (Use arrow keys)
❯ ember ෴
  ember-plugin
  rjs-ember
  ember-plus
  base
</code></pre>

<p>Select ember marked as &lsquo;෴&rsquo; and press enter to install it.</p>

<h3>3. use yo command to create the app</h3>

<p>First you need to create a project folder, you can create with command:</p>

<pre><code>mkdir myapp
yo
</code></pre>

<p>After run &lsquo;yo&rsquo;, it will give options to run generator, select Ember (use up/down arrow keys):</p>

<pre><code>  Run a generator
  Angular
 ❯Ember
  Mocha
  Karma
</code></pre>

<p>Press enter, after a while it will ask whether to include Bootstrap, feel free to select Y or n. After that you&rsquo;ll see something like this:</p>

<pre><code> create .gitignore
 create .gitattributes
 create .bowerrc
 create bower.json
 create package.json
 create .jshintrc
 create .editorconfig
 create Gruntfile.js
 create app/templates/application.hbs
 create app/templates/index.hbs
 create app/index.html
 create app/styles/style.scss
 create app/scripts/app.js
 create app/scripts/store.js
 create app/scripts/router.js
 create app/scripts/routes/application_route.js

  I'm all done. Running bower install &amp; npm install for you to install the required dependencies. If this fails, try running the command yourself.
  ....
</code></pre>

<p>It will install all js/libraries dependencies with: bower install &amp; npm install. Finally you will see ascii art like:</p>

<pre><code>     _-----_
    |       |    .----------------------.
    |--(o)--|    |     Bye from us!     |
   `---------´   |      Chat soon.      |
    ( _´U`_ )    |                      |
    /___A___\    |      Yeoman team     |
     |  ~  |     |   http://yeoman.io   |
   __'.___.'__   '----------------------'
 ´   `  |° ´ Y `
</code></pre>

<p>Yeah!</p>

<h3>4. run grunt to build the app</h3>

<p>Run grant command to build the project.</p>

<pre><code>grunt
</code></pre>

<h3>5. run grunt serve to preview and edit the app</h3>

<pre><code>grunt serve
</code></pre>

<h3>6. deploy the app</h3>

<p>after edit and create some awesome features, you definitely want to deploy the app, right? Here I&rsquo;ll show you how to deploy the app in <a href="https://divshot.com">divshot.com</a> static web hosting for developers.</p>

<p>First you need to register a account in <a href="https://divshot.com">divshot.com</a>, after register you need to install npm package for running divshot command</p>

<pre><code>npm install -g divshot-cli
</code></pre>

<p>Then use divshot command to login your account:</p>

<pre><code>divshot login
</code></pre>

<p>After that you can go to your project directory, run &lsquo;divshot init&rsquo; command:</p>

<pre><code>divshot init
name: (myapp) rociiu-ember-demo
root directory: (current) dist
clean urls: (y/n) y
error page: (error.html) n
Would you like to create a Divshot.io app from this app?: (y/n) y
Creating app ...
</code></pre>

<p>After the steps, it will create a configuration file(divshot.json) inside the root directory. Then deploy the app with &lsquo;divshot push&rsquo;:</p>

<pre><code>divshot push

Creating build ...  App does not yet exist. Creating app rociiu-ember-demo ... ✔
Hashing Directory Contents ... ✔

Syncing 15 files: [==================================================] 100%


Finalizing build ... ✔
Releasing build to development ... ✔

Application deployed to development
You can view your app at: http://development.rociiu-ember-demo.divshot.io
</code></pre>

<p>Your app should be live now.</p>

<hr />

<h4>References:</h4>

<ul>
<li><a href="http://nodejs.org">http://nodejs.org</a></li>
<li><a href="https://www.npmjs.com">https://www.npmjs.com</a></li>
<li><a href="http://yeoman.io">http://yeoman.io</a></li>
<li><a href="http://gruntjs.com">http://gruntjs.com</a></li>
<li><a href="http://emberjs.com">http://emberjs.com</a></li>
<li><a href="http://bower.io">http://bower.io</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby Refinement Note]]></title>
    <link href="http://rociiu.com/blog/2014/11/09/ruby-refinement-note/"/>
    <updated>2014-11-09T12:46:11+08:00</updated>
    <id>http://rociiu.com/blog/2014/11/09/ruby-refinement-note</id>
    <content type="html"><![CDATA[<p>Refinement is introduced in ruby 2.0, no longer a experiment feature in ruby 2.1, but still not very stable. The idea of refinement is to limit the monkeying patch scope.</p>

<p>For example, suppose we define a refinement:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">ACoolFeature</span>
</span><span class='line'>  <span class="n">refine</span><span class="p">(</span><span class="nb">String</span><span class="p">)</span> <span class="k">do</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">is_it_cool?</span>
</span><span class='line'>      <span class="nb">puts</span> <span class="s2">&quot;YES&quot;</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here we define a refinement to String class, to use the refinement we need to call <em>using</em> inside a class.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Person</span>
</span><span class='line'>  <span class="n">using</span><span class="p">(</span><span class="no">ACoolFeature</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">hello</span>
</span><span class='line'>    <span class="s2">&quot;test&quot;</span><span class="o">.</span><span class="n">is_it_cool?</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>After call using in Person class, the method is_it_cool? is available for string inside this scope.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Person</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">hello</span>
</span><span class='line'><span class="o">&gt;</span>     <span class="no">Person</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">hello</span>
</span><span class='line'><span class="no">YES</span>
</span></code></pre></td></tr></table></div></figure>


<p>That&rsquo;s it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Visualize Data With D3]]></title>
    <link href="http://rociiu.com/blog/2014/11/01/visualize-data-with-d3/"/>
    <updated>2014-11-01T22:00:10+08:00</updated>
    <id>http://rociiu.com/blog/2014/11/01/visualize-data-with-d3</id>
    <content type="html"><![CDATA[<h2>what is d3js</h2>

<p>(<a href="http://d3js.org">http://d3js.org</a>)[d3js] is very popular in visualization recently, it has unique way to render chart compare to other libraries. d3 refer to data-driven document.</p>

<h2>setup html</h2>

<pre><code>&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;D3&lt;/title&gt;
    &lt;script src="http://d3js.org/d3.v3.min.js" charset="utf-8"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h2&gt;D3js example&lt;/h2&gt;
    &lt;svg width=500 height=300&gt;
    &lt;/svg&gt;
    &lt;script&gt;
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>

<h2>use data in previous post</h2>

<pre><code>var crimesData = [
{
    "Crime type" : "Anti-social behaviour",
    "total" : 5593
},
{
    "Crime type" : "Burglary",
    "total" : 888
},
{
    "Crime type" : "Criminal damage and arson",
    "total" : 1215
},
{
    "Crime type" : "Other theft",
    "total" : 1343
},
{
    "Crime type" : "Violence and sexual offences",
    "total" : 2123
},
{
    "Crime type" : "Drugs",
    "total" : 292
},
{
    "Crime type" : "Public order",
    "total" : 577
},
{
    "Crime type" : "Shoplifting",
    "total" : 1019
},
{
    "Crime type" : "Vehicle crime",
    "total" : 689
},
{
    "Crime type" : "Possession of weapons",
    "total" : 22
},
{
    "Crime type" : "Bicycle theft",
    "total" : 271
},
{
    "Crime type" : "Other crime",
    "total" : 88
},
{
    "Crime type" : "Theft from the person",
    "total" : 172
},
{
    "Crime type" : "Robbery",
    "total" : 91
}
]
</code></pre>

<h2>write code to render bar chart</h2>

<pre><code>  var extent = d3.extent(crimesData, function(d){return d.total})
  var widthScale = d3.scale.linear().domain(extent).range([0, 500])
  var colorScale = d3.scale.category10()

  d3.select("svg").selectAll("rect")
    .data(crimesData)
  .enter()
    .append("rect")
    .attr("x", function(d, i){ return 0 })
    .attr("y", function(d, i){ return i * 30})
    .attr("width", function(d, i){ return widthScale(d.total)})
    .attr("height", function(d, i){ return 25})
    .attr("fill", function(d, i){ return colorScale(i)})
</code></pre>

<h3>get min/max value with d3.exten</h3>

<pre><code>var extent = d3.extent(crimesData, function(d){return d.total})
</code></pre>

<h3>add scale to map domain value to width in chart</h3>

<pre><code>var widthScale = d3.scale.linear().domain(extent).range([0, 500])
</code></pre>

<h3>add color scale to fill different bar with colors</h3>

<pre><code>var colorScale = d3.scale.category10()
</code></pre>

<h3>select element and bind data</h3>

<pre><code>d3.select("svg").selectAll("rect")
  .data(crimesData)
.enter()
  .append("rect")
  .attr("x", function(d, i){ return 0 })
  .attr("y", function(d, i){ return i * 30})
  .attr("width", function(d, i){ return widthScale(d.total)})
  .attr("height", function(d, i){ return 25})
  .attr("fill", function(d, i){ return colorScale(i)})
</code></pre>

<p>Here I first select the svg in the html, then select &lsquo;rect&rsquo; in this svg and bind crimes data with those rect, enter function is used to start render the element that with data binding, first I append a new rect in the svg, assign different attributes with scales defined before, notice that the function as attr second parameter as two parameter d and i, d represent each item in the crimes data and i of cource is the index of the item in crimes data.</p>

<h3>Final result</h3>

<p>  <a href="http://codepen.io/anon/pen/IwlDA">http://codepen.io/anon/pen/IwlDA</a></p>

<p>Noted that we still missing a lot of stuff in this chart like x/y axis, labels though, d3js offer functions/generators for that.</p>

<p>If you understand how svg works, you&rsquo;ll know that d3js just help us to render svg elements with helper functions.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Data Visulazation - Import Data]]></title>
    <link href="http://rociiu.com/blog/2014/10/25/data-visulazation-process-data/"/>
    <updated>2014-10-25T19:14:05+08:00</updated>
    <id>http://rociiu.com/blog/2014/10/25/data-visulazation-process-data</id>
    <content type="html"><![CDATA[<p>I have been worked on some data visualization projects in last few years for different kind of clients, used some different set of library/framework like backbonejs, raphaeljs, d3js.
Start from this post, i&rsquo;ll try to write down process on how we can do data visualization with modern technologies.</p>

<p>The data source will be <a href="http://data.police.uk">http://data.police.uk</a> , which include different crimes records in UK.</p>

<h2>Install mongodb</h2>

<p>Mongodb has many features like document, schemaless, query, etc, the reason i choose it is it&rsquo;s very easy to load the data into it using mongoimport.</p>

<pre><code>brew install mongodb
</code></pre>

<h2>Start mongodb</h2>

<pre><code>mongod
</code></pre>

<h2>Create database</h2>

<pre><code>use ukcrimes
</code></pre>

<h2>Download data from <a href="http://data.police.uk/data/">http://data.police.uk/data/</a></h2>

<h2>Import data into database</h2>

<pre><code>mongoimport --db ukpolice --collection crimes --type csv --headerline --file file_path
</code></pre>

<h2>Check imported data</h2>

<pre><code>mongo
use ukcrimes
db.crimes.find()  
</code></pre>

<p>You&rsquo;ll see data like:</p>

<pre><code>{ "_id" : ObjectId("544a7172d0e2b18dc73d060c"), "Crime ID" : "ca8de697ca1a5b0b1f76a3c0f3f652bf2e9e20a31fbf5af40df5de7fa55f63a4", "Month" : "2014-07", "Reported by" : "Avon and Somerset Constabulary", "Falls within" : "Avon and Somerset Constabulary", "Longitude" : "", "Latitude" : "", "Location" : "No location", "LSOA code" : "", "LSOA name" : "", "Outcome type" : "Offender given penalty notice" }
{ "_id" : ObjectId("544a7172d0e2b18dc73d060d"), "Crime ID" : "c50470f2a1af2a5fffaa3dd69218777200c1a9289b87dd36849325ed2585472e", "Month" : "2014-07", "Reported by" : "Avon and Somerset Constabulary", "Falls within" : "Avon and Somerset Constabulary", "Longitude" : "", "Latitude" : "", "Location" : "No location", "LSOA code" : "", "LSOA name" : "", "Outcome type" : "Offender given a drugs possession warning" }
{ "_id" : ObjectId("544a7172d0e2b18dc73d060e"), "Crime ID" : "b7458f39eb58018af53c85fd481aa2028e247baa30ceb1f095437359e78b63f6", "Month" : "2014-07", "Reported by" : "Avon and Somerset Constabulary", "Falls within" : "Avon and Somerset Constabulary", "Longitude" : "", "Latitude" : "", "Location" : "No location", "LSOA code" : "", "LSOA name" : "", "Outcome type" : "Suspect charged" }
{ "_id" : ObjectId("544a7172d0e2b18dc73d060f"), "Crime ID" : "3093f07675cd62ce39cc8eeb80261edb15d00cbee2bf2ece8d295ac6a0efab4e", "Month" : "2014-07", "Reported by" : "Avon and Somerset Constabulary", "Falls within" : "Avon and Somerset Constabulary", "Longitude" : "", "Latitude" : "", "Location" : "No location", "LSOA code" : "", "LSOA name" : "", "Outcome type" : "Suspect charged" }
</code></pre>

<h2>To understand the data columns, you can check <a href="http://data.police.uk/about/">http://data.police.uk/about/</a></h2>

<h2>Query crimes stats</h2>

<pre><code>db.crimes.group({key: { 'Crime type': 1}, reduce: function(curr, result){ result.total += 1}, initial: { total: 0 } })
</code></pre>

<p>result:</p>

<pre><code>[
{
    "Crime type" : "Anti-social behaviour",
    "total" : 5593
},
{
    "Crime type" : "Burglary",
    "total" : 888
},
{
    "Crime type" : "Criminal damage and arson",
    "total" : 1215
},
{
    "Crime type" : "Other theft",
    "total" : 1343
},
{
    "Crime type" : "Violence and sexual offences",
    "total" : 2123
},
{
    "Crime type" : "Drugs",
    "total" : 292
},
{
    "Crime type" : "Public order",
    "total" : 577
},
{
    "Crime type" : "Shoplifting",
    "total" : 1019
},
{
    "Crime type" : "Vehicle crime",
    "total" : 689
},
{
    "Crime type" : "Possession of weapons",
    "total" : 22
},
{
    "Crime type" : "Bicycle theft",
    "total" : 271
},
{
    "Crime type" : "Other crime",
    "total" : 88
},
{
    "Crime type" : "Theft from the person",
    "total" : 172
},
{
    "Crime type" : "Robbery",
    "total" : 91
}
]
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Issues of Upgrading to Yosemite Related to Homebrew]]></title>
    <link href="http://rociiu.com/blog/2014/10/19/issues-of-upgrading-to-yosemite/"/>
    <updated>2014-10-19T14:59:58+08:00</updated>
    <id>http://rociiu.com/blog/2014/10/19/issues-of-upgrading-to-yosemite</id>
    <content type="html"><![CDATA[<h2>Fix brew command</h2>

<p>In Yosemite the ruby command path changed, yosemite use ruby 2.0 as default also create a new path to link to ruby 2.0:</p>

<pre><code>/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby
</code></pre>

<p>You need to change ruby path in the first line of /usr/local/Library/brew.rb</p>

<h2>Update brew</h2>

<p>After fix the brew command, it&rsquo;s better to update brew itself to avoid other issues</p>

<pre><code>brew update
</code></pre>

<h2>Fix postgresql</h2>

<p>After upgrade, you&rsquo;ll get following error when try to run: postgres -D /usr/local/var/postgresql</p>

<pre><code>FATAL:  could not open directory "pg_tblspc": No such file or directory
</code></pre>

<p>the fix is easy, just create those directories, those directories are gone after upgrade.</p>

<pre><code>mkdir /usr/local/var/postgres/pg_tblspc
mkdir /usr/local/var/postgres/pg_twophase
mkdir /usr/local/var/postgres/pg_stat_tmp
</code></pre>

<h2>install xcode, run &lsquo;xcode select &mdash;install&rsquo; to install command tools</h2>

<h2>references</h2>

<p>  <a href="http://stackoverflow.com/questions/25970132/pg-tblspc-missing-after-installation-of-os-x-yosemite-beta/26001639#26001639">http://stackoverflow.com/questions/25970132/pg-tblspc-missing-after-installation-of-os-x-yosemite-beta/26001639#26001639</a>
  <a href="https://jimlindley.com/blog/yosemite-upgrade-homebrew-tips/">https://jimlindley.com/blog/yosemite-upgrade-homebrew-tips/</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Client Form Validation in Angularjs]]></title>
    <link href="http://rociiu.com/blog/2014/08/13/client-form-validation-in-angularjs/"/>
    <updated>2014-08-13T09:33:35+08:00</updated>
    <id>http://rociiu.com/blog/2014/08/13/client-form-validation-in-angularjs</id>
    <content type="html"><![CDATA[<p>angularjs has built-in helper to validate form in client side, here is how you can use it.</p>

<p>Your html:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>
</span><span class='line'>&lt;form name="myForm" ng-submit="submitForm(myForm)"&gt;
</span><span class='line'>  &lt;div&gt;
</span><span class='line'>    &lt;input type="email" ng-model="user.email" name="uEmail" required /&gt;
</span><span class='line'>    &lt;div ng-show="myForm.uEmail.$dirty && myForm.uEmail.$invalid"&gt;Invalid:
</span><span class='line'>      &lt;span ng-show="form.uEmail.$error.required"&gt;Tell us your email.&lt;/span&gt;
</span><span class='line'>      &lt;span ng-show="form.uEmail.$error.email"&gt;This is not a valid email.&lt;/span&gt;
</span><span class='line'>    &lt;/div&gt;
</span><span class='line'>  &lt;/div&gt;
</span><span class='line'>&lt;/form&gt;
</span></code></pre></td></tr></table></div></figure>


<p>Notice that the name in form and input fields which is used as referenced when pass form object and check whether the field is valid.</p>

<p>$dirty use to check whether the field value changed and $invalid to check whether the field in valid, these two methods are useful to show errors message for the fields.</p>

<p>Your controller:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nx">angular</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;app&#39;</span><span class="p">).</span><span class="nx">controller</span><span class="p">(</span><span class="s">&#39;SampleController&#39;</span><span class="p">,</span> <span class="p">[</span>
</span><span class='line'>
</span><span class='line'>  <span class="s">&#39;$scope&#39;</span><span class="p">,</span> <span class="nf">($scope)-&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">$scope.submitForm = </span><span class="nf">(form)-&gt;</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">form</span><span class="p">.</span><span class="nx">$valid</span>
</span><span class='line'>        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&#39;submit the form to server&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>


<p>In controller, we can use the form object to check whether the form is valid before submit data to server.</p>

<p>There&rsquo;s a lot of ways that you can valid your input fields.</p>

<ul>
<li>required</li>
<li>ng-minlength</li>
<li>ng-max-length</li>
<li>ng-pattern (use regular expression for validation)</li>
<li>email ( if you specify email as type )</li>
<li>number ( if you specify number as type )</li>
<li>url ( if you specify url as type )</li>
<li>custom validation</li>
</ul>


<p>Reference url:</p>

<p><a href="http://www.ng-newsletter.com/posts/validations.html">http://www.ng-newsletter.com/posts/validations.html</a>
<a href="http://scotch.io/tutorials/javascript/angularjs-form-validation">http://scotch.io/tutorials/javascript/angularjs-form-validation</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Log Login Activity in Devise]]></title>
    <link href="http://rociiu.com/blog/2014/07/12/log-login-activity-in-devise/"/>
    <updated>2014-07-12T09:22:32+08:00</updated>
    <id>http://rociiu.com/blog/2014/07/12/log-login-activity-in-devise</id>
    <content type="html"><![CDATA[<p>In devise, there&rsquo;s option Trackable to record sign in count and ip, but in some case there&rsquo;s need to save custom logs in database. Turns out you can use Devise hook for that.</p>

<p>Just need to put this under config/initializer/devise.rb.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="ss">Warden</span><span class="p">:</span><span class="ss">:Manager</span><span class="o">.</span><span class="n">after_set_user</span> <span class="ss">except</span><span class="p">:</span> <span class="ss">:fetch</span> <span class="k">do</span> <span class="o">|</span><span class="n">record</span><span class="p">,</span> <span class="n">warden</span><span class="p">,</span> <span class="n">options</span><span class="o">|</span>
</span><span class='line'>  <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="ss">:update_tracked_fields!</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">warden</span><span class="o">.</span><span class="n">authenticated?</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:scope</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">User</span><span class="p">)</span>
</span><span class='line'>      <span class="no">LoginLog</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">user</span><span class="p">:</span> <span class="n">record</span><span class="p">,</span> <span class="ss">organization</span><span class="p">:</span> <span class="n">record</span><span class="o">.</span><span class="n">organization</span><span class="p">,</span> <span class="ss">ip</span><span class="p">:</span> <span class="n">warden</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">remote_ip</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Implement Pagination in Backbone]]></title>
    <link href="http://rociiu.com/blog/2014/07/05/implement-pagination-in-backbone/"/>
    <updated>2014-07-05T17:44:39+08:00</updated>
    <id>http://rociiu.com/blog/2014/07/05/implement-pagination-in-backbone</id>
    <content type="html"><![CDATA[<p>Before today I&rsquo;ve written multiple times for a pagination in front end, thought it&rsquo;s good time to write down in blog for future implementation.</p>

<h2>1. Include pagination in your api for backbone collection</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">def</span> <span class="nf">index</span>
</span><span class='line'>    <span class="n">customers</span> <span class="o">=</span> <span class="n">current_organization</span><span class="o">.</span><span class="n">customers</span><span class="o">.</span><span class="n">page</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:page</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">per</span><span class="p">(</span><span class="mi">25</span><span class="p">)</span>
</span><span class='line'>    <span class="n">render</span> <span class="ss">json</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">total_count</span><span class="p">:</span> <span class="n">customers</span><span class="o">.</span><span class="n">total_count</span><span class="p">,</span>
</span><span class='line'>      <span class="n">total_pages</span><span class="p">:</span> <span class="n">customers</span><span class="o">.</span><span class="n">total_pages</span><span class="p">,</span>
</span><span class='line'>      <span class="n">current_page</span><span class="p">:</span> <span class="n">customers</span><span class="o">.</span><span class="n">current_page</span><span class="p">,</span>
</span><span class='line'>      <span class="n">per_page</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span>
</span><span class='line'>      <span class="ss">models</span><span class="p">:</span> <span class="n">customers</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h2>2. Implemment paginated backbone collection to handle the api response.</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">class</span> <span class="nc">App</span><span class="o">.</span><span class="n">Collections</span><span class="o">.</span><span class="n">PaginatedCollection</span> <span class="n">extends</span> <span class="no">Backbone</span><span class="o">.</span><span class="n">Collection</span>
</span><span class='line'>
</span><span class='line'>    <span class="ss">parse</span><span class="p">:</span> <span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="o">-&gt;</span>
</span><span class='line'>      <span class="vi">@page</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">current_page</span>
</span><span class='line'>      <span class="vi">@perPage</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">per_page</span>
</span><span class='line'>      <span class="vi">@totalCount</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">total_count</span>
</span><span class='line'>      <span class="vi">@totalPages</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">total_pages</span>
</span><span class='line'>      <span class="n">resp</span><span class="o">.</span><span class="n">models</span>
</span><span class='line'>
</span><span class='line'>    <span class="ss">url</span><span class="p">:</span> <span class="o">-&gt;</span>
</span><span class='line'>      <span class="vi">@baseUrl</span> <span class="o">+</span> <span class="s2">&quot;?&quot;</span> <span class="o">+</span> <span class="vg">$.</span><span class="n">param</span><span class="p">({</span><span class="ss">page</span><span class="p">:</span> <span class="vi">@page</span><span class="p">,</span> <span class="ss">perPage</span><span class="p">:</span> <span class="vi">@perPage</span><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<h2>3. Implement paginated view</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="k">class</span> <span class="nx">App</span><span class="p">.</span><span class="nx">Views</span><span class="p">.</span><span class="nx">Shared</span><span class="p">.</span><span class="nx">PaginationView</span> <span class="k">extends</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">template: </span><span class="nx">JST</span><span class="p">[</span><span class="s">&quot;backbone/templates/shared/pagination&quot;</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">events:</span>
</span><span class='line'>      <span class="s">&quot;click .page-item&quot;</span><span class="o">:</span> <span class="s">&quot;changePage&quot;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">initialize: </span><span class="nf">(opts={})-&gt;</span>
</span><span class='line'>      <span class="vi">@collection  = </span><span class="nx">opts</span><span class="p">.</span><span class="nx">collection</span>
</span><span class='line'>      <span class="vi">@currentPage = </span><span class="nx">@collection</span><span class="p">.</span><span class="nx">page</span>
</span><span class='line'>      <span class="vi">@perPage     = </span><span class="nx">@collection</span><span class="p">.</span><span class="nx">perPage</span>
</span><span class='line'>      <span class="vi">@totalCount  = </span><span class="nx">@collection</span><span class="p">.</span><span class="nx">totalCount</span>
</span><span class='line'>      <span class="vi">@totalPages  = </span><span class="nx">@collection</span><span class="p">.</span><span class="nx">totalPages</span>
</span><span class='line'>      <span class="vi">@pageSize    = </span><span class="nx">@collection</span><span class="p">.</span><span class="nx">length</span>
</span><span class='line'>      <span class="nx">@calPageRange</span><span class="p">()</span>
</span><span class='line'>      <span class="nx">@calPages</span><span class="p">()</span>
</span><span class='line'>      <span class="nx">@calBackwardPages</span><span class="p">()</span>
</span><span class='line'>      <span class="nx">@calForwardPages</span><span class="p">()</span>
</span><span class='line'>      <span class="vi">@pageChanged = </span><span class="nx">opts</span><span class="p">.</span><span class="nx">pageChanged</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">changePage: </span><span class="nf">(e)-&gt;</span>
</span><span class='line'>      <span class="nv">pageNumber = </span><span class="nx">$</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s">&#39;data-page&#39;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">@pageChanged</span><span class="o">?</span>
</span><span class='line'>        <span class="nx">@pageChanged</span><span class="p">(</span><span class="nx">pageNumber</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">calPageRange: </span><span class="nf">-&gt;</span>
</span><span class='line'>      <span class="vi">@pageStart = </span><span class="p">(</span><span class="nx">@currentPage</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="nx">@perPage</span> <span class="o">+</span> <span class="mi">1</span>
</span><span class='line'>      <span class="vi">@pageEnd = </span><span class="p">((</span><span class="nx">@currentPage</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="nx">@perPage</span><span class="p">)</span> <span class="o">+</span> <span class="nx">@pageSize</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">calPages: </span><span class="nf">-&gt;</span>
</span><span class='line'>      <span class="nv">min = </span><span class="nx">_</span><span class="p">.</span><span class="nx">max</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="nx">@currentPage</span> <span class="o">-</span> <span class="mi">2</span><span class="p">])</span>
</span><span class='line'>      <span class="nv">max = </span><span class="nx">_</span><span class="p">.</span><span class="nx">min</span><span class="p">([</span><span class="nx">@currentPage</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">@totalPages</span><span class="p">])</span>
</span><span class='line'>      <span class="vi">@pages = </span><span class="p">[</span><span class="nx">min</span><span class="p">..</span><span class="nx">max</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">calBackwardPages: </span><span class="nf">-&gt;</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@pages</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span>
</span><span class='line'>        <span class="vi">@firstPage = </span><span class="kc">null</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>        <span class="vi">@firstPage = </span><span class="mi">1</span>
</span><span class='line'>      <span class="nv">prevPage = </span><span class="nx">_</span><span class="p">.</span><span class="nx">max</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="nx">@pages</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">])</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@pages</span><span class="p">,</span> <span class="nx">prevPage</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">||</span> <span class="nx">prevPage</span> <span class="o">==</span> <span class="nx">@firstPage</span>
</span><span class='line'>        <span class="vi">@prevPage = </span><span class="kc">null</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>        <span class="vi">@prevPage = </span><span class="nx">prevPage</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">calForwardPages: </span><span class="nf">-&gt;</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@pages</span><span class="p">,</span> <span class="nx">@totalPages</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span>
</span><span class='line'>        <span class="vi">@lastPage = </span><span class="kc">null</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>        <span class="vi">@lastPage = </span><span class="nx">@totalPages</span>
</span><span class='line'>      <span class="nv">nextPage = </span><span class="nx">_</span><span class="p">.</span><span class="nx">min</span><span class="p">([</span><span class="nx">@totalPages</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">last</span><span class="p">(</span><span class="nx">@pages</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@pages</span><span class="p">,</span> <span class="nx">nextPage</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">||</span> <span class="nx">nextPage</span> <span class="o">==</span> <span class="nx">@lastPage</span>
</span><span class='line'>        <span class="vi">@nextPage = </span><span class="kc">null</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>        <span class="vi">@nextPage = </span><span class="nx">nextPage</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">render: </span><span class="nf">-&gt;</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">@totalCount</span> <span class="o">==</span> <span class="mi">0</span>
</span><span class='line'>        <span class="nx">@$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span>
</span><span class='line'>      <span class="nx">@$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="nx">@template</span><span class="p">({</span>
</span><span class='line'>        <span class="nv">totalCount: </span><span class="nx">@totalCount</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">pageStart: </span><span class="nx">@pageStart</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">pageEnd: </span><span class="nx">@pageEnd</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">pages: </span><span class="nx">@pages</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">currentPage: </span><span class="nx">@currentPage</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">firstPage: </span><span class="nx">@firstPage</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">prevPage: </span><span class="nx">@prevPage</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">lastPage: </span><span class="nx">@lastPage</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">nextPage: </span><span class="nx">@nextPage</span>
</span><span class='line'>      <span class="p">}))</span>
</span><span class='line'>      <span class="nx">@</span>
</span></code></pre></td></tr></table></div></figure>


<h2>4. Implement pagination template.</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="o">&lt;</span><span class="nx">div</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;col-sm-4&quot;</span><span class="o">&gt;</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">small</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;text-muted inline m-t-sm m-b-sm&quot;</span><span class="o">&gt;</span><span class="err">第</span> <span class="o">&lt;%=</span> <span class="nx">pageStart</span> <span class="o">%&gt;-&lt;%=</span> <span class="nx">pageEnd</span> <span class="o">%&gt;</span><span class="err">条</span> <span class="err">共</span><span class="o">&lt;%=</span> <span class="nx">totalCount</span> <span class="o">%&gt;</span> <span class="err">条</span><span class="o">&lt;/</span><span class="nx">small</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="o">&lt;/</span><span class="nx">div</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="o">&lt;</span><span class="nx">div</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;col-sm-8 text-right text-center-xs&quot;</span><span class="o">&gt;</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">ul</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;pagination pagination-sm m-t-none m-b-none&quot;</span><span class="o">&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="k">if</span><span class="p">(</span><span class="nx">firstPage</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>            <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;page-item&quot;</span> <span class="nx">data</span><span class="o">-</span><span class="nx">page</span><span class="o">=</span><span class="s">&quot;&lt;%= firstPage %&gt;&quot;</span><span class="o">&gt;&lt;</span><span class="nx">i</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;fa fa-angle-double-left&quot;</span><span class="o">&gt;&lt;/</span><span class="nx">i</span><span class="o">&gt;&lt;/</span><span class="nx">a</span><span class="o">&gt;&lt;/</span><span class="nx">li</span><span class="o">&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="p">}</span> <span class="o">%&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="k">if</span><span class="p">(</span><span class="nx">prevPage</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>            <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;page-item&quot;</span> <span class="nx">data</span><span class="o">-</span><span class="nx">page</span><span class="o">=</span><span class="s">&quot;&lt;%= prevPage %&gt;&quot;</span><span class="o">&gt;&lt;</span><span class="nx">i</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;fa fa-angle-left&quot;</span><span class="o">&gt;&lt;/</span><span class="nx">i</span><span class="o">&gt;&lt;/</span><span class="nx">a</span><span class="o">&gt;&lt;/</span><span class="nx">li</span><span class="o">&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="p">}</span> <span class="o">%&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="k">for</span><span class="p">(</span><span class="nx">var</span> <span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">pages</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>            <span class="o">&lt;%</span> <span class="k">if</span><span class="p">(</span><span class="nx">pages</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">==</span> <span class="nx">currentPage</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>              <span class="o">&lt;</span><span class="nx">li</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;active&quot;</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;page-item&quot;</span> <span class="nx">data</span><span class="o">-</span><span class="nx">page</span><span class="o">=</span><span class="s">&quot;&lt;%= pages[i] %&gt;&quot;</span><span class="o">&gt;&lt;%=</span> <span class="nx">pages</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">%&gt;&lt;</span><span class="nx">span</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;sr-only&quot;</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">current</span><span class="p">)</span><span class="o">&lt;/</span><span class="nx">span</span><span class="o">&gt;&lt;/</span><span class="nx">a</span><span class="o">&gt;&lt;/</span><span class="nx">li</span><span class="o">&gt;</span>
</span><span class='line'>            <span class="o">&lt;%</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>              <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;page-item&quot;</span> <span class="nx">data</span><span class="o">-</span><span class="nx">page</span><span class="o">=</span><span class="s">&quot;&lt;%= pages[i] %&gt;&quot;</span><span class="o">&gt;&lt;%=</span> <span class="nx">pages</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">%&gt;&lt;/</span><span class="nx">a</span><span class="o">&gt;&lt;/</span><span class="nx">li</span><span class="o">&gt;</span>
</span><span class='line'>            <span class="o">&lt;%</span> <span class="p">}</span> <span class="o">%&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="p">}</span> <span class="o">%&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="k">if</span><span class="p">(</span><span class="nx">nextPage</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>            <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;page-item&quot;</span> <span class="nx">data</span><span class="o">-</span><span class="nx">page</span><span class="o">=</span><span class="s">&quot;&lt;%= nextPage %&gt;&quot;</span><span class="o">&gt;&lt;</span><span class="nx">i</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;fa fa-angle-right&quot;</span><span class="o">&gt;&lt;/</span><span class="nx">i</span><span class="o">&gt;&lt;/</span><span class="nx">a</span><span class="o">&gt;&lt;/</span><span class="nx">li</span><span class="o">&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="p">}</span> <span class="o">%&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="k">if</span><span class="p">(</span><span class="nx">lastPage</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> <span class="o">%&gt;</span>
</span><span class='line'>            <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;&lt;</span><span class="nx">a</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;page-item&quot;</span> <span class="nx">data</span><span class="o">-</span><span class="nx">page</span><span class="o">=</span><span class="s">&quot;&lt;%= lastPage %&gt;&quot;</span><span class="o">&gt;&lt;</span><span class="nx">i</span> <span class="k">class</span><span class="o">=</span><span class="s">&quot;fa fa-angle-double-right&quot;</span><span class="o">&gt;&lt;/</span><span class="nx">i</span><span class="o">&gt;&lt;/</span><span class="nx">a</span><span class="o">&gt;&lt;/</span><span class="nx">li</span><span class="o">&gt;</span>
</span><span class='line'>          <span class="o">&lt;%</span> <span class="p">}</span> <span class="o">%&gt;</span>
</span><span class='line'>      <span class="o">&lt;/</span><span class="nx">ul</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="o">&lt;/</span><span class="nx">div</span><span class="o">&gt;</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Organize Angularjs Files Ftw]]></title>
    <link href="http://rociiu.com/blog/2014/06/14/organize-angularjs-files-ftw/"/>
    <updated>2014-06-14T19:47:50+08:00</updated>
    <id>http://rociiu.com/blog/2014/06/14/organize-angularjs-files-ftw</id>
    <content type="html"><![CDATA[<p>In a recent project I just started to use angularjs to develop complicated front UI, this project is not a SPA, we only use angularjs in places that ui elements is so complicated that is easier to do with front end. Since new on angularjs, i searched on the internet for best practices that organize large codebase and module naming, found couple ways.</p>

<h3>1. Put everything in one file for simplest case.</h3>

<figure class='code'><figcaption><span>app.js.coffee everything in one file</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>
</span><span class='line'>  <span class="nx">angularjs</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;myApp&#39;</span><span class="p">,</span> <span class="p">[])</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">controller</span><span class="p">(</span><span class="s">&#39;MyCtrl&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;$scope&#39;</span><span class="p">,</span> <span class="nf">($scope)-&gt;</span>
</span><span class='line'>      <span class="nv">$scope.hello = </span><span class="s">&quot;world&quot;</span>
</span><span class='line'>    <span class="p">])</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">constant</span><span class="p">(</span><span class="s">&#39;Contacts&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;Foo&#39;</span><span class="p">,</span> <span class="s">&#39;Bar&#39;</span><span class="p">])</span>
</span><span class='line'>    <span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<h3>2. Put different kind of stuff in different files</h3>

<figure class='code'><figcaption><span>app.js.coffee define app namespace</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>
</span><span class='line'>  <span class="nx">angularjs</span><span class="p">.</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;myApp&#39;</span><span class="p">,</span> <span class="p">[])</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>controllers.js.coffee define controllers</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>
</span><span class='line'>  <span class="nx">angularjs</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;myApp&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">controller</span><span class="p">(</span><span class="s">&#39;OneCtrl&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;$scope&#39;</span><span class="p">,</span> <span class="nf">($scope)-&gt;</span>
</span><span class='line'>      <span class="nv">$scope.hello = </span><span class="s">&#39;world&#39;</span>
</span><span class='line'>    <span class="p">])</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">controller</span><span class="p">(</span><span class="s">&#39;TwoCtrl&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;$scope&#39;</span><span class="p">,</span> <span class="nf">($scope)-&gt;</span>
</span><span class='line'>      <span class="nv">$scope.foo = </span><span class="s">&#39;bar&#39;</span>
</span><span class='line'>    <span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>constants.js.coffee define constants</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>
</span><span class='line'>  <span class="nx">angularjs</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;myApp&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">constant</span><span class="p">(</span><span class="s">&#39;Contacts&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;Foo&#39;</span><span class="p">,</span> <span class="s">&#39;Bar&#39;</span><span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>


<h3>3. Create directories to save different kind of files</h3>

<figure class='code'><figcaption><span>constants.js.coffee define constants</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="o">-</span> <span class="nx">app</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="nx">controllers</span><span class="o">/</span>
</span><span class='line'>    <span class="nx">OneCtrl</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="nx">TwoCtrl</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="nx">constants</span><span class="o">/</span>
</span><span class='line'>    <span class="nx">Contants</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="nx">Contacts</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<h3>4. Create features directories to store everything for each features</h3>

<figure class='code'><figcaption><span>constants.js.coffee define constants</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="o">-</span> <span class="nx">app</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="nx">Users</span>
</span><span class='line'>    <span class="o">-</span> <span class="nx">UserCtrl</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="o">-</span> <span class="nx">UserModel</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="nx">Contacts</span>
</span><span class='line'>    <span class="o">-</span> <span class="nx">ContactsCtrl</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="o">-</span> <span class="nx">ContactModel</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span></code></pre></td></tr></table></div></figure>


<h3>5. How do organize code for multiple angularjs apps</h3>

<figure class='code'><figcaption><span>constants.js.coffee define constants</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="o">-</span> <span class="nx">app</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="o">-</span> <span class="nx">modules</span>
</span><span class='line'>    <span class="nx">AppOne</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="nx">AppTwo</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="o">-</span> <span class="nx">controllers</span>
</span><span class='line'>    <span class="nx">AppOne</span><span class="o">/</span>
</span><span class='line'>      <span class="nx">OneCtrl</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="nx">AppTwo</span><span class="o">/</span>
</span><span class='line'>      <span class="nx">TwoCtrl</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>  <span class="o">-</span> <span class="nx">models</span>
</span><span class='line'>    <span class="nx">AppOne</span><span class="o">/</span>
</span><span class='line'>      <span class="nx">UserModel</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span><span class='line'>    <span class="nx">AppTwo</span><span class="o">/</span>
</span><span class='line'>      <span class="nx">ContactModel</span><span class="p">.</span><span class="nx">js</span><span class="p">.</span><span class="nx">coffee</span>
</span></code></pre></td></tr></table></div></figure>


<p>In app.js.coffee, I define top level module to include basic dependencies share between apps.</p>

<figure class='code'><figcaption><span>app.js.coffee</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="nx">angularjs</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;app&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;dep1&#39;</span><span class="p">,</span> <span class="s">&#39;dep2&#39;</span><span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>


<p>In AppOne.js.coffe, it define a new module and load app as dependencies and the shared dependencies define in app will be available in AppOne.</p>

<figure class='code'><figcaption><span>AppOne.js.coffee</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="nx">angularjs</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s">&#39;app.appOne&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;app&#39;</span><span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>


<p>In html only need to specify AppOne in place that app one is need.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>  <span class="nt">&lt;div</span> <span class="na">ng-app=</span><span class="s">&#39;app.appOne&#39;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;div</span> <span class="na">ng-controller=</span><span class="s">&quot;OneCtrl&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/div&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Conculsion</h3>

<p>I didn&rsquo;t choose solution 4 because it seems not good to put different stuff together even though it&rsquo;s easier to find files for changes. So I follow solution 3 and extend it for multiple apps.</p>
]]></content>
  </entry>
  
</feed>
