derail 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/Gemfile +3 -0
  2. data/LICENSE +20 -0
  3. data/README.md +87 -0
  4. data/VERSION +1 -0
  5. data/app/helpers/activated_link_helper.rb +48 -0
  6. data/app/helpers/flashes_helper.rb +9 -0
  7. data/app/helpers/text_helper.rb +55 -0
  8. data/derail.gemspec +24 -0
  9. data/lib/derail.rb +15 -0
  10. data/lib/derail/core_ext/string.rb +11 -0
  11. data/lib/derail/engine.rb +3 -0
  12. data/lib/derail/generators.rb +46 -0
  13. data/lib/generators/derail/app/USAGE +1 -0
  14. data/lib/generators/derail/app/app_generator.rb +147 -0
  15. data/lib/generators/derail/app/bootstrap.rb +124 -0
  16. data/lib/generators/derail/devise/USAGE +1 -0
  17. data/lib/generators/derail/devise/devise_generator.rb +25 -0
  18. data/lib/generators/derail/devise/haml/USAGE +1 -0
  19. data/lib/generators/derail/devise/haml/haml_generator.rb +13 -0
  20. data/lib/templates/devise/haml/views/_footer.html.haml +32 -0
  21. data/lib/templates/devise/haml/views/confirmations/new.html.haml +15 -0
  22. data/lib/templates/devise/haml/views/mailer/confirmation_instructions.html.erb +5 -0
  23. data/lib/templates/devise/haml/views/mailer/reset_password_instructions.html.erb +8 -0
  24. data/lib/templates/devise/haml/views/mailer/unlock_instructions.html.erb +7 -0
  25. data/lib/templates/devise/haml/views/passwords/edit.html.haml +18 -0
  26. data/lib/templates/devise/haml/views/passwords/new.html.haml +15 -0
  27. data/lib/templates/devise/haml/views/registrations/edit.html.haml +33 -0
  28. data/lib/templates/devise/haml/views/registrations/new.html.haml +17 -0
  29. data/lib/templates/devise/haml/views/sessions/new.html.haml +18 -0
  30. data/lib/templates/devise/haml/views/unlocks/new.html.haml +15 -0
  31. data/lib/templates/haml/scaffold/_form.html.haml +8 -0
  32. data/lib/templates/haml/scaffold/edit.html.haml +8 -0
  33. data/lib/templates/haml/scaffold/index.html.haml +17 -0
  34. data/lib/templates/haml/scaffold/new.html.haml +7 -0
  35. data/lib/templates/haml/scaffold/show.html.haml +12 -0
  36. data/lib/templates/scaffold_controller/controller.rb +38 -0
  37. data/vendor/assets/javascripts/innershiv.js +2 -0
  38. data/vendor/assets/javascripts/jquery_autolink.js +7 -0
  39. data/vendor/assets/javascripts/jquery_highlight.js +7 -0
  40. data/vendor/assets/javascripts/jquery_innershiv.js +21 -0
  41. data/vendor/assets/javascripts/jquery_mailto.js +8 -0
  42. data/vendor/assets/javascripts/jquery_timeago.js +149 -0
  43. data/vendor/assets/javascripts/modernizr.js +1116 -0
  44. metadata +112 -0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Samuel Cochran
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,87 @@
1
+ # Derail
2
+
3
+ A collection of helpers and libraries which I use in almost every project, and a generator to get started quickly.
4
+
5
+ Some of this stuff may graduate into gems or get contributed back to other projects.
6
+
7
+ ## Features
8
+
9
+ * Generators:
10
+ * `derail:app`: Derails a new rails project, basically doing all the following:
11
+ * Configure databases:
12
+ * development: _APPNAME_\_development/development/development
13
+ * test: _APPNAME_\_test/test/test
14
+ * production: read from environment (DATABASE/DATABASE\_USERNAME/DATABASE\_PASSWORD).
15
+ * Configure ActionMailer:
16
+ * development: default\_url\_options to `_APPNAME_.dev`, [MailCatcher](https://github.com/sj26/mailcatcher) delivery.
17
+ * test: default\_url\_options to `_APPNAME_.test`.
18
+ * Makes SASS the default stylesheet syntax (not SCSS) and converts application.css to application.css.sass.
19
+ * Converts application.js to application.js.coffee.
20
+ * Installs [RSpec](http://rspec.info/)
21
+ * Installs [Cucumber](http://cukes.info/)
22
+ * Installs [RR](https://github.com/btakita/rr)
23
+ * Installs [Guard](https://github.com/guard/guard) ([ego](https://github.com/guard/guard-ego), [bundler](https://github.com/guard/guard-bundler), [rspec](https://github.com/guard/guard-rspec), [cucumber](https://github.com/guard/guard-cucumber))
24
+ * Runs `formtastic:install`
25
+ * Runs `derail:devise`
26
+ * Removes default `index.html` and `rails.png`
27
+ * `derail:devise`: Install devise, setup a user, install [remarkable_devise](https://github.com/sj26/remarkable_devise).
28
+ * `derail:devise:haml`: Installs fully-localizable, HTML5, formtastic Devise HAML templates.
29
+ * Updated scaffold templates:
30
+ * HTML5, formtastic scaffold HAML templates.
31
+ * [Responder](https://github.com/rails/rails/tree/3-1-stable/actionpack/lib/action_controller/metal/responder.rb)-based scaffold controller.
32
+ * Helpers:
33
+ * Activated link helper, adapted from a few places. Documentation coming.
34
+ * Flashes helper, lists all your flashes in aside elements.
35
+ * Text helper with *working* truncate\_html using Hpricot.
36
+ * Vendored javascripts:
37
+ * [modernizr](http://www.modernizr.com/).
38
+ * [innershiv](http://jdbartlett.com/innershiv/) and [jQuery innershiv](http://tomcoote.co.uk/javascript/ajax-html5-in-ie/).
39
+ * [jQuery autolink, mailto and highlight helpers](http://kawika.org/jquery/index.php?section=autolink), separated for leanness.
40
+ * [jQuery.timeago](http://timeago.yarp.com/)
41
+ * Plenty more to come!
42
+
43
+ ## Use
44
+
45
+ To create a new app, I run:
46
+
47
+ rails new APPNAME --skip-test-unit --database=postgresql --template http://sj26.com/derail
48
+
49
+ For handyness in [zsh](http://zsh.org):
50
+
51
+ function derail() { rails new $1 --skip-test-unit --database=postgresql --template http://sj26.com/derail $@[2,-1] }
52
+
53
+ then
54
+
55
+ derail APPNAME
56
+
57
+ ### Vendored javascripts
58
+
59
+ Add them to your applictation's javascript files using sprockets require directives, a la jQuery:
60
+
61
+ //= require jquery_innershiv
62
+
63
+ ## Caveats
64
+
65
+ * It's Rails 3.1 only, but you should be basing your new projects on the latest and greatest! It'll be stable by the time you release... right?
66
+ * I'm presuming your using [my devise branch](https://github.com/sj26/devise/tree/template-inheritence):
67
+
68
+ gem "devise", :git => "git://github.com/sj26/devise.git", :branch => "template-inheritence"
69
+
70
+ If not, copy the HAML templates into your project and re-twiddle the footer partial.
71
+
72
+ ## TODO
73
+
74
+ * Home generator.
75
+ * Admin generator.
76
+ * Admin scaffold generator.
77
+ * Pages generator.
78
+ * (Some) in-app errors handler generator.
79
+ * Page title helper inspired by [page\_title\_helper](https://github.com/lwe/page_title_helper)
80
+ * Vendored WYSIWYG (can't decide which library).
81
+ * Formtastic WYSIWYG field helpers.
82
+ * Tilt-based renderable activerecord fields with filter white/blacklists and stored filter type.
83
+ * More tests.
84
+
85
+ ## License
86
+
87
+ Copyright (c) 2011 Samuel Cochran, released under the MIT license, see LICENSE.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,48 @@
1
+ module ActivatedLinkHelper
2
+ def activated_link_to *args, &block
3
+ if block_given?
4
+ name = capture(&block)
5
+ options = args[0] || {}
6
+ html_options = args[1] || {}
7
+ else
8
+ name = args[0]
9
+ options = args[1] || {}
10
+ html_options = args[2] || {}
11
+ end
12
+
13
+ options = options.clone
14
+ html_options = html_options.clone
15
+
16
+ url = url_for(options)
17
+ active_link_options = html_options.delete(:active) || {}
18
+
19
+ match = request.fullpath.match(/^#{Regexp.escape(url)}(?:\/(.*)$)?/)
20
+
21
+ active = if html_options.delete(:exact)
22
+ match.present? and (match[1].blank? or match[1] == "/")
23
+ elsif paths = (html_options.delete(:only_paths).presence || html_options.delete(:only_path).presence)
24
+ match.present? and (match[1].blank? or match[1] == "/") || if paths.is_a? Array
25
+ paths.include? match[1]
26
+ elsif paths.is_a? Regexp
27
+ paths.match(match[1]).present?
28
+ else
29
+ paths == match[1]
30
+ end
31
+ else
32
+ request.fullpath.match(/^#{Regexp.escape(url)}(\/|$)/).present?
33
+ end
34
+
35
+ css_class = if active
36
+ 'active'
37
+ else
38
+ 'inactive'
39
+ end
40
+
41
+ html_options[:class] ||= ''
42
+ html_options[:class] += " #{css_class}" if !css_class.blank?
43
+ html_options[:class].strip!
44
+ html_options.delete(:class) if html_options[:class].blank?
45
+
46
+ link_to(name, url, html_options)
47
+ end
48
+ end
@@ -0,0 +1,9 @@
1
+ module FlashesHelper
2
+ def flashes
3
+ safe_join(flash.keys.map do |key|
4
+ content_tag :aside, :class => ["flash", "flash-#{key.to_s.parameterize}"] do
5
+ flash[key]
6
+ end
7
+ end)
8
+ end
9
+ end
@@ -0,0 +1,55 @@
1
+ require "hpricot"
2
+
3
+ # Adapted from http://henrik.nyh.se/2008/01/rails-truncate-html-helper
4
+
5
+ module TextHelper
6
+ # Like the Rails _truncate_ helper but doesn't break HTML tags or entities.
7
+ def truncate_html(text, options={})
8
+ return if text.nil?
9
+
10
+ length = options.delete(:length) || 30
11
+ omission = options.delete(:omission).to_s || "..."
12
+ text = text.to_s
13
+
14
+ document = Hpricot(text)
15
+ omission_length = Hpricot(omission).inner_text.chars.count
16
+ content_length = document.inner_text.chars.count
17
+
18
+ content_length > length ? document.truncate([length - omission_length, 0].max).inner_html + omission : text
19
+ end
20
+ end
21
+
22
+ module HpricotTruncator
23
+ module NodeWithChildren
24
+ def truncate(length)
25
+ return self if inner_text.chars.count <= length
26
+ truncated_node = self.dup
27
+ truncated_node.children = []
28
+ each_child do |node|
29
+ remaining_length = length - truncated_node.inner_text.chars.count
30
+ break if remaining_length == 0
31
+ truncated_node.children << node.truncate(remaining_length)
32
+ end
33
+ truncated_node
34
+ end
35
+ end
36
+
37
+ module TextNode
38
+ def truncate(length)
39
+ # We're using String#scan because Hpricot doesn't distinguish entities.
40
+ Hpricot::Text.new(content.scan(/&#?[^\W_]+;|./).first(length).join)
41
+ end
42
+ end
43
+
44
+ module IgnoredTag
45
+ def truncate(length)
46
+ self
47
+ end
48
+ end
49
+ end
50
+
51
+ Hpricot::Doc.send(:include, HpricotTruncator::NodeWithChildren)
52
+ Hpricot::Elem.send(:include, HpricotTruncator::NodeWithChildren)
53
+ Hpricot::Text.send(:include, HpricotTruncator::TextNode)
54
+ Hpricot::BogusETag.send(:include, HpricotTruncator::IgnoredTag)
55
+ Hpricot::Comment.send(:include, HpricotTruncator::IgnoredTag)
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "derail"
3
+ s.version = File.read(File.expand_path("../VERSION", __FILE__)).strip
4
+ s.platform = Gem::Platform::RUBY
5
+ s.summary = "sj26's collection of rails bits and pieces."
6
+ s.description = <<-END
7
+ Derail is a collection of helpers and libraries which I use in
8
+ almost every project, and a generator to get started quickly.
9
+ END
10
+
11
+ s.author = "Samuel Cochran"
12
+ s.email = "sj26@sj26.com"
13
+ s.homepage = "https://github.com/sj26/derail"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.executables = `git ls-files`.split("\n").select{|f| f =~ /^bin/}
17
+ s.require_path = "lib"
18
+ s.extra_rdoc_files = ["README.md", "LICENSE"]
19
+
20
+ s.required_ruby_version = '>= 1.8.7'
21
+
22
+ s.add_dependency "railties", ">= 3.1.rc4"
23
+ s.add_dependency "formtastic", ">= 2.0.0.rc3"
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'derail/core_ext/string'
2
+
3
+ module Derail
4
+ VERSION = File.read(File.expand_path("../../VERSION", __FILE__)).strip
5
+
6
+ extend ActiveSupport::Autoload
7
+
8
+ require 'derail/engine'
9
+
10
+ autoload :Generators
11
+ autoload_under :ActiveRecord do
12
+ autoload :Unique
13
+ end
14
+ end
15
+
@@ -0,0 +1,11 @@
1
+ class String
2
+ def dedent
3
+ indent = lines.reject(&:empty?).map { |line| line.index(/\S/) }.compact.min
4
+ gsub /^ {1,#{indent.to_i}}/, ''
5
+ end unless method_defined? :dedent
6
+
7
+ def redent prefix
8
+ prefix = " " * prefix if prefix.is_a? Numeric
9
+ dedent.gsub! /^(?=[ \t]*\S+)/, prefix
10
+ end unless method_defined? :redent
11
+ end
@@ -0,0 +1,3 @@
1
+ class Derail::Engine < Rails::Engine
2
+ # We must be an engine to vendor assets.
3
+ end
@@ -0,0 +1,46 @@
1
+ module Derail::Generators
2
+ class Base < Rails::Generators::Base
3
+ source_root File.expand_path '../../templates'
4
+
5
+ protected
6
+
7
+ def rvm *args
8
+ options = args.extract_options!
9
+ say_status :run, "rvm #{args * " "}" # unless options[:verbose] === false
10
+ system (["rvm"] + args) * " "
11
+ end
12
+
13
+ def rvm_run *args
14
+ args << args.extract_options!.merge(:verbose => false)
15
+ rvm "--with-rubies", "default-with-rvmrc", "exec", *args
16
+ end
17
+
18
+ def bundle *args
19
+ options = args.extract_options!
20
+ say_status :run, "bundle #{args * " "}" # unless options[:verbose] === false
21
+ rvm_run "bundle", *args
22
+ end
23
+
24
+ def bundle_run *args
25
+ args << args.extract_options!.merge(:verbose => false)
26
+ bundle "exec", *args
27
+ end
28
+
29
+ # Override run to run in our rvm/bundle
30
+ alias run bundle_run
31
+
32
+ # Override generate to run in bundle
33
+ def generate *args
34
+ say_status :generate, args * " "
35
+ bundle_run "rails", "generate", *args
36
+ end
37
+
38
+ def app_name
39
+ Rails.application.class.parent_name
40
+ end
41
+
42
+ def app_slug
43
+ app_name.underscore
44
+ end
45
+ end
46
+ end
@@ -0,0 +1 @@
1
+ Derail a new rails application.
@@ -0,0 +1,147 @@
1
+ module Derail::Generators
2
+ class AppGenerator < Base
3
+ def configure_database
4
+ # The original is full of noise, ick.
5
+ remove_file "config/database.yml", :verbose => false
6
+ create_file "config/database.yml", <<-RUBY.dedent
7
+ development:
8
+ adapter: postgresql
9
+ encoding: unicode
10
+ pool: 5
11
+ database: #{app_slug}_development
12
+ username: development
13
+ password: development
14
+
15
+ test:
16
+ adapter: postgresql
17
+ encoding: unicode
18
+ pool: 5
19
+ database: #{app_slug}_test
20
+ username: test
21
+ password: test
22
+
23
+ production:
24
+ adapter: postgresql
25
+ encoding: unicode
26
+ pool: 5
27
+ database: <%= ENV["DATABASE"] %>
28
+ username: <%= ENV["DATABASE_USERNAME"] %>
29
+ password: <%= ENV["DATABASE_PASSWORD"] %>
30
+ RUBY
31
+ end
32
+
33
+ def configure_action_mailer
34
+ inject_into_file "config/environments/development.rb", <<-RUBY.redent(2), :after => /config.action_mailer.*?\n/
35
+
36
+ # Development URL
37
+ config.action_mailer.default_url_options = { :host => '#{app_slug}.dev' }
38
+
39
+ # Send mail via MailCatcher
40
+ config.action_mailer.smtp_settings = { :address => 'localhost', :port => 1025 }
41
+ RUBY
42
+
43
+ inject_into_file "config/environments/test.rb", <<-RUBY.redent(2), :after => /config.action_mailer.*?\n/
44
+
45
+ # Testing URL
46
+ config.action_mailer.default_url_options = { :host => '#{app_slug}.test' }
47
+ RUBY
48
+ end
49
+
50
+ def configure_sass
51
+ inject_into_file "config/application.rb", <<-RUBY.redent(4), :after => /config\.assets[^\n]*\n/
52
+
53
+ # Use SASS by default
54
+ config.generators.stylesheet_engine = :sass
55
+ RUBY
56
+
57
+ bundle_run "sass-convert", "app/assets/stylesheets/application.css", "app/assets/stylesheets/application.css.sass"
58
+ remove_file "app/assets/stylesheets/application.css"
59
+ end
60
+
61
+ def configure_coffee
62
+ system "mv", "app/assets/javascripts/application.js", "app/assets/javascripts/application.js.coffee"
63
+ gsub_file "app/assets/javascripts/application.js.coffee", %r{^//}, "#"
64
+ end
65
+
66
+ def install_rspec
67
+ # TODO: Make optional
68
+ generate "rspec:install"
69
+ end
70
+
71
+ def install_cucumber
72
+ # TODO: Make optional
73
+ generate "cucumber:install"
74
+ end
75
+
76
+ def install_rr
77
+ gsub_file "spec/spec_helper.rb", /[ \t]*# == Mock Framework\n(.*)\n[ \t]*config\.mock_with[ \t]*\S+\n/m, <<-RUBY.redent(2)
78
+ # == Mock Framework
79
+ config.mock_with :rr
80
+ RUBY
81
+
82
+ # TODO: Insert RR cucumber support
83
+ end
84
+
85
+ def install_guard
86
+ # TODO: Make optional
87
+ say_status :create, "Guardfile"
88
+ ["ego", "bundler", "rspec", "cucumber"].each do |guard|
89
+ bundle_run "guard", "init", guard
90
+ end
91
+ end
92
+
93
+ def generate_formtastic
94
+ # TODO: Make optional
95
+ generate "formtastic:install"
96
+ end
97
+
98
+ def generate_layouts
99
+ # TODO: Layouts
100
+ # TODO: Make optional
101
+ #generate "derail:layout"
102
+ end
103
+
104
+ def generate_home
105
+ # TODO: Home
106
+ # TODO: Make optional
107
+ #generate "derail:home"
108
+ end
109
+
110
+ def generate_devise
111
+ # TODO: Make optional
112
+ generate "derail:devise"
113
+ end
114
+
115
+ def generate_dashboard
116
+ # TODO: Dashboard
117
+ # TODO: Make optional
118
+ #generate "derail:dashboard"
119
+ end
120
+
121
+ def generate_admin
122
+ # TODO: Admin
123
+ # TODO: Make optional
124
+ #generate "derail:admin"
125
+ end
126
+
127
+ def generate_pages
128
+ # TODO: Pages
129
+ # TODO: Make optional
130
+ #generate "derail:pages"
131
+ end
132
+
133
+ def generate_errors
134
+ # TODO: Error handling
135
+ # TODO: Make optional
136
+ #generate "derail:errors"
137
+ end
138
+
139
+ def remove_index
140
+ remove_file "public/index.html"
141
+ end
142
+
143
+ def remove_rails_logo
144
+ remove_file "app/assets/images/rails.png"
145
+ end
146
+ end
147
+ end