↓ Archives ↓

RailsFTW v0.10 released, now with Ruby 1.9.3 and Rails 3.2

Rails FTW

Still hung-over from Global Game Jam 2012 (mini-write-up later) when I went to the RailsInstaller site on a whim.

Noticed that it still isn’t using Rails 3.2. So I decided to update my own to be ahead again.

Hopefully this would be the last RailsFTW version (hoping Luis would be able to convince Wayne to include MySQL to RailsInstaller so I won’t need to this anymore LOL).

This post by Bryan Bibat is from existence, refactored.

January 2012 Meetup Videos

October Meetup Videos

Coding Screencasts

I’ve been doing some programming screencasts lately over my Youtube channel. They’re not really “screencasts” ala RailsCasts but more like informal streamed videos that you’d see in Justin.tv/Twitch.tv.

These screencasts were recorded in 720p so it’s a good idea to select a higher resolution then view the videos in full screen or the large player in order for you to read the code properly.

Here I code a hexagonal “game of life”-like cellular automata. Used Ruby, Gosu, and RSpec.

Walking through coding a simple Rails app. Bunch of technologies discussed like Twitter Bootstrap, Heroku, and git.

Going through Project Euler problems via brute force using Java.

This post by Bryan Bibat is from existence, refactored.

Learn how to setup a web server pt3: Installing MySQL and PHP apps (e.g. WordPress)

WordPress Installed

Here’s a quick update to this mini-tutorial. Previous parts can be found here and here.

Installing MySQL

Installing MySQL is so simple that I don’t need to hide it behind the cut. The one in the Ubuntu repositories work just fine:

$ sudo apt-get install mysql-server-5.1

Note that you will be asked to enter a root password somewhere in the installation.

To wrap up the installation run

$ sudo mysql_install_db

to initialize the installed server and

$ sudo mysql_secure_installation

to secure it.

In mysql_secure_installation, you’ll be asked for your root password and then you’ll asked if you want to change it. Just enter “n” since there’s no reason to change it this early. Then you’ll be asked if you want to do some things to secure the database which is, of course, what we want to do so just hit Enter for each question to choose the default answer (“Y”).


Installing WordPress

Now we go to making our Ubuntu + nginx + PHP + MySQL setup more useful by installing a web app. I choose WordPress for this tutorial because it’s both popular and easy to install.

Note that most PHP web apps out there have similar installation steps i.e. install prerequisites, setup database, download and extract files, and configure the app.

Installing prerequisites

We only need to install a few extra components for WordPress to work on our box:

$ sudo apt-get install php5-mysql php5-gd

php5-mysql is obviously required to allow PHP to connect to MySQL. php5-gd may be needed if you’re uploading images inside WordPress instead of using an external hosting.

At this point we are ready to follow the Installing WordPress guide.

Creating the database

I’ve switched around steps 1 and 2 because I prefer to do file-related tasks together instead of jumping from files to database to files again.

In setting up the database, we go with the client guide. Creating a new user isn’t part of that guide, though, so we’ll have to do that too.

Connect to the database using the root user:

$ mysql -u root -p

You will be prompted for the password before you can proceed. Once in, you can now proceed with doing what you need to do. The following lines will create a database named wp and a user named wp_user whose password is password_here.

mysql> CREATE DATABASE wp;

mysql> CREATE USER wp_user;

mysql> SET PASSWORD FOR wp_user = PASSWORD("password_here");

mysql> GRANT ALL PRIVILEGES ON wp.* TO "wp_user"@"localhost" IDENTIFIED BY "password_here";

mysql> FLUSH PRIVILEGES;

mysql> EXIT

Downloading WordPress and moving it around

Now it’s time to proceed with steps 1 and 3. Use wget to download and extract the latest version of WordPress:

$ wget http://wordpress.org/latest.tar.gz

$ tar -zxvf latest.tar.gz

We’ll then move the extracted folder wordpress/ to /var/www/ to centralize our web-app stuff.

$ sudo mv wordpress /var/www/

We also need to change the ownership for the folder:

$ sudo chown -R www-data:www-data /var/www/wordpress

Configuring it to work

First we need to add our database settings to wp-config.php:

$ cd /var/www/wordpress

/var/www/wordpress$ sudo mv wp-config-sample.php wp-config.php

/var/www/wordpress$ sudo vim wp-config.php

Change the settings as follows:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wp');

/** MySQL database username */
define('DB_USER', 'wp_user');

/** MySQL database password */
define('DB_PASSWORD', 'password_here');

Now to edit our nginx settings.

$ sudo vim /etc/nginx/nginx.conf

We’ll be using a combination of suggested settings from both nginx and WordPress documents:

...
    server {
        listen       80;
        server_name *.mysite.dev;
        root /var/www/wordpress;

        if ($http_host != "mysite.dev") {
                rewrite ^ http://mysite.dev$request_uri permanent;
        }

        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
        }

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location / {
                # This is cool because no php is touched for static content
                try_files $uri $uri/ /index.php;
        }

        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass php;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
    }
}

The main changes here are the update to the root (pointing it now to /var/www/wordpress) and the try_files approach of URL rewriting (which allows nginx to act like mod_rewrite without the use of .htaccess).

Wrapping up

Restart both PHP-FPM and nginx to apply the changes we made to both.

$ sudo /etc/init.d/php5-fpm restart

$ sudo /etc/init.d/nginx restart

Then go to http://mysite.dev to proceed with the “famous 5-minute install”.

WordPress Installer

WordPress Installed

You have now successfully installed WordPress.

This post by Bryan Bibat is from existence, refactored.

Learn how to setup a web server pt2: Installing Nginx and PHP

phpinfo()

Here’s the next part of my basic web server administration tutorial.

At the first part, we set up the virtual machine. Now we’ll be setting up the web server itself.

Set Static IP Address and fake Domain Name

Before we could proceed with installing our web server, let’s do a couple of things to make our server behave more like a “normal” server.

First is to set our server’s IP address to a static IP address. There are a bunch of ways to do this (e.g. change the router settings), but we’ll just go with changing our server’s settings

Running ifconfig and route will give us the current IP address and gateway.

ifconfig and route

In this case, the new IP address is 192.168.1.125 and the gateway is 192.168.1.5. We can now apply these settings to /etc/network/interfaces. Open the said file via:

$ sudo vim /etc/network/interfaces

(For this tutorial, I’ll be using vim as the default text editor. If you find vim too daunting, you can replace all instances of vim with nano)

It will look something like:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

Now replace the last line with the following:

iface eth0 inet static
address [address here]
netmask 255.255.255.0
gateway [gateway here]

for example:

iface eth0 inet static
address 192.168.1.125
netmask 255.255.255.0
gateway 192.168.1.5

To make sure you got the static IP settings correctly, you can restart the server via

$ sudo shutdown -r now

or you could just simply restart the network interface:

$ sudo /etc/init.d/networking restart

Here we see the /etc/init.d folder where the init scripts (like networking) are placed. Aside from being executed automatically upon boot to start services, they can also be used to stop or restart the said services just like what we just did with networking. We will see more of /etc/init.d/ later in this tutorial.

Now that we’ve set the IP address as static, it’s time to set a fake domain name.

Normally, when you’ve got a server with a static IP address, you’d have to go and buy a domain name from a registrar like Namecheap and you’d go through the steps in linking that name with the IP address and waiting for the DNS propagation.

For this tutorial, we’re going to skip all that by faking it with the hosts file.

First let’s update the server’s /etc/hosts file to add our fake domain name “mysite.dev”:

sudo vim /etc/hosts

Add the line at the end:

192.168.1.125   mysite.dev

You can verify the new setting by using the ping command.

user@ubuntu:~$ ping -c 4 mysite.dev
PING mysite.dev (192.168.1.125) 56(84) bytes of data.
64 bytes from mysite.dev (192.168.1.125): icmp_seq=1 ttl=64 time=0.172 ms
64 bytes from mysite.dev (192.168.1.125): icmp_seq=2 ttl=64 time=2.38 ms
64 bytes from mysite.dev (192.168.1.125): icmp_seq=3 ttl=64 time=3.34 ms
64 bytes from mysite.dev (192.168.1.125): icmp_seq=4 ttl=64 time=1.59 ms

--- mysite.dev ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3016ms
rtt min/avg/max/mdev = 0.172/1.874/3.342/1.161 ms
user@ubuntu:~$

Now let’s apply the fake domain name mapping to the host Windows computer. Like in Linux, the hosts file in Windows requires admin privileges so we first need to run the text editor as Administrator in order to allow us to modify it.

Run as administrator

Right-click Notepad and select “Run as administrator”. Once open, you can now add the “192.168.1.125 mysite.dev” to the end of the C:\Windows\System32\drivers\etc\hosts file.

Now you could change the PuTTy settings to use “mysite.dev” instead of the actual IP address.

The actual installation of the web server below the cut.


Installing Nginx

It’s finally time to install the web server.

We won’t be using Apache, though. Instead, we’re going to go with its leaner and faster Russian counterpart nginx. We’re also going to build it from scratch (as opposed to getting it from a repository) to show you how its done in Linux machines.

Installing dependencies

We’ll need to install a few things before we could proceed with building nginx.

$ sudo apt-get install build-essential libssl-dev libpcre3-dev

build-essential contains the essential tools for compiling programs from source while the other two are libraries that nginx needs during compilation.

Building from source

~$ wget http://nginx.org/download/nginx-1.0.11.tar.gz

Using wget we download the latest stable source as of this writing. Yes, it’s a whopping 700 KB.

~$ tar zxvf nginx-1.0.11.tar.gz

We then unpack it using tar.

~$ cd nginx-1.0.11

~/nginx-1.0.11$ ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module

~/nginx-1.0.11$ make

~/nginx-1.0.11$ sudo make install

Now we finally perform the build/installation. This three-step configure-build-install scheme is pretty much how one builds any program in Linux from scratch.

This nginx build doesn’t come with an init script so we’ll have to download one off the net.

~/nginx-1.0.11$ cd ~

~$ wget https://raw.github.com/JasonGiedymin/nginx-init-ubuntu/master/nginx

~$ sudo mv nginx /etc/init.d/nginx

We still need to set a couple of things with the script:

$ sudo chmod +x /etc/init.d/nginx

$ sudo chown root:root /etc/init.d/nginx

The first command sets the script to executable and the other command gives the ownership of the script to root. Now we can run nginx:

$ sudo /etc/init.d/nginx start

You can now open http://mysite.dev to check if it’s installed properly.

nginx

Using Firebug or Chrome Developer tools will confirm the server’s really nginx 1.0.11.

nginx response headers

Tweaking nginx

Before we proceed with installing PHP, let’s apply some tweaks to nginx to make it more Apache-ish (lol) and then some.

$ sudo ln -s /usr/local/nginx/conf /etc/nginx

This creates a symbolic link in the /etc folder to match with the convention for configuration files.

$ sudo vim /etc/nginx/nginx.conf

Now we edit the configuration file like so:

user  www-data;
worker_processes  1;

pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    gzip on;
    gzip_buffers 16 8k;
    gzip_disable "MSIE [1-6]\.";
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    error_log  /var/log/nginx/error.log  debug;

    sendfile        on;
    keepalive_timeout  3;
    index              index.html index.htm;

    server {
        listen       80;
        server_name *.mysite.dev;
        root /var/www;

        if ($http_host != "mysite.dev") {
                rewrite ^ http://mysite.dev$request_uri permanent;
        }

        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
        }

    }

}

A quick summary of the changes:

  • We changed the server’s user from “nobody” to the system user “www-data”, the default user for web servers.
  • We set the file where the PID for the server would be located. This will allow our init script to stop or restart the server.
  • We enabled gzip for supported browsers to dramatically reduce the bandwidth usage.
  • We set the log to match Apache’s format.
  • We defined a handler for the *.mysite.dev domain, defining its root to be the same as Apache’s (/var/www)

Now to wrap things up:

$ sudo cp -r /usr/local/nginx/html /var/www

$ sudo chown -R www-data:www-data /var/www

We copy the html folder to /var/www and give it to www-data.

$ sudo mkdir /var/log/nginx

Just creating the log folder.

$ sudo /etc/init.d/nginx destroy

$ sudo /etc/init.d/nginx start

We force stop the server (as we haven’t defined the PID file when we started it) then start it normally.

Opening http://mysite.dev now shows us that the site is served as gzipped.

nginx response headers

Installing PHP-FPM

Unlike nginx, we won’t be building PHP from scratch. We will, however, not go with Apache’s mod_php/extension route and instead go the PHP-FPM route which, like nginx, is much leaner than the former.

Since PHP-FPM isn’t available in the official apt repositories of Ubuntu 10.04, we will have to use another repository. Nginx’s repositories may be a bit out of date (PHP v5.3.5 vs the current v5.3.8) but it should be enough for this tutorial.

$ sudo apt-get install python-software-properties

$ sudo add-apt-repository ppa:nginx/php5

$ sudo apt-get update

$ sudo apt-get install php5-fpm

The steps above will install PHP-FPM with fairly decent defaults. If you want to change some settings, you can modify the files at /etc/php5/fpm/ and restart the server via “sudo /etc/init.d/php-fpm restart“.

Now all we need to do is to tell nginx how to use PHP-FPM. Here’s our modified /etc/nginx/nginx.conf:

user  www-data;
worker_processes  1;

pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    gzip on;
    gzip_buffers 16 8k;
    gzip_disable "MSIE [1-6]\.";
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    error_log  /var/log/nginx/error.log  debug;

    sendfile        on;
    keepalive_timeout  3;
    index              index.php index.html index.htm;

    upstream php {
        server 127.0.0.1:9000;
    }

    server {
        listen       80;
        server_name *.mysite.dev;
        root /var/www;

        if ($http_host != "mysite.dev") {
                rewrite ^ http://mysite.dev$request_uri permanent;
        }

        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
        }

        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass php;
        }
    }
}

The main changes between the original are:

  • Adding “index.php” before “index.html index.htm” to let the server prioritize the former over the latter.
  • The addition of the upstream php block that points to PHP-FPM.
  • The addition of the location handler for PHP files.

We also need to modify /etc/nginx/fastcgi_params, adding the following lines at the end of the file:

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

Once done we can now restart the server via sudo /etc/init.d/nginx restart.

To test PHP, create the phpinfo() index.php file:

$ sudo sh -c 'echo "<? phpinfo();" > /var/www/index.php'

Then open http://mysite.dev again:

phpinfo()

You have now installed nginx and PHP on your web server.

Benchmarking

You can use ApacheBench to see how well your site performs under load.

$ sudo apt-get install apache2-utils

Here’s 1000 requests with 100 concurrent users (10 requests each user) to our static HTML file:

user@ubuntu:~$ ab -n 1000 -c 100 http://mysite.dev/index.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking mysite.dev (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        nginx/1.0.11
Server Hostname:        mysite.dev
Server Port:            80

Document Path:          /index.html
Document Length:        151 bytes

Concurrency Level:      100
Time taken for tests:   1.720 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      378290 bytes
HTML transferred:       157795 bytes
Requests per second:    581.31 [#/sec] (mean)
Time per request:       172.025 [ms] (mean)
Time per request:       1.720 [ms] (mean, across all concurrent requests)
Transfer rate:          214.75 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       27   79  15.7     84     102
Processing:    39   83  16.5     86     131
Waiting:       10   61  17.5     65      98
Total:        129  161  16.5    172     184

Percentage of the requests served within a certain time (ms)
  50%    172
  66%    173
  75%    173
  80%    173
  90%    178
  95%    182
  98%    183
  99%    183
 100%    184 (longest request)

Here’s the same test against our phpinfo() page:

user@ubuntu:~$ ab -n 1000 -c 100 http://mysite.dev/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking mysite.dev (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        nginx/1.0.11
Server Hostname:        mysite.dev
Server Port:            80

Document Path:          /
Document Length:        42481 bytes

Concurrency Level:      100
Time taken for tests:   8.582 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      42649000 bytes
HTML transferred:       42481000 bytes
Requests per second:    116.52 [#/sec] (mean)
Time per request:       858.186 [ms] (mean)
Time per request:       8.582 [ms] (mean, across all concurrent requests)
Transfer rate:          4853.19 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    6  16.6      0      63
Processing:    66  810 126.3    861     875
Waiting:       59  808 127.0    858     873
Total:        125  816 113.2    861     875

Percentage of the requests served within a certain time (ms)
  50%    861
  66%    862
  75%    863
  80%    864
  90%    869
  95%    874
  98%    874
  99%    875
 100%    875 (longest request)

581 and 116 requests per second? Not bad for a “low end” server.

Proceed to part 3: Installing MySQL and WordPress

This post by Bryan Bibat is from existence, refactored.

RailsFTW v0.9 released, now with Rails 3.1

Rails FTW

Thanks to a Battlefield 3 Beta losing streak that I blame on my sucky internet connection, I’ve decided to update my hack-job of a standalone Windows installer for Rails.

Now there are two separate installers, a Ruby 1.8.7 + Rails 3.0.10 installer and a Ruby 1.9.2 + Rails 3.1.0. Here’s a table to give a quick comparison between these two installers with RailsInstaller thrown into the mix:

  RailsInstaller 2 RailsFTW (Rails 3.1) RailsFTW (Rails 3.0)
Ruby version 1.9.2-p290 1.8.7-p352
Rails version 3.1.0 3.0.10
File Size ~55MB ~20MB ~10MB
DB Adapter Gems sqlite3, pg, tiny_tds (MS SQL Server) sqlite3, mysql2
Additional Features git, DevKit -
Internet Connection Required? Yes No (Bundler will fail to connect to server but new apps will still work) No
Compiled by Some of the biggest names in the Ruby community Some random third world developer. LOL

This post by Bryan Bibat is from existence, refactored.

Starting a “professional” Rails 3.1 app with Web App Theme, Devise, and Kaminari

With the recent release of web-app-theme providing Rails 3.1 support, it’s time once again for me to write a tutorial on how to earn money from cheap clients who can’t afford designers.

For reference, the previous tutorial can be read here.

crud screen

Every Rails developer knows how to create a Rails app. It’s easy as

rails new APP-NAME-HERE

But how many know how to create an app from scratch that looks good enough to sell to clients i.e. with slick design, authentication, authorization, and all that? Sure, there are tutorials out there that cover those components, but most of them cover them only in isolation from each other. A quick tutorial containing multiple components at a time would be a valuable resource to anyone planning to start a new app.

As the resident dilettante in these parts, I’ve decided to create such a tutorial based on a recent demo I made for a prospective client.

This post will discuss how to create a Rails 3.1 application that looks good enough to sell to clients (of course, YMMV) while still having components found in “professional” apps. This tutorial will cover the following:

  • Andrea Franz’s web-app-theme gem – this gem generates themes for your web app (hence the name). The demo and the list of available themes can be found on this page.
  • Devise – our authentication module. Authlogic‘s fine, but I find Devise’s approach less obtrusive.
  • Haml – replaces Erb. Not perfect (e.g. screws up with inline a tags) but the drastic decrease in code makes passing it up difficult.
  • Rspec – replaces Test::Unit. Only setup will be covered in this post, actual usage is left to the reader.
  • Kaminari – gem for pagination. We’re going to use it in place of the previous gem will_paginate

Rest of the tutorial is below the cut.

Let’s start by creating our new app with no testing framework and with MySQL as the database:

$ rails new pro-template-app-31 -d mysql -T

Now would be a good time to edit the .gitignore file to exclude files you don’t want to add to Git. Rails 3 already provides some good defaults, but if you want more possible entries there are samples available over at Github.

Once done, it’s time to make the initial commit.

$ git init
$ git add .
$ git commit -am "initial commit"

Setup Gemfile

Now is time to add the needed gems to Gemfile.

source 'http://rubygems.org'

gem 'rails', '3.1.0'
gem 'mysql2'
gem 'haml'
gem 'devise'
gem 'kaminari'

group :development, :test do
  gem 'capybara'
  gem 'rspec-rails'
  gem 'haml-rails'
  gem 'hpricot'
  gem 'ruby_parser'
  gem 'web-app-theme', '~> 0.8.0'
end

I’ve already explained most of the gems above at the beginning of this post. The only thing worth noting would be the addition of hpricot and ruby_parser, both of which are needed by web-app-theme to generate haml files.

Run “bundle install” to install the gems. After the gems are installed, all of our generators will now use Rspec instead of Test::Unit, and it can now generate Haml instead of Erb.

Generate home page

Let’s try out our app first by creating a new root page to replace the default.

$ rails g controller home index
 
$ rm public/index.html

Then edit the config/routes.rb:

ProTemplateApp31::Application.routes.draw do
  root :to => "home#index"
end

Before starting the app, don’t forget to create the database:

$ rake db:create

Start the server.

initial root page

all pictures are clickable BTW

Generate theme with web-app-theme

Here comes the fun part.

$ rails g web_app_theme:theme --engine=haml --app-name="My Latest Web App"

This will generate the layout files using the default theme in haml whose title would be “My Latest Web App”.

(In case you want to use a different theme, add --theme="THEME-NAME" to this and some of the later commands.)

Delete the default layout generated for the rails app:

$ rm app/views/layouts/application.html.erb

then refresh the page.

themed root page

It looks good, but I think we’re better off using the sample text page from the demo site.

$ rails g web_app_theme:themed home --themed-type=text --engine=haml
 
$ mv app/views/home/show.html.haml app/views/home/index.html.haml

fixed home page

Tweaking web-app-theme v0.8.0

Before we continue, let’s first fix some problems with web-app-theme 0.8.0 when used with Rails 3.1.

First, generate a copy of the current theme to your app so that you could modify them.

$ rails g web_app_theme:assets

Now for the tweaks:

  • JavaScript tag doesn’t point to the one generated by the asset pipeline. This is the reason why the sign-out links won’t work if you followed the previous tutorial. Fix here.
  • The stylesheet for alert messages are still defined under “error” class. Fix here.
  • For some odd reason, the images for buttons were moved to the spec folder. You can bring them back by manually copying them to your project’s web-app-theme asset folder. Here’s one way of doing it:

$ cp $(bundle show web-app-theme)/spec/dummy/public/images/* app/assets/images/web-app-theme/ -r

Add Devise authentication

Let’s install Devise and create our User model in the process.

$ rails g devise:install
 
$ rails g devise user

We also need to customize the login screen. To do this, we must first enable scoped views for Devise.

Then let’s generate the sign-in/sign-out layout:

$ rails g web_app_theme:theme sign --layout-type=sign --engine=haml --app-name="My Latest Web App"

Then let’s add the following files to the config/application.rb file to change the layout for sign-in/sign-up:

    config.to_prepare do
      Devise::SessionsController.layout "sign"
      Devise::RegistrationsController.layout "sign"
    end

At this point, you could generate the Devise views via

$ rails g devise:views

but the generated files are in ERb, not to mention that the layout for the sign-in/sign-up pages are different from what web-app-theme expects.

To save you from the hassle of copying the layout of those two pages, you could just copy-paste what I did here and here.

Restart the server, run rake db:migrate, and try going to the login site (/users/sign_in).

login page

Clicking “Sign up”:

sign up page

Finishing touches to Devise

Let’s do some finishing touches to the UI.

First, modify the layout such that the logout button actually works.

Now to test if Devise really works. Add the before_filter :authenticate_user! to home_controller.rb to kick us out to the login screen if we’re not logged in. While we’re at it, modify the said controller to set tell sign-out to redirect to the sign-in page.

login error

Create a test user via the rails console.

$ rails c

User.create :email => "test@example.com", :password => "123456", :password_confirmation => "123456"

You should now be able to login and logout.

login success

logout success

Theming a CRUD module

Now let’s show how to add the web-app-theme to a new CRUD module. To simplify things, we’ll use the ultra-stupidsimple blog demo.

$ rails g scaffold blog_entry subject:string content:text publish_at:datetime
...
$ rake db:migrate

Overwrite the generated files by running web-app-theme’s generator:

$ rails g web_app_theme:themed blog_entries --will-paginate --engine=haml

Since we’re using kaminari, we need to modify the controller and index page accordingly.

We will also have to modify the kaminari template to match the CSS. First generate the view files via

$ rails g kaminari:views default -e haml

then modify the files to match the layout with the demo page. Here’s one way of doing it.

We also need to modify the layout to take into account the new module.

crud screen

After that, you can still do a couple of minor tweaks to the pages to deal with their “auto-generated” jagged edges. Then you can also apply the error message fix (don’t forget to restart the server) and test it with the screens.

fixed crud

And that’s it. The complete code generated above can be found at Github.

This post by Bryan Bibat is from existence, refactored.

September Meetup Videos

Illformed requirement Syck::DefaultKey

If you’re getting the errors below, you should update rubygems to the latest, which is 1.8.10 as of this writing.

Installing cucumber-rails (1.0.4) Invalid gemspec in [/Users/crigor/.rvm/gems/ruby-1.9.2-p180@ss/specifications/cucumber-rails-1.0.4.gemspec]: Illformed requirement ["#<Syck::DefaultKey:0x00000100e779e8> 0.7.2"]

Installing database_cleaner (0.6.7) Invalid gemspec in
[/Users/crigor/.rvm/gems/ruby-1.9.2-p180@ss/specifications/cucumber-rails-1.0.4.gemspec]: Illformed requirement ["#<Syck::DefaultKey:0x00000100e779e8> 0.7.2"]

Check out http://blog.rubygems.org/2011/08/31/shaving-the-yaml-yacc.html to get the details. After upgrading rubygems to 1.8.10, I was able to install database_cleaner but I was still getting an error for cucumber-rails. The solution is to open /Users/crigor/.rvm/gems/ruby-1.9.2-p180@ss/specifications/cucumber-rails-1.0.4.gemspec and change

#<Syck::DefaultKey:0x00000100e779e8>

to =. If you’re using vim, just run

:%s/#<Syck.*>/=/

This post by Christopher Rigor is from crigor.com.