Saturday, 28 April 2007

Exploding contracts == dilemma

Two weeks ago I was bemoaning the fact that my cash flow was in the red and my savings were running away in a torrent. I was then approached by a friend for a contract. Shortly after my interview with them I had four other clients approach me. So suddenly I'm flooded with offers!

One of the other clients was a good friend of mine as well. So I had a real dilemma on my hands. I didn't want to disappoint either one.

The first contract came first - but they hesitated on giving me a "Yes definitely" answer until after I'd started to look at the second one. I felt I had to look at each of them in good faith.

The first contract offered sexy video on the web, the second a really big name financial company

The first contract offerred a relaxed, sociable startup feel with some onsite some offsite. The second offered relaxed, sociable academic feel, onsite-only, but I'd have the chance to teach the rest of the team Rails skills.

It was pretty much neck-and-neck. It was a tough decision, from the perspective of preserving friendships. But when I weighed all the pros and cons objectively, the business decision became clear. In the end, for me, it came down to the fact that the first contract could only offer three days a week, while the second offered full-time.

I start on Tuesday.

Tuesday, 24 April 2007

Presenting Rails

Ok, so this post was going to be how I gave an absolutely rocking presentation on Rails to my local LUG group (SLUG).

Unfortunately, I was giving the second talk and the first one began late and then ran way over-time. So my talk was pre-empted. The SLUG team were really nice about it (they even bought me dinner), and I'll be running it next month instead.

I certainly can't fault them - the first talk was on the cool OLPC project. I was interested in listening myself. Besides which, an extra month will give me more time to polish the talk and prepare that demo I'd meant to organise...

Anyway, I did want to mention a really cool talk I stumbled over while researching other Introductory Rails talks. Jim Weirich gave this talk and has a lot of reference material available here, but what I wanted to point out the neat slide software he used.

It's called "The Takahashi method" and is a XUL file that runs in your browser. It lets you write simple and effective slides with an image or a few words on each. These give great impact to what you're trying to say.

The data file for the slides is simple plain-text markup, so it's ultra-quick to write up your slides from your presentation notes.

Here is a link to Jim's slides and data. See how punchy that is.

Anyway, that's what I would have used... if I had the chance ;)

Friday, 20 April 2007

Coding through treacle

Coding while sick is like trying to walk through fairy-floss

I once tried to explain to my aunt (a respected Dietitian) about how you need your whole brain firing on overdrive to write truly awesome code... it was difficult to explain clearly and I didn't pull it off successfully. Apparently I left her with the feeling of "and you don't think I use my brain in my work?" which was *so* not the point I was trying to make.

In my experience, most jobs (ie non knowledge-work jobs) have an element of drudgery. Tasks that you can do with only half your brain involved. You might not be able to do them while sitting in front of the tv - or while chatting with a friend... but you can do them when you're feeling less than 100%.

Coding isn't like that. Neither are things like mathematics, theoretical physics and creative writing.

At least 95% of the tasks you do require full attention. It's not like you suddenly forget how to code (or write, or whatever), it's just that if you do that work when you're not "all there"... it'll be far more buggy and inelegant. You might be able to salvage most of it, maybe with only a bit of re-writing, but if you're seriously out of it, you'll have to re-write so much of it that you might as well write it from scratch... ie you'd be better off having not written it at all.

The last week and a half has been like that for me. I've been trying to see through a near-impenetrable fug of virus-induced head-cold.

I've watched a lot of television. I've made significant in-roads into my post-easter chocolate collection. I even began a new knitting project... but I haven't coded much.

I even had trouble concentrating enough to get through my email. When you find yourself blankly staring at the screen, and realise that you've been sitting there, doped out for ten minutes doing nothing... you know there's no point firing up the text-editor.

Still, the fog has begun to clear over the last few days, so I'm slowly picking up where I left off. Which is lucky as I'm helping a friend out - he's sub-contracted a few basic rails tasks to me on his current project. Hopefully I'll be back in full-gear next week as I have a contract-interview and a talk on Rails for my local LUG.

Tuesday, 3 April 2007

Plugins and engines and gems, oh my!

So I was talking to friend of mine about what I was doing and how a gem was too heavy for what I wanted. He pointed out that I should consider doing it as an engine instead of a plugin.

What's the difference between a plugin and an engine you ask?

I didn't know either... engines seem to be the forgotten children of Rails in all the current plugin-love that's going around (not knocking it - I like plugins too).

Anyway, it turns out that an engine is a plugin - with some differences. An engine requires that you install the "engines" plugin first - you can't just script/install the plugin itself. However, adding that engines plugin allows your own baby to do a hell of a lot more than your standard plugin-ly functions.

An engine is a complete, vertical slice of MVC. An ordinary plugin, by comparison, is generally a small chunk of functionality such as a helper library. Engines can have an /app/ directory structure identical to a full rails site. You can also add routes and migrations (with some user-tweaking required). This allows a fully encapsulated chunk of functionality (such as what I was proposing for my little blog).

Now, mephisto and typo are both gems. This is because they contain a huge amount of functionality (they well deserve their leading status in the Rails-blog field). They contain more functionality than what most people associate with a simple plugin... more than what people would associate with an engine (if people used engines more commonly) - so they are distributed as gems.

So, to sum up:

  • plugins are for small bundles of helpful code
  • engines are for encapsulated slices of vertical functionality and
  • gems are for complex, multi-functional systems.

So how do I make an engine?

The information on how to make an engine is a bit scattered about the web. There doesn't seem to be a whole lot out there in the way of tutorials (at least not compared to plugins).

Some of the info seems to be downright incorrect. The article that looked most promising was: the alterthoughts one, but it seems to be based on an old version of engine-construction that Just Doesn't Work. I couldn't get script/generate engine my_blog to give me anything but "can't find a generator for engine". This article is clearly built on an earlier version of both Rails and engines

The railsdoc on engines is fairly complete (though it's not a step-by-step tutorial). It turns out that you can just start out with a rails app - and turn it into an engine. Two things to remember:

Routes
Copy your engine's routes.rb into the root directory. Then instruct your users to add map.from_plugin :your_plugin into their routes.rb.
Migrations
If you have migrations, make sure they are numbered from 001. Then leave instructions for your user to run script/generate plugin_migration, then rake db:migrate.
Shared plugins
A blog needs to share the authentication plugin. But which authentication mechanism are you using? I could assume you're using the same as me (RESTful auth right?) but that's not likely. The best option is to write a wrapper library that allows people to override the functions with their own authentication system, if they choose.
Other plugins
If your plugin depends on other plugins there may be some duplication. I'm sure there must be a way that minimises double-loading of plugins eg if your plugin uses acts_as_taggable, and so does their site - maybe your install.rb could check for that and not bother installing it - but I think that may be over-optimisation.

I'm sure there must be a way to put all these tasks into "install.rb" - but I haven't had a chance to do that yet.

So, what have you done?

So I wrote a very tiny blog app (currently all is does are posts). It was enough to demonstrate the point for me while I figure out how to do the engine thing. I'm still playing with it in my spare time - but I probably won't get in installed until after the Easter long-weekend. At that point I'll also find somewhere to upload it so people can have a play with it.

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.

Friday, 26 January 2007

Attracting women

After the LCA dinner, a friend-of-a-friend asked me that perennial question: how do you attract women to your FOSS group? Here are my ideas.

Getting women into your group

The best way to attract women to your group - is to have women in it already.

Particularly women that are great role-models: active women that contribute and organise, like Pia Waugh (LCA2007 "Seven team"). Unfortunately, for many groups this just sets up a chicken-and-egg situation. If you don't have women already, how do you get your first ones to come along? Luckily you can leverage women in other groups. Some ideas:

Start by asking your own members. Do they have wives/girlfriends or colleagues in IT? What about other local IT communities eg local businesses? This is just like any other FOSS evangelising: these women are already in IT, but maybe have never heard of FOSS (or never realised that it could actually benefit them to come to a group like yours).

Then ask groups like yours in that are in other regions. Do they know any women that live in your area that might be interested? Would they be interested in travelling to your area and bringing their friends along, to get the ball rolling?

Look into the local, regional and national "Women in IT" groups and advertise yourself there. Promote what it is that you do, and why it would be interesting - just as you would to any other newbie.

LCA's great success this year was the large percentage of women that attended (10%). This was fuelled by the work put in by Mary Gardiner and other members of the LinuxChix group. These groups exist to help women do interesting stuff in IT - your group counts!

Even if these groups don't serve to find you any members, consider asking the women to come and speak at your group. Especially on gender issues. The linuxchix miniconf was a great success with women speaking on issues such as negotiation and the gender pay-gap issue. Women are interested in these issues... and so are men.

Retaining your women

One of the broader issues for women in the corporate world, is that women and men have their own cultures. Be mindful that women's culture is likely to be distinctly different (though no less important) than the culture you already have in your group.

Obviously I am speaking broadly and individuals differ widely, but there are some common issues with women, and understanding these issues will help you integrate.

Firstly, don't assume that your culture is better. If you have a culture in which people brag about their exploits and the loudest shouter wins the floor... don't be surprised if women stay away in droves. Women come from a culture in which it is considered polite (and expected) to await an opening before speaking. They will not jump in and say their piece just because everybody else does. If an opening is not made for them, then they may never speak at all - to the detriment of everybody.

Female culture thrives off positive feedback and encouragement. If you notice that a woman in your group has done something you think is cool - encourage her to tell people about it. Do not be surprised to find that she thinks nobody wants to know. This is a place where it's ok to tell her that she is wrong. :)

Most women are self-deprecating (by inculturation) and will often down-play their experience. Poor self-esteem is common, even in those that have many successes behind them. You may need to treat your women like "the quiet kid" who needs some encouragement to speak up.

With the particularly shy and retiring - take them under your wing a bit. If she is too afraid to do it herself, promote her successes for her and show her how much her contribution is valued. Prompt her to talk about what she did and what she learned. When she sees that you're not all big, scary people that are going to laugh at her... she'll be more likely to stay.

Don't be big, scary people that laugh. ;)

Newbie women are afraid of the same things that any newbie is afraid of. They're worried that they will look stupid amongst all these shining gods of IT. They think their dumb questions and newbie mistakes will be laughed-at. It's up to you to make sure they know that it's ok to be a beginner. This also goes for experienced women with low self-esteem - who often rate themselves as a beginner even when they are an expert.

Share your own stupid questions and mistakes. Show them that you gods are really human too and were once a newbie with dumb questions (and, in many cases, still are). Let them know that everybody asks stupid questions and nobody thinks the less of them. Make them understand that what they are going through is not only normal, but expected. This can be as simple as saying "I'm glad you asked that", when they do pluck up the courage to ask.

Finally, support (or start) a women's chapter for your group. The intent is not to have a separatist group, favourable only to a minority. It should instead be a safe haven for newbie women to socialise and network with their peers as they adjust to a new and alien culture.

Getting women into your group (and keeping them there), is a Hard Problem. But there are lots of things you can try. The effort will mostly be in the initial stages - once the ball is rolling it'll take on its own momentum, and the results (I think) are worth it.

Want to know more?

Read Val Henson's article on encouraging women in linux. It's very thorough.

First contract

So I finished up my first ever contract yesterday. It was a good start. I had been hired for a week of work to implement a payment gateway to allow people to subscribe to the site.

It started out much slower than I hoped as I managed to get the bad luck of coming down with the flu on the day I was supposed to begin. I negotiated to take the first day off, but even after I started my head was pretty fuzzy. Not good for staying at the height of my game.

So I worked some longer hours than I would have done - especially in the later days of the contract, just to try to make up for the early slow-down.

Anyway, in the end the system was successfully subscribing and unsubscribing people. I was hired for a couple of extra days to do some other stuff, so the client obviously wasn't unhappy with my work. :)

Wednesday, 24 January 2007

Linuxchix Rails talk

I gave my first ever talk at Linuxchix on Monday. It was an overview of Rails. I kept it informal as we're never sure of the venue or how many people will turn up. As it turned out there were around ten people and we sat in a fairly noisy area outside of Gloria Jean's at St Leonard's.

It apparently went quite well, given the location and the necessary informality. I briefly went over why Rails is so appealing to businesses and what it actually does to help a developer build a web app. I ended with a vague discussion about MVC architecture and took a few questions. People seemed particularly interested in the causes behind Rail's reported slowness: which unfortunately I don't actually know. So I'll have to research that for next time.

I had a few positive tips for improvement come out of it too. Mainly it was suggested that I tie the talk together with a narrative element - as people naturally respond to stories. It gives people a hook to hang onto as they follow the points you're presenting. Slides or a demo would have been good too - but that was a limitation of the venue.

Afterward, of course, we all headed off to SLUG and some interesting talks, including one on how AV was used during LCA, and another on the Google Summer-of-code project.

BusyBusy

I haven't died - I've just been busy.

First with my new contract with SugarStats.com I sadly fell ill on the first day, and left myself that day to try to recover. But I gave in and just struggled to work through the mild flu for the rest of the week - I can't sit abed for too long when there's work to be done. That filled in the rest of the second week of January.

Secondly was LCA - what a fantastic week! Keynotes and lectures from amazing speakers, cool shiny toys to play with and wonderful social evenings amongst the cool hackers that flocked to the con. I think I'll go every year from now on! I have yet to watch through all the amazing talks that I missed (while watching other amazing talks, of course). I also have some cool ideas for stuff I can contribute to Open Source... as well as several ideas for blog-posts that I'll type up - as my backlog.

The beginning of this week has been filled with the housework needed to get my house back into shape after a week of 8am-10pm days, followed by several more days working on my contract (which has been extended so I can do a few more things). In any case, I'll try to get down a few more posts in the next couple of days.

Thursday, 4 January 2007

File uploads

I wasted time today.

I didn't intend to - I was hopng to change an admin CRUD interface over to use AJAX scaffold - which is prettier than what I had before. But when it was all changed over suddenly all my file-uploading stopped working.

I checked to make sure all the file-saving code was still in place, the filenames were correct, everything but it kept simply not finding the StringIO that was clearly there in the form.

It took me way too long to discover that you Can't upload files with AJAX. It seems the JS doesn't accept the multi-part get/post data. :(

So I changed back...

but in the meantime (while I was checking all my code) I discovered the file_column plugin which is a neat little library that does all of your file-uploading for you. It even integrates with RMagick to let you do some speccy resizing etc. So it wasn't *totally* wasted effort... just not what I'd planned spending the morning working on :P

Friday, 22 December 2006

PayPal helldesk

I like text-only emails. It's a great way to avoid link-jack phishing spam, virii and annoying flashing ads. It's also a great way to get your email through an ssh connection. However, dealing with long URLs can sometimes be annoying. It doesn't seem to matter that I've set all of my settings to *not* use wrap-characters. When a link comes through it will, more-often-than-not, have a '+' sign squidged into it when it breaks onto a newline.

This is not a big problem. I've grown accustomed to copy/pasting (ok, highlight and middle-clicking) into my browser window, searching for the <CR> and a spurious '+' and removing it before hitting "Go".

This does not work for PayPal URLs

PayPal text-based email is that hideous abomination that comes sprinkled with MicoSoft proprietary characters. Lines end in '=' and there is a smattering of '?', "=20" and other random wierdness, just to make life more challenging...

I spent hours yesterday morning trying to get back into an old paypal account of mine. I did the "forgotten password email" thing. I clicked on the URL. I removed the <CR> and the clearly spurious '=' wrap-character - no go. I tried it while leaving in the '=' - no go. I tried copy/pasting the inidividual halves of the URL into my browser - no go.

I then spent an hour or more on the phone with their help-desk trying to be polite while they went through their script:
"Hi there, I'm having trouble with the forgotten-password URL. I have tried copy/pasting it into my browser, I removed the line-wrap symbol and the carriage-return, and it still doesn't work."
"Have you gone to the forgotten password page and clicked the link to send you a reminder email?"
"Yes, I've done that - I've got the email, I've clicked on the link and it doesn't work. I tried to copy the link into my browser, but that doesn't work either."
"Have you tried to copy/paste the URL into your browser?"
<sigh> <<find me somebody that understands linux... or at least somebody that knows how to *listen*!>>.

Finally he agreed that it really wasn't working for me! But their technical desk had gone home by that stage so all they could do was open a trouble-ticket with me and I would need to call them tomorrow.

I played a wild-card and tried creating an account with the email for my old company. I was coming in for some final work this morning. I used Evolution there so I could look at the URL and compare. I wasn't sure if it'd help - but figured it was a better shot than fretting about the next level of helldesk support.

Example URL from Evolution: https://developer.paypal.com/devscr?cmd=_signup-el&ac=Uqht43A9suP7A-qEw=
Wi6tvquhPE8gVgEPX5Rr7vBWrMTj8uOWmJ2eh6wavzjhIQWjjkrfCT8x4rJvA

Example from mutt: https://developer.paypal.com/devscr?cmd=3D_signup-el&ac=3DKiXOj6ebBnR5sJZhj=
xP1NKTMTbq6pyy7COF6tQRj-BkZjbnAvkAjAwLMiTalSVT94OmHniMPIMI9Iw

Note the "3D" after each of the (real) '=' signs. I have no idea what character PayPal's text-email generator thinks they are supposed to represent - or why Evolution seems to gloss over them, but removing them makes it all work.

Tuesday, 12 December 2006

So I finally ditched dry_scaffold after a few too many annoying little things. There's apparently a new version coming out that fixes a lot of these minor annoyances... but it's not stable enough to use just yet - and my life is moving on without it.

The most annoying to me were:
1) Not allowing me to use apostrophes in generated form fields. It didn't just escape them out before saving. It silently removed them from your field as you typed it. :P
2) No proper support for modules. This becomes annoying when most of your sites have both a publically-accessible view of your Thingies and an Admin::ThingyController to do your thingy CRUD. dry_scaffold would look at this and expect your model to be kept in app/models/admin/thingy.rb, so you'd have to have a copy in your base model directory and a symlink in that directory if you wanted to have just one model file for two controllers to access... not exactly DRY in my book.

Tuesday, 5 December 2006

Moist file upload

Cool, so I just figured out how to integrate file-upload with moist scaffold. If you can already do this while standing on your head - well, why are you reading my blog? ;) Otherwise, here are the basic steps:

Generate a moist scaffold

This can be done as per my previous post. You have to generate it using less_dry so that you can extend the create/update actions in the controller. Also - make sure your model has a string column to hold the filename - I'll assume that this is called "thumbnail" from now on.

Configure the column

In your model file you need to update the filename-column's has_column details to something similar to this:

  has_column "thumbnail",{
    :in_list => true,
    :sortable => false,
    :filterable => false,
    :type => :custom
  }

The important bit being being the :type => :custom. This tells dry_scaffold to go look in the helper for methods that generate the edit-field and list-display. If we were to filter on this column, we could also specify a filter-function, but I haven't done this. I've turned off filtering and sorting for this column - though I could have done a filter/sort on the filename.

Put list/edit methods into the helper

module ThingyHelper
    def thumbnail_edit(one_row, column)
        file_field "thingy", "thumbfile"
    end
    def thumbnail_list(one_row)
        image_tag "/images/thumbnails/#{one_row.thumbnail}", :size => "64x64"
    end
end

These are the methods I mentioned above. The edit method creates a file upload field that is named *differently* to the column that will store the eventual URL. If you want to store the whole image file into the db - go ahead, but I figured it'd be nicer to put them into an images directory.

The list method just displays the file squished into 64x64. It'd be nicer to work some RMagick, but I didn't bother for this example. Note: the reference to one_row is a hack - this is how dry_scaffold refers to the current row of the list. To access other values out of the row, you have to use it - but it seems brittle to me.

Update controller+model to manipulate image

When the user does a browse/upload on a file - it passes the StringIO object through to the controller. This file needs to be saved into the images directory - and just the URL put into the db.

Other sites have covered this already (in a variety of forms): read the rails article here (you may need to go back to a non-spam version). Pick a favourite way and you're done.

Monday, 4 December 2006

Moist scaffold

I've just discovered dry_scaffold and it's lots of fun. It does exactly what a scaffold was originally intended for: ie to hold the basic shape of the CRUD bits of a rails application while you get around to replacing the bits that need replacing.

This is as opposed to the rails-standard script/generate scaffold, which generates tons of files that you may not be ready to (or may not ever) change. IMO the standard scaffold-generator is less like a scaffold, and more like a rough-shaped mud-hut slapped quickly together that you can modify.

Unfortunately, if you need more than one of these, you get several nearly-identical rough mud-huts piled randomly about the place. They each begin with their own complete set of infrastructure which you can (try) to modify to be more DRY, but tends to end up with some residual wetness that is just really hard to get rid of without a lot of effort.

By contrast, dry_scaffold adds new model objects like storeys in a high-rise (with shared ventilation and lifts and... ok, I'm going too far now). The basic infrastructure is shared because it's all contained in the engine. Much DRYer.

All this being said, it's still quite new and so has its issues. The main one that I see is the spotty documentation. So here's a rough guide for where to go looking:

  • To get the basic dry_scaffold up and running, use the standard dry_scaffold page, but use your own model (obviously) and ignore where it says to update layouts/admin.rhtml.
  • If you need to only slightly adjust how the fields are added/listed or filtered, you have a range of options available to you. The data are stored in your model object as a set of columns with configuration options. Check out the has_column rDoc to see all the options available. The rDoc is available here, and has_column is listed in the frame at top-right.
  • If you need to do some serious readjustment of the code, or plan on using dry_scaffold simply as the stop-gap while you replace the structure, then you really need a "moist" scaffold. You will need to run the generate command with the following form: script/generate dry_scaffold ModelName ControllerName less_dry. This will generate a minimal controller that allows you to override/extend any actions you need; while continuing to be extremely slim-line. AFAIK there is no documentation on this, but from general mucking about it seems straight-forward.
  • If you have more questions, there is a forum available here.

Sunday, 3 December 2006

Kill the ugly duckling!

For years, now, I've had a "tradesman's website"... you know, how the tradesman comes home and doesn't want to do *more* work, so they let their own house go. That's what my website has been like now for a while. I've suffered brief bouts of inspiration, followed by a flurry of new stuff - only to get caught up in what I was doing at work and not want to do any web-development once I got home :P

But that's gotta change - and the old styling is really not cutting it for me. So the first thing I've done is to get some graphic desgin done... I'll be getting the first look at the result on Monday and have been really looking forward to it!

I've never had to brand myself before, and that's essentially what I'm doing. I've worked with branding for products, companies and services, events and concepts - but never for myself. I had a chance to chat about what I like, how I see myself being portrayed and even a few of my favourite hobbies (eg calligraphy) and now I'm really looking forward to the results.