Integrating OpenAds with Rails

December 21, 2006

Integrating OpenAds and Rails isn’t that painful. Adding the code to the right spots (see below) will let you do something like this in your views:

<%= render_ad_banner('728x90') %>
<%= render_ad_banner('728x90', :what => 'zone:107') %>
<%= render_ad_banner('728x90', :refresh => 30) %>

The first pulls a banner from the default zone for the given size. The second specifies the size, but overrides the zone. The third uses the default, but requests that the banner refresh every 30 seconds.

See below for how it all works. In a nutshell, we define some values in config/site.yml, set them up config/environements.rb then use them in the render_ad_banner() helper method.

Note the bit about ‘static_banners’. This gets used if we’re using static banners, so be sure to have a static banner in each size named appropriately in your public/images/static_banners directory.

An added benefit of this setup is that each banner is rendered inside an iframe. Whatever your feeling about iframes this gives us some protection against third-party HTML banners that would otherwise blow the page completely apart.

Also, creating a “.ad_banner” CSS element allows you to set some consistent decoration for every banner on your site, be it borders, padding, whatever.

config/site.yml

defaults: &defaults
  use_static_banners: false
  banner_zones: { 
                 '230x100' : 97,
                 '258x150' : 98,
                 '478x80' : 102,
                 '728x90' : 28,
                 '125x125' : 30,
                 '120x600' : 31,
                } 
  phpads_url: ads.domain.com

config/environments.rb

#
    # Read in the site.yml file
    #
    SITE_YAML = YAML::load(ERB.new(IO.read('#{RAILS_ROOT}/config/site.yml'), nil, '-').result)
    SITE_YAML.freeze

    SITE_YAML_ENV = SITE_YAML[RAILS_ENV]
    SITE_YAML_ENV.freeze

    #
    # Ad Banners
    #
    # * Use static banners unless otherwise defined
    # * Define the default zones for the given sizes
    #
    BANNER_STATIC = SITE_YAML_ENV['use_static_banners']
    BANNER_STATIC.freeze

    BANNER_ZONES = SITE_YAML_ENV['banner_zones']
    BANNER_ZONES.freeze

app/helpers/application_helper.rb

# 
# Return the HTML necessary to display an ad banner of the given +size+.
# +options+ takes the following optional keys:
# 
# * :what => what (see phpads for details)
# * :refresh => number of seconds to cycle.
#
#
def render_ad_banner(size, options = {})
  what = options[:what]
  refresh = options[:refresh]

  width, height = size.split(/x/)
  width_em = width.to_f / 10.0

  if BANNER_STATIC then
    banner = image_tag('static_banners/#{size}.gif', {:alt => '', :size => size})
  else
    if what.nil? || what.empty? then
      if BANNER_ZONES[size].nil? then
        banner = image_tag('static_banners/#{size}.gif', {:alt => '', :size => size})
      end
      what = 'zone:' + BANNER_ZONES[size].to_s
    end

    if banner.nil? then

      require 'md5'
      n = ('a' + (MD5.md5(Time.new.to_f.to_s)).to_s)[0..7]

      unless refresh.nil? || refresh.to_i <= 0 then
        refresh = '&amp;refresh=#{refresh}'
      else
        refresh = ''
      end

      server_name = SITE_YAML[RAILS_ENV]['phpads_url'] || request.env['SERVER_NAME']

      banner = "<iframe id='#{n}' name='#{n}' 
        src='http://#{server_name}/banrotate/adframe.php?n=#{n}&amp;what=#{what}&amp;target=_blank#{refresh}' 
        framespacing='0' frameborder='no' scrolling='no' 
        width='#{width}' 
        height='#{height}'
        ><a href='http://#{server_name}/banrotate/adclick.php?n=#{n}' 
          target='_blank'><img src='http://#{server_name}/banrotate/adview.php?what=#{what}&amp;n=#{n}' 
                  border='0' alt=''></a></iframe>"

    end
  end

  "<div class='ad_banner' style='width: #{width_em}em'>#{banner}</div>"

end