Friday 30 March 2007

A blog to call my own

So, I've been thinking about shifting my blog over to my homepage recently. Why? well blogger's great, but I really need to move out and find a blog of my own. I want a tighter control over the content, I want to integrate it with my website's styling and layout and maintaining it in two places violates the DRY principle...

Ok, so I'm lazy and don't want to have to maintain stylesheets/layouts in two places :P

So anyway, in Rails, the major blog movers-and-shakers atm are Mephisto and Typo. They're both great. They provide heaps of functionality and have a thriving developer community. But they're a little on the top-heavy side. All the bells an whistles, Mephisto is almost a full CMS... you have to pretty much install either one as a new app (or hack it a lot ot fit with your existing one).

This is great if:

  1. you're starting an entirely new website from scratch
  2. you like using a CMS-approach to organise your site for you
  3. you're ok with your blog being a completely independant rails app.

In my case:

  1. I already have a pre-existing website. It might not be much, but I like what I've done and I don't want to have to re-hack it to fit around my blog software. Conversely, I don't want to spend hours hacking my blog software to fit in with my website - and risk destabilising the upgrade path (which kinda defeats the purpose).
  2. I'm a rails freelancer - not a stay-at-home mum. I like to get my hands dirty in the innards of my site. I don't like having the structure of said site dictated to me by some upstart CMS (no matter how shiny). I like to call the shots on my own turf
  3. We're seriously violating the DRY principle here. Why on earth would I want to maintain two separate sets of layout/styling? or two separate authentication systems? Single sign-on is a PITA. Yes, there are solutions, but why invite the problem into your home? and you couldn't integrate the layouts (eg put your latest post on the homepage) without contortions. No RESTful articles_path for you!

What I really want is to be able to do something like
script/plugin install blog
and have it all Just Work(tm). That doesn't seem available anywhere.

So, I've decided to write my own.

It won't be anything flash, just something bog-simple to allow me to post articles, tag them, let people comment and generate an RSS feed. It won't have whizz-bang flickr integration (well, probably not), but it's all that most people seem to need.

I'll post updates here as I progress.

Tuesday 27 March 2007

No to death threats!

I am shocked and horrified. By this post outlining sexually explicit death threats levelled against Kathy Sierra. This behaviour is outrageous and should not be tolerated. Kathy is a wonderful person, an excellent speaker and a giving member of the tech community. She has my full support. My thoughts and best wishes go out to her as she copes with her current situation.

Let's not let it happen again. If you notice such unruly behaviour forming in your own blog/forum/community - head it off. Inform the person that this behaviour is not appropriate. If that doesn't work - then do something more drastic (ban them from the site and call the police).

[Update: Andy Carvin has posted (on "stop cyber bullying day") a social network he has set up to help people combat cyber-bullying here.]

Sunday 25 March 2007

Social overload

So, just how many Rails social sites are out there? Seems everyone and his dog is in the process of creating a new one. I suppose this shouldn't be really surprising given how deeply entwined Rails is with the "Web 2.0 revolution"... but still.

Here is a shortlist of my current profiles:

Working With Rails
By far the best of the lot. It seems to have been around the longest - and if you're not on it, you're not anybody. This is the site that features the luminaries of the Ruby and Rails world. It also seems to be in active upgrade mode atm. They've just added a whole bunch more features.
Network of Ruby Freelancers
You can't access this site without registering. The concept is that this site marrys up freelancers with firms looking to hire. It's still a bit rough-and-ready, but it's only really just been launched. Still, there are already over 50 freelancers listing on it. They also cater for sub-contracting, allowing you to quote your sub-contract rate so other freelancers can pass their work on if they're overloaded.
Rails for all
I find this site to be way too complicated. I really like the navigation options (something that WWR is missing), but once you start trying to get to actual data, things aren't intuitive. It's also not as stable as it could be (the search fell over for no reason). There's a lot of potential here, but I think the developers tried to swallow too much at once. It has about the same level of functionality as WWR, but is far less dependable.
Freelancers on rails
Not a social-site per se, but a google-group intended for conversations about freelance rails contracting. Mentoring, tips and experiences. The members are pretty helpful and the topics cover a wide range of issues within freelancing. Worth joining if you're a freelancer.
Technorati
Ok, so this definitely isn't a rails-specific social site, but there are a lot of rails-specific blogs available here. I probably don't need to say more.

Friday 16 March 2007

Choices list

A basic CRUD list page tends to have various ways of manipulating the content - sorting, filtering etc. Most of these apply to a single column of data, so the UI will generally end up with a button, link or other input in the column-head. I found that I often needed a list of choices where some referred to a single column and others didn't (eg "Sort by: date, popularity, controversy") or choices that have no bearing on the data at all (eg "View as: User, Moderator, Admin").

It was annoying to have to type out the HTML for these lists of choices each time, with appropriate styling to highlight the "current item" etc so I wrote up a helper. My example uses RESTful paths - but could be quickly modified for legacy paths too.

    def make_choicelist(title,fieldname,choices,path_hash)
    # creates a horizontal list displaying a set of choices the user can
    # pick from including urls for each choice.
       cur_val = params[fieldname]
       str = "<div class=\"hlist\"><span class=\"head\">#{title}</span>"
       choices.each do |label,value| 
         path = url_for path_hash.merge(fieldname => value)
         str << "<span class=\"#{(cur_val && cur_val == value.to_s) ? "current" : "item"}"
         str << "\">#{link_to_unless_current(label, path)}</span>"
       end 
       str << "</div>"
       str
    end

You can then pass it:

  • The title of the choice list
  • The name and current value of the field that saves the state of this item
  • The set of choices (label+value) that this field can take
  • The basic URL of the page apart from this field - as a hash (so we can merge in the new value)
    
   <%  choices = [["Admin", :admin],
                ["Moderator", :mod]
                ["User", :user]] -%>
  <%= make_choicelist "View as:", :user_type, choices, 
                 hash_for_widgets_path -%>

The code will generate the list with the given title, and will add each option after it - highlighting whichever is the current choice. You can pair this with your stylesheet to restyle the choice-list appropriately. A really basic style example is below:

/* used for horizontal lists - generally for depicting choices */
.hlist {
  padding: 0px;
  background-color: #EEE;
  color: #333;
  border: 1px solid #333;
}
/* short, descriptive heading for the list */
.hlist .head {
  padding-left: 10px;
  padding-right: 10px;
  font-weight: normal;
}
/* list items */
.hlist .current, .hlist .item {
  font-weight: bold;
  margin-right:3px;
}
/* the currently-selected item */
.hlist .current {
  padding: 3px;
  border: 2px inset black;
  background-color: #333;
  color: #CCC;
}
/* an unselected item */
.hlist .item {
  background-color: silver;
  font-weight: bold;
}
/* the link for an unselected item */
.hlist .item a {
  border: 2px outset black;
  color: #333;
  background-color: silver;
  text-decoration: none;
}
.hlist .item a:hover {
  border: 2px inset black;
  background-color: #444;
  color: #CCC;
}

Which will give you something that looks like this:

Tuesday 6 March 2007

Sliding Doors tabbing in Rails

So I wanted to find a way of doing tabbed navigation in Rails for my own website. Naturally I asked Aunty google for help, who came up with many links to this article on tabnav. It looks pretty neat and I had a play with it. It is pretty easy to set up and works quite nicely *however*, it automatically puts, not only the tabs, but the page-content div into the page as well. This means you have to jigger with the css and can't just use the tabs (without the content div) if you don't wish to.

I also really like the classic Sliding Doors CSS look. So I decided to carve my own path in the bush, so to speak. I plan to clean it up a bit and turn it into a generator/plugin of my very own. For now, here are the lumps o' code I used to get it working together.

Sliding Doors styles

This is the standard set of sliding doors styles taken almost directly from the tutorial (and tweaked a little for the images I'm using). Clearly you also need the proper images - have a look at the tutorial for what's needed here.

/* these are used for dHTML positioning and style of tab menu. Much of this
 * was taken from "A list apart"s article on the "Sliding Doors technique".
 * http://www.alistapart.com/articles/slidingdoors/
 * This is an amazing article and well worth the read.*/
#header {
  /* the tab div needs to match the page background */
  background: #38cbff url(http://example.com/page_bg.png) top left repeat-x;
  
  float:left;
  width:100%;
  font-size:85%;
  line-height:normal;
  margin: 0px 0px 0px 110px;
  padding-right: 30px;
  border-bottom: 2px solid;
}
#header ul {
  margin:0;
  padding:5px 0 0 0;
  list-style:none;
}
#header li {
  float:left;
  background:url("/images/ButOffRight.png") no-repeat right top;
  margin:0;
  padding:0 15px 0 0;
}
#header a {
  float: left; /* one half of IE5 hack */
  display: block;
  background: url("/images/ButOffLeft.png") no-repeat left top;
  padding: 10px 0px 5px 15px;
  text-decoration: none;
  font-weight: bold;
  color:#fed;
}
#header a:hover {
  color:#fff;
}
#header #current {
  background-image:url("/images/ButOnRight.png");
}
#header #current a {
  background-image:url("/images/ButOnLeft.png");
  color:#222;
  padding-bottom:5px;
}

/* Commented Backslash Hack
   hides rule from IE5-Mac \*/
#header a {float:none;}
/* End IE5-Mac hack */

/* IE6 hack for padding around tabs */
* html #header a {padding: 0px 0px 5px 15px;}

Layout item

I kept the tabs in a partial template so they could be shared by multiple layouts (if necessary). Standard Rails practice puts shared partials into /app/views/shared Thus, to pull the tabs into the layout requires:

<%= render :partial => 'shared/tabs' -%>

Tab helper function

Each tab is generated using this helper. It creates the list item given the name and preferred link options, hilighting the tab if the user is on the actual page already. I'm tossing up whether to allow highlighting even when your on the main page of a group of pages - it's a GUI question that has pros and cons.

    def make_tab(t)
    # creates a navigation tab out of the given information.    
      tab = "<li"
      tab << ' id="current"' if current_page?(t[:options])
      tab << '>'
      tab << link_to(t[:name], t[:options])
      tab << '</li>'
      tab
    end

Tabs partial template

This bit is probably the messiest part. I'm just using a temporary variable to hold the tabs here - it should be passed into the partial, so the partial can be re-used with different tab-sets (right now I only use one, so it doesn't matter). Later I plan to make a Tab class and have a standard set of tabs loaded from a config file. This standard set can then be added-to or overridden just like columns in the AJAX scaffold.

<div id="header">
  <% tabs = [{:name => 'home', 
                :options => {:controller => :home, :action => :index}},
             #{:name => 'portfolio', 
             #   :options => {:controller => :portfolio}},
             {:name => 'resume', :options => 'resume.pdf'},
             {:name => 'blog', 
                :options => 'http://rubyglasses.blogspot.com/'},
                ] -%>
      
  <!-- tabbed browsing of main site areas --> 
  <ul>
    <% tabs.each do |t| -%>
      <%= make_tab t -%>
    <% end -%>
  </ul>
</div>

New Zealand and Flat HTML

I've spent a few weeks in New Zealand on holiday, which is why I've been so quiet for the past month. BTW, New Zealand is breathtakingly beautiful. But now I'm getting back into work mode again - and trying not to think of the extra kilos I've put on from all the insanely good food over there.

I've been spending some time working on my site - though, as yet, have nothing to show for it. I'm currently replacing what I have already there - trying to make it a bit more dynamically-generated. But I haven't actually deployed that yet. I'll be blogging about my sliding doors tabbing system in a moment, though, so I figured I should mention it.

Mainly I feel good as I set up a really quick website for my Aunt and Uncle. My Aunt is a Dietitian and together they have a business doing HACCP accreditation. This is something to do with making sure people are handling food safely in their kitchens (eg in Nursing Homes). They wanted a really bog-standard website up so people know they're Out There.

This is what I came up with: Simply HACCP

It's actually a flat-html site atm, but I used rails to generate the pages as a sort of overkill CMS. I wanted to see if it was worthwhile doing something like this - and it seems to be just fine. It meant I could work independantly on the layout/styling/content. When I was happy I just dumped it all to flat html and saved each file. There are only four pages, so that part wasn't hard.

In all it only took me about 2.5 hours of work - though, admittedly I had done some of the styling at an earlier date - including finding and splicing together the foody pictures from the creative commons. Maybe I can do ordinary websites as well as web apps. Of course, my web design is exceedingly basic - but it was reasonable enough for my Aunt to be happy. It's never going to win a design award, but compared with the crud that can come out of your standard FrontPage site it's even reasonably professional.