XCode 4 Twilight Theme
I was looking for a decent XCode 4 Twilight theme today. I found a few options but nothing that made Objective-C look like Ruby does in Textmate. So I decided to try and create my own.
What does it look like?
Below is a sample of what Objective-C code looks like in XCode 4. As you can see I like a big font for readability but you can always adjust that to your liking.
Installation
Install the font
I’m using the Inconsolata font. You don’t have to use it but I think its pretty cool.
Install the theme
Download the theme from GitHub to ~/Library/Developer/Xcode/UserData/FontAndColorThemes.
Restart XCode if its already open. After that just select the theme in the XCode preferences under Fonts & Colors.
That should do it. Enjoy.
Code highlighting with CodeRay in Jekyll
The built-in code highlighter in Jekyll uses Pygments to highlight code. The problem is that Pygments is really slow. Instead I opted to use CodeRay since its quite a bit faster. Here is a plugin for highlighting code in Jekyll via CodeRay.
Installation
Install the CodeRay gem
$ gem install coderay
Install the plugin
Copy the following code to _plugins/code.rb:
module Jekyll
require 'coderay'
class CodeBlock < Liquid::Block
def initialize(tag_name, lang, tokens)
@lang = lang.strip.downcase.to_sym
super
end
def render(context)
"#{CodeRay.scan(super.join.strip, @lang).div(:css => :class)}"
end
end
end
Liquid::Template.register_tag('code', Jekyll::CodeBlock)
Usage
Wrap your code blocks
Once you have the plugin installed, you can wrap any code in a block like so:
{% code ruby %}
# Your code goes here...
{% endcode %}
You can pass in any of the following languages supported by CodeRay:
- C, C++
- CSS
- Delphi
- diff
- ERB+HTML
- Groovy (beta)
- HTML
- Java
- JavaScript
- JSON
- Nitro-XHTML
- PHP
- Python
- Ruby
- Scheme (beta)
- SQL
- XML
- YAML
CSS styling for highlighted code
I haven’t found many pre-made stylesheets for CodeRay but here is a RailsCasts version and a GitHub version to get you started.
Automatically create and paginate categories in Jekyll
I recently ported this blog over to Jekyll. One thing that you don’t get out of the box is the ability to automatically generate index pages for categories.
After some searching I found some solutions that would either generate or paginate category index pages but not both. Using generator code I found on the Jekyll GitHub page and some code provided on Keith Marran’s website, I was able to cobble together something that did what I needed.
Installation
Create a layout
First create a layout in the _layouts directory named “category.html”. This layout just basically defines how you want your category index pages to look. Here is a sample of my category index layout.
Make sure you have a category defined
The next step is to make sure you have defined a category in the YAML Front Matter for each post like so:
---
category: CATEGORY-NAME-HERE
---
Download the plugin
Grab the plugin from GitHub and place it in the plugins directory of your Jekyll site.
Take it for a spin
After installing the plugin, build your Jekyll site. Category index pages should now exist for each the categories on your blog. You should also be able to paginate the posts like I did in my category layout.
Ruby on Rails vs CakePHP Performance Test
I’ve been using CakePHP for a few years as my primary development framework. I recently started using Ruby on Rails and I was wondering which language/framework was actually faster.
Since Ruby (and inherently Rails) has gotten such a bad reputation over the years of being slow, I decided to test out both frameworks on my own server so I can see for myself what the difference actually is in regard to performance.
Keeping the Test Simple
For my testing I decided to keep it very simple. Both frameworks would load States from a database, order them by name and print out an unordered list (UL) to html. The test didn’t need to be complicated. I was just looking to see how long it took for a request to hit the server, go through the framework stack and return results.
Server Details
- 256MB RAM
- Ubuntu 10.10
- Apache 2 (MPM prefork)
- MySQL 5.1.49
Ruby specific
- Ruby 1.9.2 via RVM
- Passenger 3.0.7
PHP specific
- PHP 5.3.3
- APC (for PHP opcode caching)
Apache MPM prefork settings
StartServers 2
MinSpareServers 1
MaxSpareServers 5
MaxClients 10
MaxRequestsPerChild 100
Passenger settings
PassengerMaxPoolSize 2
PassengerPoolIdleTime 144
PassengerMaxInstancesPerApp 1
RailsAutoDetect off
Ruby on Rails Setup
- Rails 3.0.6
- Running in “production” mode
Virtual Host
<VirtualHost *:80>
ServerName daniel-salazar.com
ServerAlias rails.daniel-salazar.com
DocumentRoot /var/www/sites/daniel-salazar/speed_rails/public
RailsBaseURI /
RackEnv production
<Directory /var/www/sites/daniel-salazar/speed_rails>
Options FollowSymLinks
AllowOverride none
</Directory>
</VirtualHost>
Layout (app/views/layouts/application.html.erb)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Rails Speed Test</title>
</head>
<body>
<%= yield %>
</body>
</html>
Model (app/models/state.rb)
class State < ActiveRecord::Base
end
View (app/views/states/index.html.erb)
<ul>
<% @states.each do | state | %>
<li><%= state.name %></li>
<% end %>
</ul>
Controller (app/controllers/states_controller.rb)
class StatesController < ApplicationController
def index
@states = State.order('name ASC')
end
end
CakePHP Setup
- CakePHP 1.3.8
- DEBUG = 0 (production mode)
- .htaccess disabled, rewrite rules done in the virtual host configuration
Virtual Host
<VirtualHost *:80>
ServerName daniel-salazar.com
ServerAlias cake.daniel-salazar.com
DirectoryIndex index.php
DocumentRoot /var/www/sites/daniel-salazar/speed_cake/app/webroot
<Directory /var/www/sites/daniel-salazar/speed_cake/app/webroot>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Options -Indexes FollowSymLinks -MultiViews
AllowOverride none
</Directory>
</VirtualHost>
Layout (app/views/layouts/default.ctp)
<!DOCTYPE html>
<html lang="en">
<head>
<title>CakePHP Speed Test</title>
</head>
<body>
<?= $content_for_layout; ?>
</body>
</html>
Model (app/models/state.php)
class State extends AppModel {
}
View (app/views/states/index.ctp)
<ul>
<? foreach($states as $state): ?>
<li><?= $state['State']['name']; ?></li>
<? endforeach; ?>
</ul>
Controller (app/controllers/states_controller.php)
class StatesController extends AppController {
function index() {
$this->set('states', $this->State->find('all', array('order' => 'State.name ASC')));
}
}
Benchmarking the Frameworks
I used Apache Bench on my Mac to test the performance of both the Rails install and the CakePHP install. The command I ran was:
$ ab -n 1000 -c 5 URL_ADDRESS
That command sent 1000 requests (5 concurrent) to each framework install.
I ran the benchmarking 3 times per framework. Alternating frameworks between each test.
The Results
Surprisingly Ruby on Rails beat out CakePHP in most categories. That’s definitely not what I was expecting to see.
Averages
| Ruby on Rails | CakePHP | |
| Document Path: | /states | /states |
| Document Length: | 1233 bytes | 1288 bytes |
| Total transferred: | 1610000 bytes | 1601000 bytes |
| Time per request: | 31.405 ms | 33.866 ms |
| Requests per second: | 32.03 | 29.54 |
Conclusion
There’s been so much debate on “Ruby vs PHP” and “Rails vs CakePHP” out there. Its good to know that these days it doesn’t really matter which one you go with since they’re so close in regard to performance. Its all a matter of which language/framework you prefer and what server limitations you might have. Either way both are excellent frameworks to have in your toolbox as a developer.
CakePHP 1.3 custom find types
I’ve been messing around this weekend with creating custom CakePHP find types in 1.3. Honestly I’m really not sure if this is the “best practice” approach for how it should be done. It all seems to be working well though. If you have a better way of doing this, please drop a comment below.
Getting started
You need to have a property in your model that tells CakePHP what methods you have defined as custom find types. In this case, I want to create a custom find type that will only find “published” articles:
class Article extends AppModel {
var $_findMethods = array(
'published' => true
);
}
Create your custom find method
Next I’m going to define a “base” method for retrieving published articles.
class Article extends AppModel {
var $_findMethods = array(
'published' => true
);
function _findPublished($state, $query, $results = array()) {
if($state == 'before') {
$baseQuery = array(
'conditions' =>array('Article.is_published' => 1),
'order' => 'Article.created DESC',
'fields' => array(
'Article.id',
'Article.category_id',
'Article.views',
'Article.title',
'Article.excerpt',
'Article.thumbnail',
'Article.created',
'Article.modified'
)
);
$query = Set::merge($query, $baseQuery);
return $query;
}
return $results;
}
}
Notice the call to if($state == ‘before’). Here you can modify and return the query before Cake actually performs the query. If the query has already been performed, it just returns the results.
Also note the piece of code that reads $query = Set::merge($query, $baseQuery). This will let me pass in additional conditions from the controller and merge the base query with any additional parameters I might pass in.
Using the new find type
Now when I want to find my published articles I can just call $this->Article->find(‘published’).
Paginate the custom find type from the controller
I had to create this beforeFind() method in my AppModel to get this all working correctly for pagination:
class AppModel extends Model {
var $actsAs = array('Containable');
var $recursive = -1;
function beforeFind($query = array()) {
$defaultFindTypes = array('all', 'first', 'count', 'neighbors', 'list', 'threaded');
if($this->findQueryType == 'count' && !empty($query['type']) && !in_array($query['type'], $defaultFindTypes)) {
$findTypeMethod = '_find' . ucfirst($query['type']);
$findTypeQuery = $this->{$findTypeMethod}('before', $query, null);
$query['conditions'] = $findTypeQuery['conditions'];
}
return $query;
}
}
In my controller this is how I’m now paginating on my custom find type (Notice I’m adding in a few more options to the “published” base query we defined in the model)
class ArchivesController extends AppController {
var $uses = array('Article');
function index() {
$this->paginate['Article'] = array(
'published',
'limit' => 5,
'contain' => array(
'Category.id',
'Category.name',
'Category.slug',
'Category.thumbnail',
'Comment.id',
'Comment.approved = 1'
)
);
$articles = $this->paginate('Article');
$this->set('articles', $articles);
}
}
I’ve highlighted the line above in green that tells CakePHP which find type to use.
My complete Article model
class Article extends AppModel {
var $name = 'Article';
var $belongsTo = array(
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'article_id',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => 'Comment.created ASC',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
var $_findMethods = array(
'published' => true,
'mostViewed' => true
);
function _findPublished($state, $query, $results = array()) {
if($state == 'before') {
$baseQuery = array(
'conditions' =>array('Article.is_published' => 1),
'order' => 'Article.created DESC',
'fields' => array(
'Article.id',
'Article.category_id',
'Article.views',
'Article.title',
'Article.excerpt',
'Article.thumbnail',
'Article.created',
'Article.modified'
)
);
$query = Set::merge($query, $baseQuery);
return $query;
}
return $results;
}
function _findMostViewed($state, $query, $results = array()) {
if($state == 'before') {
$baseQuery = array(
'conditions' =>array('Article.is_published' => 1),
'order' => 'Article.views DESC',
'fields' => array(
'Article.id',
'Article.category_id',
'Article.title',
'Article.excerpt',
'Article.thumbnail',
'Article.created',
'Article.modified'
),
'limit' => 5
);
$query = Set::merge($query, $baseQuery);
return $query;
}
return $results;
}
}
Wrapping up
Hope you found this helpful. If you have a better solution, please let me know in the comments.