<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shiki &#187; Web Development</title>
	<atom:link href="http://shikii.net/blog/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://shikii.net/blog</link>
	<description>I&#039;m so bad with words that I can&#039;t even make a cool tagline</description>
	<lastBuildDate>Fri, 13 Jan 2012 00:14:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>FirePHP on Nginx: 502 Bad Gateway</title>
		<link>http://shikii.net/blog/firephp-on-nginx-502-bad-gateway/</link>
		<comments>http://shikii.net/blog/firephp-on-nginx-502-bad-gateway/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 11:41:09 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[firephp]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=589</guid>
		<description><![CDATA[We have switched from Apache to Nginx a month ago. PHP is running on FastCGI using PHP-FPM. I have just recently tried to debug our app using FirePHP and got a 502 Bad Gateway response from Nginx. It looks like Nginx by default limits the header output. This is the error in Nginx&#8217;s error log: [...]]]></description>
			<content:encoded><![CDATA[<p>We have switched from Apache to Nginx a month ago. PHP is running on FastCGI using <a href="http://en.wikipedia.org/wiki/PHP-FPM">PHP-FPM</a>. I have just recently tried to debug our app using FirePHP and got a 502 Bad Gateway response from Nginx. It looks like Nginx by default limits the header output. This is the error in Nginx&#8217;s error log:</p>

<pre><code>2011/09/21 09:36:16 [error] 816#0: *5 upstream sent too big header while reading response header from upstream, 
  client: 192.168.56.1, server: v.piclyf.com, request: "GET /pics HTTP/1.1", 
  upstream: "fastcgi://127.0.0.1:9000", host: "v.piclyf.com", referrer: "http://v.piclyf.com/dashboard"
</code></pre>

<p>The fix that I found is to increase the values of <a href="http://wiki.nginx.org/HttpFcgiModule#fastcgi_buffer_size"><code>fastcgi_buffer_size</code></a> and <a href="http://wiki.nginx.org/HttpFcgiModule#fastcgi_buffers"><code>fastcgi_buffers</code></a>. Add these 2 directives to your PHP FastCGI config in Nginx (i.e. <code>/etc/nginx/sites-available/default</code>):</p>

<pre><code>location ~ \.php$ {
  root /your/site/root;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_pass 127.0.0.1:9000;

  # set these two:
  fastcgi_buffer_size 16k;
  fastcgi_buffers 4 16k;
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/firephp-on-nginx-502-bad-gateway/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Autoloading namespaced libraries in Yii Framework</title>
		<link>http://shikii.net/blog/autoloading-namespaced-libraries-in-yii-framework/</link>
		<comments>http://shikii.net/blog/autoloading-namespaced-libraries-in-yii-framework/#comments</comments>
		<pubDate>Sun, 01 May 2011 14:05:36 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=479</guid>
		<description><![CDATA[To integrate libraries using namespaces into a Yii Framework project, you can simply use Yii::setPathOfAlias to have the classes autoloaded by Yii when needed. Just specify the root namespace as the alias and the physical location of that root alias as the path. Using Predis as an example, if we put the code in: /vendors/predis/lib/Predis [...]]]></description>
			<content:encoded><![CDATA[<p>To integrate libraries using namespaces into a Yii Framework project, you can simply use <a href="http://www.yiiframework.com/doc/api/1.1/YiiBase#setPathOfAlias-detail"><code>Yii::setPathOfAlias</code></a> to have the classes autoloaded by Yii when needed. Just specify the <strong>root</strong> namespace as the alias and the physical location of that root alias as the path.</p>

<p>Using <a href="https://github.com/nrk/predis">Predis</a> as an example, if we put the code in:</p>

<pre><code>/vendors/predis/lib/Predis
</code></pre>

<p>We&#8217;ll add it to Yii as an alias named <code>Predis</code> so classes under it can be autoloaded:</p>

<pre><code>Yii::setPathOfAlias('Predis', '/vendors/predis/lib/Predis');
</code></pre>

<p>Now when we call <code>new Predis\Client()</code>, Yii will look for a file named <code>Client.php</code> in <code>/vendors/predis/lib/Predis</code>. The same holds true for other classes under subfolders (e.g. <code>Predis\Commands\Append</code>).</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/autoloading-namespaced-libraries-in-yii-framework/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Organizing jQuery projects: Objects and Namespaces</title>
		<link>http://shikii.net/blog/organizing-jquery-projects-objects-and-namespaces/</link>
		<comments>http://shikii.net/blog/organizing-jquery-projects-objects-and-namespaces/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 09:30:58 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[organization]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=458</guid>
		<description><![CDATA[This is a pattern we&#8217;ve been using to organize a big jQuery project that is now composed of 150+ files. When we first started with the project, we kept all page components in their respective jQuery plugins. This was good enough at that time. But as the project grew it became harder and harder to [...]]]></description>
			<content:encoded><![CDATA[<p>This is a pattern we&#8217;ve been using to organize a big jQuery project that is now composed of 150+ files. When we first started with the project, we kept all page components in their respective jQuery plugins. This was good enough at that time. But as the project grew it became harder and harder to maintain it.</p>

<p>What we did to solve it was go back to basics: use plain JavaScript objects instead of plugins and group them using namespaces.</p>

<h2>Plain objects vs plugins</h2>

<p>This looks like a step back from making cool plugins but there are actually some benefits. Let&#8217;s look at this horizontal slider plugin as an example:</p>

<pre><code>// start slider plugin
(function($) {

  var internal = {
    init: function($el) {
      $el.data('currentPage', 0);
    },

    showPage: function($el, page) {
      // do some fancy animations to show the given page
      $el.data('currentPage', 2);
    },

    currentPage: function($el) {
      return $el.data('currentPage');
    }
  };

  $.fn.slider = function(options) {
    if (typeof options != 'undefined' &amp;&amp; options == 'currentPage')
      return internal.currentPage($(this[0]));

    return this.each(function() {
      if (typeof options == 'undefined')
        internal.init($(this));
      else if (options == 'showPage')
        internal.showPage($(this), arguments[1]);
    });
  };

})(jQuery);

// and use it like this:
$('#mydiv').slider(); // assume there's a &lt;div id="mydiv"&gt;&lt;/div&gt; in the HTML
$('#mydiv').slider('showPage', 2);
alert($('#mydiv').slider('currentPage')); // 2
</code></pre>

<p>We&#8217;re expecting an output like the <a href="http://www.ndoherty.biz/demos/coda-slider/1.1.1/">Coda Slider</a>. The above code is just a skeleton that shows how we&#8217;d probably make a horizontal slider plugin. If we were to convert this into a JavaScript object, it would look like this:</p>

<pre><code>// the slider plugin as an Object
(function() {

  Slider = {
    currentPage: 0,
    $el: null, // a public reference to the HTML element we'll work with

    // this should be called first before doing anything else       
    init: function($el) {
      this.$el = $el; // save a reference to the element so we can use it later
      return this;
    },

    showPage: function(page) {
      // do some animations using this.$el
      this.currentPage = page;
    }
  };

})(jQuery);

// and use it like this
var slider = Object.create(Slider).init($('#mydiv')); // instantiate a new Slider object and pass in the &lt;div&gt;
slider.showPage(2);
alert(slider.currentPage); // 2
</code></pre>

<p>This pattern takes advantage of <strong>prototypal inheritance</strong> (<code>Object.create</code>) to create a new instance of <code>Slider</code>. The advantages of this are:</p>

<ul>
<li>It&#8217;s much cleaner and easier to understand since you&#8217;re sort of creating a &#8220;class&#8221; and one would just have to create a new instance to use it.</li>
<li>It&#8217;s not tightly coupled with jQuery. If it ever happens that you&#8217;ll have to switch to a different library, it&#8217;ll be easier to do so.</li>
<li>Object members are exposed (e.g. <code>currentPage</code>), can easily be inspected and used.</li>
</ul>

<p>The disadvantages of this are:</p>

<ul>
<li>A single instance can operate on a single element only. You can easily work around this though.</li>
<li>It&#8217;s not a jQuery plugin &#8212; it&#8217;s not cool (debatable)</li>
</ul>

<h4>Prototypal inheritance</h4>

<p>The <code>Object.create()</code> method is not part of JavaScript but is a common pattern used to create a new object whose prototype is the given object. This allows us to inherit the members of Slider into a new (instantiated) object.</p>

<pre><code>if (typeof Object.create !== 'function') {
  Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
  };
}
</code></pre>

<p>There are more discussions about this from <a href="http://javascript.crockford.com/prototypal.html">Douglas Crockford</a> and <a href="http://alexsexton.com/?p=51">Alex Sexton</a></p>

<h2>Namespaces</h2>

<p>Now that we have simple objects instead of plugins, we can easily group these into namespaces &#8212; objects within objects. We can have a base namespace:</p>

<pre><code>App = {};
</code></pre>

<p>And then put our objects under it:</p>

<pre><code>App.Slider = {
  // slider code here
};

// util functions under a base Utils namespace
App.Utils = {
  foo: function() {
    // ...   
  },
  bar: function() {
    // ...
  }
};

// group related objects under a single namespace
App.SidebarComponents = {
  About: {
    // ...
  },
  TagCloud: {
    // ...
  },
  CategoryList: {
    // ...
  }
};

// create a slider
var slider = Object.create(App.Slider).init($('#div'));
// call a util function
App.Utils.foo();
</code></pre>

<p>This now looks at least more organized and maintainable. And you&#8217;d have a nice DOM view (FireBug):</p>

<p><img src="http://shikii.net/blog/wp-content/uploads/2011/03/dom.jpg" alt="" title="dom" width="730" height="164" class="aligncenter size-full wp-image-459" /></p>

<p>What we can learn from this is that jQuery doesn&#8217;t really force you to follow a specific design pattern. It&#8217;s excellent at DOM manipulation, but it doesn&#8217;t provide much outside that. This is actually good, since this means that you can apply your own design <em>on top</em> of it. jQuery should be <strong>part</strong> of your project and not the <strong>backbone</strong> of your project.</p>

<p>Speaking of backbone, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> is a great complement to jQuery that&#8217;s definitely worth checking out.</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/organizing-jquery-projects-objects-and-namespaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing with Ruby: Silly backup tool for Amazon S3</title>
		<link>http://shikii.net/blog/playing-with-ruby-silly-backup-tool-for-amazon-s3/</link>
		<comments>http://shikii.net/blog/playing-with-ruby-silly-backup-tool-for-amazon-s3/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 10:11:26 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=398</guid>
		<description><![CDATA[To celebrate the New Year, I played a little with Ruby. I made this small Ruby script to download all original image files of PicLyf stored in Amazon S3: #!/usr/bin/env ruby require 'rubygems' require 'aws/s3' bucket = 'bucket_name' AWS::S3::Base.establish_connection!( :access_key_id =&#62; 'our_access_key', :secret_access_key =&#62; 'our_secret_key' ) last_key = nil while true do puts "Getting objects [...]]]></description>
			<content:encoded><![CDATA[<p>To celebrate the New Year, I played a little with Ruby. I made this small Ruby script to download all original image files of <a href="http://piclyf.com">PicLyf</a> stored in <a href="https://s3.amazonaws.com/">Amazon S3</a>:</p>

<pre><code>#!/usr/bin/env ruby

require 'rubygems'
require 'aws/s3'

bucket = 'bucket_name'

AWS::S3::Base.establish_connection!(
  :access_key_id     =&gt; 'our_access_key',
  :secret_access_key =&gt; 'our_secret_key'
)

last_key = nil
while true do
  puts "Getting objects " + (last_key == nil ? "" : "after #{last_key}")
  objects = AWS::S3::Bucket.objects bucket, :max_keys =&gt; 10, :marker =&gt; last_key

  objects.each do |object|
    # download file if it is the original and if it doesn't exist locally yet
    if !File.exist?(object.key) &amp;&amp; object.key.match(/^\w+_o.\w+$/)
      puts "Downloading #{object.key} "
      open(object.key, 'w') do |file|
        AWS::S3::S3Object.stream(object.key, bucket) do |chunk|
          file.write chunk
        end
      end
    end
  end

  last_key = objects.last.key if !objects.empty?
end
</code></pre>

<p>The scripts loops through all objects from S3 and downloads only the original image files (ours have the &#8220;*_o.jpg&#8221; pattern). If it reaches the end of the loop, it will wait for new objects.</p>

<p>This is really just a simple silly script but it&#8217;s a good Ruby exercise :)</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/playing-with-ruby-silly-backup-tool-for-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Creating a custom image service for Twitter for iPhone Tweetbot</title>
		<link>http://shikii.net/blog/creating-a-custom-image-service-for-twitter-for-iphone/</link>
		<comments>http://shikii.net/blog/creating-a-custom-image-service-for-twitter-for-iphone/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 00:52:30 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=191</guid>
		<description><![CDATA[Update Jan 13, 2012: It looks like setting a custom image service is no longer available on Twitter for iPhone. Tweetbot allows it though. This article still works for Tweetbot. For the rest of this article, please treat the text &#8220;Twitter for iPhone&#8221; as any app that supports custom image services (e.g. Tweetbot). We&#8217;ve just [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update Jan 13, 2012</strong>: It looks like setting a custom image service is no longer available on Twitter for iPhone. <a href="http://tapbots.com/software/tweetbot/">Tweetbot</a> allows it though. This article still works for Tweetbot. For the rest of this article, please treat the text &#8220;Twitter for iPhone&#8221; as any app that supports custom image services (e.g. Tweetbot).</p>

<div class="wp-caption alignright">
  <img src="http://shikii.net/blog/wp-content/uploads/2010/08/img_0031.png" alt="" title="Custom Image Service" width="320" height="240" class="alignright size-full wp-image-217" />
</div>

<p>We&#8217;ve just recently deployed a custom endpoint to allow <a href="http://itunes.apple.com/app/twitter/id333903271?mt=8">Twitter for iPhone</a> users to post their pics through <a href="http://piclyf.com">PicLyf</a>.</p>

<p>When you attach an image to a tweet, Twitter for iPhone will upload that image to the image service of your choice. It allows you to choose from various image services (e.g. yFrog, Twitpic, TweetPhoto) or a custom image service. In our (PicLyf) case, it was custom. We made a custom endpoint: <code>http://api.piclyf.com/twitter</code>. Using this url as the custom image service, attached images will be uploaded to the user&#8217;s PicLyf account.</p>

<h2>Implementation</h2>

<p>This functionality works through the use of <a href="http://dev.twitter.com/pages/oauth_echo">OAuth Echo</a>. From Twitter:</p>

<blockquote>
  <p>OAuth Echo is a means to securely delegate OAuth authorization with a third party while interacting with an API. Within the Twitter ecosystem, we use OAuth Echo as a means to allow your application to use services such as Twitpic and yfrog.</p>
</blockquote>

<p>You may want to read about OAuth Echo first. Basically, Twitter for iPhone sends you the image along with the OAuth credentials of the user who wants to upload the image. Note that the OAuth credentials also includes the app&#8217;s consumer key. What you&#8217;ll have to do is use these credentials and verify them with the Twitter API. If the verification succeeds, you will receive the user&#8217;s Twitter information. You may then save the image in your server and link it with the user&#8217;s Twitter account. Lastly, you will have to return the correct response to Twitter for iPhone specifying the url where the image can be viewed:</p>

<pre><code>&lt;mediaurl&gt;http://foo.com/bar/pic-url.html&lt;/mediaurl&gt;
</code></pre>

<h3>Sample code in PHP</h3>

<p>Here is a sample class which encapsulates the OAuth Echo process:</p>

<pre><code>class TwitterOAuthEcho
{
  public $verificationUrl = 'https://api.twitter.com/1/account/verify_credentials.json';
  public $userAgent = __CLASS__;

  public $verificationCredentials;

  /**
   *
   * @var int
   */
  public $resultHttpCode;
  /**
   *
   * @var array
   */
  public $resultHttpInfo;
  public $responseText;

  /**
   * Save the OAuth credentials sent by the Consumer (e.g. Twitter for iPhone, Twitterrific)
   */
  public function setCredentialsFromRequestHeaders()
  {    
    $this-&gt;verificationCredentials = isset($_SERVER['HTTP_X_VERIFY_CREDENTIALS_AUTHORIZATION']) 
      ? $_SERVER['HTTP_X_VERIFY_CREDENTIALS_AUTHORIZATION'] : '';
  }

  /**
   * Verify the given OAuth credentials with Twitter
   * @return boolean
   */
  public function verify()
  {
    $curl = curl_init($this-&gt;verificationUrl);
    curl_setopt($curl, CURLOPT_USERAGENT, $this-&gt;userAgent);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Authorization: ' . $this-&gt;verificationCredentials,
      ));

    $this-&gt;responseText = curl_exec($curl);
    $this-&gt;resultHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    $this-&gt;resultHttpInfo = curl_getinfo($curl);
    curl_close($curl);

    return $this-&gt;resultHttpCode == 200;
  }
}
</code></pre>

<p>The <code>setCredentialsFromRequestHeaders</code> method saves the OAuth credentials sent by the consumer (e.g. Twitter for iPhone, Twitterrific). These credentials will be used in the <code>verify</code> method which sends the verification request to Twitter.</p>

<p>Using the class above, your custom image service page <em>(e.g. <code>http://api.piclyf.com/twitter</code>)</em> should handle the request like this:</p>

<pre><code>$oauthecho = new TwitterOAuthEcho();
$oauthecho-&gt;userAgent = 'My Custom Image Service App 1.0';
$oauthecho-&gt;setCredentialsFromRequestHeaders();
if ($oauthecho-&gt;verify()) {      
  // Verification was a success, we should be able to access the user's Twitter info from the responseText.
  $userInfo = json_decode($oauthecho-&gt;responseText, true);
  $twitterId = isset($userInfo['id']) ? $userInfo['id'] : null;      
  // You can use $userInfo or $twitterId above to maybe check if you have a record of this user
  // in your db.

  // You can access the uploaded image using $_FILES. Save it and create a url where it can be accessed.

  // Return the image url back to the consumer
  $imagePageUrl = 'http://somwhere.com/image1';
  echo '&lt;mediaurl&gt;' . $imagePageUrl . '&lt;/mediaurl&gt;';

} else {
  // verification failed, we should return the error back to the consumer
  $response = json_decode($oauthecho-&gt;responseText, true);      
  $message = isset($response['error']) ? $response['error'] : null;      
  if (!headers_sent())
    header('HTTP/1.0 ' . $oauthecho-&gt;resultHttpCode);
  echo $message;
}
</code></pre>

<p>The code above is just a sample and your final code will look very different especially if you&#8217;re using a framework. I&#8217;ve also left
out the part where you&#8217;ll get the image from $_FILES and save/process it. That is beyond the scope of this article.</p>

<h2>Notes</h2>

<p>The note in Twitter for iPhone&#8217;s custom image service screen says you can get more (developer) info in this url: http://developer.atebits.com. As of this writing, the information on that page is no longer accurate. Twitter for iPhone no longer sends you the user&#8217;s username and password. The info at <a href="http://twitterrific.com/ipad/poweruser">Twitterrific</a> is more accurate. And yes, if your service works for Twitter for iPhone, it should work on Twitterrific too.</p>

<h3>Further reading:</h3>

<ul>
<li><a href="http://www.bennadel.com/blog/1965-Creating-A-Custom-Image-Upload-Service-For-Tweetie-Twitter-For-iPhone-Using-ColdFusion.htm">Creating A Custom Image Upload Service For Tweetie (Twitter For iPhone) Using ColdFusion</a></li>
<li><a href="http://dev.twitter.com/pages/oauth_echo">Using OAuth Echo</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/creating-a-custom-image-service-for-twitter-for-iphone/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Why I don&#8217;t code in Ruby</title>
		<link>http://shikii.net/blog/why-i-dont-code-in-ruby/</link>
		<comments>http://shikii.net/blog/why-i-dont-code-in-ruby/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 15:35:57 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/why-i-dont-code-in-ruby/</guid>
		<description><![CDATA[Well, not yet anyway. Perhaps when those hosting prices go down I&#8217;d go and take a shot at building something useful. I did start reading a few books on Ruby and Rails. It&#8217;s an incredibly awesome and fun language. I&#8217;ve never been very excited when learning a new language. I drool when I see Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>Well, not yet anyway. Perhaps when those hosting prices go down I&#8217;d go and take a shot at building something useful. I did start reading a few books on Ruby and Rails. It&#8217;s an incredibly awesome and fun language. I&#8217;ve never been very excited when learning a new language. I drool when I see Ruby code. It&#8217;s easy to learn but I&#8217;ve already forgotten most about it since I don&#8217;t use it fulltime.</p>

<p>If it were just me, I&#8217;d have built <a href="http://piclyf.com">PicLyf</a> using Ruby to make it more exciting. But there&#8217;s the city talent pool we had to think of. Currently, it&#8217;s hard to find good PHP developers. I reckon it&#8217;ll be more hard to find those who know Ruby.</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/why-i-dont-code-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Studio (Eclipse) Remote Editing through a secure proxy</title>
		<link>http://shikii.net/blog/zend-studio-eclipse-remote-editing-through-a-secure-proxy/</link>
		<comments>http://shikii.net/blog/zend-studio-eclipse-remote-editing-through-a-secure-proxy/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 15:47:05 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[putty]]></category>
		<category><![CDATA[remote-editing]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tunnel]]></category>
		<category><![CDATA[zend-studio]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=11</guid>
		<description><![CDATA[Remote Editing in Zend Studio for Eclipse has to be one of the biggest reasons why I use it in my current job. I work from home and our team&#8217;s development environment is securely setup on a Linux server with a firewall open only to specific IP addresses. This is a no biggie if my [...]]]></description>
			<content:encoded><![CDATA[<p>Remote Editing in Zend Studio for Eclipse has to be one of the biggest reasons why I use it in my current job. I work from home and our team&#8217;s development environment is securely setup on a Linux server with a firewall open only to specific IP addresses. This is a no biggie if my IP address never changes or if I work only in one place. Unfortunately, that&#8217;s not the case for my DSL setup &#8212; I get a different IP address everyday. And since I can&#8217;t bug the server admin every time I need to have my IP address added to the firewall, I connect through our proxy server first and then connect to the main development server. The setup&#8217;s kinda like this:</p>

<p style="text-align: center;"><img class="size-full wp-image-16 aligncenter" title="Local Machine to Proxy Server to Development Server setup" src="http://shikii.net/blog/wp-content/uploads/2009/08/zendstudioproxy.jpg" alt="Local Machine to Proxy Server to Development Server setup" width="640" /></p>

<p>The problem now is Zend Studio doesn&#8217;t seem to support this kind of setup. At least, that&#8217;s what I concluded after so many hours of googling. Then I found this super awesome <a href="http://paulstamatiou.com/how-to-surf-securely-with-ssh-tunnel">article</a>. We can use Putty! Or just plain ol&#8217; Terminal on a Mac (Linux should be the same I think).<span id="more-11"></span></p>

<h2>Tools needed</h2>

<p>Of course you need Zend Studio for Eclipse. You just need <a href="http://www.putty.org/">Putty</a> if you&#8217;re on Windows. You&#8217;ll just need the already available/installed Terminal on a Mac (it&#8217;s in <em>Applications &gt; Utilities</em>).</p>

<h2>Proxy setup</h2>

<p>Open up Putty/Terminal. Enter this into the console:</p>

<p><code>ssh -D 8080 username@proxydomain.com</code></p>

<p>The &#8220;8080&#8243; should be an unused port on your machine. In most cases, port 8080 is fine. The &#8220;username&#8221; should be the user name you need to login to the proxy server (ie proxydomain.com). You should be prompted with the password after entering this command. This will create a tunnel on the port 8080 where all HTTP traffic will go through the proxy server. That is, if an application uses the port 8080 as a proxy. This won&#8217;t have any effect on your current applications (i.e. browsers) unless you modify your settings to use this proxy. Please note that you&#8217;ll have to keep the terminal window open so your proxy session won&#8217;t be destroyed. There are probably other ways to make it work without the window left open but I&#8217;m content with this.</p>

<h2>Modifying Zend Studio settings</h2>

<p>Since we now have a proxy available, we need to instruct Zend Studio to use it.</p>

<ol>
    <li>Open Zend Studio.</li>
    <li>Go to Preferences (located under the <em>Application</em> menu on Mac and under <em>Window</em> on Windows)</li>
    <li>Navigate to <em>General &gt; Network Connections</em></li>
    <li>Set the proxy setting to <em>Manual proxy configuration</em>. And enter <strong>127.0.0.1</strong> in the SOCKS proxy field and <strong>8080</strong> on the Port field beside that.</li>
</ol>

<p>Your setup should look something like this:</p>

<div id="attachment_19" class="wp-caption aligncenter" style="width: 650px"><img class="size-full wp-image-19" title="Zend Studio Network Settings" src="http://shikii.net/blog/wp-content/uploads/2009/08/Preferences-1.jpg" alt="Zend Studio Network Settings" width="610" /><p class="wp-caption-text">Zend Studio Network Settings</p></div>

<p>Save the settings and you should be ready to open up a connection to the target server (in this case, the main development server). Create a remote connection to your target server like you normally would. I couldn&#8217;t discuss that here but <a href="http://files.zend.com/help/Zend-Studio-Eclipse/remote_systems_view.htm">this</a> might help.</p>

<h3>Other References</h3>

<ul>
    <li><a href="http://paulstamatiou.com/how-to-surf-securely-with-ssh-tunnel">How To: Surf Securely with an SSH Tunnel</a></li>
    <li><a href="http://www.linuxjournal.com/content/use-ssh-create-http-proxy">Use SSH to Create an HTTP Proxy</a></li>
    <li><a href="http://blogs.techrepublic.com.com/security/?p=421">Use PuTTY as a secure proxy on Windows</a></li>
    <li><a href="http://files.zend.com/help/Zend-Studio-Eclipse/remote_systems_view.htm">Zend Studio Remote Systems View</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/zend-studio-eclipse-remote-editing-through-a-secure-proxy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Serving PNGs in your website</title>
		<link>http://shikii.net/blog/serving-pngs-in-your-website/</link>
		<comments>http://shikii.net/blog/serving-pngs-in-your-website/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 03:32:34 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[png]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=317</guid>
		<description><![CDATA[Just found this script from 24 ways which allows your images in PNG format to be transparent in IE6. Very helpful indeed. It&#8217;s easy to setup, just copy the code in your source directory and paste the call to the script in your html head.]]></description>
			<content:encoded><![CDATA[<p>Just found this <a href="http://24ways.org/2007/supersleight-transparent-png-in-ie6">script</a> from 24 ways which allows your images in PNG format to be transparent in IE6. Very helpful indeed. It&#8217;s easy to setup, just copy the code in your source directory and paste the call to the script in your html head.</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/serving-pngs-in-your-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

