The ELC Community Blog
A knowledge exchange on Ruby on Rails and Agile Development
Creating new generator commands
by Daniel Lunde on November 19, 2007
Extending the built-in generator commands
The built-in generator commands will do most of what you would expect (like copy files, create directories, create a file based on a template, and generate migrations), but there are times when we need it do something a little more unique.
For instance, inserting a line (or lines) of code into a given file. In my case I needed to add a new entry into my crossdomain.xml. The following method will insert a new string either before or after a given string match.
This technique builds on the strategy that the scaffold generator uses to insert a map.resources into the routes.rb.
def file_insert(path, insert_me, sentinel, insert_before=true)
fullpath = destination_path(path)
content = File.read(fullpath)
unless content.include? insert_me
content = content.gsub /(#{Regexp.escape(sentinel)})/mi do |match|
(insert_before) ? "#{insert_me}#{match}" : "#{match}#{insert_me}"
end
File.open(fullpath, 'wb') { |file| file.write(content) }
logger.updated path
else
logger.identical path
end
end
And here we make the change to the crossdomain.xml
def crossdomain()
path = 'public/crossdomain.xml'
domain_list = " <allow-access-from domain=\"#{dns_name}\" />\n"
domain_list += " <allow-access-from domain=\"*.#{dns_name}\" />\n"
sentinel = '</cross-domain-policy>'
file_insert(path, domain_list, sentinel)
end
Using those methods, updating the crossdomain.xml file is easy. And if you happen to re-run the generator with the same parameters, it reports it as identical and won't re-insert the string a second time.
Bringing it all together
So where do we put these methods? You can actually stick them in with your custom generator.
class MyCustomGenerator < Rails::Generator::NamedBase
attr_reader :dns_name
def initialize(runtime_args, runtime_options = {})
super
@dns_name = args.join.downcase
end
def manifest
record do |m|
# Add something ridiculous
m.file_insert('public/500.html', "<h3>Ridiculous</h3>", "<body>", false)
# Add crossdomain entry
m.crossdomain
end
end
protected
# Add your custom methods here...
def file_insert(...)
def crossdomain()
end
Now if I could just write a generator to build my entire website...
Timeline
- OpenSocial? What's that?
- Ruby on Rails, OpenSocial Container plugin 0.1.0
- Ruby on Rails primer for Java developers
- OpenSocial container plugin 0.0.1
- Ultraviolet syntax highlighting in Mephisto
- Creating new generator commands
- Testing Libraries
- Rendering views without a web request in rails
- Can I Take a Test Drive?
- Points and Velocity in Trac Reports
- Installing Freeimage + image_science on Leopard
Comments