07/11/2010: Using ImageMagick To Create Horizontally Repeating Background Image
Using ImageMagick To Create Horizontally Repeating Background Image
- Find an image that you want to slice vertically, which I'll refer to as the base image. This slice is what will be repeated across the background of the web page.
- Use the
identify home_page.jpg
command to find out some details about the base image. The result of this command looks like this:home_page.jpg JPEG 1300x1380 1300x1380+0+0 8-bit DirectClass 736KiB 0.240u 0:00.240
- For our purposes, the first set of numbers is sufficient. They hold the width and height.
- The next step involves extracting a vertical slice (top to bottom) from the base image. Use this command:
convert -extract 10x1380+0+0 home_page.jpg body_background.png
. Notice that you can vary the width of the slice using the first number. In this case, I use 10 but some other number is probably more appropriate for you. - If you want to test various widths, you can 'tail' the background image using
display -update 1 body_background.png
which redisplays the image every second. - Once you've got the vertical slice, you need to integrate it with your web page.
- Use CSS similar to this:
body { background-image: url('body_background.png'); background-repeat: repeat-x; }
07/01/2010: Using module_eval to Define Instance Methods in a Ruby Gem to Enable Per-Model Configuration
In the last post, I mentioned that I wrote a small gem to post changes to ActiveRecord models to Twitter. In that version, the configuration was handled by a YAML file. I wanted to evolve the gem so that developers could switch Twitter accounts for each model.
Basically, I wanted to able to the use the following:
class Place < ActiveRecord::Base alastrina :twitter => { :username => 'alastrina_gem', :password => 'QQQQQQ' } end
After a bit of tinkering and searching, I decided to use the following code in my gem.
ALASTRINA_CONFIGURATION_FILE = 'config/alastrina.yml' module Alastrina def self.included(base) base.extend(ClassMethods) end module ClassMethods def alastrina hash module_eval do def configuration throw "Missing #{ALASTRINA_CONFIGURATION_FILE}" unless File.exists? ALASTRINA_CONFIGURATION_FILE @config ||= YAML::load(File.read(ALASTRINA_CONFIGURATION_FILE)) end if hash[:twitter] def send_to_twitter? true end eval"def twitter_username\n\"#{hash[:twitter][:username]}\"\nend\n" eval "def twitter_password\n\"#{hash[:twitter][:password]}\"\nend\n" else def send_to_twitter? @twitter_flag ||= !configuration['twitter'].blank? end def twitter_username @twitter_username ||= configuration['twitter']['username'] if send_to_twitter? end def twitter_password @twitter_password ||= configuration['twitter']['password'] if send_to_twitter? end end end end end def after_save if send_to_twitter? require 'twitter' throw "Missing Twitter userid" if twitter_username.blank? throw "Missing Twitter password" if twitter_password.blank? send_via_twitter end end private def send_via_twitter if changes.size > 0 httpauth = Twitter::HTTPAuth.new(twitter_username, twitter_password) client = Twitter::Base.new(httpauth) begin client.update(changes.to_yaml) rescue RAILS_DEFAULT_LOGGER.error "alastrina.send_via_twitter; Unable to send change. Message[#{$!}] Change[#{changes.to_yaml}]" end end end end ActiveRecord::Base.class_eval { include Alastrina }
The key insight to this code is how the hash passed on the alastrina
of the Model is passed down into the instance. The code is fairly straightforward once you see what the eval is doing.