Mr eel

Web Development

Getting the Rug Pulled From Under Your Feet

So, recently we’ve learned that Merb will be merged with Rails.

This is complete bullshit. I’m strongly opposed to the idea and I think it’s a huge mistake. I won’t enumerate all the reasons why — I think that’s all going to be thrashed to death in the coming days — but I do have a number of specific objections that I want to highlight.

Firstly, this means removing choice and competition between Merb and Rails, which despite the occasional friction, I considered to be a good thing. It doesn’t benefit the Ruby community to shift back to one monolithic framework.

I choose to use Merb for practical and philosophical reasons — basically it’s smaller, faster and easier to grasp as a whole. The development process has also always seemed more transparent and open to contributions from outside the core developers. It was a real viable choice to Rails.

But, what’s most irritating about this decision is the secrecy. There is a community of Merb users and developers who weren’t given a chance to comment on or participate in the choice. Instead we get one secretive clique schmoozing up with another secretive clique. It’s damned rude.

The end result is that the term Merb Community has no meaning to them. They don’t give a shit. If you ever used Merb, pimped it to clients or other developers, bought a Merb book, made a plugin, paid for training or went to Merb Camp — you’re being treated like a sucker. They’ve just given you a kick in the balls and you’re being told you’re gonna love it.

I’m damned bitter. I hate the idea and am disgusted at the lack of transparency and condecention implied in the decision.

I now have no interest in Merb at all. They can go to hell.

EDIT: For a good explanation of the merge, read this post by Matt Aimonetti. I’ve since tempered my views a little — although I’m still against the merge in principle and hate the secrecy surrounding the choice — Matt has helped put things into perspective.

Posted on December 24th, 2008 | There are 13 comments

A Content Management System That Doesn’t Annoy Me

I’ve used a fair amount of content management systems over the years. They’re all pretty awful. I won’t enumerate over all the reasons, since plenty of other grumpy people have done that already. Instead I thought I might highlight two of the main concerns I have when using a CMS.

I’m an Expert, Let Me Get All Experty

In other words, don’t try to dumb everything down so that a theoretical every-man can use the system. That’s a lofty aim, but seriously unlikely to succeed. I’m not talking about the admin and administration interface, I’m referring to the bits that let you actually build the site — the templates, styles etc.

Plenty of systems expect you to do ridiculous things like edit templates inside a web interface. Bah! I have a text editor for that. Just expose the templates to me in the file system and let me hack them as I need.

Themes? Utterly stupid. No serious CMS should have anything like themes. They increase the complexity of the implementation for little benefit. Having to hack a theming engine because it’s doing something stupid or is otherwise inflexible is annoying.

Basically, if we assume that a CMS and accompanying templates/styles will be set-up by people who understand how websites work, we don’t need to try and get clever with the implementation.

Extending the System Should Not Mean Using a Narrow API

If you use a CMS for a lot of client work you will have them ask for custom functionality. This is inevitable, so it’s vital that you are able to extend the CMS without going insane.

This comes in a number of forms:

Most CMSs attempt to solve this by implementing a plugin API. Initially this seems simple enough, but it has some draw-backs. Generally you are limited to what the API gives you.

As for modifying the code in the CMS proper; OMG ARE YOU CRAZY? If you’re reduced to hacking the CMS into a custom version, you will lose your shit at some point in the future. Firstly, you need to maintain those changes — think you can remember the modifications you made in someone else’s code-base all those months ago? Secondly, upgrading is going to kick your arse, because you’ll need to remerge your hacks, then make sure they work.

Let’s Make Yet Another CMS

So that’s all basically an introduction and justification for making another CMS. As part of my work at Freerange Future we’ve been developing a new system. I know, I know, every web-shop seems to go out and make it’s own CMS, but honestly, this is gonna be worth it.

It’s built on top of Merb, MIT licensed and implemented as a merb-slice, meaning we can easily over-ride it’s behaviour and still upgrade it without going nuts. I also t plays nice with your own code.

Most importantly in my opinion, it doesn’t assume you’re an idiot. It won’t hold your hand, instead it assumes you know enough Ruby to be dangerous, but can be trusted not to take an eye out with it.

It’s called Gluttonberg and it lives in a repository on Github. The README and Wiki go into a little more detail about the implementation and features we plan to build, so if you’re curious, please have a look.

It’s obviously still a work in progress so if you’re interested in contributing please just message me on GitHub (lukesutton) and I’ll give you commit access to the main repo, no questions asked.

With the power of Gluttonberg, it’s my hope that we can power-slam the entire internet.

Posted on October 30th, 2008 | There are 0 comments

Sass & Haml - A Sweet Romance Begins

If you’re just starting out using Sass, you can make things easier on yourself by having it automatically compile the stylesheets with every request. This tip applies to both Rails and Merb. Just add the following bit of code to your development.rb file.


Sass::Plugin.options[:always_update] = true

P.S. After being dubious for some time, I’ve now begun my romance with Haml and Sass. It’s sweet indeed. Terse, auto-formatting, variables. Oh my. Delicious.

Posted on January 20th, 2008 | There are 2 comments

More New Merb (0.5 is out now)

Just a quick heads-up. Merb has moved pretty quickly over the last few weeks, with lots of nice additions, code refactoring and general polish.

Now, Merb 0.5 is out. You can install it via RubyGems. Ezra has release notes on his blog.

Well done to all the devs! Merb just keeps looking better and better as it goes along. Yay!

Posted on January 10th, 2008 | There are 0 comments

CSS - Image Replacement Hot Melon Jam Fu

There are loads of image replacement techniques and I think I’ve experimented with most of them. More recently I’ve hit on a set of rules that are pretty bulletproof and thankfully don’t require any kind of hacks.

It hinges on using the letter-spacing rule — big ups to Beej for putting me onto that one. The basic idea is that you set the letter spacing to a negative value. The text essentially collapses and disappears. The best part is that the element doesn’t otherwise change. It still keeps it’s width, height and positioning. You can now freely change the height or width without having to make hacks to accommodate Internet Explorer’s horrible rendering engine.


.imageReplacement {
  background:left top no-repeat url(/images/heading.gif);
  letter-spacing:-1000em;
  text-indent:-1000em;
  width:250px;
  height:70px;
}

There are two quirks to look out for here. Firstly the letter spacing has to be -1000em. After experimentation, other more patient people have discovered that it is the value that works reliably across most browsers. Secondly, the text-indent is there to hide the text in Safari and early version of IE, where the letter-spacing rule does not correctly apply. It forces the text to sit outside the container, so it disappears. Using both text-indent and letter-spacing together means you’ll hide the text reliably in most browsers.

I’m not sure it’s the Holy Grail of image replacement, but it’s pretty good!

P.S. .imageReplacement is a horrible class name. I only use it as an example. I prefer to use class names that refer to what the element is and what it does, rather than how it looks. Much easier to modify later on.

Posted on November 30th, 2007 | There are 2 comments

Rails - acts_as_tree Select Helper

Do you have a model with acts_as_tree? At some point you probably might want to generate a select with a representation of your tree — say categories and sub-categories for blog posts or something. I’ve seen some slightly nasty ways of doing this, so I thought I might try my hand at something cleaner.

Firstly, the most efficient way of building the options for the select is via recursion. Secondly, you shouldn’t try to do it with one method, otherwise you’ll end up checking conditions repeatedly — Is this the top level? Do I have to write out the select open or select close? — when you really don’t need to.

So I’ve split my helper into two methods. One to generate the select tag and another for the options. The method for the options recurses, going through each level in the hierarchy.


def select_for_tree(model, name, entries, options = {})
  # Grab the current value of the specified attribute
  current = instance_variable_get("@#{model}").send(name)
  # Build the option tags
  option_tags = options_for_tree(entries, current, 0)
  # Check to see if we need to include a blank entry at the top
  option_tags.insert(0, content_tag(:option)) if options[:include_blank]
  # Build the select tag
  select_tag("#{model}[#{name}]", option_tags, :id => "#{model}_#{name}")
end

def options_for_tree(entries, current, level)
  options = ''
  entries.each do |entry|
    attrs = {:value => entry.id}
    attrs[:selected] = 'selected' if entry.id == current
    options < < content_tag(:option, ("- " * level) + entry.name, attrs)
    # This is the bit that does the recursion.
    options << options_for_tree(entry.children, current, level + 1) unless entry.children.empty?
  end
  options
end

Not particularly clever, but it was interesting trying to get something reasonably simple and clean.

Posted on November 27th, 2007 | There are 3 comments

Just What The Bloody Hell is a Merb?

I’ve posted about Merb a few times, but I noticed I haven’t actually given anything like an introduction to the framework, which might be useful considering it’s not too well-known. Well, I’m not gonna do that since other nicer, better-spoken people have done it already. So here is a few links to get you started.

Merb

The official site, which has got a good overview of the framework and installations. I recommend starting with the Why Merb? page, which will hopefully convince you to give it a serious look. After that, look at the Features page.

Merb & Datamapper: Getting Rolling

A quick introduction to installing Merb and DataMapper. It should be enough to get you started coding. A slight aside; DataMapper is a really awesome ORM, my preferred choice when using Merb.

Wycats’ Introduction to Plugins

Plugins in Merb are implemented as Gems, not a custom format. The benefits for doing this are manifold. Here Wycats gives a good overview of both creating and using Merb plugins.

Wycats on the Mailer

Merb’s mailer is a very nice, well thought out bit of work.

Hassox - The Great Merb Speedup

Merb is pretty fast. The code in trunk is even faster. There has been loads of good work in the last month or so, which has seen Merb speed up many times over. Hassox has got some rather tasty benchmarks :)

Hassox - The Provides API

Previously Merb had a respond_to API similar to that in Rails. This has since been replaced with a cleaner alternative; the provides declaration.

Posted on November 22nd, 2007 | There are 0 comments

Ye Newbyes Gyde to Routing in Merb

The part of the Merb I’ve found most interesting lately is the routing. A fair number of people will be familiar with the routing in Rails. Have you ever considered how useful it is? For simple cases it does it’s job with no fuss, but if you want to get clever, most of the time you’re just out of luck.

Consider this; how do you route a request based on the subdomain? Can’t. How about based on the protocol? Nope. The port number? Naah. How about using a regular expression to analyze a URL? Shit out of luck my friends.

Merb’s routing holds the answers! It can do all of that with a much nicer syntax in it’s DSL. So, for the sake of illustration I might run through a few examples from an application I’m currently working on — I’m no expert, so these will just be simple ones.

First something real simple. Sending requests on the root url to a particular controller and action. First we match() the url. Then we specify the controller and action we want to send it to. OK… so not that clever.


r.match('/').to(:controller => 'home', :action => 'index')

Another simple one to demonstrate the use of place holders in the match. Any parts of the URL that appear where you specify a place holder will then be available in the routing.


r.match('/:controller/:action').
  to(:controller => ':controller', :action => ':action')

Just to demonstrate, you could have a weird URL scheme like this:


r.match('/:id/:controller').
  to(:controller => ':controller', :action => 'show', :id => ':id')

Now time to show some awesomeness. You can send requests to controllers that live in a particular module based on the subdomain.


r.match('/:controller/:action', :subdomain => ':subdomain').
  to(:controller => ':subdomain/:controller', :action => ':action')

This would be perfect for redirecting the requests via an admin subdomain. So requests to admin.domain.com/users would get sent to the controller/action Admin::Users#index. Nice!

I should also point out that you can also easily turn each one of these route declarations into a named route. Like so:


r.match('/login').to(:controller => 'users', :action => 'login').name(:login)

You just call #name at the end of the route declaration and pass in a symbol which will be the name you can then use in your #url calls inside controllers and views.

Ok, one last cool thing. You can match to a segment of a URL, then define a bunch of sub-matches. This is done by passing a block to the match method.


r.match('/admin') do |admin|
  admin.match("/:controller").
    to(:controller => "admin/:controller", :action => 'index')
  admin.match("/:controller/:id").
    to(:controller => "admin/:controller", :action => ":show", :id => ':id')
  %w(edit delete).each do |action|
    admin.match("/:controller/:id/#{action}").
      to(:controller => "admin/:controller", :id => ":id", :action => action)
  end
end

So what I’ve done here is match against /admin then we go onto our sub-matches. First the controllers index action. Then with an id, we map to the show action. Finally we map to the new and delete actions. This isn’t a real world example, since we’re only crudely emulating RESTful routing, but it shows how flexible you can be with matching parts of a url.

In my next Merb(ivorian) post I’ll go into a little more detail about the resources route declarations and doing some more clever stuff with ports and sub-domains. OH YEA.

Posted on November 20th, 2007 | There are 1 comment

New Site, New Site I Even Love Saying the Word Site

So, I got a bit bored and stuff. For no particular reason, I thought I might have a go at redoing the design for this blog. I like what I’ve ended up with. It’s well serious.

It was an experiment with trying to get the markup as minimal as possible. I’ve only used three divs, the rest is all nice semantic stuff. The next step is to actually get it to validate as XHTML 1.1. This might be a bit tricky since every link needs to have a title attribute — eeek! — and the source needs to start with the XML prolog. The last is a tricky one. Many many browsers and servers just blow up when trying to serve an XML doc using the text/html mime-type — which is derived from the extension.

Validation seems positively quiotic sometimes. I shouldn’t say it less the standards-types beat me up, but I really don’t see the point of many of the requirements in the spec. So rather than fussing about it, I figure I’ll just work to keep things neat, tidy and consistent.

That will have to do.

Posted on November 20th, 2007 | There are 2 comments

Fixtures with Datamapper and Merb

If you’re to be using Datamapper with Merb, you might be wondering how to get your test fixtures into your test database.

Thankfully it’s pretty simple. For those of you using Rspec, just stick this bit of code in you spec/spec_helper.rb


# Make sure the schema is in sync
DataMapper::Base.auto_migrate!

def fixtures(*files)
  files.each do |name|
    klass = Kernel::const_get(Inflector.classify(Inflector.singularize(name)))
    entries = YAML::load_file(File.dirname(__FILE__) + "/fixtures/#{name}.yaml")
    entries.each do |name, entry|
      klass::create(entry)
    end
  end
end

If you haven’t seen the auto_migrate! in DataMapper before, be aware that it destroys and recreates your database schema. I like to add it to my spec_helper so that the test DB is in sync with development, without me having to run a rake task.

This method assumes your fixtures are in the spec/fixtures directory and use the yaml extension. If you’re using .yml instead, you’ll need to change the third line in the fixtures method.

Now just call fixture inside your describe blocks.


describe "make sure the yowie is real" do
  fixtures :yowies
end

Keep in mind this will likely be a bit slow if you have loads and loads of fixtures, but for simple cases it works nice!

Posted on November 12th, 2007 | There are 0 comments

All contents © 2005—2007 Luke Matthew Sutton