Posts from steve.blog - Home...

Easy Syntax Highlighting Helper

sudo gem install uv

(read this if you're having trouble)

def highlight(options = {:format =>"ruby"}, &block)
  Uv.parse( yield, "xhtml", options[:format], false, "twilight")
end

Which gives you:

<% highlight do %>
    class Person < ActiveRecord::Base
    end
<% end %>

Here's the CSS for the 'twilight' theme.

Oh and I do realise the irony of posting code about syntax highlighting with no highlighting...

References:

Ultraviolet gem

Merb with DataMapper & CouchDB

Ever the one to follow the cool kids, I've been experimenting with these up & coming technologies.

You can follow my progress via github: Merb, DataMapper & CouchDB

Finally on Twitter

Will I regret it? Will I say anything interesting? You can only find out by following me.

Quick & Easy attribute protecting per ActiveRecord instance

Here's an idea:

class Member < ActiveRecord::Base
    ProtectedAttributes = [:is_admin]

    def protect_attributes!
      @protect_attributes = true
    end

    def attributes=(attributes)
      if @protect_attributes
        attributes.symbolize_keys!
        attributes = attributes.delete_if {|key, value| ProtectedAttributes.include? key }
      end

      super
    end
end

enabling:

>> member = Member.new
>> member.protect_attributes!
>> member.update_attributes(:is_admin => 1)
>> member.is_admin
=> 0

Meaning you can use mass-assignment methods on the front end without worrying about users spoofing form posts.

Thoughts?

Tags: code

Simple application wide configuration in Rails

lib/app_config.rb:

class AppConfig  
  def self.load
    config_file = File.join(RAILS_ROOT, "config", "application.yml")

    if File.exists?(config_file)
      config = YAML.load(File.read(config_file))[RAILS_ENV]

      config.keys.each do |key|
        cattr_accessor key
        send("#{key}=", config[key])
      end
    end
  end
end

config/initializers/app_config.rb:

require 'app_config'

AppConfig.load

config/application.yml:

development:
    merchant_email: bob@thebuilder.com

test:
    merchant_email: test@thebuilder.com

Then from anywhere in your application:

AppConfig.merchant_email  ->  bob@thebuilder.com
Tags: code

Using Git with multiple staged deployments - Part 2

I wrote about this a little while a go and said I'd report back my findings.

It's been a few months now and generally I've been pleased with the method. Here's what we're doing:

config/deploy/production.rb:

set :deploy_to, "/curve21/www/application"
set :branch, "production"
set :deploy_via, :remote_cache

config/deploy/staging.rb:

set :deploy_to, "/curve21/www/application"
set :branch, "staged-feature"

Pushing out changes to production

With this setup, pushing changes live is simply a matter of merging a development branch into production and running:

cap production deploy

If there is a small bug to fix, we fix it in the production branch and deploy straight away. Those changes can be merged into development branches if needed.

Staging

Initially, we tried having a 'staging' branch, but that got very messy. Sometimes, we have more than one project or feature on the go at the same time for the same site. What we really needed was to be able to point the staging server to which ever branch we wanted. To achieve this, we ditched the staging branch and just set it to what ever we want at the time.

In conclusion...

I've been really pleased with this setup so far. Overall it's given us the flexibility to work on features, push them out for showing the client while still being able to easily bug fix and maintain the live site.

Resources

Enumerable.any?

def requires_signup?
  requires_signup = false

  ancestors.each do |parent|
    requires_signup = true if parent.signup_required?
    break
  end

  requires_signup
end

or:

def requires_signup?
  ancestors.any? {|parent| parent.signup_required? }
end

Lovely.

Using Git with multiple staged deployments

Like most developers, at Curve21 generally have our applications set up with 2 remote environments - staging & production. New developments are deployed to the staging server for final checking & sign-off before being pushed out to the wilderness.

We've also (as many have) recently moved to using Git for a source control. A lot has been written about Git in the past few months and suffice to say we've found it fantastic. One thing I've not seen a lot about though is how to deal with different deployments targets.

Here's an idea we've had which we're trying out on a project. I'm interested to get feedback and to hear about any other ways people are working with Git.

The Idea

Basically, we need to be able to do the following:

So, here's the setup we're testing out:

The 'new feature' workflow looks like this:

  1. Create a branch for a new feature
  2. Merge new feature into master
  3. Rebase master into staging
  4. Deploy to staging server
  5. When ready, merge staging into production
  6. Deploy to production server

With this setup, you have ultimate flexibility over what goes where. The master branch tracks the main development which is shared to all developers. When a new feature needs to be tested it can be easily pushed to the staging server.

If there are bugs to be fixed in production, these can be fixed in the production branch and deployed without picking up or affecting the items in development or out on staging. Capistrano can pick up any branch you ask it to for a specified environment.

Once we've tried this out and fine-tuned it, I'll post the results. If it works and others are interested, I'll sort out a tutorial for our we're doing it.

So - feedback & questions welcome!

Protx: An update

Last year I wrote a rather angry post about the quality of service provided by Protx during a system upgrade.

This caused a bit of a stir, possibly due to the high Google ranking and certainly the derogatory tone of the post.

I've since been contacted by Simon Black who took over as Managing Director of Protx last year. He has been pushing through a number of changes that he hopes will improve the customer support experience.

One of the more apparent surface changes is an update of the Protx support pages. The change in tone from the original pages is very positive:


"At Protx we are passionate about providing high quality support and service to our customers. Our technicians are trained to ensure that they provide you with a professional service and the correct technical response to your question.

We are happy to speak to you over the phone, communicate via email, or if you prefer you can resolve the query yourself using our in-depth website. You choose the method that’s best for you.

We aim to pick up calls within 60 seconds and respond to emails within 24 hours."


Simon also sent the following update on the progress they've been making to improve the service:
"Since last August Protx has transformed it's support operation by more than doubling the size of the team and investing in training and development. During 2008 there will be continual improvements to the way we provide customer service which will include overhauling the entire Support web pages.

Our aim is provide an excellent customer experience and we are proud to receive feedback showing that this is now happening more and more. The software platform we launched last Summer has resulted in a significant decrease in the number of Support issues raised on average. It has also allowed us to launch new features, for example, a much more efficient method for taking regular payments.

In the coming months and years we will invest significantly to ensure we provide a great service, remain the easiest payment gateway to integrate with and provide more and more added value to our customers' businesses.

Any customers or developers that are unhappy with the service they have received from Protx can send an email to feedback@protx.com and they will receive a prompt response from one of our senior managers."


I'm not sure I'd use Protx again, but I think it's great to see positive action being taken on something as important as customer service.

Customer service is a product itself in any successful company. It should be treated with the same care and attention as you give other products you sell.

StaticMatic 2 is coming

StaticMatic is currently going through a major over-haul. There are loads of great features in the works as well as changes to the way to core works.

The major change is that StaticMatic 2 will now use ActionPack. This means we get loads of great new features:

On top of this we also now have:

We're also now hanging out with cool kids on github: http://github.com/stevebartholomew/staticmatic/tree/master.

Call to Arms

Now, we need your help. StaticMatic 2 is not yet feature complete. There is still a lot of work to do with getting all the current features in as well as working up the new stuff.

What we need is for you to try out the new features on your existing StaticMatic sites. The great thing is, you can run the new version without conflicting with the current one:

  1. Download the edge version into your site's root directory:

    ~/Sites/mygreatsite $ git clone git://github.com/stevebartholomew/staticmatic.git

  2. Create a Rakefile in your site's root containing this:

    require 'rake' require 'staticmatic/lib/tasks/staticmatic'

That's it. You can use the new StaticMatic commands:

rake preview
rake build

Or you can use your Gem version:

staticmatic preview .
staticmatic build .

The main thing that needs testing is integration into ActionView - try out the helpers, see what happens. There's a fair few hoops to jump through to make ActionView happy being separated from ActionController so it can play up!

New to StaticMatic?

If you're new to StaticMatic, you can try out the new version by installing the current one and creating a new site:

sudo gem install staticmatic
staticmatic setup mygreatsite

and following the instructions above.

Be Gentle!

There's a fair way to go before we're ready for a release, but hopefully you can still have fun trying out the new features. Join us over at the Google Group for more discussion.

Tags: code

Passenger (mod_rails)

We've been developing client applications with Rails for a few years now. We're not really a hosting company, but our love of Rails meant that it was easier to host client apps ourselves than faff around trying to get them running on their own ISP's servers. Hosting in house took that pain away.

It's worked well, but now we're running quite a few, it's getting pretty cumbersome to manage. We still manually set up mongrels for each one, define the proxy requests in apache, restart - rinse and repeat.

This is one of the reasons that I got so excited about Passenger (mod_rails).

Passenger has been getting a fair bit of press in it's short life out in the public so far and it's easy to see why. While it's not the answer to all the scaling issues that come with a web app, it's a fantastic way to simplify the deployment and hosting process, especially for shared hosts.

In the same way that we set up mongrels to fire up our rails apps and keep them running while apache sends requests between them, Passenger loads up the rails framework and our application code when a request is made.

The framework and application code are kept loaded and are shared by separate worker processes. These worker processes are started up and shutdown based on the load on the app.

The best thing about this is that it happens behind the scenes with very little configuration. Restarting your application is a 'touch tmp/restart.txt' away and the rest is done for you.

We've already started trial this with our internal applications and it'll be interesting to see how it pans out. If this means that our lives are made easier and more hosting companies consider rails, this is looks to be a very important development.

Remember when we use to worry about servers & scaling?

I'm so ridiculously excited about Google App Engine.

In the next year or so, I hope we see more and more hosting companies taking on this model.

Removing the need to worry about servers and scaling will be great for everyone. If you're a hosting company, I strongly recommend you look into how you could do this. Most developers would pay over the odds for the pain of servers & scaling to be taken away.

Tags: code

Email Standards

Battling with browsers is a daily chore for most web developers. Web standards put up a great fight to get proper support into browsers, but what of email clients?

There are actually more ways to view your mail shots than there are to view your website - what with both desktop and online clients. All of these have different support for html and css.

Often the developer's answer is to strip everything back to basics or put hacks in to make things work correctly - but there is another way!

Last november the guys from Campaign Monitor set up the Email Standards Project that should hopefully do for emails what we already have for websites.

Passionate People

From 37signals: "There are only people who are passionate about what they do, and people who aren’t"

This fact is so much more important than some people realise. Just think about how different it is when you're served by someone with passion at a cafe. Imagine if a company made sure that that passion was number one on the agenda for employees.

That's exactly what 37s work experiments are all about.

"I don't have time"

I hate "I don't have time". It should be banned. It's used all the time and it's rarely true.

"I don't have time" normally means one of 2 things:

Owning an old house means that I have a constant list of DIY jobs to do. Often I don't get as much done as I'd like. I could say "I don't have time" but that's simply not true. It tends to be "I could do that, but I'd rather go out for dinner".

The second example mostly crops up for me in development work. People say they don't have time to test or create proper application structure. They then proceed and spend 3 times longer with loads more stress hacking and debugging a unwieldy application.

People like "I don't have time" because it shifts responsibility. The world is obviously giving you too many things to do.

So here's the bottom line: get over yourself and think about whether you really "don't have the time".

You're either prioritising something else - which is fine - or your prioritising the wrong thing - which means you need to take a step back and decide on what's really important.

We're hiring!

The time has come for Curve21 to expand a bit more, so we're looking for a developer to join our growing team in Brighton.

Here's the official line: http://www.curve21.com/jobs/developer.html

Let us know if you're interested!

You know you work with computers when...

Last night I actually looked for the time at the top right hand corner of the magazine I was reading...

Review: Practical Rails Social Networking Sites

Good

Not so good

Overall

Despite being pitched as more advanced on the 'Apress Roadmap', this book would equally appeal to people new to Rails and those with a bit more experience. It's 'real-world' project approach makes the learning much more relevant - a must for motivation.

Rating: 8/10

Tags: reviews

Gorillas and Chocolate

Hands down, best advert ever:

Handling content in a Haml template

I get asked this a lot about StaticMatic & Haml: Structured templates are great for HTML markup, but what about the actual content of pages?

As StaticMatic is used to manage static sites, you'll quite often have your page's content in a Haml template. While Haml works great for logical HTML markup, it can be a bit cumbersome when working with actual content:

%p 
  This is a paragraph of text with a 
   = link "website link", "http://www.stephenbartholomew.co.uk"
   in the middle.
%p
  It's even worse when the link is at the
  = link "end", "http://www.stephenbartholomew.co.uk"
  \.

Thankfully, there is a simple solution in the form of filters:

:markdown
  This is a paragraph of text with a [link](http://www.stephenbartholomew.co.uk) in the middle.

  It's pretty great [now](http://www.stephenbartholomew.co.uk).

This can be used in any Haml templates - it's not specific to StaticMatic. It is however more apparent :0)

Haml has a number of different filters available including plain text, ruby, redcloth and textile - check out the docs for more information.

next page »