Saturday 26 July 2008

xml_hidden plugin

Recently I've been investigating the steps needed to open up FilmAmora's API to the outside world. That means supplying xml data so people can do what they want with it.
But I didn't want sensitive data in models to be exposed in the xml. And I also am too lazy to write custom to_xml methods for everything.

So I wrote a plugin call xml_hidden That lets you set something on the class to hide certain attributes from xml output.

class Film < ActiveRecord::Base
attr_xml_hidden :acquiring_url, :id, :created_at
end


Now whenever I output a film to xml those values can't be seen.

Sunday 20 July 2008

Escaping for JavaScript

Recently I've started to use the most excellent Prototip2 for doing sexy tooltip stuff. It works a treat.
The only problem I have had is that some of the things I want to put into the tips have single quotes in them (e.g Bob's Team). I was surprised to find that Rails doesn't (as far as I could find) have a handy dandy way of making strings JS friendly. So I whipped up this extention to Erb::Util.
I hope some of you find it useful. It will escape single quotes and as an added bonus it also does the html escaping so you only have to make one call.

class ERB
module Util
def js_escape(str)
h(str.gsub(/[']/, '\\\\\''))
end

alias js js_escape
module_function :js
module_function :js_escape
end
end


I put this into an initializer.

You can then call it from your views like this:

<%=js team.name%>

Monday 14 July 2008

Combating XSS

This info is available elsewhere, but as I always forget, this is a good place to repeat it.

Install the White List plugin. Get it here

Once installed you'll need to add the following line to the init.rb of the white_list plugin:
ActionView::Base.send :include, WhiteListHelper


In the Application.rb (Application Controller)
include HtmlFilterHelper
before_filter :sanitize_params


Then I have a class called HtmlFilterHelper
module HtmlFilterHelper
def sanitize_params(params = params)
params = walk_hash(params) if params
end

private
def walk_hash(hash)
hash.keys.each do |key|
if hash[key].is_a? String
hash[key] = white_list(hash[key])
elsif hash[key].is_a? Hash
hash[key] = walk_hash(hash[key])
elsif hash[key].is_a? Array
hash[key] = walk_array(hash[key])
end
end
hash
end

def walk_array(array)
array.each_with_index do |el,i|
if el.is_a? String
array[i] = white_list(el)
elsif el.is_a? Hash
array[i] = walk_hash(el)
elsif el.is_a? Array
array[i] = walk_array(el)
end
end
array
end
end


For what it is worth, I also do stuff like this:

<%=white_list synopsis.synopsis[0,100].gsub(/<\/?[^>]*>/, "")%>


Which removes any html-style tags from the text and then white_list's it before outputting.

Wednesday 9 July 2008

Becoming a Git

Recently the SVN repository service we were using for FilmAmora had a lengthy outage. So, being a real Rails-er I decided to switch over to GitHub. Getting the source up into it was pretty easy.

So, I went ahead and started making changes and doing git commit's and all that good stuff. Well, today I went to the projects homepage on GitHub and you can imagine my surprise and horror when I saw that it looked like nothing had been checked in since my original commit.

Wot de hell?!

I then scoured the net for Git for dummies without success. So here it is:

1) Do all the stuff they tell you do to to get your code in.
2) Do your commits... but remember that for some strange reason you are committing into your LOCAL Git repository.
3) here's the key - do a git push! that will chuck your code up onto the server.

Seems perhaps obviously, but coming from an svn or cvs background it confused the hell out of me.
At a later date (probably this weekend) I will write a little Git note about how this works from the perspective of someone used to using one of the more traditional source code systems.

Saturday 5 July 2008

Euro-friendly permalinks

Permalink_fu is rather an awesome thing. The only drawback is that it doesn't really handle accented characters very well. I've looked around and seen a bunch of solutions that attempt to be 'clever' and do the substitution on one line, etc. But I decided that I'd rather go for brute force.
I created an extension to String with one method called 'no_accents':
class String
def no_accents


Then I do a whack of these:

    str = self
#Spanish letters
str = str.gsub("á", "a")
str = str.gsub("é","e")

For upper and lower case.
Obviously there is a big list. Right now I am just doing Spanish, French and German as they are the ones I am most interested in.

I had to make a change to Permalink_fu to call my method first:
    def escape(str)
str = str.no_accents
s = ((translation_to && translation_from) ? Iconv.iconv(translation_to, translation_from, str) : str).to_s


But that's all.

Here is the file. What I did is put it in my initializers directory.

If you add to it maybe you could post your additions. I am sure some clever-clogs out there will come up with a more slick solution. But... mine works!