TextMate Bundle Management

Installing and managing TextMate bundles has always been a pain. You have to check it out from source, figure out where in the filesystem it goes, and restart TextMate.

Fortunately, someone was clever enough to make an automated solution to this problem. It handles all these cases: fetching the source, putting it in the right place, and reloading TextMate.

It's available on GitHub as a gem, so you'd think you'd be able

sudo gem install wycats-textmate

Not so much. The executable the gem seems broken. Let's install it by hand:

git clone git://github.com/wycats/textmate.git
cd textmate
rake gem
sudo gem install pkg/*.gem

Now let's see what's available:

textmate remote

Lots of goodies. Let me just install a few for the stuff I regularly use...

textmate install "Ruby Haml" GitHub
textmate install "Ruby Shoulda" GitHub
textmate install HTML GitHub
textmate install Git GitHub
textmate install "Javascript Jquery" GitHub
textmate install "Nginx" GitHub
textmate install "Ruby C Extensions" GitHub
textmate install "Ruby on Rails" GitHub

If you happened to installed one of these in the past, you'll need to uninstall it first.

textmate uninstall "Ruby on Rails"

That's all there is to it.

Determine if content_for was used

One of those common things to do is have a sidebar with content, which is dynamic based on where you are in the app. The common solution uses content_for :sidebar, and yield :sidebar. In practice, this looks like:

<!-- In app/views/layouts/application.html.erb -->
<html>
  <body>
    <div id="sidebar">
      <%= yield :sidebar %>
    </div>

    <div id="content">
      <%= yield %>
    </div>
  </body>
</html>
<!-- In app/views/foo/index.html.erb -->
<% content_for :sidebar do %>
  im in ur sidebar showing of ur foo
<% end %>

<ul>
  <li>Foo</li>
  <li>Bar</li>
</ul>

This way, you get the custom content in sidebar when you specify. Here's the kink: you yield the sidebar inside your sidebar div, so the containing sidebar div is always going to be rendered, whether or not there's anything rendered inside of it.

Annoying.

Wouldn't it be awesome to conditionally render the containing div? Yeah, but there's not a builtin way as far as I can tell.

Why don't we take a peek into content_for's implementation, and try to understand what it's doing:

def content_for(name, content = nil, &block)
  existing_content_for = instance_variable_get("@content_for_#{name}").to_s
  new_content_for      = existing_content_for + (block_given? ? capture(&block) : content)
  instance_variable_set("@content_for_#{name}", new_content_for)
end

So, if I understand it, for sidebar, it would be doing:

  • Getting existing content in @content_for_sidebar
  • Generate content from the block, and combine it with the existing content
  • Set @content_for_sidebar to the combined content

So, if @content_for_sidebar is nil, I think we can safely know that content_for :sidebar has not been used. Let's try this out:

<!-- In app/views/layouts/application.html.erb %>
<html>
  <body>
    <% unless @content_for_sidebar.nil? %>
      <div id="sidebar">
        <%= yield :sidebar %>
      </div>
    <% end %>

    <div id="content">
      <%= yield %>
    </div>
  </body>
</html>

Does it work? Yes. Am I a naughty, naughty boy who should be punished? That's kind of irrelevant, but it feels kludgy to be checking the Rails internals in the view. How about we do something-a-like-this:

# in app/helpers/application_helper.rb
module ApplicationHelper
  def content_given?(name)
    content = instance_variable_get("@content_for_#{name}")
    ! content.nil?
  end
end
<!-- In app/views/layouts/application.html.erb %>
<html>
  <body>
    <% if content_given? :sidebar %>
      <div id="sidebar">
        <%= yield :sidebar %>
      </div>
    <% end %>

    <div id="content">
      <%= yield %>
    </div>
  </body>
</html>

That definitely feels nicer. Maybe it should be included with Rails? As a plugin? As a gem? All of the above?

Focusing a form field at page load with MochiKit

As far as I can tell, the only way to make a form field be focused by default at page load is by using Javascript.

Code snippets you find online will typically do something like:

<html>
  <head>
    ...
  </head>
  <body onload="document.someform.somefield.focus()">
    ...
  </body>
</html>

That's nice and all, but this can be problematic when you have other onload methods for your body tag.

MochiKit has some nice facilities for handling events like this, what it calls MochiKit.Signal. It allows you to connect however many functions to a particular event as you need.

Here's how I did it:

<html>
  <head>
    ...
    <script type="text/javascript" src="/your/path/to/MochiKit.js"></script>
    <script type="text/javascript">
      var focusInitialInput = function() {
        document.someform.somefield.focus();
      }
      connect(window, 'onload', focusInitialInput);
    </script>
  </head>
  <body>
    ...
  </body>
</html>

Pretty simple. This is only scratching the surface of MochiKit's Signal handling.