undercarriage 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2ec3241ab6e053eb78aa66e3aed56473b299ebef9c48c08c415a7f9c04b0eb70
4
+ data.tar.gz: c0e0393b7f2d1c383eadb22af21ac440fe5651eea335f71241289918f754b547
5
+ SHA512:
6
+ metadata.gz: 423946c74cd8e1f5d313627933fd3f6a27d663e0e580d78ae5d56f202117d8348d56eb42315498e32878e0bdb39e30f7e48c021e4207b2221197c0d0edf7c73b
7
+ data.tar.gz: 5613f293beb7bac032d58f7aed7f686f67e6c8219ba52708690e591e874246e4fd86a60c91dc98c04a518a739b2e883dc7fc8f1ed1e47f8955bef20e955cc270
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2021 David Freerksen
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.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Undercarriage
2
+
3
+ **\*Undercarriage is currently under development. It is not ready for production use.\***
4
+
5
+ Undercarriage is a set of concerns to add to your application to trim some of the fat from controllers and models.
6
+
7
+ ## Requirements
8
+
9
+ * Ruby >= 2.5
10
+ * Rails >= 6.0.3
11
+
12
+ ## Installation
13
+
14
+ Add to your application's Gemfile
15
+
16
+ ```ruby
17
+ gem 'undercarriage', '~> 0.1'
18
+ ```
19
+
20
+ Run the bundle command
21
+
22
+ ```bash
23
+ $ bundle install
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ TODO
29
+
30
+ ## TODO
31
+
32
+ * [ ] Allow a way to set locale instead of relying on browser preferred language in `Undercarriage::Controllers::LocaleConcern`
33
+
34
+ ## Code Analysis
35
+
36
+ TODO
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it ([https://github.com/dfreerksen/undercarriage/fork](https://github.com/dfreerksen/undercarriage/fork))
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'Undercarriage'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ require 'bundler/gem_tasks'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # desc "Explaining what the task does"
4
+ # task :undercarriage do
5
+ # # Task goes here
6
+ # end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'undercarriage/controllers/action_concern'
4
+ require 'undercarriage/controllers/kaminari_concern'
5
+ require 'undercarriage/controllers/locale_concern'
6
+
7
+ require 'undercarriage/railtie'
8
+
9
+ ##
10
+ # Undercarriage
11
+ #
12
+ # Undercarriage is a set of concerns to add to your application to trim some of the fat from controllers and models.
13
+ #
14
+ module Undercarriage
15
+ # Your code goes here...
16
+ end
@@ -0,0 +1,233 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ module Controllers
5
+ ##
6
+ # Action helpers
7
+ #
8
+ # Helpers for the controller or view to help identify the action
9
+ #
10
+ # Usage
11
+ # class ExamplesController < ApplicationController
12
+ # include Undercarriage::Controllers::ActionConcern
13
+ # end
14
+ #
15
+ module ActionConcern
16
+ extend ActiveSupport::Concern
17
+
18
+ included do
19
+ helper_method :action?,
20
+ :collection_action?,
21
+ :create_action?,
22
+ :create_actions?,
23
+ :edit_action?,
24
+ :edit_actions?,
25
+ :index_action?,
26
+ :member_action?,
27
+ :new_action?,
28
+ :new_actions?,
29
+ :show_action?,
30
+ :update_action?,
31
+ :update_actions?
32
+ end
33
+
34
+ ##
35
+ # Check action
36
+ #
37
+ # Check if action is a certain action type
38
+ #
39
+ # Usage
40
+ # action?(:show) # true
41
+ # action?('show') # true
42
+ # action?(:index) # false
43
+ #
44
+ # @param action_method [String, Symbol] the action to test
45
+ # @return [Boolean] if action matches
46
+ #
47
+ def action?(action_method)
48
+ action == action_method.to_sym
49
+ end
50
+
51
+ ##
52
+ # Check if index
53
+ #
54
+ # Check if action is the index action type. The check will pass if it is an `index` action
55
+ #
56
+ # Usage
57
+ # index_action? # true
58
+ # index_action? # false
59
+ #
60
+ # @return [Boolean] if action is action type
61
+ #
62
+ def index_action?
63
+ action?('index')
64
+ end
65
+
66
+ ##
67
+ # Check if show
68
+ #
69
+ # Check if action is the show action type. The check will pass if it is a `show` action
70
+ #
71
+ # Usage
72
+ # show_action? # true
73
+ # show_action? # false
74
+ #
75
+ # @return [Boolean] if action is action type
76
+ #
77
+ def show_action?
78
+ action?('show')
79
+ end
80
+
81
+ ##
82
+ # Check if new
83
+ #
84
+ # Check if action is the new action type. The check will pass if it is a `new` action
85
+ #
86
+ # Usage
87
+ # new_action? # true
88
+ # new_action? # false
89
+ #
90
+ # @return [Boolean] if action is action type
91
+ #
92
+ def new_action?
93
+ action?('new')
94
+ end
95
+
96
+ ##
97
+ # Check if create
98
+ #
99
+ # Check if action is the create action type. The check will pass if it is a `create` action
100
+ #
101
+ # Usage
102
+ # create_action? # true
103
+ # create_action? # false
104
+ #
105
+ # @return [Boolean] if action is action type
106
+ #
107
+ def create_action?
108
+ action?('create')
109
+ end
110
+
111
+ ##
112
+ # Check if edit
113
+ #
114
+ # Check if action is the edit action type. The check will pass if it is an `edit` action
115
+ #
116
+ # Usage
117
+ # edit_action? # true
118
+ # edit_action? # false
119
+ #
120
+ # @return [Boolean] if action is action type
121
+ #
122
+ def edit_action?
123
+ action?('edit')
124
+ end
125
+
126
+ ##
127
+ # Check if update
128
+ #
129
+ # Check if action is the update action type. The check will pass if it is an `update` action
130
+ #
131
+ # Usage
132
+ # update_action? # true
133
+ # update_action? # false
134
+ #
135
+ # @return [Boolean] if action is action type
136
+ #
137
+ def update_action?
138
+ action?('update')
139
+ end
140
+
141
+ ##
142
+ # Check if collection
143
+ #
144
+ # Check if action is a collection action type. An action is a collection type if it is the `index` action
145
+ #
146
+ # Usage
147
+ # collection_action? # true
148
+ # collection_action? # false
149
+ #
150
+ # @return [Boolean] if action is collection type
151
+ #
152
+ def collection_action?
153
+ collection_actions.include?(action)
154
+ end
155
+
156
+ ##
157
+ # Check if create or new
158
+ #
159
+ # Check if action is a create or new action type. The check will pass if it is a `create` or `new` action
160
+ #
161
+ # Usage
162
+ # create_actions? # true
163
+ # create_actions? # false
164
+ #
165
+ # new_actions? # true
166
+ # new_actions? # false
167
+ #
168
+ # @return [Boolean] if action is actions type
169
+ #
170
+ def create_actions?
171
+ create_actions.include?(action)
172
+ end
173
+ alias new_actions? create_actions?
174
+
175
+ ##
176
+ # Check if member
177
+ #
178
+ # Check if action is a member action type. An action is a member type if it is the `edit`, `show`, or `update`
179
+ # action
180
+ #
181
+ # Usage
182
+ # member_action? # true
183
+ # member_action? # false
184
+ #
185
+ # @return [Boolean] if action is member type
186
+ #
187
+ def member_action?
188
+ member_actions.include?(action)
189
+ end
190
+
191
+ ##
192
+ # Check if edit or update
193
+ #
194
+ # Check if action is an edit or update action type. The check will pass if it is an `edit` or `update` action
195
+ #
196
+ # Usage
197
+ # update_actions? # true
198
+ # update_actions? # false
199
+ #
200
+ # edit_actions? # true
201
+ # edit_actions? # false
202
+ #
203
+ # @return [Boolean] if action is actions type
204
+ #
205
+ def update_actions?
206
+ update_actions.include?(action)
207
+ end
208
+ alias edit_actions? update_actions?
209
+
210
+ protected
211
+
212
+ def action
213
+ action_name.to_sym
214
+ end
215
+
216
+ def collection_actions
217
+ %i[index]
218
+ end
219
+
220
+ def member_actions
221
+ %i[edit show update]
222
+ end
223
+
224
+ def create_actions
225
+ %i[create new]
226
+ end
227
+
228
+ def update_actions
229
+ %i[edit update]
230
+ end
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ module Controllers
5
+ ##
6
+ # Kaminari pagination
7
+ #
8
+ # Helpers for Kaminari style pagination. Note that the Kaminari gem is not loaded with dependency. It must be added
9
+ # to your own Gemfile
10
+ #
11
+ # Usage
12
+ # class ExamplesController < ApplicationController
13
+ # include Undercarriage::Controllers::KaminariConcern
14
+ #
15
+ # def index
16
+ # @examples = Examples.page(page_num).per(per_page)
17
+ # end
18
+ # end
19
+ #
20
+ module KaminariConcern
21
+ extend ActiveSupport::Concern
22
+
23
+ included do
24
+ helper_method :page_num, :per_page
25
+ end
26
+
27
+ ##
28
+ # Items per page
29
+ #
30
+ # The number of items to return in pagination. Will use the Kaminari config `default_per_page` (typically `25`)
31
+ # for the count and will look for `per` in the URL paramaters to override.
32
+ #
33
+ # This is asseccible from the View as `per_page`
34
+ #
35
+ # Usage
36
+ # /examples?per=100 # Return 100 items per page
37
+ # /examples?per=10&page=3 # Return page 3 of items with 10 items per page
38
+ #
39
+ # @return [Integer] the number of items per page
40
+ #
41
+ def per_page
42
+ params.fetch(per_page_key, per_page_default).to_i
43
+ end
44
+
45
+ ##
46
+ # Page number
47
+ #
48
+ # Will look for the Kaminari config `param_name` (typically `page`) in the URL paramaters.
49
+ #
50
+ # This is asseccible from the View as `page_num`
51
+ #
52
+ # Usage
53
+ # /examples?page=5 # Return page 5 of items
54
+ # /examples?per=10&page=3 Return page 3 of items with 10 items per page
55
+ #
56
+ # @return [Integer] the page number
57
+ #
58
+ def page_num
59
+ params.fetch(page_num_key, page_num_default).to_i
60
+ end
61
+
62
+ protected
63
+
64
+ def per_page_key
65
+ :per
66
+ end
67
+
68
+ def page_num_key
69
+ Kaminari.config.param_name
70
+ end
71
+
72
+ private
73
+
74
+ def per_page_default
75
+ Kaminari.config.default_per_page
76
+ end
77
+
78
+ def page_num_default
79
+ 1
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ module Controllers
5
+ ##
6
+ # Identify locale for translations
7
+ #
8
+ # Identify locale based on `HTTP_ACCEPT_LANGUAGE`. Browser preferred language is passed with the request as
9
+ # `en-US, en;q=0.9` where `en-US` (English with US dialect) is the preferred language with `en` (generic English) as
10
+ # an acceptable language.
11
+ #
12
+ # When preferred language cannot be identified or no translation is available, fall back to `I18n.default_locale`
13
+ # (typically `en`).
14
+ #
15
+ # Usage
16
+ # class ExamplesController < ApplicationController
17
+ # include Undercarriage::Controllers::LocaleConcern
18
+ # end
19
+ #
20
+ module LocaleConcern
21
+ extend ActiveSupport::Concern
22
+
23
+ included do
24
+ around_action :identify_locale
25
+
26
+ helper_method :html_lang, :html_dir
27
+ end
28
+
29
+ ##
30
+ # Lang
31
+ #
32
+ # Helper for Views to return the identified language.
33
+ #
34
+ # Usage
35
+ # <html lang="<%= html_lang %>"> #=> '<html lang="de">'
36
+ # <html lang="<%= html_lang %>"> #=> '<html lang="de-at">'
37
+ #
38
+ def html_lang
39
+ I18n.locale.to_s
40
+ end
41
+
42
+ ##
43
+ # Text direction
44
+ #
45
+ # Helper for Views to return text direction based on locale. Display text left-to-right for all languages but a
46
+ # few languages which should display as right-to-left. Returns `rtl` for the following languages:
47
+ #
48
+ # * Arabic
49
+ # * Aramaic
50
+ # * Azeri
51
+ # * Divehi
52
+ # * Hebrew
53
+ # * Persian/Farsi
54
+ # * Urdu
55
+ #
56
+ # Usage
57
+ # <html dir="<%= html_dir %>"> #=> <html dir="ltr">
58
+ # <html dir="<%= html_dir %>"> #=> <html dir="rtl">
59
+ #
60
+ def html_dir
61
+ rtl_languages = %w[am ar az dv fa he ur]
62
+
63
+ html_lang.start_with?(*rtl_languages) ? 'rtl' : 'ltr'
64
+ end
65
+
66
+ protected
67
+
68
+ def identify_locale(&action)
69
+ I18n.with_locale(first_available_locale, &action)
70
+ end
71
+
72
+ private
73
+
74
+ def first_available_locale
75
+ preferred_locales = (accepted_languages_header << I18n.default_locale.to_s).uniq
76
+ available_locales = I18n.available_locales.map(&:to_s)
77
+
78
+ preferred_locales.intersection(available_locales).first
79
+ end
80
+
81
+ def accepted_languages_header
82
+ accepted_languages = request.env['HTTP_ACCEPT_LANGUAGE'] || ''
83
+
84
+ accepted_languages.gsub(/\s+/, '').split(',').map do |lang|
85
+ lang.split(';q=').first
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ class Railtie < ::Rails::Railtie
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: undercarriage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Freerksen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 6.0.3
27
+ description: Undercarriage is a set of concerns to add to your application to trim
28
+ some of the fat from controllers and models.
29
+ email:
30
+ - dfreerksen@gmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - MIT-LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - lib/tasks/undercarriage_tasks.rake
39
+ - lib/undercarriage.rb
40
+ - lib/undercarriage/controllers/action_concern.rb
41
+ - lib/undercarriage/controllers/kaminari_concern.rb
42
+ - lib/undercarriage/controllers/locale_concern.rb
43
+ - lib/undercarriage/railtie.rb
44
+ - lib/undercarriage/version.rb
45
+ homepage: https://github.com/dfreerksen/undercarriage
46
+ licenses:
47
+ - MIT
48
+ metadata:
49
+ bug_tracker_uri: https://github.com/dfreerksen/undercarriage/issues
50
+ documentation_uri: https://www.rubydoc.info/github/dfreerksen/undercarriage/master
51
+ homepage_uri: https://github.com/dfreerksen/undercarriage
52
+ source_code_uri: https://github.com/dfreerksen/undercarriage
53
+ wiki_uri: https://github.com/dfreerksen/undercarriage/wiki
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '2.5'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.0.3
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Controller and model concerns for Ruby on Rails.
73
+ test_files: []