pineapples 0.1.0 → 0.3.34

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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/bin/pineapples +4 -9
  6. data/lib/pineapples/actions/apply.rb +34 -0
  7. data/lib/pineapples/actions/base/action.rb +72 -0
  8. data/lib/pineapples/actions/base/target.rb +136 -0
  9. data/lib/pineapples/actions/chmod.rb +28 -0
  10. data/lib/pineapples/actions/copy_file.rb +48 -0
  11. data/lib/pineapples/actions/create_file.rb +114 -0
  12. data/lib/pineapples/actions/directory.rb +115 -0
  13. data/lib/pineapples/actions/empty_directory.rb +71 -0
  14. data/lib/pineapples/actions/get.rb +38 -0
  15. data/lib/pineapples/actions/git.rb +17 -0
  16. data/lib/pineapples/actions/gsub_file.rb +36 -0
  17. data/lib/pineapples/actions/insert_into_file.rb +131 -0
  18. data/lib/pineapples/actions/inside.rb +69 -0
  19. data/lib/pineapples/actions/keep_file.rb +15 -0
  20. data/lib/pineapples/actions/prepend_to_class.rb +26 -0
  21. data/lib/pineapples/actions/rails/copy_migration.rb +67 -0
  22. data/lib/pineapples/actions/rails/erb_converters.rb +37 -0
  23. data/lib/pineapples/actions/rails/rails.rb +186 -0
  24. data/lib/pineapples/actions/remove_file.rb +28 -0
  25. data/lib/pineapples/actions/ruby.rb +49 -0
  26. data/lib/pineapples/actions/shell.rb +40 -0
  27. data/lib/pineapples/actions/template.rb +35 -0
  28. data/lib/pineapples/actions.rb +124 -39
  29. data/lib/pineapples/app_builder.rb +70 -0
  30. data/lib/pineapples/app_generator.rb +187 -0
  31. data/lib/pineapples/build_tasks/root_files.rb +23 -0
  32. data/lib/pineapples/error.rb +7 -0
  33. data/lib/pineapples/helpers.rb +34 -0
  34. data/lib/pineapples/parser.rb +37 -0
  35. data/lib/pineapples/setting.rb +155 -0
  36. data/lib/pineapples/settings.rb +31 -0
  37. data/lib/pineapples/templates/.buildpacks +2 -0
  38. data/lib/pineapples/templates/.editor-config +11 -0
  39. data/lib/pineapples/templates/.example.env.tt +11 -0
  40. data/lib/pineapples/templates/.example.rspec +3 -0
  41. data/lib/pineapples/templates/.gitignore +23 -0
  42. data/lib/pineapples/templates/Aptfile +0 -0
  43. data/lib/pineapples/templates/Gemfile.tt +89 -0
  44. data/lib/pineapples/templates/Guardfile +27 -0
  45. data/lib/pineapples/templates/Procfile +1 -0
  46. data/lib/pineapples/templates/README.md.tt +32 -0
  47. data/lib/pineapples/templates/Rakefile +6 -0
  48. data/lib/pineapples/templates/app/assets/javascripts/application.js +1 -0
  49. data/lib/pineapples/templates/app/assets/javascripts/libs.js +2 -0
  50. data/lib/pineapples/templates/app/assets/stylesheets/application.scss +1 -0
  51. data/lib/pineapples/templates/app/controllers/application_controller.rb.tt +48 -0
  52. data/lib/pineapples/templates/app/controllers/auth/confirmations_controller.rb +2 -0
  53. data/lib/pineapples/templates/app/controllers/pages_controller.rb +6 -0
  54. data/lib/pineapples/templates/app/helpers/application_helper.rb +59 -0
  55. data/lib/pineapples/templates/app/helpers/title_helper.rb +77 -0
  56. data/lib/pineapples/templates/app/models/user!=needs_user_model!.rb.tt +28 -0
  57. data/lib/pineapples/templates/app/views/common/_flashes.html.erb +16 -0
  58. data/lib/pineapples/templates/app/views/common/_footer.html.erb +3 -0
  59. data/lib/pineapples/templates/app/views/common/_header.html.erb +5 -0
  60. data/lib/pineapples/templates/app/views/layouts/application.html.erb.tt +33 -0
  61. data/lib/pineapples/templates/app/views/pages/home.html.erb +4 -0
  62. data/lib/pineapples/templates/bin/bundle +3 -0
  63. data/lib/pineapples/templates/bin/rails +8 -0
  64. data/lib/pineapples/templates/bin/rake +8 -0
  65. data/lib/pineapples/templates/bin/setup +33 -0
  66. data/lib/pineapples/templates/bin/spring +15 -0
  67. data/lib/pineapples/templates/browserlist +4 -0
  68. data/lib/pineapples/templates/config/application.rb.tt +43 -0
  69. data/lib/pineapples/templates/config/boot.rb +5 -0
  70. data/lib/pineapples/templates/config/database.yml.tt +20 -0
  71. data/lib/pineapples/templates/config/environment.rb +5 -0
  72. data/lib/pineapples/templates/config/environments/development.rb +64 -0
  73. data/lib/pineapples/templates/config/environments/production.rb +77 -0
  74. data/lib/pineapples/templates/config/environments/test.rb +34 -0
  75. data/lib/pineapples/templates/config/i18n-tasks.yml +13 -0
  76. data/lib/pineapples/templates/config/initializers/assets.rb +11 -0
  77. data/lib/pineapples/templates/config/initializers/backtrace_silencers.rb +7 -0
  78. data/lib/pineapples/templates/config/initializers/carrierwave.rb +22 -0
  79. data/lib/pineapples/templates/config/initializers/cookies_serializer.rb +3 -0
  80. data/lib/pineapples/templates/config/initializers/filter_parameters_logging.rb +4 -0
  81. data/lib/pineapples/templates/config/initializers/inflections.rb +16 -0
  82. data/lib/pineapples/templates/config/initializers/mime_types.rb +4 -0
  83. data/lib/pineapples/templates/config/initializers/pry.rb +10 -0
  84. data/lib/pineapples/templates/config/initializers/redis.rb +3 -0
  85. data/lib/pineapples/templates/config/initializers/session_store.rb.tt +3 -0
  86. data/lib/pineapples/templates/config/initializers/wrap_parameters.rb +14 -0
  87. data/lib/pineapples/templates/config/locales/en.yml +19 -0
  88. data/lib/pineapples/templates/config/puma.rb +21 -0
  89. data/lib/pineapples/templates/config/routes.rb.tt +10 -0
  90. data/lib/pineapples/templates/config/secrets.yml +11 -0
  91. data/lib/pineapples/templates/config/smtp.rb +11 -0
  92. data/lib/pineapples/templates/config.ru.tt +7 -0
  93. data/lib/pineapples/templates/db/migrate/01_enable_postgres_extensions.rb +15 -0
  94. data/lib/pineapples/templates/db/migrate/02_create_data_migrations.rb +14 -0
  95. data/lib/pineapples/templates/db/migrate/03_devise_create_users.rb +41 -0
  96. data/lib/pineapples/templates/db/migrate/04_add_role_field_to_users.rb +7 -0
  97. data/lib/pineapples/templates/lib/devise!=devise!/ajax_failure.rb +11 -0
  98. data/lib/pineapples/templates/lib/extensions/form_builder.rb +24 -0
  99. data/lib/pineapples/templates/lib/extensions/http_errors.rb +34 -0
  100. data/lib/pineapples/templates/lib/extensions/to_boolean.rb +45 -0
  101. data/lib/pineapples/templates/lib/logging/custom_rack_logger.rb +11 -0
  102. data/lib/pineapples/templates/lib/logging/custom_request_logger.rb +65 -0
  103. data/lib/pineapples/templates/lib/simple_form/components/append.rb +15 -0
  104. data/lib/pineapples/templates/lib/simple_form/components/prepend.rb +15 -0
  105. data/lib/pineapples/templates/lib/tasks/admin!=user_role_field!.rake +52 -0
  106. data/lib/pineapples/templates/lib/tasks/auto_annotate_models.rake +37 -0
  107. data/lib/pineapples/templates/lib/templates/erb/scaffold/_form.html.erb +14 -0
  108. data/lib/pineapples/templates/lib/virtus/virtus.rb +23 -0
  109. data/lib/pineapples/templates/public/404.html +67 -0
  110. data/lib/pineapples/templates/public/422.html +67 -0
  111. data/lib/pineapples/templates/public/500.html +66 -0
  112. data/lib/pineapples/templates/public/favicon.ico +0 -0
  113. data/lib/pineapples/templates/public/robots.txt +5 -0
  114. data/lib/pineapples/version.rb +1 -1
  115. data/lib/pineapples.rb +17 -2
  116. data/pineapples.gemspec +16 -15
  117. metadata +208 -2
@@ -0,0 +1,155 @@
1
+ module Pineapples
2
+ class Setting
3
+ attr_reader :name, :type, :default, :question, :options
4
+ attr_accessor :value
5
+
6
+ VALID_TYPES = [:boolean, :numeric, :string, :symbol]
7
+
8
+ def initialize(name, options = {})
9
+ raise ArgumentError, "option name can't be nil" if name.nil?
10
+ raise ArgumentError, "type can't be nil" if options[:type].nil?
11
+
12
+ type = options[:type].to_sym
13
+
14
+ raise ArgumentError, "Type :#{type} is not valid for options." if type && !valid_type?(type)
15
+
16
+ @name = name
17
+ @type = type || :string
18
+ @default = options[:default]
19
+ @value = @default if @default
20
+ @question = options[:prompt]
21
+ @options = Array(options[:options])
22
+
23
+ validate_options_type!
24
+ validate_type!(default)
25
+ validate_value_in_options!(default)
26
+ end
27
+
28
+ def value=(setting)
29
+ validate_type!(setting)
30
+ validate_value_in_options!(setting)
31
+ @value = setting
32
+ end
33
+
34
+ def valid_type?(type)
35
+ VALID_TYPES.include?(type)
36
+ end
37
+
38
+ def has_default?
39
+ @default || (@default == false)
40
+ end
41
+
42
+ def has_options?
43
+ @options.present?
44
+ end
45
+
46
+ VALID_TYPES.each do |type|
47
+ define_method :"#{type}?" do
48
+ self.type == type
49
+ end
50
+ end
51
+
52
+ def ask_setting
53
+ if has_options?
54
+ ask_with_options
55
+ else
56
+ if boolean?
57
+ ask_boolean
58
+ else
59
+ ask
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def ask_with_options
67
+ puts
68
+ index = Ask.list(question_string, options_with_color, inquirer_options)
69
+ puts
70
+ answer = options[index]
71
+ self.value = cast_to_type(answer)
72
+ end
73
+
74
+ def ask_boolean
75
+ puts
76
+ answer = Ask.confirm(question_string, inquirer_options)
77
+ puts
78
+ self.value = cast_to_type(answer)
79
+ end
80
+
81
+ def ask
82
+ puts
83
+ answer = Ask.input(question_string, inquirer_options)
84
+ puts
85
+
86
+ self.value = cast_to_type(answer)
87
+ end
88
+
89
+ def question_string
90
+ result = ' ' * $terminal.indent_size
91
+ result << question.light_yellow
92
+ result << default_string if has_default?
93
+ end
94
+
95
+ def options_with_color
96
+ options.map{ |option| option.to_s.light_blue }
97
+ end
98
+
99
+ def default_string
100
+ " (default: #{default})".light_green
101
+ end
102
+
103
+ def cast_to_type(setting)
104
+ case type
105
+ when :numeric
106
+ setting.to_f
107
+ when :string
108
+ setting.to_s
109
+ when :symbol
110
+ setting.to_sym
111
+ else
112
+ setting
113
+ end
114
+ end
115
+
116
+ def validate_type(setting)
117
+ value_type = case setting
118
+ when nil
119
+ return true
120
+ when TrueClass, FalseClass
121
+ :boolean
122
+ when Numeric, Hash, Array, String, Symbol
123
+ setting.class.name.downcase.to_sym
124
+ end
125
+ type == value_type
126
+ end
127
+
128
+ def validate_type!(setting)
129
+ if !validate_type(setting)
130
+ raise ArgumentError, "Setting's value must match its type."
131
+ end
132
+ end
133
+
134
+ def validate_value_in_options!(setting)
135
+ if has_options? && !options.include?(setting)
136
+ raise ArgumentError, "New setting value must be one of the options"
137
+ end
138
+ end
139
+
140
+ def validate_options_type!
141
+ if options.any?{ |option| !validate_type(option) }
142
+ raise ArgumentError, "Option #{option} value doesn't match setting type"
143
+ end
144
+ end
145
+
146
+ def get_type_class
147
+ Object.const_get(type.to_s.capitalize)
148
+ end
149
+
150
+ def inquirer_options
151
+ {clear: false, response: false}
152
+ end
153
+
154
+ end
155
+ end
@@ -0,0 +1,31 @@
1
+ require 'pineapples/setting'
2
+
3
+ module Pineapples
4
+ module Settings
5
+ def settings
6
+ @settings
7
+ end
8
+
9
+ def setting(name, opts)
10
+ raw_setting = Pineapples::Setting.new(name, opts)
11
+
12
+ @settings ||= {}
13
+
14
+ self.settings[name] = raw_setting
15
+
16
+ define_method name do
17
+ self.settings[name].value
18
+ end
19
+
20
+ define_method :"#{name}=" do |value|
21
+ self.settings[name].value = value
22
+ end
23
+
24
+ define_method :"#{name}?" do
25
+ value = self.send(name)
26
+ value.present?
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,2 @@
1
+ https://github.com/ddollar/heroku-buildpack-apt
2
+ https://github.com/heroku/heroku-buildpack-ruby
@@ -0,0 +1,11 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+
6
+ indent_style = space
7
+ indent_size = 2
8
+ end_of_line = lf
9
+
10
+ trim_trailing_whitespace = true
11
+ insert_final_newline = true
@@ -0,0 +1,11 @@
1
+ # Copy this file into a new file called ".env" in the root of the project.
2
+ # The dotenv gem will load the contents of .env into the environment when
3
+ # Rails starts. Access values like this: ENV["RAILS_SECRET_KEY_BASE"]
4
+ #
5
+ # The purpose of this file is to keep secrets out of source control.
6
+ # For more information, see: https://github.com/bkeepers/dotenv
7
+
8
+ SECRET_KEY_BASE=<%= app_secret %>
9
+ SIDEKIQ_WEB_USERNAME=admin
10
+ SIDEKIQ_WEB_PASSWORD=password
11
+ LOG_ASSETS = false
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
@@ -0,0 +1,23 @@
1
+ *.DS_Store
2
+
3
+ /.bundle
4
+ /.ruby-gemset
5
+ /.rvmrc
6
+ /.rspec
7
+
8
+ /.env
9
+ /.foreman
10
+
11
+ /coverage/*
12
+
13
+ /log
14
+
15
+ /vendor/assets/bower_components
16
+ *.bowerrc
17
+ bower.json
18
+
19
+ /public/system
20
+ /public/assets
21
+
22
+ /spec/tmp
23
+ /tmp
File without changes
@@ -0,0 +1,89 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ruby '<%= RUBY_VERSION %>'
4
+
5
+ gem 'dotenv-rails', groups: [:development, :test]
6
+
7
+ gem 'rails', '<%= RAILS_VERSION %>'
8
+
9
+ gem 'pg'
10
+ gem 'postgres_ext'
11
+ gem 'schema_plus'
12
+
13
+ gem 'date_validator'
14
+ <% if devise? -%>
15
+ gem 'devise'
16
+ <% end -%>
17
+ gem 'email_validator'
18
+ gem 'fast_blank'
19
+ gem 'fixme', github: 'henrik/fixme'
20
+ <% if user_role_field? -%>
21
+ gem 'highline', require: false
22
+ <% end -%>
23
+ gem 'hiredis'
24
+ gem 'pry-byebug'
25
+ gem 'pry-rails'
26
+ gem 'rack-cache'
27
+ gem 'redis', require: ['redis', 'redis/connection/hiredis']
28
+ gem 'redis-rails'
29
+ gem 'require_all'
30
+ gem 'responders'
31
+ gem 'seed_migration'
32
+ gem 'show_data'
33
+ gem 'simple_enum'
34
+ gem 'simple_form'
35
+ gem 'sidekiq'
36
+ gem 'virtus'
37
+
38
+ # Front-end gems
39
+ gem 'autoprefixer-rails'
40
+ <% if bootstrap? -%>
41
+ gem 'bootstrap-sass', '~> 3.3.5'
42
+ <% end -%>
43
+ gem 'coffee-rails', '~> 4.1.0'
44
+ <% if bootstrap? -%>
45
+ gem 'font-awesome-rails'
46
+ <% end -%>
47
+ gem 'jquery-rails'
48
+ gem 'sassc-rails'
49
+ gem 'momentjs-rails'
50
+ gem 'uglifier', '>= 1.3.0'
51
+
52
+ <% if heroku? -%>
53
+ group :production do
54
+ gem 'heroku-deflater'
55
+ gem 'rack-timeout'
56
+ gem 'rails_12factor'
57
+ end
58
+ <% end -%>
59
+
60
+ group :production, :development do
61
+ gem 'puma'
62
+ end
63
+
64
+ group :development do
65
+ gem 'annotate', '~> 2.6.6'
66
+ gem 'better_errors'
67
+ gem 'binding_of_caller'
68
+ gem 'guard-livereload', '~> 2.4', require: false
69
+ gem 'rack-livereload', github: 'johnbintz/rack-livereload'
70
+ gem 'rb-fsevent', group: :darwin, require: false
71
+ gem 'rb-inotify', group: :linux, require: false
72
+ gem 'quiet_assets'
73
+ end
74
+
75
+ group :test do
76
+ gem 'capybara'
77
+ gem 'database_cleaner'
78
+ gem 'factory_girl_rails'
79
+ gem 'rspec-rails', '~> 3.2'
80
+ gem 'shoulda'
81
+ end
82
+
83
+ group :development, :test do
84
+ gem 'spring'
85
+ gem 'web-console', '~> 2.0'
86
+ end
87
+
88
+ # bundle exec rake doc:rails generates the API under doc/api.
89
+ gem 'sdoc', '~> 0.4.0', group: :doc
@@ -0,0 +1,27 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ # Run just the livereload monitor with: `guard -P livereload`
5
+ guard :livereload do
6
+ watch(%r{app/views/.+\.(erb|haml|slim)$})
7
+ watch(%r{app/helpers/.+\.rb})
8
+ watch(%r{public/.+\.(css|js|html)})
9
+ watch(%r{config/locales/.+\.yml})
10
+ # Rails Assets Pipeline
11
+ watch(%r{(app|lib|vendor)(/assets/\w+/(.+\.(css|js))).*}) { |m| "/assets/#{m[3]}" }
12
+ watch(%r{(app|lib|vendor)(/assets/\w+/(.+)\.(scss))}) { |m| "/assets/#{m[3]}.css" }
13
+ watch(%r{(app/assets/stylesheets/shared/)(\w+/(.+)\.(scss))}) { |m| "/assets/application.css" }
14
+ end
15
+
16
+ # guard :minitest, spring: true do
17
+ # # Rails 4
18
+ # watch(%r{^app/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
19
+ # watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
20
+ # watch(%r{^app/controllers/(.+)_controller\.rb$}) { |m| "test/integration/#{m[1]}_test.rb" }
21
+ # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
22
+ # watch(%r{^app/workers/(.+)\.rb$}) { |m| "test/unit/workers/#{m[1]}_test.rb" }
23
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "test/unit/lib/#{m[1]}_test.rb" }
24
+ # watch(%r{^lib/tasks/(.+)\.rake$}) { |m| "test/unit/lib/tasks/#{m[1]}_test.rb" }
25
+ # watch(%r{^test/.+_test\.rb$})
26
+ # watch(%r{^test/test_helper\.rb$}) { 'test' }
27
+ # end
@@ -0,0 +1 @@
1
+ web: bundle exec puma -C config/puma.rb
@@ -0,0 +1,32 @@
1
+ # <%= app_name.humanize %>
2
+
3
+ ## Getting Started
4
+
5
+ After you have cloned this repo, run this setup script to set up your machine
6
+ with the necessary dependencies to run and test this app:
7
+
8
+ % ./bin/setup
9
+
10
+ It assumes you have a machine equipped with Ruby, Postgres, etc. If not, provision
11
+ your machine with [this script].
12
+
13
+ [this script]: https://github.com/thoughtbot/laptop
14
+
15
+ After setting up, you can run the application using [foreman]:
16
+
17
+ % foreman start
18
+
19
+ If you don't have `foreman`, see [Foreman's install instructions][foreman]. It
20
+ is [purposefully excluded from the project's `Gemfile`][exclude].
21
+
22
+ [foreman]: https://github.com/ddollar/foreman
23
+ [exclude]: https://github.com/ddollar/foreman/pull/437#issuecomment-41110407
24
+
25
+ ## Guidelines
26
+
27
+ Use the following guides for getting things done, programming well, and
28
+ programming in style.
29
+
30
+ * [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol)
31
+ * [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices)
32
+ * [Style](http://github.com/thoughtbot/guides/blob/master/style)
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1 @@
1
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
@@ -0,0 +1,48 @@
1
+ require_dependency 'application_responder'
2
+ require_dependency 'ipaddr'
3
+
4
+ class ApplicationController < ActionController::Base
5
+ <% if pundit? -%>
6
+ include Pundit
7
+
8
+ <% end -%>
9
+ # Prevent CSRF attacks by raising an exception.
10
+ # For APIs, you may want to use :null_session instead.
11
+ protect_from_forgery with: :exception
12
+ <% if pundit? -%>
13
+
14
+ rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
15
+
16
+ <% end -%>
17
+ def self.responder
18
+ ApplicationResponder
19
+ end
20
+ <% if devise? -%>
21
+
22
+ def guest_user?
23
+ !current_user
24
+ end
25
+
26
+ <% end -%>
27
+ <% if user_role_field? -%>
28
+ def guest_user
29
+ User.guest
30
+ end
31
+ <% end -%>
32
+
33
+
34
+
35
+ protected
36
+
37
+ def local_request?
38
+ local_network = IPAddr.new('192.168.0.0/8')
39
+ request.local? || local_network === request.remote_ip
40
+ end
41
+ <% if pundit? -%>
42
+
43
+ def user_not_authorized(exception)
44
+ flash[:error] = 'You are not authorized to perform this action.'
45
+ redirect_to(request.referrer || root_path)
46
+ end
47
+ <% end -%>
48
+ end
@@ -0,0 +1,2 @@
1
+ class Auth::ConfirmationsController < Devise::ConfirmationsController
2
+ end
@@ -0,0 +1,6 @@
1
+ class PagesController < ApplicationController
2
+
3
+ def home
4
+ end
5
+
6
+ end
@@ -0,0 +1,59 @@
1
+ module ApplicationHelper
2
+ def parent_layout(layout)
3
+ layout = layout.to_s
4
+ layout = "layouts/#{layout}" unless layout.include?('/')
5
+
6
+ @view_flow.set(:layout, output_buffer)
7
+
8
+ output = render file: layout
9
+
10
+ self.output_buffer = ActionView::OutputBuffer.new(output)
11
+ end
12
+
13
+ def modal_for(id, modal_title = nil, &block)
14
+ modal_id = id + '-modal'
15
+ modal_body = capture(&block)
16
+ render partial: 'common/modal', locals: {modal_id: modal_id,
17
+ modal_title: modal_title,
18
+ modal_body: modal_body}
19
+ end
20
+
21
+ def svg_tag(filename, options = {})
22
+ options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
23
+
24
+ assets = Rails.application.assets
25
+ file = assets.find_asset(filename + '.svg').body.force_encoding('UTF-8')
26
+ doc = Nokogiri::HTML::DocumentFragment.parse file
27
+
28
+ svg = doc.at_css 'svg'
29
+
30
+ svg["class"] = options[:class] if options[:class]
31
+ svg["id"] = options[:id] if options[:id]
32
+ svg["width"] = options[:width] if options[:width]
33
+ svg["height"] = options[:height] if options[:height]
34
+
35
+ raw doc
36
+ end
37
+
38
+ def close_button_tag(options = {})
39
+ options = Hash(options).reverse_merge!({type: 'button', class: 'close', aria: {label: 'Close'}})
40
+ content_tag :button, options do
41
+ content_tag :span, aria: {hidden: 'true'} do
42
+ '&times;'.html_safe
43
+ end
44
+ end
45
+ end
46
+
47
+ def icon_tag(name)
48
+ content_tag :i, nil, class: "icon icon-#{name}"
49
+ end
50
+
51
+ def flash_class(level)
52
+ case level.to_sym
53
+ when :notice then 'alert alert-success'
54
+ when :error then 'alert alert-danger'
55
+ when :alert then 'alert alert-danger'
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,77 @@
1
+ module TitleHelper
2
+
3
+ def title(additional_context = {}, opts = {})
4
+ if content_for?(:title)
5
+ provide(:title)
6
+ else
7
+ context = controller.view_assigns.merge(additional_context).symbolize_keys
8
+ PageTitle.new(controller_path, action_name, context, opts)
9
+ end
10
+ end
11
+
12
+ class PageTitle
13
+ attr_reader :controller_path, :action_name, :context,
14
+ :application_name, :include_application_name, :separator
15
+
16
+ def initialize(controller_path, action_name, context, opts)
17
+ @controller_path = controller_path
18
+ @action_name = action_name
19
+ @context = context
20
+ @application_name = opts[:application_name] || humanized_application_name
21
+ @include_application_name = opts[:include_application_name] || true
22
+ @separator = opts[:separator] || ' – '
23
+ end
24
+
25
+ def to_s
26
+ title = translate_action
27
+ if include_application_name
28
+ title << "#{separator}#{application_name}" if title != application_name
29
+ end
30
+ title
31
+ end
32
+
33
+
34
+
35
+ private
36
+
37
+ def translate_application_name
38
+ return application_name if application_name.present?
39
+ I18n.t(application_title, default: humanized_application_name)
40
+ end
41
+
42
+ def humanized_application_name
43
+ guess_title_key.underscore.humanize.gsub(/\S+/, &:capitalize)
44
+ end
45
+
46
+ def translate_action
47
+ I18n.t("titles.#{controller_i18n_key_lookup_path}.#{action_name}",
48
+ context.merge(default: defaults))
49
+ end
50
+
51
+ def application_title_key
52
+ :'titles.application'
53
+ end
54
+
55
+ def guess_title_key
56
+ Rails.application.class.to_s.split('::').first
57
+ end
58
+
59
+ def controller_i18n_key_lookup_path
60
+ controller_path.gsub('/', '.')
61
+ end
62
+
63
+ def defaults
64
+ default_keys_in_lookup_path + [application_title_key, guess_title_key]
65
+ end
66
+
67
+ def default_keys_in_lookup_path
68
+ defaults = []
69
+ lookup_path = controller_i18n_key_lookup_path.split('.')
70
+ while lookup_path.length > 0
71
+ defaults << ['titles', *lookup_path, 'default'].join('.').to_sym
72
+ lookup_path.pop
73
+ end
74
+ defaults.reverse
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,28 @@
1
+ class User < ActiveRecord::Base
2
+ <% if user_role_field? -%>
3
+ as_enum :role, [:guest, :regular, :trusted, :moderator, :admin],
4
+ source: :role, map: :string, accessor: :whiny
5
+
6
+ before_create do
7
+ self.role = :regular
8
+ end
9
+
10
+ def self.guest
11
+ User.new
12
+ end
13
+
14
+ def guest?
15
+ new_record?
16
+ end
17
+
18
+ def regular?
19
+ persisted? && role == :regular
20
+ end
21
+ <% end -%>
22
+
23
+ <% if devise? -%>
24
+ def send_devise_notification(notification, *args)
25
+ devise_mailer.send(notification, self, *args).deliver_later
26
+ end
27
+ <% end -%>
28
+ end
@@ -0,0 +1,16 @@
1
+ <% if flash.any? %>
2
+ <div class="flashes">
3
+ <% flash.each do |key, messages| %>
4
+ <div class="<%= flash_class(key) %>">
5
+ <% close_button_tag(data: {dismiss: 'alert'}) %>
6
+ <ul>
7
+ <% Array(messages).each do |message| %>
8
+ <li>
9
+ <%= message %>
10
+ </li>
11
+ <% end %>
12
+ </ul>
13
+ </div>
14
+ <% end %>
15
+ </div>
16
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <footer class="footer">
2
+
3
+ </footer>
@@ -0,0 +1,5 @@
1
+ <header class="header">
2
+ <nav class="header-nav">
3
+ <%= link_to t(:home), root_path %>
4
+ </nav>
5
+ </header>