<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Simon's Blog</title>
 
 <link href="http://blog.jodet.com/" />
 <updated>2012-01-01T20:53:46+01:00</updated>
 <id>http://blog.jodet.com/</id>
 <author>
   <name>Simon Jodet</name>
   <email>simon@jodet.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/jodet/blog" /><feedburner:info uri="jodet/blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Vim</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/jSbU5kwdrJc/vim" />
   <updated>2012-01-01T00:00:00+01:00</updated>
   <id>http://blog.jodet.com/vim</id>
   <content type="html">&lt;p&gt;&lt;img src="/img/technology/2012-01-01-vim/vim_logo.png" class="post-img float-right"/&gt;
While I'm learning Ruby (and a bit of Python) I decided to make things a bit more difficult and I started to learn &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a while, I thought Vim was just a way for some developers to show off and snob us, the stupid people using "notepad-like" editors.
While I still think that really smart "notepad-like" editors like Eclipse, Netbeans and Intellij Idea can be really useful and let developers code and read code faster, I can now understand why Vim is a very valid contender in the race to the best text editor. But damn! The learning curve is steap!&lt;/p&gt;

&lt;p&gt;To help me, I found this blog from this canadian dude, Derek Wyatt, and his screencasts teaching how to use Vim. He's a bit crazy (especially in the first video) but his style and passion actually helps a lot.&lt;/p&gt;

&lt;p&gt;So if you ever consider learning how to use Vim or get better at using it, take the time to watch &lt;a href="http://www.derekwyatt.org/vim/vim-tutorial-videos/vim-novice-tutorial-videos/"&gt;Derek Wyatt's screencasts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By the way, this is my first post written using Vim and I swear I didn't used the arrow keys (almost).&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/jSbU5kwdrJc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/vim</feedburner:origLink></entry>
 
 <entry>
   <title>A quick Ruby port</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/wBe6prmyrts/some-quick-ruby-port" />
   <updated>2011-12-18T00:00:00+01:00</updated>
   <id>http://blog.jodet.com/some-quick-ruby-port</id>
   <content type="html">&lt;p&gt;Still on my journey to learning the Ruby language, I've ported a small PHP script I've written a while ago to quickly eject external drives on my MacBook Pro in Ruby.&lt;/p&gt;

&lt;p&gt;I converted it to &lt;a href="/uploads/usb_eject.app.zip"&gt;an app&lt;/a&gt; with Automator&lt;/p&gt;

&lt;p&gt;Here is the code (MIT license):&lt;/p&gt;

&lt;script src="https://gist.github.com/1492740.js?file=usb_eject.rb"&gt;&lt;/script&gt;


&lt;p&gt;Comments and critics are welcome.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/wBe6prmyrts" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/some-quick-ruby-port</feedburner:origLink></entry>
 
 <entry>
   <title>My journey with Ruby</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/q0Lo0J8iWwA/my-journey-with-ruby" />
   <updated>2011-12-10T00:00:00+01:00</updated>
   <id>http://blog.jodet.com/my-journey-with-ruby</id>
   <content type="html">&lt;p&gt;&lt;img src="/img/technology/2011-12-10-my-journey-with-ruby/ruby.png" class="post-img float-left"/&gt;
I'm a developer. But as a developer, I'm fairly faithful. I really seriously started programming with PHP. I learned and used this language thouroughly. I consider myself an expert programmer in this language.&lt;/p&gt;

&lt;p&gt;It's more or less my native language. My second language is JavaScript. I started playing with it a long time ago but really discovered its power in 2007 with Mootools.&lt;br/&gt;
Yes Mootools! jQuery is for sissies! Just kidding, jQuery is fine but if you want to really learn JavaScript, try Mootools or ExtJS, read &lt;a href="http://shop.oreilly.com/product/9780596101992.do"&gt;this&lt;/a&gt;, Crockford's &lt;a href="http://shop.oreilly.com/product/9780596517748.do"&gt;book&lt;/a&gt; and watch &lt;a href="http://yuiblog.com/crockford/"&gt;his lectures&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've played with other languages, some really close to what I know - ActionScript is just JavaScript- others a little more different like Python. Python is nice but we have our fair share of Python developers at the office. What's the fun of learning a new language if you have the security of being able to ask the guy next door?&lt;/p&gt;

&lt;p&gt;So as you probably guessed with this article's title, I've decided to learn Ruby. And I just figured out that I should document this journey. I don't know if it'll help anybody but, heh, why not?&lt;br/&gt;
So to be fair, I've tried Ruby before. Not very seriously. And because of this blog actually. It's built on &lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; which is written in Ruby. When I wanted to change some stuff I realized I should probably learn Ruby first.&lt;/p&gt;

&lt;p&gt;This introduction is already way too long so let's get to the point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby is a pretty cool language, clearly designed for the convenience of the developer, with a lot of alternative syntaxes and shortcuts.&lt;br/&gt;
The language is, I feel, sometimes a bit too forgiving, leaving the developer free to write bad code without realizing it.&lt;/li&gt;
&lt;li&gt;I just love the fact that Ruby has closures. It's like a mix between PHP and JavaScript.&lt;/li&gt;
&lt;li&gt;Gems seem to be a lot better than PHP's PEAR.&lt;/li&gt;
&lt;li&gt;The documentation is huge, a bit too much actually. My first tries at Ruby were a bit rushed. I've been hearing praises for Ruby On Rails for so long, I tried to learn the language through RoR.&lt;br/&gt;
Even though there is a lot of &lt;a href="http://railsforzombies.org/"&gt;good tutorials&lt;/a&gt;, you should start by learning Ruby first, RoR second. So, I got the &lt;a href="http://shop.oreilly.com/product/9780596529864.do"&gt;Learning Ruby&lt;/a&gt; book and just read it. It's not a perfect book, I feel it sometimes even expressed dangerous opinions for junior developers. But if you want to learn the basics of the language, it does the trick.&lt;/li&gt;
&lt;li&gt;Still regarding the documentation, for whatever reason, it's hard for me to understand the reference documentation. It's just a mess for me. I tried to learn the language with a small program that manipulate file paths. In other words, strings. When I started looking for a way to use Regexp, I hit &lt;a href="http://www.ruby-doc.org/core-1.8.7/Regexp.html"&gt;a wall&lt;/a&gt;. Where is the legend? Where is the real life example? Oh I see, I have to use the &lt;code&gt;new&lt;/code&gt; method to transform a string in a pattern. I mean, the php.net documentation is not that good but a least you get examples in their context...&lt;/li&gt;
&lt;li&gt;I took me 2 hours and a lot of digging to understand why my &lt;code&gt;require 'json'&lt;/code&gt; directive didn't work even though I had installed the gem. Actually, I still don't understand why, I just found that with &lt;code&gt;require 'rubygems'&lt;/code&gt; before, it was working.&lt;/li&gt;
&lt;li&gt;Even though Ruby is installed by default on Mac OS X, some struff doesn't really work well. Or I just broke it earlier digging in my system. I'm currently using the macports version of Ruby (1.8.7). I may eventually decide to compile it myself or use rvm.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So, for the couple of geeks that'll read this, if you know soemthing about Ruby, have advices, books I should read, please let me know in the comments :)&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/q0Lo0J8iWwA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/my-journey-with-ruby</feedburner:origLink></entry>
 
 <entry>
   <title>RIP Steve Jobs</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/gswfMBa_s3o/rip_steve" />
   <updated>2011-10-06T00:00:00+02:00</updated>
   <id>http://blog.jodet.com/rip_steve</id>
   <content type="html">&lt;div style="text-align:center;"&gt;&lt;a href="http://www.apple.com/stevejobs/"&gt;&lt;img src="/img/misc/2011-10-06-rip_steve/rip_steve.png" style="max-width:600px;"/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/gswfMBa_s3o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/rip_steve</feedburner:origLink></entry>
 
 <entry>
   <title>Jekyll and Node</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/fsK34n__SRw/jekyll-and-node" />
   <updated>2011-09-12T00:00:00+02:00</updated>
   <id>http://blog.jodet.com/jekyll-and-node</id>
   <content type="html">&lt;p&gt;&lt;img src="/img/technology/2011-09-12-jekyll-and-node/jekyll_node.png" class="post-img float-left"/&gt;
Sorry but here's a new post about this blog. I've already talked about my choice of &lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; as the engine for this blog.&lt;/p&gt;

&lt;p&gt;Don't worry, I'm still very happy with it!&lt;br/&gt;
But we're not in the 20th century anymore and even if I don't need 99% of the features delivered by Wordpress, some are important to me.&lt;/p&gt;

&lt;h4&gt;External links&lt;/h4&gt;

&lt;p&gt;I like the external links of my site to open a new tab/window (with the HTML &lt;code&gt;target="_blank"&lt;/code&gt; attribute).&lt;br/&gt;
Since I didn't want to dig into Jekyll's rendering process, I chose to add the HTML attribute to all external links with some JavaScript:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="js"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;domain_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;//&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;all_links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;domain_root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;domain_root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_blank&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Yes I use jQuery and yes some of you will scream but I don't care, most of your CPU's cores are idle right now so I decided to put them to work a bit.&lt;br/&gt;
In modern browsers, it shouldn't slow down your browsing experience at all.&lt;/p&gt;

&lt;h4&gt;Twitter&lt;/h4&gt;

&lt;p&gt;I will tweet 10 times more than I'll post here (at least and not counting RTs). So I wanted my Twitter feed included in this blog.&lt;br/&gt;
My first reflex was to try out Twitter's official JavaScript widget but let's be honest it's really ugly! And customize it is a pain in the a**.&lt;/p&gt;

&lt;p&gt;So after searching a bit, I chose &lt;a href="http://tweet.seaofclouds.com/"&gt;Tweet!&lt;/a&gt;. A lot more options, a dedicated CSS and I host it so I can fiddle a bit with it.  I used Twitter's official icons and CSS sprites though.&lt;/p&gt;

&lt;h4&gt;RSS, Categories and SEO&lt;/h4&gt;

&lt;p&gt;For those, just go to this &lt;a href="http://vitobotta.com/how-to-migrate-from-wordpress-to-jekyll/"&gt;blog entry&lt;/a&gt;. It contains everything you need to build an RSS feed (I used feedburner to track you though :p ), the &lt;a href="http://localhost:4000/categories/index.html"&gt;Categories&lt;/a&gt; page and do Search Engine Optimization (sitemap, keywords, etc.). Great stuff for everyone who wants to use/switch to Jekyll.&lt;/p&gt;

&lt;h4&gt;Comments&lt;/h4&gt;

&lt;p&gt;As you can see, I'm using &lt;a href="http://disqus.com/"&gt;Disqus&lt;/a&gt;. Not much more to add.&lt;/p&gt;

&lt;h4&gt;Style&lt;/h4&gt;

&lt;p&gt;I'm using &lt;a href="http://twitter.github.com/bootstrap/"&gt;Bootstrap&lt;/a&gt;, the CSS toolbox from the Twitter team. Really easy for a style-impaired guy as myself. Works great on iOS too.&lt;/p&gt;

&lt;h4&gt;Search&lt;/h4&gt;

&lt;p&gt;Finally, I get to the point where I discuss the second item of this entry's title: Node. The unofficial name of this beast is Node.js and for those who lived underground for the past year, it's server-side JavaScript on top of an event loop or as Ryan Dahl puts it: "evented I/O for V8 JavaScript".&lt;br/&gt;
There are a lot of resources available on the interwebs if you're interested in Node. I suggest you take a look at &lt;a href="http://www.youtube.com/watch?v=jo_B4LTHi3I"&gt;Ryan Dahl's talk&lt;/a&gt; and read this &lt;a href="http://nodebeginner.org/"&gt;tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, search. How do you add search to a static website?&lt;br/&gt;
First reflex: Google. Tried it, didn't work, too complicated and they even ask for money. No thanks.&lt;br/&gt;
Second idea: any plugin available for Jekyll? &lt;a href="https://github.com/PascalW/jekyll_indextank"&gt;Yes&lt;/a&gt; but (there's always a "but", I know you saw it coming) it uses indextank API which a freemium service. No thanks.&lt;br/&gt;
Third idea: I can do it myself! But to stay consistent, let's not use PHP, Ruby or some usual server side language.&lt;/p&gt;

&lt;p&gt;Let's populate the backlog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As a user, I'm browsing a fast static website, I don't want the search field to take forever to answer me&lt;/li&gt;
&lt;li&gt;As a geek, I want to play with cutting edge technology&lt;/li&gt;
&lt;li&gt;As a lazy geek, I don't want to spend too much time learning a new language&lt;/li&gt;
&lt;li&gt;As a lazy geek, I don't want to spend too much time setup-ing the whole thing&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Let's map this to Node and the existing setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast? Node is designed to be fast! It's designed to deliver high concurrency with its event-loop.&lt;/li&gt;
&lt;li&gt;Cutting edge technology? Oh it's young but already used on production setups such as LinkedIn.&lt;/li&gt;
&lt;li&gt;No new language? It's JavaScript!&lt;/li&gt;
&lt;li&gt;Setup? Node is its own server. For security reasons though, it's reversed-proxied by Nginx. I didn't want to install a database server so I chose SQLite.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is first an indexing script and then the server part that delivers search results.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/simonjodet/blog/blob/master/search_indexer/search_indexer.js"&gt;indexing script&lt;/a&gt; parses a striped-down list of the posts generated by Jekyll and populate the SQLite DB. It is ran at build time. It seems simple but writing non-blocking code and looping are not that easy to mix the first time. If you checkout the source code, you may notice there is unused code for word indexing. I'll use this for autocompletion suggestions when I have time.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/simonjodet/blog/blob/master/search/search.js"&gt;server&lt;/a&gt; queries the SQLite DB for search results and returns JSON to the search AJAX query. Here, it is really simple, just had to clean up search queries to avoid SQL injections. Some duplicated code to clean up though :$&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is it setup?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So the search indexer is ran at built time from a git hook script.&lt;br/&gt;
I have a bare repository (&lt;code&gt;/var/www/blog_repo/&lt;/code&gt;) acting as a remote for both my local repo and the deployed repo (&lt;code&gt;/var/www/blog/&lt;/code&gt;). I also have a Github repo to share this &lt;em&gt;great&lt;/em&gt; code. When I push from my local repo, the bare repo post-receive hook is ran:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git push github master &lt;span class="c"&gt;# Push updates to the Github repo&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/blog/ &lt;span class="c"&gt;# Go to the deployed repo&lt;/span&gt;
env -i git pull origin master &lt;span class="c"&gt;# Update the deployed repo&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/var/lib/gems/1.8/bin/:$PATH&amp;quot;&lt;/span&gt;
jekyll --no-auto &lt;span class="c"&gt;# Build the blog &lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/blog/search_indexer/
node search_indexer.js &lt;span class="c"&gt;# Build the search index&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The only thing it doesn't do is start the node server because I didn't figured out yet how to run an &lt;a href="http://upstart.ubuntu.com/"&gt;upstart&lt;/a&gt; script as a non-root user. Here's the upstart script:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;description &lt;span class="s2"&gt;&amp;quot;node.js server&amp;quot;&lt;/span&gt;
author      &lt;span class="s2"&gt;&amp;quot;Simon Jodet&amp;quot;&lt;/span&gt;

start on started mountall
stop on shutdown

respawn
respawn limit 99 5

script
    &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/var/www&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;exec &lt;/span&gt;sudo -u www-data /usr/bin/node /var/www/blog/search/search.js &amp;gt;&amp;gt; /var/log/node.log 2&amp;gt;&amp;amp;1
end script
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The good thing is that I only need to reload it when I update the search server script which is not that often.&lt;/p&gt;

&lt;p&gt;Finally, the server is behind a Nginx reverse proxy. I'll let you search the web on how to setup Nginx as a reverse proxy. Here's the virtual host configuration:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="nginx"&gt;&lt;span class="k"&gt;server&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt;   &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt;  &lt;span class="s"&gt;blog.jodet.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/50x.html&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="s"&gt;/var/www/nginx-default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;access_log&lt;/span&gt;  &lt;span class="s"&gt;/var/log/nginx/jodet_access.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;error_log&lt;/span&gt;  &lt;span class="s"&gt;/var/log/nginx/jodet_error.log&lt;/span&gt; &lt;span class="s"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/search/&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt;         &lt;span class="s"&gt;http://127.0.0.1:1337/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt;  &lt;span class="s"&gt;/var/www/blog/_site&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Simple, right? Nginx rocks! And guess, what? It is built on an event loop too.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;If you have questions or see an issue with my setup, drop me a comment please. It will be much appreciated!&lt;/p&gt;

&lt;p&gt;Finally, my blog's code is available for all to check on &lt;a href="https://github.com/simonjodet/blog"&gt;Github&lt;/a&gt;. Apart from the blog posts, it's under the MIT license so you're free to do whatever you want with my code (but not my posts!).&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/fsK34n__SRw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/jekyll-and-node</feedburner:origLink></entry>
 
 <entry>
   <title>Recent PHP discoveries</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/xl2H6zzi-h8/recent-php-discoveries" />
   <updated>2011-08-25T00:00:00+02:00</updated>
   <id>http://blog.jodet.com/recent-php-discoveries</id>
   <content type="html">&lt;p&gt;&lt;img src="/img/technology/2011-08-25-recent-php-discoveries/php-med-trans.png" class="post-img float-left"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trim&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I just discovered that the &lt;a href="http://us.php.net/manual/en/function.trim.php" title="trim documentation"&gt;trim&lt;/a&gt; function I've been using for so long to remove whitespaces around strings can also remove any other character. I've been cleaning &lt;em&gt;by hand&lt;/em&gt; those path items of possible trailing slashes for so long...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Curl issue with PHP 5.3.8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've encountered an issue on a project after updating to PHP 5.3.8 (the dotdeb package on Debian).&lt;br/&gt;
If you're calling a HTTPS domain with a self-signed certificate, &lt;code&gt;CURLOPT_SSL_VERIFYPEER&lt;/code&gt; to 0 is not enough anymore. &lt;code&gt;CURLOPT_SSL_VERIFYHOST&lt;/code&gt; should be also set to 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HEAD stop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Accordind to &lt;a href="https://students.mimuw.edu.pl/~ai292615/php_head_trick.pdf"&gt;this&lt;/a&gt;, calling PHP with the HEAD http method will make stop execution on the first output. This is potentially dangerous and a security breach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;British PHP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What would have happened if PHP had been invented by some British chap? The answer is &lt;a href="http://www.addedbytes.com/blog/if-php-were-british/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/xl2H6zzi-h8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/recent-php-discoveries</feedburner:origLink></entry>
 
 <entry>
   <title>One</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/RMaGOB60OIA/one" />
   <updated>2011-08-24T00:00:00+02:00</updated>
   <id>http://blog.jodet.com/one</id>
   <content type="html">&lt;p&gt;&lt;img src="/img/misc/2011-08-24-one/u2_one.jpg" class="post-img float-right"/&gt;
Ok. For the &lt;em&gt;tenth&lt;/em&gt; time at least, I'm starting a blog. I'm like a little school girl promising to herself every year to keep a diary. Epic fail each time...&lt;/p&gt;

&lt;p&gt;Every time, there is a good reason for me to start a blog. This time around, I really wanted to use Jekyll and get rid of Wordpress.&lt;/p&gt;

&lt;p&gt;Wordpress is probably one of the best blog engine out there. However, it doesn't fit my needs and has a number of major flaws:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wordpress is too stressful. I mean my blog got hacked a couple of time with 0-day injection issues. This engine is way to much used and like Windows is a favorite target for hackers.&lt;/li&gt;
&lt;li&gt;I don't need this bloated engine to write maybe ten posts in total before I switch to something else again.&lt;/li&gt;
&lt;li&gt;Jekyll seems to be a nice little tool and it gives me an excuse to use 2 things I've been using a lot lately: Git and markdown-like writing with Sphynx.&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/RMaGOB60OIA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/one</feedburner:origLink></entry>
 
 <entry>
   <title>Filtering a Phar content</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/V89VO_a-9RI/filtering-a-phar-content" />
   <updated>2011-06-18T00:00:00+02:00</updated>
   <id>http://blog.jodet.com/filtering-a-phar-content</id>
   <content type="html">&lt;p&gt;If you don't like regular expressions or if they're not enough, take a look at &lt;a href="https://gist.github.com/1032868"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you don't know what Phars are, it's &lt;a href="http://us.php.net/manual/en/book.phar.php"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/V89VO_a-9RI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/filtering-a-phar-content</feedburner:origLink></entry>
 
 <entry>
   <title>Mixing up TDD, PHPUnit, Namespaces and Jenkins</title>
   <link href="http://feedproxy.google.com/~r/jodet/blog/~3/FEcDtvoCo6o/mixing-up-tdd-phpunit-namespaces-and-jenkins" />
   <updated>2011-02-22T00:00:00+01:00</updated>
   <id>http://blog.jodet.com/mixing-up-tdd-phpunit-namespaces-and-jenkins</id>
   <content type="html">&lt;p&gt;Hi all,&lt;/p&gt;

&lt;p&gt;First of all, if you're not a PHP developer, don't read this.&lt;/p&gt;

&lt;p&gt;This post will be about my tries and misses with &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt;. To make things harder, I'm adding into the mix &lt;a href="http://www.phpunit.de/manual/3.6/en/index.html"&gt;PHPUnit&lt;/a&gt; (of which I have minimal knowledge), &lt;a href="http://www.php.net/manual/en/language.namespaces.php"&gt;namespaces&lt;/a&gt; (because I'm also a JavaScript developer and I feel at home now) and &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt; (fka Hudson).&lt;/p&gt;

&lt;p&gt;First of all and against all odds, TDD is fun! I swear, I really enjoy it. And adding Jenkins multiply the fun because you can gloat, showing off you 100% test coverage, your sky-rocketing test count, etc.&lt;/p&gt;

&lt;p&gt;Now, I wouldn't write a post just to say TDD is fun. Anyway TDD becomes fun and worthy of the effort when you have figured out some quirks of the different tools.&lt;/p&gt;

&lt;p&gt;PHPUnit is a pain in the a**. But it seems to be the de facto standard so... I'm waiting for a stable version of &lt;a href="http://blog.mageekbox.net/?category/Projets/atoum"&gt;Atoum&lt;/a&gt; though.&lt;/p&gt;

&lt;p&gt;I got 3 major issues with PHPUnit:&lt;/p&gt;

&lt;p&gt;1- On a previous project, I found out the process isolation support is incomplete. To have a real process isolation, you have to put your tests in separate files! And it is really long to run the complete test suite. So you've got 3 options: multiply the file count of your project, curse PHPUnit's author or rewrite your project and stop using constants for everything...&lt;/p&gt;

&lt;p&gt;2- Namespace support is weird, especially when using type hinting of classes. My advice: use full-qualified names. Not a big deal, you SHOULD always use full-qualified names anyway. That way, your fellow developer will not have to learn the whole namespace hierarchy to understand your code.&lt;/p&gt;

&lt;p&gt;3- Mocks are cool but they're not meant to fix all your problems. You want to test if an object's method is called: mocks are the solution. You want to make sure that during a future rewrite your fellow developer will not forget to update the client class of another? Use a real instance of the object, not a mock of it. Here's a stupid example:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Conf&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get_conf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//do something&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;set_conf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//do something&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Conf&lt;/span&gt; &lt;span class="nv"&gt;$conf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$conf_entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$conf&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get_conf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;key&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nv"&gt;$conf&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;set_conf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;value2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nv"&gt;$conf_entry_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$conf&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get_conf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$conf_entry_2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                 &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;To make sure the &lt;code&gt;get_conf&lt;/code&gt; method is called by &lt;code&gt;Client&lt;/code&gt;'s constructor, use a mock.&lt;br/&gt;
To make sure the exception is thrown if &lt;code&gt;$conf_entry_2&lt;/code&gt; is empty, use an instance of &lt;code&gt;Conf&lt;/code&gt;. Why?&lt;br/&gt;
Because someday, &lt;code&gt;Conf&lt;/code&gt; may return &lt;code&gt;null&lt;/code&gt; instead of &lt;code&gt;false&lt;/code&gt; after a rewrite. The &lt;code&gt;Conf&lt;/code&gt; unit tests will be changed and the developer will be happy, he's got 100% passed tests. But the &lt;code&gt;Client&lt;/code&gt; class has not been changed because you've mocked &lt;code&gt;Conf&lt;/code&gt; to return false. The tests are passing but the developer didn't rewrite &lt;code&gt;Client&lt;/code&gt; to test &lt;code&gt;$conf_entry_2&lt;/code&gt; against &lt;code&gt;null&lt;/code&gt; instead of &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I've also got an issue using autoloading with namespaces. I'm not sure it's related to PHPUnit but anyway... I liked the solution I found because it will prevent some possible code collision which is the main benefit of namespaces in the first place. The solution? Instead of naming your autoload function &lt;code&gt;__autoload()&lt;/code&gt;, use a specific and very unique name such as &lt;code&gt;myFantasticAutoloadingFunctionThatKicksAss()&lt;/code&gt; and use the &lt;code&gt;spl_autoload_register()&lt;/code&gt; function to register it as an autoload function. After that PHPUnit was able to find my classes by himself.&lt;/p&gt;

&lt;p&gt;Now TDD is starting to be fun.&lt;/p&gt;

&lt;p&gt;PS: I will update this page if I find other quirks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've got 2 new quick tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I use Netbeans to code and it is really simple to have a split screen in Netbeans. Just drag the file tab you want to split to the right and you'll have a split screen. Really handy for TDD to write your test and your code side by side.&lt;/li&gt;
&lt;li&gt;I found out that mocking 2 consecutive calls to the same method is not explained in PHPUnit's documentation. But it's simple: instead of using &lt;code&gt;once()&lt;/code&gt;, &lt;code&gt;any()&lt;/code&gt; or &lt;code&gt;none()&lt;/code&gt; in &lt;code&gt;expects()&lt;/code&gt;, use &lt;code&gt;at(0)&lt;/code&gt; for the first call and &lt;code&gt;at(1)&lt;/code&gt; in the second and so on. You can even make the mock return different values each time. I needed this in my previous example because you usually retrieve configuration more than once.&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/jodet/blog/~4/FEcDtvoCo6o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://blog.jodet.com/mixing-up-tdd-phpunit-namespaces-and-jenkins</feedburner:origLink></entry>
 
 
</feed>

