Website updates

It’s been a long time—years in fact—since I last updated my website. Despite the relative silence during that time on my part, a lot happened.

A new design

Without a doubt, the previous design was dated. It was crafted just before HTML5 and responsive design became main–stream. This new design is simple. It’s purpose is to let the reader focus on the content, and nothing more. There are still some major pieces of functionality I’d like to add, and a number of ideas I want to experiment with.

Updated software

In truth, I abandoned my old publishing system. I meant to keep it up–to–date, and see it evolve over time. However, that just wasn’t the case. My new system uses some code from the old one, but for the most part, it is brand new. As a result, I’ll be publishing a new tutorial on building a, ‘contact’, form using Rails 4 (ETA ).

HTTPS is becoming more and more popular. Soon, it will even have a role in search rankings. I attended a fantastic talk at Google I/O 2014 which inspired me to start making the switch. My entire site can now be browsed securely, and it will eventually become the default (I just need to work out a few bugs first).

Everything else

A lot happened in the last few years. Academia continues to be my life. In the time that passed, I earned both a certificate and diploma in computer systems technology. The next 3 to 4 years of my life are in pursuit of a degree. My interests are with computer science, but I’m studying towards a degree in geomatics. A multi–disciplined education is more interesting to me (and more useful in general).

It’s safe to expect more updates from now on. There’ll be a ramp–up period as I work on content to publish. I’m not sure how often a new post will be up, and I don’t want to commit to an unrealstic schedule. So for now, I’ll just let things happen as they will.

Contact form in Rails 3

This is an updated version of a tutorial I originally wrote in 2008 on building a contact form with Ruby on Rails.

The goal of this tutorial is to build a form that when submitted will validate and email the data.

Prerequisites

To simplify this, I’m just using Google Apps to manage email addresses. If you have your own email server just modify the settings as needed. To get started you’ll need:

  1. A Google Apps account, of course
  2. Ruby on Rails 3.2.2 (give or take a few version numbers)

Configuring Rails for GMail

In an existing or new application, open config/application.rb. Insert the following snippet in the Application class.

config.action_mailer.smtp_settings = {
  :address              => "smtp.gmail.com",
  :port                 => 587,
  :domain               => "yourdomain.dev",
  :user_name            => "from@yourdomain.dev",
  :password             => "Super-Secure-Password",
  :authentication       => :plain,
  :enable_starttls_auto => true
}

config.action_mailer.default_url_options = {
  :host => "yourdomain.dev"
}

Set the value of :domain to the domain you’re using for Google Apps, and :user_name and :password to your Google Apps account credentials. In the second block replace :host with the domain where the application is reachable from. The :host option is used to ensure that all links in email templates generate full URLs.

The Message Model

To allow validation of the message, I create a model and just include ActiveModel’s validations. Allowing the model to be written just like any other Rails model.

Create the file app/models/message.rb, or with a name of your choice. Make the file look similar to the following.

class Message

  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name, :email, :subject, :body

  validates :name, :email, :subject, :body, :presence => true
  validates :email, :format => { :with => %r{.+@.+\..+} }, :allow_blank => true
  
  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end

end

This is fairly self explanatory. A message can have a subject and body, as well as the name and email address of the sender. All of the fields are required, and the email address is verified with a regular expression.

The Mailer Model and Views

Run rails g mailer NotificationsMailer. This generates app/mailers/notifications_mailer.rb.

We'll want notifications_mailer.rb to look similar to this snippet. Check out the ActionMailer API for specifics on what’s happening here.

class NotificationsMailer < ActionMailer::Base

  default :from => "noreply@youdomain.dev"
  default :to => "you@youremail.dev"

  def new_message(message)
    @message = message
    mail(:subject => "[YourWebsite.tld] #{message.subject}")
  end

end

Replace :to, :from and :subject with the address you’d like the email sent to, the address it’s being sent from (should be the one you configured the Rails application with), and the subject of the email.

Create the file:

app/views/notifications_mailer/new_message.text.erb

How the message looks is entirely up to you. Here’s an example of how it could be laid out.

Name: <%= @message.name %>

Email: <%= @message.email %>

Subject: <%= @message.subject %>

Body: <%= @message.body %>

The Controller and View

Run rails g controller contact and then open app/controllers/contact_controller.rb.

The controller will only need two actions: new and create.

class ContactController < ApplicationController

  def new
    @message = Message.new
  end

  def create
    @message = Message.new(params[:message])
    
    if @message.valid?
      NotificationsMailer.new_message(@message).deliver
      redirect_to(root_path, :notice => "Message was successfully sent.")
    else
      flash.now.alert = "Please fill all fields."
      render :new
    end
  end

end

To get these actions working, open up config/routes.rb and insert the following two lines.

match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post

When a GET request is made to /contact, the new action is called. When a POST request is made to /contact, the create action is called.

Create app/views/contact/new.html.erb. As with the email template, this template is entirely up to you, I'm only providing an example of what it could look like.

<%= form_for @message, :url => contact_path do |form| %>
  <fieldset class="fields">
    <div class="field">
      <%= form.label :name %>
      <%= form.text_field :name %>
    </div>
    
    <div class="field">
      <%= form.label :email %>
      <%= form.text_field :email %>
    </div>
    <div class="field">
      <%= form.label :subject %>
      <%= form.text_field :subject %>
    </div>
    
    <div class="field">
      <%= form.label :body %>
      <%= form.text_area :body %>
    </div>
  </fieldset>
  
  <fieldset class="actions">
    <%= form.submit "Send" %>
  </fieldset>
<% end %>

Try it

Start your rails server and go to /contact. Fill out the form and hit send. If everything was done correctly an email should arrive in the inbox of the address specified.

git-push with specific SSH key

I figured this was worth a post, as I’ve never ran into this problem before. I’ve been working on setting up a server, to which I connect using RSA. The standard name for an RSA key file is id_rsa(.pub). However, as I use my ‘standard’ key elsewhere, I wanted to use a specific key for this server.

Connecting via SSH to the server with the key is as simple as adding -i /path/to/key. The problem arose when I needed to be able to push to a Git repository hosted on the server, and adding -i to git-push doesn’t work.

The solution was to add a Host directive to my ~/.ssh/config file. Then, use that Host to connect to when push’ing to the remote server.

If it doesn’t exist, create the file ~/.ssh/config. Add the following to it, editing where necessary.

Host RemoteServer
  HostName remote-server.tld
  User git
  IdentityFile ~/.ssh/remoteserver_key

Remember to reload SSH after creating this file. This example config would be the equivalent of running a command like ssh git@remote-server.tld -i ~/.ssh/remoteserver_key. You can even run ssh RemoteServer to test the connection out.

In your Git repository, add a new remote repository. Here I’ve called it origin, as the convention might have it.

git remote add origin RemoteServer:path/to/repository.git

Instead of specifying a user @ a domain, it uses the name of the Host in the SSH config. The path/to/repository.git is relative, on the average system, that will probably point to /home/git/path/to/repository.git.

Try running a git push origin master to see if it works!

Exception notification for Rails 3

Using the popular ExceptionNotification plugin has changed slightly in Rails 3. One thing to note is that the official repository has moved from the Ruby on Rails GitHub organization to Sebastian Martinez’s account. Let’s get started.

Add the gem to an applications Gemfile.

gem 'exception_notification'

Then install the actual gem with either, gem install exception_notification, or by running bundle install from the application’s root.

Open the environment configuration file for which the application requires exceptions being reported from, typically this is config/environments/production.rb. Inside the application’s configure block, place the following code, editing where necessary.

# For a full list of configurable options, see the gem's GitHub home page.
config.middleware.use ExceptionNotifier,
  :email_prefix => "[Application Name] ",
  :sender_address => %{ "Application Name" <noreply@application-name.ca> },
  :exception_recipients => %w{ recipient.1@application-name.ca }

When the application is running on production, and assuming it’s set up with an email server, it will send the proper notification when an error occurs!

Text field placeholder in CoffeeScript using jQuery

The HTML5 placeholder attribute is great. Styling it, however, isn’t as great (it is possible though). I implemented my own in JavaScript. Conventions encouraged me to use jQuery and CoffeeScript. I’ll show what it looks like in both jQuery and CoffeeScript for the curious.

The Form

<form action="/posts/search/" method="get" class="search">
  <input class="placeholder" name="q" type="text" value="Search" />
</form>

In jQuery

$(function(){
  $(".search input").focus(function() {
    if(this.value === "Search") {
      this.value = "";
      this.className = "textinput";
    }
  });
  
  $(".search input").blur(function(){
    if(this.value === "") {
      this.value = "Search";
      this.className = "placeholder";
    }
  });
});

The same code in CoffeeScript

jQuery ->
  $(".search input").focus ->
    if @value == "Search"
      @value = ""
      @className = "textinput"
    
  $(".search input").blur ->
    if @value == ""
      @value = "Search"
      @className = "placeholder"

My search form on the top–right is running this exact code. It’s very simple: when the field is selected and the value is “Search”, the field is cleared and a class of textinput is set (just changes the text colour); when the field is de–selected and its value is blank, the value is reset to the default, “Search”, and the class is changed to placeholder (again, just a colour change).

Resources

For the curious, RailsCasts has an episode outlining the basics of CoffeeScript. Also, of course, is the CoffeeScript website.