Backup

Living with Regret

Many of my articles deal with researching and the effect it has on the company's dealings with clients. Now, I feel that another issue has to take the forefront: system and assets back-up. I have had the worst luck lately when dealing with computers, company data and the need to back things up. Working at a Web firm, it's easy to take backing up for granted because everything already has two copies: all the articles, client assets, help archives, etc. exist both on our local drives as well as on the Web servers. But this is the exception to the rule as most businesses don't have such redundancy in place.

I still can recall my personal data loss tragedies... One day I accidentally erased my first PC's 500MB drive trying to retrieve a paper I wrote for history class. Another day I lost all my documents, media and impressive collection of ms-dos based games to a suddenly defective drive. The memories haunt me...

Thanks to continually dropping technology prices, a back-up array or separate storage solution has fallen within reach of the average home user. Still, people are losing their data in their own personal tragedies every day, simply because data back-ups only gets serious consideration about five seconds too late.

A while ago, I consulted with a company on a new computer setup. Under normal circumstances, this should have been a simple, straight-forward, "Buy, Back-up, Program and Go." Unfortunately, their current computer was using Windows '98 and its drive had crashed an hour before I had gotten there. Once a Windows '98 drive has spun its last sector there's simply no hope. I had the unpleasant honor of explaining that their data and projects had gone to 'a better place', all because they hadn't taken my suggestion to pick up a 80GB back-up drive for an easy $70.

The data of any business is a precious commodity, and working without a back-up system is walking on a tightrope without a net. Thankfully, there are many data storage solutions that can meet the needs and budgets of business and personal users.

Hardware Solutions

One simple solution that a user can get either for business or personal use is a 1TB (terabyte) drive, an amount that is virtually impossible to fill without a vast media collection. While this drive is not lacking in capacity, I would be concerned that a drive failure would result in such an immense loss. Personally, I prefer to spread out all my data on multiple drives so that if one fails I have a copy of it somewhere else.

For a business or user that needs to back-up multiple computers, a networked or wireless drive may be an excellent solution. The D-Link DSM-G600 Wireless G Network Storage Enclosure allows you to place drives on a shared network. Another solution would be an attached network storage like the Iomega StorCenter 1TB WI-FI Network storage drive. The drives are already formatted and ready to go, and have wireless connectivity and network adapters for additional server storage.

For those users that need storage on a tight budget I would recommend one of two choices. A 500GB external drive like the Seagate Freeagent Desktop costs between $90-150. For the more ambitions, you can combine a 500GB hard drive (about $100 and getting cheaper) with an external enclosure (check out the Eagle Consus W-Series SATA to USB and the eSATA External Storage System (ET-CSWESU2-BK) Black).

I recently have been introduced to an innovative storage solution called Drobo, the world's first storage robot. I have to say the concept looks promising, I wish that I could get my hands on one to play with. Based on information from their site, here are some pros and cons of the Drobo:

Pros:

  • You can swap drives (SATA only please) in and out of Drobo and data is automatically and redundantly redistributed to protect from drive failure. This is like RAID only better: I don't trust RAID based systems because of their rigid nature. With RAID, adding or removing a drive requires a full reboot and, depending on the RAID configuration, a single drive failure could still corrupt the whole array.
  • No babysitting required, the Drobo takes care of itself.
  • There's no loss of productivity between files and data while drive swapping.

Cons:

  • The Drobo's price of $499 and up is a significant roadblock to becoming an early adopter. Keep an eye out for this price to start dropping, however, as the technology spreads.
  • It only comes with USB 2.0 connections, eSATA and standard networking capabilities would have been welcome features.

While using an external drive is sufficient for many purposes, some users are turning to software solutions that help automate the back-up process.

Software Solutions for Macs

There is an integrated solution that ships with every new Mac called Time Machine. Time Machine makes a full copy of your computer's data when it is initialized and then simply records the changes made to your data. Its automation is paired with a fun, intuitive user interface that let's a user 'fly through time' to find the file that was deleted, edited or saved over. Thanks to its excellent integration within OSX and other peripherals like Time Capsule, Time Machine is the likely choice for backing up Macs.

One other possible solution is MacBackups which does online, offsite back-ups of your Mac.

Software Solutions for PCs

Nero offers a back-up feature in its Nero 8 software. It can automate the back-up process and allows for manual back-ups as well

Norton Ghost is also an excellent option. It's not a tradition back-up program in that you have to restart and load PC-dos in order to make your back-up. The benefit to this approach is that it can restore your entire computer with your programs intact rather than simply your documents.

I hope this is a resource that can help make your back-ups easy and painless, but no matter what, please, PLEASE, back up your files!



Image

A long standing complaint among web designers is the lack of variety in typefaces that can be reliably used and guaranteed to display across all web browsers and operating systems. For the most part, designers are stuck with Arial, Verdana, Georgia, Times, or the standard serif and sans-serif implementations, though this list can be supplemented by expanding the font stack. Granted, the standard typefaces are optimized for web and will render well across the the board at various sizes, with anti-aliasing on or off, but occasionally designers need to spice things up with additional typefaces in an accessible, search-friendly manner without resorting to pre-rendered images. Two options currently exist to help remedy the situation: sIFR and Safari Embedded Fonts.

sIFR (Scalable Inman Flash Replacement)

sIFR has been available for a few years and has had a good reception across the web community. It was created as a way for designers to display any typeface on a web site without requiring the visitor to have that typeface previously installed. It uses a combination of Adobe Flash and Javascript to dynamically replace text, and is completely accessible and search engine friendly. The current stable build of sIFR is version 2, with version 3 currently in development, hopefully to be released in a stable form in the near future.

sIFR requires both Javascript to be turned on and the Flash plugin to be installed. If either of these requirements are not met, the default styles designated by the designer will be used and the visitor will never know the difference. However, the wide adoption of Flash and Javascript will ensure it works for most visitors. sIFR is best used in moderation with elements like headlines, rather than entire blocks of body text.

How to use it

After downloading sIFR, the first step is to open the sifr.fla in Adobe Flash, replace the typeface with one of your choosing, and export the file as a Flash movie. This is explained in more detail in the sIFR Documentation. Next, in the <head> of your HTML document, insert links to the sIFR CSS and Javascript files:

<head>
  .....
  <link rel="stylesheet" href="sIFR-screen.css" type="text/css" media="screen" />
  <link rel="stylesheet" href="sIFR-print.css" type="text/css" media="print" />
  <script src="sifr.js" type="text/javascript"></script>
  <script src="sifr-addons.js" type="text/javascript"></script>
  .....
</head>

Before the the closing <body> tag of your HTML document, insert the Javascript to call the sIFR replacement methods on all the elements you want to transform:

.....
<script type="text/javascript">
if(typeof sIFR == "function"){
	  sIFR.replaceElement(named({sSelector:"body h1", sFlashSrc:"blackletter.swf", sColor:"#000000", sBgColor:"#dddddd", sFlashVars:"textalign=center"}));
  sIFR.replaceElement(named({sSelector:"body h2", sFlashSrc:"blackletter.swf", sColor:"#000000", sBgColor:"#FFFFFF"}));
};
</script>
</body>
.....

The sIFR.replacementElement method takes a number of options such as color, background color, link and hover colors, padding, and several more as described in detail in the sIFR Documentation. You may have to play around with these options and tinker with your CSS to perfect your transformations.

View the Example »

You should see something like:

sIFR Example

Pitfalls

sIFR does a good job of working across a variety of browsers and degrades rather gracefully when it can't be used. That said, there are a few issues that arise with its use. Occasionally sIFR can slow the rendering of a web site, and can also create a visible 'flash' as the text is replaced by Flash. Additionally, visitors won't be able to copy and paste a combination of sIFR text and normal HTML text.

Embedding Fonts with @font-face and Safari

With the recent release of Safari 3.1 from Apple comes the ability for a web designer to reliably display any TrueType font of their choosing on a web site without Flash or Javascript, allowing them to style it with CSS as they wish. Visitors' browsers will seamlessly download the typeface and render the design in all its glory as was intended by the designer. Surprisingly, Internet Explorer has actually supported font-face embedding since version 4, but unsurprisingly, Microsoft's implementation only works with a proprietary .EOT font format.

How to use it

Implementing the @font-face property is actually quite simple. It acts just like any other CSS selector as shown in the example code below. Define a name for your font-family and then provide an absolute or relative url() to the typeface file. The url() acts just like url() for background-image. Once you've defined the typeface, simply use the new font-family within any selector as you would normally.

@font-face {
  font-family: "OldeEnglish";
  src: url(OldeEnglish.ttf) format("truetype");
}

h1 { font-family: "OldeEnglish"; }

View the Example (works only in Safari 3.1+) »

You should see something like:

Safari Embedded Fonts Example

Pitfalls

One major downfall to using embedded typefaces is that the technique currently only works in Safari 3.1. However, other browsers will degrade gracefully and use the next font in the font stack. Unfortunately, a designer may be using different line-height, font-size, letter-spacing, or word-spacing specific custom typeface, making the next typeface in the stack unreadable. No word yet on whether future versions of Firefox, Internet Explorer, or Opera will join in the font embedding party, but a designer can hope.

Copyright issues also arise with @font-face. Quality typefaces from type foundries often cost hundreds to thousands of dollars and don't generally include licenses that allow for legal distribution to the public. Since the fonts used with @font-face are required to be publicly accessible, they could potentially be downloaded by any user who has a peek inside your stylesheet. There are many freely downloadable fonts available on the web, but a majority of those are rather low quality and should probably be avoided anyways.

With Great Power Comes Great Responsibility…

The two tools are a welcome addition to a designers arsenal, especially when it comes to web typography. However, these new tools do open the door for typeface abuse and potentially illegible, tacky designs. Unless that's specifically what you're going for, as a designer you should still use sound judgement and restraint. Just because you can, doesn't mean you should. With that said, go forth and experiment!

Helpful Resources & References



Unknown

A while ago, I was given the task of converting a working Java web application to Ruby on Rails. The word on the street was that Ruby on Rails was great for a 'green' project, lays i.e. starting from scratch - but not so good for a legacy application.

However, since the database I was using already had an auto-increment primary-key column 'id' for every table, I didn't run into that many problems. There was, however, one bit of functionality I puzzled over for a while.

The application was a project tracking application: projects with attached assignments, and each assigment was associated with a document of some sort. The document types weren't really related to each other all that much, except for a few common attributes and the fact that they could be assigned. To protect the names of the innocent, I will pretend the types of items were articles, books and blog posts. If you consider those, they don't have a lot in common. No article or blog post needs an isbn, and no book needs a date posted field. They are all pretty distinct conceptually; the commonality can be found in that each are something an editor might need to work on - i.e. they are all coherent bodies of text.

I looked at the existing Java code. The application had classes Article, Book and Post all derived from Document. But there was no 'documents' table - only articles, books and posts.

Technically this is Multi-table inheritance since each type of object gets its own table. This is not something supported by Rails. Rails supports the idea of Single Table Inheritance (STI): put every record in one table. This often works out very well because it is efficient and simple.

However, I didn't want to force all these records into one table for a variety of reasons. One such reason is I wanted to make sure no Book was created without an isbn - but if I put them all in one table, the isbn field would have to allow for NULL (for articles for instance). Some would argue this an application level concern, but I think if you can guarantee data validity at the database level - and bolster that reliability on the application side - you are much better off than just merely relying on the application.

Another reason was because I've found, when rewriting an application in Rails, the longer I can push forward keeping the original data structure intact the better. That way I can run both applications at the same time as I figure out the functionality of the first. In the ideal world, the functionality of the original app would be fully detailed in a spec somewhere. This project, unfortunately, was deeply rooted in the actual world.

The currently working Java application was using an ORM, just like Rails does. The ORM for this project was something from the Apache group called the ObjectRelationalBridge or OJB for short. I looked into the code to see how it was achieving this multi-table inheritance. Basically it was using a simple table to keep track of what the next unique id should be for a given 'type'. Some databases support sequences that do this, but not MySQL 3.

The name of the table was sequences and it looked roughly like this:

sequences
id type_name value
1 document 5825

Whenever it was time to create a new Article, Book or Post, the database went to this table looking for the 'value' in the row with the 'type_name' = 'document', used that value to assign an id in a table corresponding to the object, and incremented the value. So the next Article would get an id of 5826 which would be stored in the id column of articles, the next Book would get an id of 5827 in the id column of books and so on. Pretty simple.

The other tables were structured something along these lines (this is a simplification):

projects

  • id
  • subject
  • start_date
  • end_date
  • status

assignments

  • id
  • document_id
  • document_type
  • start_date
  • end_date
  • status
  • project_id

articles

  • id
  • title
  • author_id
  • published

books

  • id
  • title
  • author_id
  • isbn

posts

  • id
  • title
  • author_id
  • slug

So how do I go about duplicating the functionality in Rails? Ideally, I'd like not to have to normalize all data into one big table, and ideally, I'd like to do something that doesn't mess with the internals of Rails, simply using the conventions that are already there. Over the years, I've found meddling with the internals of a framework can come back to bite you. Call me paranoid.

First Try

So, working in the most basic Rails idioms, I start off with something like this:

class Project  < ActiveRecord::Base
  has_many :assignments
end

class Sequence  < ActiveRecord::Base
end

class Article  < ActiveRecord::Base
  before_create :generate_key

  def generate_key
    type_name = "document"
    key = Sequence.find(:first, :conditions => [ "type_name = ?", type_name])
    new_id = key.value + 1
    key.value = new_id
    key.save
    self.id = new_id
  end
end

class Book  < ActiveRecord::Base
  before_create :generate_key

  def generate_key
    type_name = "document"
    key = Sequence.find(:first, :conditions => [ "type_name = ?", type_name])
    new_id = key.value + 1
    key.value = new_id
    key.save
    self.id = new_id
  end
end

class Post  < ActiveRecord::Base
  before_create :generate_key

  def generate_key
    type_name = "document"
    key = Sequence.find(:first, :conditions => [ "type_name = ?", type_name])
    new_id = key.value + 1
    key.value = new_id
    key.save
    self.id = new_id
  end
end

That will take care of those Document objects getting their correct id, then I just have to make the Assignment reference it. This will work fine as a belongs_to since there can only be one match per row.

class Assignment  < ActiveRecord::Base
  belongs_to :project

  belongs_to :article, :foreign_key => 'document_id'
  belongs_to :book, :foreign_key => 'document_id'
  belongs_to :post, :foreign_key => 'document_id'
end

That's all fine and good, but I wanted to clean up my code for 3 reasons:

  1. I've had to copy and paste the generate_key and before_create :generate_key code 3 times already. Not very DRY.
  2. There is nothing in the code itself to indicate that there is a relationship between a Book, an Article and a Post.
  3. I have to type in belongs_to for each type of object. I figure there must be a way to make this more succinct.

Second Try

First order of business: fix all those redundant generate_key methods. Well, how do you go about adding both class method (before_create) and an instance method to a class? Answer: a Module.

The Rails library likes to use the base.extend(SomeModule) convention by defining ClassMethods and InstanceMethods submodules. This works great and is a good convention to follow. If there are not many instance methods, though, I've found calling module_eval within ClassMethods will work just as well (see below).

module GeneratedKey

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods

    def has_generated_key(object_name)
      object_name = object_name

      # add the before_create hook and make sure
      # we can access the object_name in instance
      # methods
      class_eval <<-CODE
           before_create :generate_key

           cattr_accessor :object_name
           @@object_name = object_name
      CODE

      # add the generate_key instance method
      # NOTE: i've skimmed over worrying about Symbol
      # vs. String for clarity
      module_eval <<-CODE
        def generate_key
          type_name = object_name.to_s
          key = Sequence.find(:first, :conditions => [ "type_name = ?", type_name])
          new_id = key.value + 1
          key.value = new_id
          key.save
          self.id = new_id
        end
      CODE

    end
  end

end

This means when I put has_generated_key :some_value in the preface of a class definition, the class will call the generate_key function before it runs create to generate the id value from the sequences table. Now I can set up my classes using inheritance. The only odd thing about that is that I have to set the table name on subclasses (otherwise it will always look for a 'documents' table).

class Document < ActiveRecord::Base
  include GeneratedKey
  has_generated_key :document
end

class Article < Document
  set_table_name "articles"
end

class Book < Document
  set_table_name "books"
end

class Post < Document
  set_table_name "posts"
end

The only thing left is to clean up that belongs_to :book, belongs_to :article etc. stuff in the Assignment class. Once again, I can just factor it out into a module.

module GenericAssociations

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods

    def belongs_to_type(object_name, implementations=[])

      object_name = object_name

      # take the array of implementations and do belongs_to for
      # each one
      implementations.each do |implementation|
        code = <<-CODE belongs_to  :#{implementation},
                                   :foreign_key => '#{object_name.to_s}_id'
        CODE

        class_eval code
      end

      # build up an if for each type of object i.e.
      # if article
      #   return self.article
      # end
      # if book
      #   return book
      # end
      # etc...

      if_loop = ""
      implementations.each do |implementation|
        if_loop += <<-CODE
            if self.#{object_name.to_s}_type == "#{implementation}"
               return self.#{implementation.to_s}
            end
        CODE
      end

      # add the 'document' method
      code = <<-CODE
         def #{object_name.to_s}
            #{if_loop}
         end
      CODE


      module_eval(code)

    end

  end

end

This creates a method belongs_to_type that is called during class definition, taking the type (as a Symbol) and an Array of the allowable subclasses as parameters. It also adds a method whose name is derived from the type (in this case document) that will loop through all the values and pick out which kind it is based on a *_type field value. Now I can just write this code for my Assigment class:

class Assignment < ActiveRecord::Base
  include GenericAssociations

  belongs_to :project, :foreign_key => 'project_id'
  belongs_to_type :document, [:book, :article, :post]
end

So the only major surgery I might have had to do on the original database design was to add a document_type field to the assigments table. But that's it and, in my case, there was already a field by that name anyway because it was still necessary for the UI. Now I can write code like this to get the Document of an Assignment (and because of duck-typing - any field I need I can just reference when I need it):

project = Project.find(1)

project.assignments.each do |assignment|
  print assignment.document
end

I can still retrieve only books, or only articles:

articles = Article.find(:all)
articles.each do |article|
  print article
end

books = Book.find(:all)
books.each do |book|
  print book
end

And I can still create an Article, Book or Post the same way I would any other object:

article = Article.new
article.save

Download files here: multi_table_article.zip

Note: The download includes a Rakefile in which you need to set up the db, username and password that matches your own. Then run rake. The default task runs some tests using a Ruby version of doctest, something from the Python world I'd like to see used in the Ruby world. The basic idea of doctest is that you can copy the results of an interactive interpreter session (in Ruby's case IRB) into comments in your Ruby code and rerun those transcripts as a form of regression testing. For example:

#doctest Check that 1 + 1 = 2
>> 1 + 1
=> 2
>> 2 + 3
=> 5
=end

I included a slightly modified version so that I could run the test from Rake. For a more official version see http://code.google.com/p/ruby-roger-useful-functions/wiki/DocTest



Esc2

Confessions of the Unix-Deficient

Okay, fine, I'll admit it... When it comes to shell scripting, I don't know my Bash from my Tsch. My command line abilities reached an all time high when I figured out how to pipe lines into 'grep'. I still hold my breath any time I use 'cat' and I say a quick prayer before firing up 'vim'. I must have suffered some head trauma because I can't remember a thing I learned from my 'Unix for Macs' book.

Despite these deficiencies, however, I've still wanted to get into shell scripting for one reason - automation. Rails and Textmate have helped to DRY up my day significantly, but I still waste time and, more importantly, attention on simple, routine tasks. I knew that I wanted my first task to be automating the process of opening up all the programs and windows I need for a project. I wanted to be able to simply type 'fire_up my_project' into iTerm and have it open a tab for the server, a tab for the console and a tab for the project directory. I wanted it to then open the project in TextMate (without the pesky directories like /doc and /log) and then open the site in Firefox.

I knew this was all possible, but how much Unix wizardry was I going to have to learn?

Ruby to the Rescue

Thankfully, it didn't take me long to realize that shell scripts don't have to be written in Bash, they can also be written in Ruby! All it took was a little setup and I was ready to automate.

First, I needed a place to put my new commands. I decided to create a /bin directory in my home directory (ie ~/bin). I then needed to add this to my $PATH by inserting the following at the bottom of my bash_profile (to access this file, use mate ~/.bash_profile in the console).

export PATH="~/bin:$PATH"

Now any file in this directory can be accessed as a command from the command line. I created a file in /bin called 'fire_up' (no file type suffix) and set its permissions to be executable by typing this in the command line:

chmod 755 ~/bin/fire_up

In order to be able to use Ruby in this script, the Ruby shebang needs to be the first line in the script:

#!/usr/bin/env ruby

Once that's in there you can use all the Ruby you want. Arguments passed into the script from the command line are stored in the ARGV array.

Bringing iTerm to Life

Small Print: I should mention that the following solution is only going to work for the iTerm console (pick it up at http://iterm.sourceforge.net/index.shtml), it will not work with Apple's Terminal program.

Though I now had the flexibility and power of Ruby at my disposal, I still wasn't sure how I could use it to control iTerm. After a little poking around, I found that iTerm supports Applescript. Using Applescript I would be able to fully control iTerm's windows, tabs, colors, the works. After a bit of work, I was able to wrap these Applescript commands into an easy to use, fully Ruby library I call TerminalWindow. The class is used like this:

# EXAMPLE - Use the current iTerm window, cd to a project 
# and open in TextMate, launch the server and the console 
# and title them

  TerminalWindow.current do |window|
    window.open_tab :project_dir do |tab|
      tab.write "cd ~/projects/my_project/trunk"
      tab.write "mate ./"
      tab.title = "MyProject Dir"
    end
    window.open_tab :server do |tab|
      tab.write "cd ~/projects/my_project/trunk"
      tab.write "script/server -p 3005"
      tab.title = "MyProject Server"
    end
    window.open_tab :console do |tab|
      tab.write "cd ~/projects/my_project/trunk"
      tab.write "script/console"
      tab.title = "MyProject Console"
    end
  end

Full documentation on the rest of the TerminalWindow functionality is located within the class file.

It's Show Time!

Now with the TerminalWindow library it is a simple task to create an implementation in the fire_up file. Here is my implemenation with instructions on how to customize it to your own liking. To implement, you assign a path, port number and title for each of your projects. When 'fire_up my_project' is run, the script finds the information associated with my_project, uses the TerminalWindow class to launch the needed iTerm windows, launches the project in TextMate with the mate command and launches Firefox with another Applescript command.

So feel free to make your own implementations with the TerminalWindow library, hopefully it will be a valuable tool in removing the routine tasks from your day.

Download TerminalWindow and fire_up now!



Partials_article_image

A Problem with Partials

Partials are incredibly powerful and flexible tools for a Rails developer; they help to DRY up view code, contextualize distinct presentational ideas and modularize markup for use in HTML or Javascript. It's been my experience, however, that each developer seems to use partials in a different way and, while I appreciate the value of personal coding style, these variations can cause confusion between developers.

The following techniques have proven to be 'best partial practices' for my fellow developers and myself. Adhering to these ideas helps us to keep our code consistent, legible and portable.

Keeping Organized

Organization and naming conventions are two initial hurdles in developing effective partials. It is an easy mistake to start arbitrarily organizing and naming partial files without thinking through their roles within the application.

I think that one pitfall is using (or at least over-using) a /views/shared directory for storing partials that will be used by many controllers. I used to use the /shared folder after seeing it used in the prominent Rails books and tutorials, and initially the logic of such a directory makes sense (especially before REST became the norm). That logic breaks down, however, when virtually ALL of your partials exist in that folder! If partials are meant to be reusable and flexible, shouldn't they all be in the shared folder? This is what would happen to me, and suddenly my file names lost a lot of meaning. What does the partial shared/thumbnail show? What about shared/favorite?

Certainly you can simply use more concise naming (user_thumbnail, favorite_video) but I have found that it's best to place these partials in the view folder of the related resource. There's nothing magical about the /shared directory, it's just as easy to use :partial => 'users/thumbnail' as it is to use :partial => 'shared/user_thumbnail'. I find storing the partial in /views/users, /views/videos, etc. helps to clarify the partial's function and keeps my files in order.

Another good practice is utilizing singular and plural naming conventions. In a recent project I was using two partials with poor names: shared/user_block and shared/user_thumb. The user_block partial accepted an array of Users as the :object and passed it on as :collection to the user_thumb partial, placing it all in a wrapper. I found that a name like user_block doesn't help me remember what the partial does - does it display a block of users, or one user in a block? By renaming my partials as users/thumbs and user/thumb, respectively, I was able to clarify their purposes and make it obvious which would display a single thumb versus a collection of them.

One other pitfall is mixing up where wrapper HTML is stored. A sidebar, for example, may have a series of modules that all use a common wrapper and header markup. Some of these modules are stored in their own partials, so should the wrapper markup go inside the partial? Or should that markup stay in the view file and wrap the render method call? Either might be appropriate given any set of circumstances, but the most important thing to remember is to keep it consistent! Placing the wrapper in one partial but leaving it out of another can only lead to confusion down the road.

No Partial is an Island... or is it?

In software development modular design is king. The ability to create portable, flexible and self-sufficient chunks of code significantly helps speed up development and code reuse. So why not apply the same principles to partials? Partials, like any other code, can become much more robust and useful when given good defaults, error handling and documentation.

If a partial were a method then :object, :collection and :locals would be the arguments. Unlike arguments, however, there is no built-in way to ensure that these passed variables are valid or even present. It is simple, however, to mimic this functionality within the RHTML template. For example, the following partial displays a series of thumbnails for recently added videos (the partial name is videos/recent_thumbs):

  <% limit ||= 10 %>
  <% videos = recent_thumbs || Video.find_recent_videos(limit) %>
  <div id="recent_video_thumbs">
    <%= render :partial => 'videos/thumb', :collection => videos %>
  </div>

Default values are supplied for each variable that can be passed in to the render method. The number of videos displayed (limit) can be passed in through the :locals hash, otherwise it defaults to 10. The :object parameter, which reads as recent_thumbs within the partial, will be used if given; otherwise, the partial uses the Video class to find the most recent videos. This partial can be passed some, all or none of those parameters and will still work correctly.

But wait! Isn't this placing application logic in the view?! Isn't this strictly taboo?! Though it may approach that line, I believe this is still clean code. The actual logic is still stored within the Video#find_recent_videos method and this behavior is only the fallback behavior, not the primary functionality. In this situation it works, but that may not always be the case. If a fallback collection would not be available, proper error handling should be used instead:

<% raise ArgumentError, "The videos/recent_thumbs partial requires an array
of Video objects passed as :object." unless recent_thumbs %>

Using these techniques achieves two goals. First, the developers are given more flexibility and less trouble with partials that can 'take care of themselves.' These partials can be easily dropped into a view and rely on defaults that can later be easily overridden. The developers are also given some 'documentation' about how the partial works. It may not be rDoc, but these variable 'declarations' at the top of a partial make it very clear what :locals it takes and whether it takes an :object and/or a :collection.

With a Little Help From My Friends

When passing a collection to a partial, I have often found the "collection_name_counter" variable to be very helpful (ie the thumb_counter in :partial => 'thumb'). This dynamic variable, built-in by Rails, gives the current index within the passed collection. As helpful as that can be, I usually find it to be incomplete without having access to the collection itself. Without the collection array I have no idea if the current index is the last item, the first item or any in between!

For a while I simply passed in the collection both as :collection as well as :locals => {:collection => @collection}. It worked, but it wasn't very DRY. To fix this I created a simple monkey patch module called PartialEnhancer. This hacks the partial code so that you have access to two more dynamic variables. If the partial were named "thumb" the variables would be thumbs and thumbs_count. The thumb_count variable simply stores the length of the collection for comparison with thumb_counter while the thumbs plural variable accesses the collection array directly. It's now very simple to find where a given object is within the overall collection within a partial.

Another partial-related problem struck me when I began working on a project that used a great number of nested partials within nested layouts. Whenever I had to change some view markup it was often very difficult to figure out where that markup was! Which stacked partial, layout or view did it belong to? To help me find my way I created another monkey patch module called PartialExposure. This module hacks the render method so that every layout and partial is wrapped in an HTML comment. Each comment displays the filename and path of each partial file and reveals exactly where it starts and stops. Thanks to that module I can now instantly figure out where display code exists, even on projects that I am not familiar with. Just make sure you only use it in Development!

Download the PartialEnhancer and PartialExposure files.



Mark1

Over time, a developer will reach a point where he or she will need to rethink the time-consuming slow zones in the development process. Often these slow zones are aspects that are overlooked—maybe it is something the developer doesn't enjoy doing each and every time. But with each and every time comes a chance to experiment in the hopes of turning a rocky road into a fast lane.

CSS was once that rocky road for me. Writing line after line, refreshing, and testing just took up a lot of time. As my development skills grew, so did the way I write CSS. As a Rails developer, it is tempting to use tools, Ruby gems or other dynamic alternatives to generate CSS in an unconventional way. Before considering dynamic alternatives, we should first take a second look at our CSS file and see how we can improve.

Lets say for the header we have the following:

div#header {
   width: 800px;
   background: url(/images/header.jpg) no-repeat;
}

div#header h1 {
   font-size: 24px;
   font-family: Arial, sans;
   color: #333333;
}

div#header ul#nav {
   width: 800px;
}

div#header ul#nav li {
   padding: 3px 5px;
   border: 1px #6699FF solid;
}

div#header ul#nav li a {
   color: #000033; 
   text-decoration: none;
}

div#header ul#nav li a:hover {
   text-decoration: underline;
}

Nothing special here; just basic CSS. This way of writing CSS is common, as it is found in most textbooks and tutorials. We start with a selector, then a few style declarations for the element specified in the selector. I had written CSS this way for years, until my stylesheets became huge documents with thousands of lines. There had to be a better way.

So I started experimenting with how I organized my CSS. With a few simple changes, I was able to write CSS much faster, significantly reducing development time—time that was then spent on more important aspects of the application. I started by not writing every declaration on a new line, but instead keeping them on one line like so:

div#header { width: 800px; background: url(/images/header.jpg) no-repeat; }

div#header h1 { font-size: 24px; font-family: Arial, sans; color: #333333; }

div#header ul#nav { width: 800px; }

div#header ul#nav li { padding: 3px 5px; border: 1px #6699FF solid; }

div#header ul#nav li a { color: #000033; text-decoration: none; }

div#header ul#nav li a:hover { text-decoration: underline; }

By not creating a new line for each declaration, I have cut the number of lines in my CSS file by 70 to 80 percent, thus turning a CSS file with over 2500 lines to one with about 500. Keeping our declarations on the same line as the selector is a small step that will only lead to more experimentation.

So now we have a selector with all its declarations on one line, then a new line and so on. If we remove the new line between each selector, it cuts the number of lines in half:

div#header { width: 800px; background: url(/images/header.jpg) no-repeat; }
div#header h1 { font-size: 24px; font-family: Arial, sans; color: #333333; }
div#header ul#nav { width: 800px; }
div#header ul#nav li { padding: 3px 5px; border: 1px #6699FF solid; }
div#header ul#nav li a { color: #000033; text-decoration: none; }
div#header ul#nav li a:hover { text-decoration: underline; }

But removing all the blank lines makes it so hard to read. If we have hundreds of lines, it would be a nightmare for us and other developers to read. So let's line up our declarations to make our selectors easier to find:

div#header                   { width: 800px; background: url(/images/header.jpg) no-repeat; }
div#header h1                { font-size: 24px; font-family: Arial, sans; color: #333333; }
div#header ul#nav            { width: 800px; }
div#header ul#nav li         { padding: 3px 5px; border: 1px #6699FF solid; }
div#header ul#nav li a       { color: #000033; text-decoration: none; }
div#header ul#nav li a:hover { text-decoration: underline; }

Now our selectors are much easier to spot, and the one line code is much easier on the eyes. This experimentation is starting to become interesting. Very interesting. Take a second look at the code we have typed above. There is now a visible pattern with the selectors, and, with patterns, we can read the code much faster, quickly finding the one selector we need. But that's not all! We are also showing inheritance. For example, the ul#nav belongs to div#header. The ul#nav has li elements with links in them as well. With this structure, we don't have to keep switching between our stylesheets and html pages—everything we need to know is in the CSS. Previously, we would have had to scroll back and forth to notice this. But since the selectors look like a staircase, we can easily find the child elements. This gives writing one line CSS a bigger advantage over traditional multiline CSS in terms of organization. But as always, we can take it a step further.

What if we have a selector with many child elements? For example, the selector that ends with a:hover is currently our largest selector. Long selectors will lead to the need to scroll sideways, which we should try to avoid as much as possible. Also, long selectors may make it hard to keep track of which declaration belongs to which selector due to huge gaps of space between the two.

Now let's review our CSS code. Currently all belongs to #header, which is a id and therefore unique. A h1 in #header will be dark gray and using Arial, while elsewhere it wouldn't inherit those styles. There is a nav in #header, which is also unique. So a li with the selector in #header #nav or just #nav will have the same styles. Whereas we were previously too specific with our styles, let's now be less specific by starting our selectors with a common parent.

div#header        { width: 800px; background: url(/images/header.jpg) no-repeat; }
div#header h1     { font-size: 24px; font-family: Arial, sans; color: #333333; }
ul#nav            { width: 800px; }
ul#nav li         { padding: 3px 5px; border: 1px #6699FF solid; }
ul#nav li a       { color: #000033; text-decoration: none; }
ul#nav li a:hover { text-decoration: underline; }

There is now a smaller gap, making our selectors and declarations easy to follow, but we lose the pattern and visible inheritance. To fix this, let's add a new line between the #header and ul#nav. Let's also re-adjust the space between the selectors and declarations to the longest selector accordingly.

div#header    { width: 800px; background: url(/images/header.jpg) no-repeat; } 
div#header h1 { font-size: 24px; font-family: Arial, sans; color: #333333; } 

ul#nav            { width: 800px; } 
ul#nav li         { padding: 3px 5px; border: 1px #6699FF solid; } 
ul#nav li a       { color: #000033; text-decoration: none; } 
ul#nav li a:hover { text-decoration: underline; }

Great! Now our code is organized into chunks by the common parent, which increases the visible organization of our code. Just by reading the very first item in the selector, we know that everything in the chunk belongs to that parent. For example, the first chunk styles everything relating to #header and in the second chunk, all styles relate to #nav. Once again, if this was multiline we would have to scroll up and down to find this information, while with one line, if we wanted to style the #nav, we would just skip the whole #header chunk.

The one line CSS method came about after many years of writing CSS. For me, it has greatly increased the speed of which I write and edit CSS because of the visible grouping and visible inheritance. The method described here isn't right or wrong by any means, and it may not be ideal for everyone. At the end of the day, writing one-line or multi-line CSS is a matter of personal preference—since they both will render the same to the end user. Writing one-line css is a example I wanted to share on how the simplest code reorganization can lead to faster and more efficient development. Next time there is a slow zone in your development process, I highly recommend to give your code a second look and experiment with it's organization, the smallest steps can travel the farthest.



Cache

Just want to skip to the good stuff? Check out our new ERB Caching technique now!

I've always had a love/hate relationship with Rails caching. The guys on the Rails team have supplied us with several tools for the job and have taken most of the pain out of it. Between page caching, action caching and fragment caching, you usually can find a method that will suit your application.

Easy as it may be, however, these caching techniques do come at a cost. The more caching you use,the more control you lose over your site and your user experience. These tradeoffs have proventhe most significant when developing social networking sites, where high traffic demands efficient caching but the need for user personalization demands constant fresh content.

So which do you use? Here are the pros and cons of the existing Rails caching methods, plus a brand new technique we are using at Killswitch we call ERB Caching.

Page Caching (The Unattainable Ideal)

From the perspective of performance and speed, nothing can beat the rewards of page caching. When rendering a page, Rails saves the generated markup as HTML into the /public folder. From that point on, subsequent requests for the same URL will be served by Apache, leaving Rails completely out of the process. This takes tremendous strain off of Rails and allows a single server to handle significant traffic. Even if the cached pages' time to live (ttl) is only a few minutes, the performance savings are fantastic.

Using page caching has worked well for us on some of our large scale projects. For one such project, we used the Akamai service to handle requests for cached pages, taking even more load off of our server. With this setup, a single server with only a few mongrel instances has been able to easily serve thousands ofunique visitors daily on a high profile, media-intensive site.

As ideal as this is, using page caching becomes an impossibility if you want any kind of personalization on your site (and you probably do). Since Rails is left out of the equation and Apache is serving static HTML files, it's nearly impossible to include any personalized content on the site (except for using Javascript trickery, of course). This is why page caching is used infrequently in the industry as users demand personalized, community oriented experiences.

Action Caching (Close, But Not Quite)

For more flexibility (and fewer performance gains) Rails supplies action caching. This feature is similar to page caching in that the entire output page is still cached. This time, however, Rails is in charge of serving thefile. This means that you can use before/after filters and sessions to determine what to send to the user. For example, you can send one page if the user is a logged in member, another if they are not.

With this additional layer of control, this technique is more applicable to community-driven apps. However, simple things like putting the logged-in user's name at the top of the page is still difficult/impossible, since all logged in users would be served the same cached page.

Many of the deficiencies of this method were fixed by the action_caching plugin (http://blog.craz8.com/action-cache-plugin/), which allows for conditional caching, control over cache storage options and more. The functionality of action caching has also been significantly extended with our creation of ERB Caching, described below, which uses action caching as its foundation. More on that coming up in a few paragraphs...

Fragment Caching (It Works, But Still...)

Fragment caching has become the standard caching mechanism of large, dynamic, user-driven sites. It gives you all the flexibility you need, though the performance savings aren't much compared to those of page and actioncaching. This method allows you to mix generated content with chunks of the view that are cached and then reassembled on every render.

Using fragment caching helps speed up page renders, reduces database queries and is definitely better than using no caching at all! Still, I couldn't help feeling like there must be a better way. Working on social networking sites that could almost use action caching became frustrating - I wanted the benefits of fully cached pages and was tired of working with views littered with <% cache ... %> fragment caching code.

With that goal in mind, the idea for ERB Caching was developed.

ERB Caching (Finally, the Best of Both Worlds!)

I always had a sense that action caching was more powerful than it let on. You get the control and power of Rails, but still are given the performance benefits of caching the entire page.

My specific challenge was building a social networking site where every page on the site would have extra user-centric modules on it if the user was logged in. The modules are fairly simple, just some links and buttons that would initialize user actions. Still, their creation was dependent on knowing whether the user was logged in and knowing who they were.

The solution was to actually store ERB code in the cached views. The cache file is loaded into Rails, after which the ERB Caching code does a quick parsing to render any remaining ERB. The final file is then sent to the user, fresh and personalized.

Here's an arbitrary example:

In main_controller.rb:

before_filter :setup_vars
caches_action :index

def index
  @message = "Hello from index!"
end

def setup_vars
  @message = "Hello from before_filter!"
end

In index.rhtml:

<p>This time will get cached and be the same on every page view: <%= Time.now %><p>
<p>This time, however, will update on every page view: <%%= Time.now %><p>
<p>The message set in the controller is: <%%= @message %><p>

When this view is first rendered, any ERB tags with two percent signs will not be rendered, but simply replaced by single percent signs. This is what the contents of the cache file will then look like:

<p>This time will get cached and be the same on every page view: Fri Feb 08 14:43:54 -0600 2008<p>
<p>This time, however, will update on every page view: <%= Time.now %><p>
<p>The message set in the controller is: <%= @message %><p>

The trick is then to render this a second time in an after_filter. Any variables set in a before filter will be available in this second rendering.

This is what the first page render produces:

<p>This time will get cached and be the same on every page view: Fri Feb 08 14:43:54 -0600 2008<p>
<p>This time, however, will update on every page view: Fri Feb 08 14:43:54 -0600 2008<p>
<p>The message set in the controller is: Hello from index!<p>

... and the second page view produces:

<p>This time will get cached and be the same on every page view: Fri Feb 08 14:43:54 -0600 2008<p>
<p>This time, however, will update on every page view: Fri Feb 08 14:47:17 -0600 2008<p>
<p>The message set in the controller is: Hello from before_filter!<p>

As you can see, any "double" ERB tag that is in a view will be cached as a single ERB tag and then rendered freshly on every request. This becomes very useful when you want to cache whole pages, but also want to have the current user's name displayed on the page. Simply set @user in a before_filter and then use <%%= @user.name %> in your view.

The code required to make this work is surprisingly simple and is all included in the erb_cache.rb file. Just place the file in /lib and put require 'erb_cache' in your environment.rb file. You will also have to put ActionController::Base.perform_caching = true in environment.rb if you want to test this out in development.

Also, don't forget to get the ActionCache plugin, it provides some excellent features.

This is still under development, so if you have any trouble with it, please let us know!

Download the ERB Caching File



Print1

I’ve always had a bit of a love affair with books and magazines. The dog-eared pages, the smell of the ink, the crack of the spine – like receiving a handwritten letter in the mail, it’s a tactile experience that is satisfying in terms of its rarity in our digital world. As a designer, I am never ashamed to judge a book by its cover, and I delight in the visual details, typographic and otherwise. But is print becoming an anomaly, or in the frightening words of The Simpsons, is the medium dying?

More and more often, people are turning to the web for information. Newspaper circulation is declining, and blogs are becoming the go-to avenue for unedited, collective conversation. The web has the power to reach the masses, fluidly and flexibly, via searchable and linkable content, and slick, experiential interfaces. In this media-rich world, where we are bombarded with images in an aggressive, almost subliminal way, the internet seems the only medium that can keep up. We seem to be refusing to settle for anything less than constant On-Demand content, where the dissemination of information is free and democratic.

But all this is not news. What is changing, however, is that larger companies have started to forego more traditional avenues in favor of the broad outreach of the internet. A project we just completed for an architecture firm, a flash New Years greeting, reached thousands of clients and contacts around the world in a matter of seconds. Flexible in its delivery, and dramatic in design, the digital card was a perfect solution for a company that prides itself in green practices. Large and small companies alike have an increasing need for a variety of avenues to reach their target audience, and “going digital” can help them reach a new demographic. Likewise, some magazines (like the recently-retired Punk Planet, and teen ‘zines ElleGirl and Teen People) have made the switch from print to digital (either by choice or necessity), allowing for a constant influx of user-driven content, and a cost-effective approach to visual communication. Sites like Craigslist have rendered the Classified section of the newspaper useless, as the up-to-the-minute content of the online portal can’t be challenged.

In the ever-changing digital realm, however, content is disposable. While a beautiful book, or a screenprinted poster, or a letterpressed card may remain in your office indefinitely, as items of contemplation or “objets d'art,” digital content dies quickly and absolutely. This isn’t necessarily a bad thing. The web’s ethereal and expendable qualities force us to constantly evolve, to consistently revisit our intentions and to design for lasting impact.

I will always, unwaveringly, be a die-hard print addict. There’s just nothing like coherent, well-edited, beautiful print pieces, where the grid is king, typography is queen, and CMYK is the official language. I will often advocate print collateral over web-based material – the physical and portable benefits of print (and our visceral reaction to it) are too important– but I may have selfish motives. It’s a YouTube world now (or maybe it's a *shameless plug alert* Jackass World), and the limitless reach of the internet is too exciting to write off. Our time is becoming more and more valuable as the world changes rapidly around us, and it’s our responsibility as members of the creative and technical communities to be at the forefront of this evolution. And, for the purposes of full disclosure, I get my news online. C’est la vie.



Colin_blog2

Installing and configuring the Globalize plugin can be difficult, but it usually goes easily if you follow the instructions. There's nothing I can say about that that's not thoroughly covered elsewhere. Adapting your coding style to use it is almost as easy as advertised.

But once you have it up and running there are a lot of subtle things that can still give you headaches down the line. For many of our international sites, the workflow is this:

  • The client goes back and forth on designs, and we make a prototype like usual.
  • Before getting started, we installed the Globalize plugin. Once we have the site roughed out and the design is approved, Globalize has automatically generated a list of the unique phrases in our app. (You might want to clear the translations table and re-test every page so your list doesn't include obsolete or phased out phrases).
  • Then we hand the list to our client, who sends it to the team of translators, who send it back to us, and we slurp it into the database with a simple script (just loop through the languages and Locale.set, then Locale.set_translation)

That's technically all you need to do to globalize your app. But, if you want your application to be as scalable as possible—or you'd like to keep your developers from pulling their hair out—here are some tips.

  • If at all possible, never translate phrases over 256 characters. If you do, you'll have to change globalize_translations.tr_key and and globalize_translations.text to a "text" field instead of a "string" (or varchar). That will work just fine, but, if you can avoid having to do that, it will really pay off to be able to add an index to tr_key and language_id.
  • Make sure your validation messages are each translated individually, not en-masse in your view, or your translators will have extra work. That is, you want to avoid adding this to your translations table: "Errors: Name cannot be blank. Email address is not valid.", and instead have several seperate rows like this: "Errors:", "Name cannot be blank", "Email address is not valid" and so forth.
  • You may have to turn off view caching in your environments/production.rb if you're running a mongrel cluster, or you might get spontaneous, random language changes as your users navigate the site! (change config.action_controller.perform_caching and config.cache_classes to "false")
  • Don't stress too much about translating the word "Browse..." or "Choose File" on your file upload buttons- you can't change that! That's controlled by the user's browser, and it probably looks fine to them already.
  • Lastly, here's a handy query for generating statistics on how many translations you've added to the system for each language:
SELECT english_name, COUNT(*) num_phrases 
FROM globalize_languages gl LEFT JOIN globalize_translations gt ON gl.id = gt.language_id
GROUP BY english_name ORDER BY english_name
  • And this rake task will generate a spreadsheet-checklist of phrases that still require translation.
    translation_checklist.rake
    Copy it to your lib/tasks folder, and run it to, in this case, make a pipe-delimited checklist, without a column for "English".
rake skip_languages=English delimiter="|" db:translation_checklist > whatever_file.csv



A

While identifying a problem, I always keep the A.C.E model in mind. A.C.E stands for Assess, Contain, Eliminate. Let me explain how the A.C.E model works as a trouble-shooting tool for development testing, after the launch of a website.

A. Assess. Trace the site or application activity from the launch date to the day the problem first occurred. Use any original or back-up data that you have on hand and compare it to the client copy. If there is something that was added or taken out, find out why. It could be a simple solution if the problem stems from something environmental or technical. Find out if there have been any changes (major or minor) in the client’s capacity to host the site or application (i.e. switched hosting companies, bought a new server, etc.).

Also look for any irregularities or errors that would not have come up during testing—things like too many user requests (a common issue in commercial sites or sites for huge corporations). Let the client know that an application or site designed to handle 10,000 unique visitors may have trouble handling hundreds of thousands, since the requests to view and use the site will lead to denial of service.

It is prudent to look at the type of hardware in use to narrow down any problems before and after the launch. We test using the minimal requirements of a site, knowing that if it works using moderate to contemporary equipment, it will work with cutting edge server equipment. Once the problem has been assessed and identified, we move to the next stage.

C. Containment. Whether it’s a small programming bug or a major error, it is the responsibility of the tester to be candid to the client about the extent of the situation. There are numerous factors as to why the bug got past the testing phase, such as not enough testing time, launch was pushed ahead of schedule, or the like. But the fact of the matter is the problem exists, and it has to be dealt with.

A tester would be able to contain the problem and anticipate if the solution could accidentally cause another issue. In this case, the best course of action would be to not take the application or site offline, but to limit outside access to the resource. It wouldn’t make any sense to continue to grant access to something that, in the user’s mind, does not work.

At worst, the application or site would have to limit user access for a few days until everything is corrected and functional. It is in the client’s best interest to welcome user feedback, as this feedback could improve client interaction. Now that there is an understanding of the expectations and requirements of the client, this knowledge can be applied to the next project.

E. Elimination of issues can take many forms but the results are always the same: resolution of outstanding issues and client satisfaction. No matter what the cause, it is important to learn from the recent crisis (and believe me, to the client, it was a crisis). For the next project, the professional will remember the causes of the issue and can take a different approach. In turn, the client can plan ahead and adjust for extra testing and leeway in case of delays.

The goal of research and the A.C.E model is to make sure that anything we do as professionals is up to the standards of our clients. Anyone with the right training can make an application or website and make it look pretty. But a professional will take into account the client’s individual needs, user expectation, and the scalability of the end product.

This methodology and practice, as outlined above, has obvious benefits, such as limiting usage while testing and Q&A occurs, as well as setting client expectations for deployments and quality control throughout a project, as well as during those critical days after launch. The world of software, like many other technical fields, present its own core list of challenges and we aim to achieve the highest level of stability and consistency for the websites we build.