[Nitro] Generating scaffolding / stub codes?

James Britt james_b at neurogami.com
Tue Feb 21 23:14:10 EST 2006

Bryan Soto wrote:
> On 2/21/06, *James Britt* <james_b at neurogami.com 

>     On the other hand, I wrote my own controller stub generator with very
>     little effort.
>     Perhaps there should be a way for people to submit their own generators
>     for possible inclusion in future releases.
> If you're interested in submitting them, please just email them here. :)
> It's not exactly a formal process, but it could be a nice way to pioneer 
> things.

I followed a times-tested procedure: Copy the files for 'app' and munge 
them up.  BTW, my controller gen no longer works, as I've installed 
Nitro 0.28 and I now get this:

can't activate gen (= 0.27.0), already activated gen-0.28.0] 

So there needs to be a way to separate the custom templates from 
specific versions of gen, Nitro, etc.

But, assuming that:

   gen app MyAppName

drives a call to

   require "gen/#{generator}/gen.rb"
  require "gen/app/gen.rb"

inside the gen script

  gen controller Main

would invoke

  require "gen/controller/gen.rb"

So  created a new subdir, 'controller', off the gen directory (in my 
gems tree)

As with the 'app' subdir needed for the app generator, my new folder has 
a gen.rb file.

Basically stealing the behavior of the 'app' generator, I came up with this:


require 'nano/dir/self/recurse'

require 'gen'
require 'nitro'

PROTO_DIR = File.join( Nitro::LibPath, '..', 'controller_proto')

# gen controller - Nitro controller generator.
# This generator will create some basic files to get you
# started fleshing out your Nitro web controller.
# The proto directory structure in the standard Nitro
# distribution is used as reference.
# === Example
# gen controller ~/my_controller
# This will generate a new Nitro controller in the
# ~/my_controller folder.

class AppGen < Gen

   def setup
     @ctrl_name = ARGV[0] || usage()
     @ctrl_path = File.expand_path( File.dirname( @ctrl_name ) )

   def run
     if File.exists? @ctrl_name
       STDERR.puts "ERROR: Path #{@ctrl_name} already exists! Aborting!"
       exit 1

     puts "Copying proto controller  to '#@ctrl_name'"
     src = IO.read( "#{PROTO_DIR}/proto_controller.rb" )
     src.gsub!( 'PROTOTEMPLATES', @ctrl_name.downcase )
     src.gsub!( 'PROTO', @ctrl_name.capitalize )

     File.open( "#{@ctrl_path}/#{@ctrl_name.downcase}_controller.rb" , 
'wb' ){ |f| f.puts src}

     puts 'Done'


$generator = AppGen.new

# The end :)

This first thing to note is that this code, as with 'app', expects to 
find template files in PROTO_DIR. It then copies over those files to the 
target location.

I created a 'controller_proto' along side the existing 'proto' dir used 
by the 'app' generator.  But you can see that this ties my customer 
generator to that version of Nitro. :(

My generator needed to create class code based on the given for the 
controller, so my template files have some BIGBLOCK strings that get 
swapped out with the correct values.

class PROTOController < Nitro::Controller

   def initialize( *args )
     @template_root = "/templates/PROTOTEMPLATES"
     super *args


   def myname
     __FILE__.split( '/' ).last.to_s


It's pretty simple; the issues now are figuring out how and where to 
store such generators so that updating gen and/or Nitro does not break 
anything.  (I seem to recall issues with rubygems and installing items 
to DATADIR or something.  One hackish option is to install the prototype 
folders to RUBY_BIN (or something) or some other known fixed place.)

> ...

> Re: gems;
> Looking at the gen script, it seems that if you follow the directory 
> structure gen/#{generator}/gen.rb, or to use your controller generator 
> as an example,
> gen/controller/gen.rb
> # gen controller params_go_here
> would actually find it now thanks to how Rubygems works. Completely 
> untested though. Of course you'd potentially have a lot of collisions if 
> it caught on so some formal system would have to be worked out. 

That's how my stuff worked.  Yes, collisions are possible; that's true 
now of any gem, I believe.  Have to see how gems handles it if I try to 
install a gem that claims an existing name and version of some other gem.

> I'd 
> imagine that's why the Rails folk went with the plugin idea?

I believe that plug-ins install to a specific application; they become 
part of that application's base code and alter the core Rails classes at 
runtime (I think; the one plugin I tried so screwed my Rails app I 
removed it fairly quick, and haven't had a reason to use any others.)

But a Nitro generator (though there is no good reason to couple them to 
Nitro, really) should be available system-wide.

James Britt

“Design depends largely on constraints.”
  — Charles Eames

More information about the Nitro-general mailing list