Permalink
Browse files

Initial version, very rough in the edges and not tested thoroughly.

  • Loading branch information...
1 parent f527dea commit e1d6b2aa8d5279ca0823f33463d1fb0c8c205e3c @grimen committed Apr 16, 2009
Showing with 800 additions and 0 deletions.
  1. +20 −0 MIT-LICENSE
  2. +29 −0 README.textile
  3. +47 −0 Rakefile
  4. +11 −0 generators/USAGE
  5. +107 −0 generators/dry_scaffold/dry_scaffold_generator.rb
  6. +19 −0 generators/dry_scaffold/templates/controller_inherited_resources.rb
  7. +130 −0 generators/dry_scaffold/templates/controller_standard.rb
  8. +64 −0 generators/dry_scaffold/templates/functional_test_standard.rb
  9. +2 −0 generators/dry_scaffold/templates/helper_standard.rb
  10. +19 −0 generators/dry_scaffold/templates/prototypes/controller_inherited_resources.rb
  11. +130 −0 generators/dry_scaffold/templates/prototypes/controller_standard.rb
  12. +64 −0 generators/dry_scaffold/templates/prototypes/functional_test_standard.rb
  13. +2 −0 generators/dry_scaffold/templates/prototypes/helper_standard.rb
  14. +3 −0 generators/dry_scaffold/templates/prototypes/view__form.html.haml
  15. +9 −0 generators/dry_scaffold/templates/prototypes/view__item.html.haml
  16. +12 −0 generators/dry_scaffold/templates/prototypes/view_edit.html.haml
  17. +17 −0 generators/dry_scaffold/templates/prototypes/view_index.html.haml
  18. +12 −0 generators/dry_scaffold/templates/prototypes/view_new.html.haml
  19. +14 −0 generators/dry_scaffold/templates/prototypes/view_show.html.haml
  20. +4 −0 generators/dry_scaffold/templates/view__form.html.haml
  21. +10 −0 generators/dry_scaffold/templates/view__item.html.haml
  22. +12 −0 generators/dry_scaffold/templates/view_edit.html.haml
  23. +18 −0 generators/dry_scaffold/templates/view_index.html.haml
  24. +12 −0 generators/dry_scaffold/templates/view_new.html.haml
  25. +13 −0 generators/dry_scaffold/templates/view_show.html.haml
  26. +20 −0 tasks/dry_scaffold.rb
View
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Jonas Grimfelt
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
@@ -0,0 +1,29 @@
+h1. DRY SCAFFOLD
+
+h2. SYNOPSIS
+
+...
+
+h2. DESCRIPTION
+
+...
+
+h2. INSTALLATION
+
+...
+
+h2. BASIC USAGE
+
+...
+
+h2. ADVANCED USAGE
+
+...
+
+h2. BUGS & FEEDBACK
+
+...
+
+h2. LICENSE
+
+...
View
@@ -0,0 +1,47 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+NAME = "dry_scaffold"
+SUMMARY = %Q{Generating DRY views for your RESTful application.}
+HOMEPAGE = "http://github.com/grimen/#{NAME}/tree/master"
+AUTHOR = "Jonas Grimfelt"
+EMAIL = "grimen@gmail.com"
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = NAME
+ gem.summary = SUMMARY
+ gem.description = SUMMARY
+ gem.homepage = HOMEPAGE
+ gem.author = AUTHOR
+ gem.email = EMAIL
+
+ gem.require_paths = %w{lib}
+ gem.files = %w(MIT-LICENSE README.textile Rakefile) + Dir.glob(File.join('{generators,tasks}', '**', '*'))
+ gem.executables = %w()
+ gem.extra_rdoc_files = %w{README.textile}
+ end
+rescue LoadError
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
+end
+
+desc %Q{Run unit tests for "#{NAME}".}
+task :default => :test
+
+desc %Q{Run unit tests for "#{NAME}".}
+Rake::TestTask.new(:test) do |test|
+ test.libs << 'lib'
+ test.pattern = 'test/**/*_test.rb'
+ test.verbose = true
+end
+
+desc %Q{Generate documentation for "#{NAME}".}
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = NAME
+ rdoc.options << '--line-numbers' << '--inline-source' << '--charset=UTF-8'
+ rdoc.rdoc_files.include('README.textile')
+ rdoc.rdoc_files.include(File.join('lib', '**', '*.rb'))
+end
View
@@ -0,0 +1,11 @@
+NAME
+ dry_views_generator - short description of the generator
+
+SYNOPSIS
+ ...
+
+DESCRIPTION
+ ...
+
+EXAMPLE
+ ./script/generate dry_scaffold ModelName [-r/--skip-resourceful] [-f/--skip-formtastic]
@@ -0,0 +1,107 @@
+class DryScaffoldGenerator < Rails::Generator::Base
+
+ CONTROLLERS_PATH = File.join('app', 'controllers').freeze
+ FUNCTIONAL_TESTS_PATH = File.join('test', 'functional').freeze
+ HELPERS_PATH = File.join('app', 'helpers').freeze
+ VIEWS_PATH = File.join('app', 'views').freeze
+ MODELS_PATH = File.join('app', 'models').freeze
+
+ RESOURCEFUL_COLLECTION_NAME = 'collection'.freeze
+ RESOURCEFUL_SINGULAR_NAME = 'resource'.freeze
+
+ PARTIALS = %w{form item}.freeze
+ ACTIONS = %w{new edit show index}.freeze
+
+ attr_reader :collection_name
+
+ def initialize(runtime_args, runtime_options = {})
+ super
+
+ @controller_name = @name.pluralize
+
+ self.base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
+ @controller_class_name_without_nesting, @controller_underscore_name, @controller_plural_name = inflect_names(base_name)
+ @controller_singular_name = self.base_name.singularize
+
+ if @controller_class_nesting.empty?
+ @controller_class_name = @controller_class_name_without_nesting
+ else
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
+ end
+ end
+
+ def manifest
+ record do |m|
+ # Check for class naming collisions.
+ m.class_collisions(self.controller_class_path, "#{self.controller_class_name}Controller", "#{self.controller_class_name}Helper")
+ m.class_collisions(self.class_path, "#{self.class_name}")
+
+ # Controllers
+ m.directory File.join(CONTROLLERS_PATH, self.controller_class_path)
+ controller_template = options[:skip_resourceful] ? 'standard' : 'inherited_resources'
+ m.template "controller_#{controller_template}.rb",
+ File.join(CONTROLLERS_PATH, self.controller_class_path, "#{self.controller_file_name}_controller.rb")
+
+ # Functional Tests
+ m.directory(File.join(FUNCTIONAL_TESTS_PATH, self.controller_class_path))
+ m.template 'functional_test_standard.rb',
+ File.join(FUNCTIONAL_TESTS_PATH, self.controller_class_path, "#{self.controller_file_name}_controller_test.rb")
+
+ # Helpers
+ m.directory(File.join(HELPERS_PATH, self.controller_class_path))
+ m.template 'helper_standard.rb',
+ File.join(HELPERS_PATH, self.controller_class_path, "#{self.controller_file_name}_helper.rb")
+
+ # Views
+ m.directory File.join(VIEWS_PATH, self.class_path)
+ PARTIALS.each do |partial|
+ m.template "view__#{partial}.html.haml",
+ File.join(VIEWS_PATH, self.file_name, "#{partial}.html.haml"),
+ :assigns => {:options => options}
+ end
+ ACTIONS.each do |action|
+ m.template "view_#{action}.html.haml",
+ File.join(VIEWS_PATH, self.file_name, "#{action}.html.haml"),
+ :assigns => {:options => options}
+ end
+
+ # Routes
+ m.route_resources self.controller_file_name
+
+ # Models - use Rails default generator
+ m.dependency 'model', [self.name] + @args, :collision => :skip
+ end
+ end
+
+ protected
+
+ def model_name
+ class_name.demodulize
+ end
+
+ def assign_names!(name)
+ super
+ @collection_name = options[:skip_resourceful] ? @plural_name : RESOURCEFUL_COLLECTION_NAME
+ @singular_name = options[:skip_resourceful] ? @singular_name : RESOURCEFUL_SINGULAR_NAME
+ @plural_name = options[:skip_resourceful] ? @plural_name : RESOURCEFUL_SINGULAR_NAME.pluralize
+ end
+
+ def add_options!(opt)
+ opt.separator ''
+ opt.separator 'Options:'
+ opt.on('-r', '--skip-resourceful',
+ "Generate generic 'inherited_resources' style URL names, i.e. collection_url, resource_url, etc. " +
+ "Requires gem 'josevalim-inherited_resources'") do |v|
+ options[:skip_resourceful] = v
+ end
+ opt.on('-f', '--skip-formtastic',
+ "Generate semantic 'formtastic' style forms. Requires gem 'justinfrench-formtastic'") do |v|
+ options[:skip_formtastic] = v
+ end
+ end
+
+ def banner
+ "Usage: #{$0} dry_scaffold ModelName [-r/--skip-resourceful] [-f/--skip-formtastic]"
+ end
+
+end
@@ -0,0 +1,19 @@
+class <%= controller_class_name %>Controller < InheritedResources::Base
+
+ actions :index, :show, :new, :create, :edit, :update
+ respond_to :html, :xml, :json
+
+ protected
+
+ def collection
+ paginate_options ||= {}
+ paginate_options[:page] ||= (params[:page] || 1)
+ paginate_options[:per_page] ||= (params[:per_page] || 20)
+ @<%= self.controller_file_name.pluralize %> ||= end_of_association_chain.paginate(paginate_options)
+ end
+
+ def resource
+ @<%= self.controller_file_name %> ||= end_of_association_chain.find(params[:id])
+ end
+
+end
@@ -0,0 +1,130 @@
+class <%= controller_class_name %>Controller < ApplicationController
+
+ before_filter :load_resource, :except => [:index, :new, :create]
+ before_filter :load_and_paginate_resources, :only => [:index]
+
+ # GET /<%= controller_file_name.pluralize %>
+ # GET /<%= controller_file_name.pluralize %>.xml
+ # GET /<%= controller_file_name.pluralize %>.json
+ def indexw
+ @<%= controller_file_name.pluralize %> = <%= controller_class_name %>.all
+
+ respond_to do |format|
+ format.html # index.html.haml
+ #format.js # index.js.rjs
+ format.xml { render :xml => @<%= controller_file_name.pluralize %> }
+ format.json { render :json => @<%= controller_file_name.pluralize %> }
+ end
+ end
+
+ # GET /<%= controller_file_name.pluralize %>/1
+ # GET /<%= controller_file_name.pluralize %>/1.xml
+ # GET /<%= controller_file_name.pluralize %>/1.json
+ def show
+ respond_to do |format|
+ format.html # show.html.haml
+ #format.js # show.js.rjs
+ format.xml { render :xml => @<%= controller_file_name.singularize %> }
+ format.json { render :json => @<%= controller_file_name.singularize %> }
+ end
+ end
+
+ # GET /<%= controller_file_name.pluralize %>/new
+ # GET /<%= controller_file_name.pluralize %>/new.xml
+ # GET /<%= controller_file_name.pluralize %>/new.json
+ def new
+ @<%= controller_file_name.singularize %> = <%= controller_class_name %>.new
+
+ respond_to do |format|
+ format.html # new.html.haml
+ #format.js # new.js.rjs
+ format.xml { render :xml => @<%= controller_file_name.singularize %> }
+ format.json { render :json => @<%= controller_file_name.singularize %> }
+ end
+ end
+
+ # GET /<%= controller_file_name.pluralize %>/1/edit
+ def edit
+ end
+
+ # POST /<%= controller_file_name.pluralize %>
+ # POST /<%= controller_file_name.pluralize %>.xml
+ # POST /<%= controller_file_name.pluralize %>.json
+ def create
+ @<%= controller_file_name.singularize %> = <%= controller_class_name %>.new(params[:<%= controller_file_name.singularize %>])
+
+ respond_to do |format|
+ if @<%= controller_file_name.singularize %>.save
+ flash[:notice] = '<%= controller_file_name.singularize.humanize %> was successfully created.'
+ format.html { redirect_to(@<%= controller_file_name.singularize %>) }
+ #format.js # create.js.rjs
+ format.xml { render :xml => @<%= controller_file_name.singularize %>, :status => :created, :location => @<%= controller_file_name.singularize %> }
+ format.json { render :json => @<%= controller_file_name.singularize %>, :status => :created, :location => @<%= controller_file_name.singularize %> }
+ else
+ #flash[:error] = '<%= controller_file_name.singularize.humanize %> could not be created.'
+ format.html { render 'new' }
+ #format.js # create.js.rjs
+ format.xml { render :xml => @<%= controller_file_name.singularize %>.errors, :status => :unprocessable_entity }
+ format.json { render :json => @<%= controller_file_name.singularize %>.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /<%= controller_file_name.pluralize %>/1
+ # PUT /<%= controller_file_name.pluralize %>/1.xml
+ # PUT /<%= controller_file_name.pluralize %>/1.json
+ def update
+ respond_to do |format|
+ if @<%= controller_file_name.singularize %>.update_attributes(params[:<%= controller_file_name.singularize %>])
+ flash[:notice] = '<%= controller_file_name.singularize.humanize %> was successfully updated.'
+ format.html { redirect_to(@<%= controller_file_name.singularize %>) }
+ #format.js # update.js.rjs
+ format.xml { head :ok }
+ format.json { head :ok }
+ else
+ #flash[:error] = '<%= controller_file_name.singularize.humanize %> could not be updated.'
+ format.html { render 'edit' }
+ #format.js # update.js.rjs
+ format.xml { render :xml => @<%= controller_file_name.singularize %>.errors, :status => :unprocessable_entity }
+ format.json { render :json => @<%= controller_file_name.singularize %>.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /<%= controller_file_name.pluralize %>/1
+ # DELETE /<%= controller_file_name.pluralize %>/1.xml
+ # DELETE /<%= controller_file_name.pluralize %>/1.json
+ def destroy
+ respond_to do |format|
+ if @<%= controller_file_name.singularize %>.destroy
+ flash[:notice] = '<%= controller_file_name.singularize.humanize %> was successfully destroyed.'
+ format.html { redirect_to(resources_url) }
+ #format.js # destroy.js.rjs
+ format.xml { head :ok }
+ format.json { head :ok }
+ else
+ flash[:error] = '<%= controller_file_name.singularize.humanize %> could not be destroyed.'
+ format.html { redirect_to(resource_url(@<%= controller_file_name.singularize %>)) }
+ #format.js # destroy.js.rjs
+ format.xml { head :unprocessable_entity }
+ format.json { head :unprocessable_entity }
+ end
+ end
+ end
+
+ protected
+
+ def collection
+ paginate_options ||= {}
+ paginate_options[:page] ||= (params[:page] || 1)
+ paginate_options[:per_page] ||= (params[:per_page] || 20)
+ @<%= controller_file_name.pluralize %> ||= end_of_association_chain.paginate(paginate_options)
+ end
+ alias :load_and_paginate_resources :collection
+
+ def resource
+ @<%= controller_file_name.singularize %> ||= end_of_association_chain.find(params[:id])
+ end
+ alias :load_resource :resource
+
+end
Oops, something went wrong.

0 comments on commit e1d6b2a

Please sign in to comment.