derail 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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