Archive for ruby

Firefox 3.0.3 and 500 Internal Errors with Javascript

I had a very confusing situation today with a multipart form that was for uploading a picture to a new web service I’m working on.

In Safari the form upload worked.  Even in Internet Explorer 6 the form upload worked (after I fixed the dodgy MIME-type that IE passes through for JPG images - image/pjpeg for those interested).

The form I was trying to submit had the multipart attribute set correctly, and also had some javascript to disable the file selection, form submission button, and show a spinner to indicate that something is happening, and they don’t try and submit the file twice if they’re sending in a large image.

My submit tag orginally looked like this (Ruby on Rails)


<%= submit_tag 'Upload Photo', :class => "formbutton", :id => "submit-button", :onClick => "$('upload-form').submit();Form.disable('upload-form');Effect.toggle('footnote', 'appear', {duration: 0});Effect.toggle('spinner', 'appear', {duration: 0});" %>

I was very confused as it did work in those other browsers, but not in Firefox.

The key to fixing this was to add return false; to the end of the javascript statement…


<%= submit_tag 'Upload Photo', :class => "formbutton", :id => "submit-button", :onClick => "$('upload-form').submit();Form.disable('upload-form');Effect.toggle('footnote', 'appear', {duration: 0});Effect.toggle('spinner', 'appear', {duration: 0});return false;" %>

What I find particularly confusing about this is that everything I read on the “return false;” statement leads me to believe that this form should not be submitted - however - return true does not work (500 Internal Server Error returned).  But what the hey - it works.

No comment »

Radiant CMS Tutorial - Custom Javascript in Admin Pages

At the moment I’m working on a fairly complex extension for Radiant CMS.  In creating the administrative pages I want to use a javascript library that is not distributed with the core radiant code.  This post will describe how to implement your own extension that can use an external javascript library, without playing around with any of the core radiant files to inject the javascript into the administrative layout.

It’s actually really easy to do.  If you haven’t created a Radiant extension before I’d recommend following this tutorial on the Radiant wiki.

Inside the Radiant GEM, the standard page layout resides at app/views/layouts/application.html.haml

The lines of code that insert the javascript tags are:


    - @javascripts.uniq.each do |javascript|
      = javascript_include_tag javascript

The @javascripts variable is populated from inside the app/controllers/application_controller.rb file.  The culprit is below.


  def include_javascript(script)
    @javascripts << script
  end

Pretty simple huh?  So, all you need to do, is call this method from within your new controller, because all controllers inherit from the application_controller.rb file, so they have access to this method, and you can have different javascript included for each method if you so wish.  In (assuming the example LinkRoll extension was built as linked above) vendor/extensions/link_roll/app/controllers/admin/links_controller.rb 


  def index
    include_javascript("admin/mootools-1.2-core-yc.js")
    @links = Link.find(:all)
  end

That will insert a link to admin/mootools-1.2-core-yc.js inside the admin/links/index page.  Righto, so now the only thing left to do is get the mootools-1.2-core-yc.js file into the actual public/javascripts/admin directory within the project.  What you want to do is alter the vendor/extensions/link_roll/link_roll_extension.rb file so that within the activate method the file is copied over.  I’d recommend making a public/javascripts/admin directory within your extension folder, and putting the file in there.  Then, when activate is called on the link_roll_extension.rb file, the activate method will copy the file over to the projects public/javascripts/admin directory.  You should also delete the file when the deactivate method is called in the link_roll_extension.rb file.

Questions and comments please!

Comments (1) »

Mnemonic Password Generator - a la Ruby

I wanted to have a mnenonic password generator for a little application that I’m writing in ruby, and couldn’t find one out there. So, I rolled my own. Actually, it’s a knock-off of a Python one I found, but that doesn’t really matter.

Do with this what you will. Hope it’s useful to someone.


def generateMnemonicPassword(letters=8, digits=4)
consonants = "bdfghklmnprstvwz"
vowels = "aeiou"
password = ""
(1 .. letters).each do |i|
range = i%2 == 1 ? consonants : vowels
password = password + range[rand(range.length), 1]
end
(1 .. digits).each do |i|
password = password + rand(10).to_s
end
password
end

It outputs fun and pronounceable passwords such as tepelopu8058, vonobuba6145 and kipowetu0270.

Enjoy!

No comment »

Time for the big upgrade

Righto, I’ve been putting it off long enough. Got the GiST has been running on rails 1.1.6 almost since it has been launched, and I’d like to take advantage on some of that RESTful 2.0 goodness. So, I’ve decided it’s time to upgrade it.

I’ve got a couple of issues though. I currently use (shhhh, I’m about to say a dirty word) Engines to handle my user logins and roles… They don’t work with much past rails 1.1.6. I also don’t have good admin screens on the application, and whenever I need to do maintenance (which is very rare) I need to go and edit the database directly :-(

So, there are a number of things that I want to do to the app.

  1. Upgrade to Rails 2.0.2
  2. Convert my user login goodies to use acts_as_authenticated
  3. Get another way to handle roles
  4. Implement Streamlined for admin screens
  5. Write some tests - I’ve was a bit slack when I initially wrote Got the GiST
  6. Refactor my code - this goes without saying - some of it is a bit shabby

The main issue I have is that I’m not sure what order I want to do this in. The issue that I have is there are a number of dependencies. For example, old-style Engines doesn’t work past 1.1.6 - and I have my complete login and role system built around that. streamlined don’t appear to work with Rails 1.1.x. acts_as_authenticated requires a simple bit of script hackery to work with 1.1.6, so that might be able to come early…

I think what I’m going to do is drop Engines ASAP. That’s the main cause of my pain. I need to recreate with acts_as_authenticated essentially the same methods for authentication as login_engine currently has, as well as find a (perhaps temporary) solution to my roles issues. Then I’ll set about writing tests. Next step I think could be to upgrade to 1.2.6, and then implement streamlined. I think I’ll then be ready for a migration to Rails 2.0.

Unless someone else has a much better suggestion!

No comment »

scRUBYt - Hot, New Ruby Web-Scraping Toolkit Released

scRUBYt - Hot, New Ruby Web-Scraping Toolkit Released

Peter Cooper over at rubyinside.com has recently blogged about scRUBYt - a new ruby based web scraping toolkit.

It looks super-powerful.

Basically, you define an extractor, which can pull HTML (even including posting form data, such as product searches), click on links, pull content from the page and create XML with it.

What I particularly like about this is now this gives developers the ability to very simply include content from sites that aren’t mashup-friendly (ie, REST or SOAP APIs). I mean, it was of course possible before, but this just seems so much easier. No-ones content is safe!

No comment »

Lonely, lonely classes

I just had my most pleasant experience with Singletons ever. I had a little problem I was trying to solve in ruby, and I contacted a friend of mine who is quite a good developer. He suggested I should be looking at global variables, to static (class) variables, or singletons. I gave globals a go, and they didn’t give me the love I expected, so I said “bye bye” to them - probably never to be used again. I next tried Singletons.

Ruby defines a Singleton module. This is mixin’d with your code thusly:


class Lonely
include Singleton
end

Easy peasy.

That, creates a singleton of Lonely for you. The include modifies the signatures of the new and allocate Class methods (Lonely.new and Lonely.allocate) to be private, and creates (or modifies) some other methods to provide some loveliness (gory details to be found at http://www.ruby-doc.org/stdlib/libdoc/singleton/rdoc/index.html).

Basically, then all you need to do is call the instance method of the class you have created.


m = Lonely.instance

And then you can use m as you like. You can create more


m = Lonely.instance
n = Lonely.instance

And m and n refer to the same instance. Nice Singleton. No need for me to check out class variables. I think my Singleton will be more portable. BTW - Don’t try to .new your class - you’ll get a NoMethodError thrown as the new method has been made private by the mixin.

Ruby rocks.

No comment »

VerseLogic » Wordpress OpenID Plugin

I just installed the VerseLogic wordpress OpenID plugin. This means that you guys (if you have an OpenID already) don’t have to explicitly register on my site to comment. You can just log in with your OpenID, and an account will be created here for you. No more passwords!

You can get a free OpenID at http://myopenid.com/

To find out more about OpenID, check it all out here.

Comments (2) »

Scope, creep. Part 2.

Ah. The satisfying feeling of knowing you’ve created some elegant and functional code. That piece of functionality took a bit longer than I expected. Now to make it more robust. I’ve got a bit of error checking and feedback to insert, then we’re ready to roll.
See more progress on: Start my own business

No comment »

wtf is racc?

racc is the rubyised implementation of lex/yacc. I want to learn this as I’ve got some file parsing that needs doing, and this is the proper way to parse files. It’s a lot of guesswork at the moment…
Check http://i.loveruby.net/en/projects/racc/ to see what I’m on about.

See more progress on: learn to use racc

No comment »

Scope, creep.

It’s getting the better of me. I thought of a feature today that the application really should have. Now, I just have to build it in. Shouldn’t take me too long, I’ve just completed my design, now onto the coding.
See more progress on: Start my own business

No comment »