Error: I'm afraid this is the first I've heard of a "rss;>different" flavoured Blosxom. Try dropping the "/+rss;>different" bit from the end of the URL.

Fri, 14 Nov 2008

Duncan Prints

I've long been a fan of James Duncan Davidson's photography. He's probably best known for his exceptional work as the official shooter at O'Reilly software conferences. You may not see him, but he's always there. Indeed, Duncan is the lens through which many of us have truly seen the emotion of a keynote speaker or the excitement of an attendee. But what I admire most about Duncan is his versatility. He can capture amazing photos in the worst possible indoor lighting conditions all day, and then snap a gorgeous nature scene on his road trip home. He makes it look so easy. If only he knew how much he's cost me in camera gear. :-)

Earlier this year, Duncan started selling some of his non-conference prints online. I had already fallen in love with a couple of the photos he chose, and I was thrilled by the prospect of owning a print copy. But I must admit, I've never ordered print photography online, and frankly I was hesitant to try it. Part of my hesitation was just the unknown process of going from a digital image I bought online to a print copy hanging on my wall. And I was also a bit worried that some degree of quality might be sacrificed along the way. After all, when you buy art, you're making an investment.

I'm extremely happy to report that I'm now the proud owner of two Duncan prints. The process was super easy and the quality is absolutely amazing! Rather than tell you how it all works, I thought I'd show you.

First, you go to the Zenfolio storefront and pick your favorite Duncan photos. This is art; you get to pick the photos that speak to you.

Duncan Prints

If you've followed Duncan's road trips over the last few years, you'll recognize many of these shots. There's a story behind every picture. Duncan has told some of the stories in his blog. I would encourage you to find the story behind the picture you like, perhaps the next time you see Duncan at a conference. Knowing the photographer and hearing his story makes the photo more valuable to you.

The second decision you need to make is the size of each print you picked:

Duncan Prints

The size you choose might be as simple as the size of your wall or the size of your budget. Remember that this is the print size, and does not account for framing. In general, a frame will add 3-4" to each side of a print. In my case, I used a tape measure to estimate which size fit on my office wall with plenty of room to breathe. I ended up selecting one 16" x 24" print and one 12" x 18" print (displayed below).

Once you've picked prints and sizes, the checkout process is super easy (and does not require an account):

Duncan Prints

A couple days later, your prints show up on your doorstep:

Duncan Prints

I ordered on a Tuesday and the prints arrived on Friday. For some reason I expected the shipping to be expensive, and was surprised that USPS Priority Mail was only $5.45. (FedEx Next Day was also available for $10.25.) Although you order the prints through Zenfolio, they use Mpix as their print and fulfillment partner:

Duncan Prints

This single box contained both of my prints in a rigid cardboard structure:

Duncan Prints

I was very impressed with the care in which the prints were packaged and shipped. Inside the box, each picture is lightly affixed to a cardboard backing and carefully wrapped in a plastic sleeve:

Duncan Prints

The prints themselves are absolutely gorgeous!

Duncan Prints

Seriously, Duncan is meticulous when it comes to print color correction. These images don't do it justice. My jaw dropped when I first saw this print, and I'm still amazed every day when I look at it.

Once you've received your prints, you'll want to get them framed and matted. Now, I'm certainly no pro at this. And thankfully you don't have to be either. I just left my prints unframed for a few days to enjoy their natural color. Then I took the prints to a local frame shop and asked the friendly gal: "If these were your prints, how would you frame and mat them?" She seemed to appreciate that I asked for her advice. And after taking in the prints for a few minutes, she drew my attention to the subtle colors. Then she recommended a few framing and matting combos that would complement the colors and frame each print nicely. Of course, I'd been thinking about ideas too, so we went through a couple iterations. I ended up framing both prints for around $200 (thanks in part to a sale at the frame shop). It was actually a lot of fun!

To give you some perspective on the sizes, here's the 16" x 24" print:

Duncan Prints

And here's the 12" x 18" print:

Duncan Prints

I haven't quite decided where to hang each one yet. When I placed the order I thought I knew where they would go, but I'm so happy with how they turned out that now I can't commit to just one place. :-)

I hope seeing these pictures fills in some of the unknowns you might have about ordering Duncan's prints online. He's really done a fantastic job making these prints easily accessible while at the same time staying true to the quality of his work. If you like Duncan's photography, this is a great way to support his work!

#

Thu, 02 Oct 2008

Free Brain Food

I'm excited to see Bill Dudney's iPhone screencasts, and the definitive iPhone book, finally see the light of day!

Here's a little secret: On the screencast page you'll find a link to a 20-minute "Getting Started with Xcode and Interface Builder" screencast that's absolutely free. In that screencast, Bill shows you how to build the simplest of iPhone apps (a Hello World app). More important, he shows you how it works—from main triggering Nib files being loaded, to wiring up interface controls, and all the way through a button push running code that you write.

You won't learn everything (that's what the rest of the series is about), but the freebie screencast is a great way to get started. You can follow along and have a basic iPhone app running in just a couple minutes. Fun stuff!

#

Thu, 18 Sep 2008

Cocoa Quick Start

I've been gearing up for some client work using Cocoa, and along the way I had the pleasure of being a tech reviewer for Daniel Steinberg's latest book Cocoa Programming: A Quick-Start Guide for Developers. I don't often review books here, but this book is exceptional. I think it has the potential to help folks who are interested in building native Mac (and iPhone) applications finally break into Cocoa development. The book was just released as a beta. Here's a rundown of what's inside and how it's been helpful to me.

After getting a quick lay of the land in the first chapter, Chapter 2 jumps right into building a simple web browser in Cocoa. That sounds fairly complicated for your first Cocoa app. I remember bracing for the unavoidable moment when I'd have to copy in a bunch of code I didn't understand. Thankfully, it's not that kind of book.

What I like most about this book is that it makes learning Cocoa fun and accessible. At the same time, I never felt like Daniel was waving his hands or dumbing anything down. He respected that I was a programmer, but didn't take advantage of that by making me wade through unfamiliar code to get to the good stuff. After all, a simple web browser in Cocoa is just a text field, a web view, and two buttons to navigate forward and back. You can lay out and wire up those components to act like a browser using Interface Builder without writing a single line of code. That's what the second chapter is all about: getting visual early! When I'm learning a new set of tools, I like to focus on one thing at a time. In this case, I was introduced to Interface Builder without having to tackle Objective-C, and I chalked up a quick win.

Of course, you'll need to write some code to make your web browser different from all the others. But again, you really don't want to stop and learn the entire Objective-C language just to add a new feature to the web browser. Chapter 3 is a gentle introduction to sending messages in Objective-C. If you've never seen the selector syntax, it can be a little awkward at first. The best way I've found to learn how it works is to start sending messages to existing Cocoa libraries. It turns out you can practice this in Interface Builder too. By the end of Chapter 3 my web browser and I were a little smarter.

Once you're comfortable with sending messages to existing objects, you're ready to create some Objective-C classes and objects of your own. Interface Builder can only do so much. Chapter 4 is where the rubber meets the road. Daniel walks you through creating a controller and how to make connections with Interface Builder through actions and outlets. I really like how he starts with a controller that's just a middleman, then incrementally expands its responsibility. It doesn't take a lot of Objective-C code, but it was just enough to make me feel comfortable creating classes with methods and instance variables. Daniel kept building up my confidence, one step at a time. And doing the exercises in each chapter kept me engaged.

Sending messages to a controller is one way to respond to user actions, but it's only part of the picture. In most Cocoa applications there's lot of stuff happening behind the scenes, too. The Cocoa frameworks can call back into your application via delegate methods and send notifications when certain things happen. Chapter 5 shows you how to use delegates and notifications to update the browser's title bar when a page finishes loading and update a progress bar as it's loading. Again, the process of building an application is driving what you need to learn, and when. That's exactly the way I like to new learn things.

At this point in the book I'm feeling pretty good about myself, and I'm really enjoying learning something new. I'm also surprised to find myself liking Objective-C. But I know that Daniel has been kindly delaying the topic of memory management until it's necessary, and it's been a few years since I've had to clean up after myself. The Cocoa event loop does a lot of this for you, and Objective-C 2.0 includes a garbage collector, but Cocoa applications often need to take more direct control (and iPhone apps always do). Chapter 6 steps away from the web browser to show you how to create objects with properties, and how to make them good stewards of memory. I suspect everyone has a slightly different mental model for understanding the retain-release cycle. This chapter was the first explanation of Objective-C memory management that really worked for me.

As this book is currently in beta, it's not yet complete. I'm very much looking forward to Daniel's new chapters as they come. That said, this beta book has already given me everything I need to start building my own Cocoa applications. And that's really the point. It's designed to get you up and running quickly, and help you through the first couple weeks of moving to Cocoa. To that end, I think Cocoa Programming: A Quick-Start Guide for Developers is simply brilliant!

#

Thu, 04 Sep 2008

Learn Cocoa With Me

One of the perks of running a training outfit is I get to pick the topics that I want to learn better and the instructors I'd want to teach me. (Ok, the abundant snacks are perks too, but everybody gets those.) Why Cocoa? Well, it's a lot of fun to learn. And Mac OS X applications are cool. Oh, and you need to know Cocoa and the Mac development tool chain to create iPhone applications. Need I say more? :-)

Seriously, building GUI applications with Cocoa is a lot of fun. And you absolutely must know Objective-C and Cocoa to build iPhone applications. But there's a fairly steep learning curve to the platform. You're up against a new language, a new set of libraries, a new IDE, and perhaps even a new development style. Heck, I've been fiddling around with Xcode and Interface Builder for years, and I must admit that I still don't fully "get it". What would really seal the deal is to spend a few days with a couple experts and have them show me how they build Mac applications. And that kind of interaction is exactly what a Studio is all about!

So I'm excited to announce our new Cocoa Studio in Denver, CO on October 28-30. I believe this three-day course is the best way to get a jump start on building GUI applications on the Mac (or the iPhone). You better believe I'll be a student in this one. Check out the outline and sweet venue for more details.

Who's teaching it? I couldn't be happier with the instructors we landed. You'll learn directly from two seasoned Cocoa developers and authors. Daniel Steinberg and Bill Dudney really know their stuff, and they're excited to help you become a Mac OS X developer. They both have programming backgrounds in Objective-C and Cocoa, a few books and screencasts underway, and even a couple commercial applications. Equally important, they're experienced teachers and trainers with great personalities. I'm really looking forward to seeing them in action as co-teachers.

So if you're planning to build GUI applications on the Mac (or the iPhone), this Studio is for you. Register by September 28th to reserve your seat and save $300. And if you've attended any of our other courses, you'll save another $300 on top of that. Either way, it's gonna be a lot of fun.

I hope to see you there!

#

Wed, 06 Aug 2008

Building Static Websites with Webby

Let's suppose that last week your long-lost cousin Bubba called to see if you'd design the website for his new bait and tackle shop. (Hey, he's a progressive redneck.) You figured it would be a quick and easy job—he just needed a few "purty pages to git my new bidness on the World Wide Web." So you hacked together a couple static HTML pages with pictures of Bubba and his charming bait, and uploaded them to his GoDaddy account. Bubba was pleased as punch. You reckoned (hoped) you'd never hear from him again.

But it turns out Bubba was just getting started. Once he saw those first pages light up, the ideas started flowing like tobacco to a spittoon. Then he asked for new pages for all sorts of stuff: a mission statement, a series of tips on how to fish like a pro, the GPS coordinates of his favorite fishing holes, and so on.

Now you're in a pickle. The site was only supposed to have a couple pages, and so you played the ol' copy/paste trick on the header, footer, and sidebar. With all these new pages coming down the pike, you need to DRY things up in a hurry.

Being a Rails programmer, the first thing that comes to mind is layouts, helpers, and partials. But let's face it, managing a full Rails application is overkill for this job. (Bubba's not that progressive.) Instead, you'd prefer to simply use a familiar layout, helper, and partial style for now with the option of easily migrating to Rails later, if necessary.

Hello, Webby!

Webby (created by Tim Pease) takes text files written in your favorite markup language, combines them with layouts, helpers, and partials, and generates HTML files. You upload these HTML files to your web server and away you go. Simply put, Webby makes it easy to build static websites without duplication.

1. Install It

Webby is a Ruby gem, which means even Bubba could handle the install.

$ gem install webby

Don't be too alarmed by all the other gems Webby relies on to get its job done. All the dependent gems are mostly common stuff.

You can also check out Webby on GitHub.

2. Build the Default Website

To build our website with Webby, the files need to live in a directory structure that Webby understands. (Hey, Webby has opinions, too.) There's not much to it, and the webby generator creates everything for us.

$ webby bubbas_bait

That creates a bubbas_bait directory with a Rakefile and several directories:

Rakefile
content/
layouts/
lib/
output/
tasks/
templates/

We'll look at each of these directories as we go. For now, let's just pull the trigger and see what happens.

$ cd bubbas_bait
$ rake

Running the default Rake task creates a bunch of files in the output directory, including an index.html file. Where did that file come from? Well, it's pretty simple.

When we run rake to "build" the site, Webby copies the files in the content directory to the output directory. Some files, such as images, are copied verbatim into the output directory. Nothing too tricky there. However, the content directory can also contain special files (called pages) that include a snippet of meta-data at the top. These pages are first "compiled" into HTML files (using our favorite markup language) and then copied into the output directory. In this case, Webby transformed the default content/index.txt file into the output/index.html file. (It also copied the Blueprint CSS framework and the S5 presentation CSS into the output directory.)

If you want to clear out the output directory and build the site from scratch, use

$ rake rebuild

If we now open the output/index.html file in our browser, we see the default page for our website. So far, so good.

3. Make a Page, Any Page

Before we dive into converting Bubba's existing HTML files into Webby-managed files, let's start by creating a new page for his mission statement.

$ rake create:page mission_statement

That creates a mission_statement.txt file in the content directory, and opens the file in our default text editor. After changing the default text to include Bubba's mission statement, the file looks like this:

---
title: Mission Statement
filter:
  - erb
  - textile
---
h1(title). <%= h(@page.title) %>

To sell world-class bait by the pound, and have fun doing it!

The YAML-formatted text at the top between the dashed lines is the meta-data for the page. All the text after the meta-data section is content that gets rendered into the resulting HTML file.

The meta-data section is simple, yet powerful. First, it contains page attributes such as title in this example. We can add arbitrary page attributes to the meta-data section and reference their values in the page using the @page.attribute notation within an ERB expression. In this case, we use @page.title to add the page title to the top of the page.

The meta-data section also contains instructions that tell Webby how to process the page. For example, the way a page is generated hinges on the filter attribute. It lists the filters that need to be applied to the page's contents in order to transform it into an HTML file in the output directory. In this case, the ERB and Textile filters will be run, in that order. We need the erb filter so that the stuff between the <% and %> (the ERB expression) will get evaluated. And since our page content is in the Textile format, we need the textile filter to transform the page into HTML. If instead we wanted to use raw HTML, which we'll use from here on, we'd simply remove the textile filter. Other filter options include markdown, haml, outline, basepath, and tidy. (See, Webby isn't that opinionated.)

Having changed a page, if we rebuild the site, only those pages that have been modified are copied to the output directory.

$ rake
[13:43:04]  INFO: creating output/mission_statement.html
4. Autobuild and Serve It Up

Now let's say we make another change to the content/mission_statement.txt file. To have a look at the final HTML file, we'd need to run the rake command to rebuild the site and open the resulting HTML file in our browser. That's sorta tedious. Thankfully, we can tighten up the feedback loop with Webby's autobuild feature.

 $ rake autobuild

The autobuild task starts a build loop that keeps the output directory up to date as files change. Whenever a page is created or updated, its corresponding HTML file is automatically generated in the output directory. Better yet, the autobuild task serves up the files in the output directory on port 4331 using Heel , a small static web server built using Rack and Thin. That way we can immediately see changes reflected in our browser.

5. Frame It With a Layout

Next we need to put everything that's common to all the pages—the header, footer, sidebar, etc.—in one file and let Webby combine it with the contents of each page to produce the HTML file. That is, each page file should contain only the information for that page and no more.

To do that, we update the layouts/default.rhtml file to include our site's layout. Here's an example layout file:

---
extension: html
filter:    erb
---
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title><%= @page.title %></title>
  <link rel="stylesheet" type="text/css" href="/css/site.css" />
</head>
<body>
  <div id="header">
    Bubba's Bait and Tackle Shop
  </div>
  <div id="content">
    <%= @content %>
  </div>
  <div id="sidebar">
    Side Dishes
  </div>
  <div id="footer">
    Copyright <%= Time.now.strftime('%Y') %> Bubba's Bait Shop. 
    Steal it, and we'll hunt you down!
  </div>
</body>
</html>

Notice that the layout file contains meta-data just like regular page files. In this case, we're using raw HTML rather than Textile, so we only need the erb filter. The extension attribute specifies the filename extension that will be appended to every file this layout generates.

The layout file's job is to wrap the page-specific content in a consistent layout. The content of each page is accessible in the layout via the @content variable. So, we simply add the <%= @content %> line where we want the page content to show up in the layout. In addition to the @content variable, the layout also has access to all the attributes of the current page being rendered via the @page variable. For example, we're using @page.title to set the page title in the HTML header.

By default, the layouts/default.rhtml will be used as the layout file. However, if we need to generate a certain page with a specific layout, we can explicitly set the layout file for any page using the layout page attribute. For example, perhaps the mission statement page should have a more corporate feel to it. To change the layout, the mission_statement.txt page's meta-data would look something like this:

---
title: Mission Statement
layout: corporate
filter:
  - erb
  - textile
---

This assumes we have a layout file called _corporate.rhtml in the layouts directory.

6. Summons a Helper

Bubba likes to show off by quoting the weight of fish landed by his aromatic bait. These weights are listed on various pages around the site. We need the weights to be formatted consistently. Specifically, the weights get reported in ounces, but should be displayed in pounds and ounces.

Rather than inline the code for the weight conversion in several pages, we can write a helper method and call it from any page. To do that, we create a weight_helper.rb file, for example, in the lib directory. Just like in Rails, a helper in Webby is a Ruby method in a module.

module WeightHelper
  def format_weight(weight_in_ounces)
    lbs, ounces = weight_in_ounces.divmod(16)
    sprintf("%d lbs, %d ounces", lbs, ounces)
  end
end

Webby::Helpers.register(WeightHelper)

Unlike Rails, helpers must be explicitly registered as we did on the last line.

Then, wherever we need to display a weight on a page, we call the helper method in an ERB expression like this:

<%= format_weight(70) %>

Pretty cool.

7. Paginate A Gogo

Remember that series of pro fishing tips that Bubba wrote? To let the drama build, we can use pagination to spread them across multiple pages. Let's assume that the individual tip pages are in a directory called tips in the content directory. First we create a top-level tips page:

$ rake create:page tips

We want the contents of the tips.txt page to display the individual tip pages ten at a time in reverse chronological order. To do that, we can use the @pages.find method to fetch all the pages inside the tips directory and sort them. Then we pass the collection of pages, and the number of tips per page, to the paginate method. Here's the full tips.txt file:

---
title: Pro Fishing Tips
filter:
  - erb
  - textile
---

<h1><%= h(@page.title) %></h1>

<%
  tips = @pages.find(:all, 
                     :in_directory => "tips",
                     :recursive    => true,
                     :sort_by      => "mtime",
                     :reverse      => true)
  paginate(tips, 10) do |page|
%>
  <div class="tips">
    <%= render(page) %>
  </div>
<% end %>

<%= link_to("Prev", @pager.prev) if @pager.prev? %>
<%= link_to("Next", @pager.next) if @pager.next? %>

The paginate method hands each tip page to the block where we simply render the page within a styled div. Finally, at the bottom of the page, we use the link_to method to generate the pagination links. The @pager object was created when we called the paginate method. It has methods including prev and next to navigate the pages.

8. Reuse Snippets with Partials

Let's say we end up including pagination on a couple more pages. Along the way we add page numbers and tart up the style of the pagination links. Instead of duplicating the pagination links on each page, we'd like to encapsulate the pagination links in one file and reuse it on all the pages that have pagination. That's where partials come in handy.

First we create the partial file:

$ rake create:partial pagination

That generates a content/_pagination.txt file. (Note that partial filenames begin with an underscore and they aren't copied to the output directory.) Inside the partial file, we add the HTML that generates the pagination links:

---
filter: erb
---
<div id="pagination" class="rounded">
  <strong><%= name %> Pages</strong>:
  <%= link_to("Prev", @pager.prev) if @pager.prev? %>
  <% 1.upto(@pager.number_of_pages) do |page_num| %>
    <% if @pager.number == page_num %>
      <%= page_num %>
    <% else %>
      <%= link_to(page_num, @pager.page(page_num).url) %>
    <% end %>
  <% end %>
  <%= link_to("Next", @pager.next) if @pager.next? %>
</div>

Then we use the render method at the bottom of our content/tips.txt page, for example, to include the partial into the page.

<%= render(:partial => "pagination", :locals => {:name => 'Tip'}) %>

Looking back at the _pagination.txt file, we see two variables: @pager and name. Remember that the @pager object was accessible in the original content/tips.txt page, so it's accessible in this partial as well. We use the @pager object here to generate navigation links and display page numbers. The name variable is accessible because we added it to the locals hash when calling the partial. We use it to change the text that appears next to the pagination links.

If you're a Rails programmer, you'll notice that the partial syntax is exactly the same.

9. Generate Stylesheets, Too!

So far we've only used Webby to generate HTML files, but in fact Webby can transform any kind of text into something else. For example, let's say we have our site's stylesheet in the content/css/site.css file. When we build the site, Webby will simply copy it over to the output/css/site.css file. However, if we add meta-data to the top of the stylesheet file, Webby will transform it for us.

What's this good for? Well, do you ever get tired of typing (and remembering) those hex color codes in your CSS files? If so, you're not alone. Here's an example content/css/site.css file that uses page attributes to name the colors:

---
extension: css
filter:    erb
layout:    nil   # no layout
color:
  bubba_blue:  "#3366FF"
  bubba_brown: "#996600"
---
body {
  font-family: Verdana, "Bitstream Vera Sans", sans-serif;
  background: <%= @page.color['bubba_blue'] %>;
}
table {
  border: 4px solid <%= @page.color['bubba_brown'] %>;
}
th,td {
  border: 2px solid <%= @page.color['bubba_brown'] %>;
}

The color attribute is a hash of color names and hex codes that we can reference in the page using the @page.color[] syntax. Notice that we also set the layout attribute to nil because the resulting output/css/site.css doesn't need a layout.

10. Deploy It

Deploying our website is as easy as building the site and uploading the contents of the output directory to our web server. Remember, everything except partial files are copied from the content directory to the output directory when we build the site. Your content directory can include an arbitrary number of subdirectories to organize your content any way you like. (Consider removing the s5 and css/blueprint directories if you aren't using them.)

If we don't already have an easy way to upload our files, Webby gives us a few Rake tasks to automate that process using rsync or ssh.

In the top-level Rakefile, we need to add three variables:

SITE.user = 'bubba'
SITE.host = 'bubbas-bait.com'
SITE.remote_dir = '/path/to/webserver/root/'

Then to upload the contents of the output directory using rsync, use

$ rake deploy

By default, the deploy task will use rsync to copy the files to the directory specified in the SITE.remote_dir variable. (Look in the tasks/deploy.rake file for details.) If you'd prefer uploading via ssh, use the deploy:ssh task.

And that's all there is to it! We have a simple, yet flexible, way to remove duplication from our content and upload it to our web server.

Importing Existing Files

Now that we've created pages, layouts, helpers, and partials, importing our existing static HTML files into Webby is a breeze. Each existing file currently includes all the layout and page-specific HTML. To DRY it up, we just repeat these steps for each file:

  1. Copy the layout code into the layouts/default.rhtml file. (Most of the files will likely have the same default layout, and you can create custom layout files for those that are different.)

  2. Copy the page-specific content into a corresponding .txt file under the content directory. You can mirror the directory structure of your existing site in the content directory.

  3. Write helper methods to encapsulate view logic and keep the pages DRY.

  4. Extract reusable snippets into partials so you can render them from multiple pages.

Finally, copy any asset directories into the content directory. Webby will copy it over wholesale. For example, if you have an images directory in your existing site, just copy it into the content directory.

Writing Your Own Tasks

Webby includes a number of Rake tasks for common chores when building a website. We've used several of them:

$ rake -T
rake autobuild            # Continuously build the website
rake blog:post            # Create a new blog post
rake build                # Build the website
rake clobber              # Delete the website
rake create:atom_feed     # Create a new atom_feed
rake create:page          # Create a new page
rake create:partial       # Create a new partial
rake create:presentation  # Create a new presentation
rake deploy               # Deploy the site to the webserver
rake deploy:rsync         # Deploy to the server using rsync
rake deploy:ssh           # Deploy to the server using ssh
rake growl                # Send log events to Growl (Mac OS X only)
rake heel:start           # Start the heel server to view website (not for ...
rake heel:stop            # Stop the heel server
rake rebuild              # Rebuild the website
rake validate             # Alias to validate:internal
rake validate:external    # Validate hyperlinks (include external sites)
rake validate:internal    # Validate hyperlinks (exclude external sites)

As you continue to work on your site, you may find opportunities to automate other chores. Just create a file with a .rake extension in the tasks directory and add your Rake tasks to it. It's worth looking at the built-in task files in the tasks directory for examples.

The Bubba Blog

Ok, we're going a little overboard here, but creating a blog illustrates the power of Webby. We said that Webby can be used to generate any kind of text, and that includes generating XML files for RSS or Atom news feeds. So if Bubba decides one day that he'd like to do some blogging, we can generate a blog post page:

$ rake blog:post i_got_me_a_blog

That creates a content/blog/2008/08/05/i_got_me_a_blog.txt file, for example, where we can add the text for a blog post. Then we generate an Atom feed file using

$ rake create:atom_feed bubba_blog

If we then build the site, we'll end up with an output/bubba_blog.xml file that includes all the blog entries found in the output/blog directory.

Transitioning to Rails

If at some point we need the full power of Rails, it's fairly easy to make the transition. Webby and Rails both use ERB to render pages, so converting the page files into Rails view files is straightforward. As well, the layout, helper, and partial syntax match very closely to the same facilities in Rails. It's great to be able to take incremental steps like this rather than jumping straight to Rails before you need it.

So the next time you're faced with building a static website, give Webby a whirl! I've happily used it to build several static websites now. Frankly, I'm a bit surprised it hasn't received more press. Perhaps this tutorial will help Webby get the attention it deserves.

#

Tue, 27 May 2008

Announcing Pragmatic Screencasts!

I learn something new every time I watch a developer work. Sometimes it's the little things, like a new command-line trick or a method I've never used. Other times it's the big things that you can only learn while watching them "in the zone": their thought processes, how they refactor code, when they choose one technique over another, how they troubleshoot problems along the way, and so on. Indeed, the best way to get inside a developer's head is to watch him work. So I try to shoulder-surf as much as I can because it helps me find ways to improve my development workflow.

I've had the good fortune to meet experienced developers working with a number of different languages and tools. Unfortunately, I can't always sit next to them as they build applications. So I did the next best thing—I asked them to record what's going on inside their head while incrementally building an application. And I took on the role of development editor so they could focus on showing you how they work. That turned into a bigger project than any of us imagined.

It's been a long time in the making, but I'm excited to announce the launch of our new screencasts project. To start with we have episodes in the following four series:

Each series has a few 20-30 minute episodes to start the season, and more episodes are on the way. You can follow along with each twist and turn as they add new features to shape the application over time. For $5 per episode, you can download and watch DRM-free episodes in QuickTime and iPod/iPhone format when and where it's convenient for you. These folks have put a ton of work into creating these screencasts, and I hope you'll support their time and effort.

This is very much an organic project. We'll be releasing new episodes every couple weeks or so, and we're planning to release new screencasts on other topics, as well. (Let me know if you're interested in becoming a screencast creator.) Make sure to check out the free previews, and we hope you'll join us for the full season!

#

Fri, 23 May 2008

Book Signing at RailsConf

If you'll be at RailsConf next week, there's an easy way to get your copy of Advanced Rails Recipes signed by a number of recipe contributors. (With over 50 contributors, it's a tad more difficult to hunt them down one by one.)

We've arranged a group book signing during the 12:35pm lunch break on Friday at the Powell's Books booth. We hope you'll stop by, get your book signed a bunch of times by these great Rails chefs, and just have fun!

#

Mon, 12 May 2008

Advanced Rails Recipes Is Shipping!

The paper book version of Advanced Rails Recipes is now shipping! If you bought the combo pack during beta (thanks!), you should be receiving your paper copy any day now if you haven't already. Dave surprised me with a copy at the beginning of a Studio last week. I'm really happy with the way everything turned out, and it feels good to finally have this one in circulation.

You might still be wondering what's inside the book. Reading the table of contents is a good start (and includes a couple freebies), but I thought you might also want to see a few recipes in action. So I put together a short (12 minute) screencast that highlights the results of 17 recipes with strong visual appeal. (Watch the screencast.)

Big shouts out to all the contributors! You guys rock.

#

Fri, 04 Apr 2008

The Little Things

Indy

I've always been fascinated by macro photography, but had never ventured into that small world for fear of getting sucked in. Then I remembered that I'm taking pictures simply because it's fun (and presents a good challenge). Why not try macro!

So last week I finally broke down and bought a macro lens (the Canon EF 100mm F2.8) which arrived today. Now, the first thing you're supposed to do with a macro lens is shoot a big hairy insect. Trust me, I'll get there. But bugs don't just stand still, which is unfortunate when you're trying to practice with a new lens. And it snowed overnight here, which means the springtime bugs aren't out yet (but the ones that are definitely stand still!).

So instead of stalking insects, I thought I'd try a close-up of a fairly old comic book. I know, you're supposed to shoot macro straight at the subject, but flat pages aren't very interesting. I like the way the pixels give it texture. Many thanks to Duncan for help with the color correction in Lightroom. That's a whole different challenge in itself, though equally enjoyable.

All the photography books say this, and they're absolutely right: You need a tripod to do this. When you get dialed in on the details, you feel every little vibration. I've also been using a shutter release cable to bump my odds of getting tack-sharp shots. (Yeah, the mirror lock trick comes next.) In this case, I switched over to manual focus because auto-focus was squirrelly.

Anyway, I hope you enjoy it. Comments in Flickr are always appreciated!

#

Fri, 28 Mar 2008

Deploying Rails Applications on Leopard: Part III

Part III of my three-part Apple Developer Connection series on Rails has been posted. It's titled Deploying Rails Applications on Mac OS X Leopard because it picks up where we left off in Part II by deploying the application to Leopard Server using Capistrano.

I had a lot of fun writing this piece in particular because I got to play around with the new features in Leopard Server. It comes pre-installed with lots of Rails deployment goodies to streamline the process: Apache 2.2, mod_proxy_balancer, MySQL, Mongrel, Capistrano, and so on. As well, Apple created an enhanced version of mongrel_rails that, among other things, registers your Mongrel processes with Bonjour. The upshot is you can configure your Rails-powered web site right from Server Admin.

Enjoy!

#