markup_attributes 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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +100 -0
  4. data/Rakefile +27 -0
  5. data/app/helpers/markup_attributes_helper.rb +66 -0
  6. data/lib/markup_attributes/engine.rb +5 -0
  7. data/lib/markup_attributes/version.rb +3 -0
  8. data/lib/markup_attributes.rb +137 -0
  9. data/lib/tasks/markup_attributes_tasks.rake +4 -0
  10. data/spec/dummy/Rakefile +6 -0
  11. data/spec/dummy/app/assets/config/manifest.js +2 -0
  12. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  13. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  14. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  15. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  16. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  17. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  18. data/spec/dummy/app/jobs/application_job.rb +2 -0
  19. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  20. data/spec/dummy/app/models/application_record.rb +3 -0
  21. data/spec/dummy/app/models/basic_model.rb +3 -0
  22. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  23. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  24. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  25. data/spec/dummy/bin/bundle +3 -0
  26. data/spec/dummy/bin/rails +4 -0
  27. data/spec/dummy/bin/rake +4 -0
  28. data/spec/dummy/bin/setup +33 -0
  29. data/spec/dummy/bin/update +28 -0
  30. data/spec/dummy/config/application.rb +29 -0
  31. data/spec/dummy/config/boot.rb +5 -0
  32. data/spec/dummy/config/cable.yml +10 -0
  33. data/spec/dummy/config/database.yml +14 -0
  34. data/spec/dummy/config/environment.rb +5 -0
  35. data/spec/dummy/config/environments/development.rb +46 -0
  36. data/spec/dummy/config/environments/production.rb +71 -0
  37. data/spec/dummy/config/environments/test.rb +36 -0
  38. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  39. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
  41. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  42. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  43. data/spec/dummy/config/initializers/inflections.rb +16 -0
  44. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  45. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  46. data/spec/dummy/config/locales/en.yml +33 -0
  47. data/spec/dummy/config/puma.rb +34 -0
  48. data/spec/dummy/config/routes.rb +3 -0
  49. data/spec/dummy/config/spring.rb +6 -0
  50. data/spec/dummy/config/storage.yml +34 -0
  51. data/spec/dummy/config.ru +5 -0
  52. data/spec/dummy/db/dummy_development.sqlite3 +0 -0
  53. data/spec/dummy/db/dummy_test.sqlite3 +0 -0
  54. data/spec/dummy/db/migrate/20190131160549_create_basic_models.rb +10 -0
  55. data/spec/dummy/db/migrate/20190131173158_translation_table_for_basic_model.rb +13 -0
  56. data/spec/dummy/db/migrate/20190201155355_add_second_attribute_to_basic_models.rb +5 -0
  57. data/spec/dummy/db/schema.rb +33 -0
  58. data/spec/dummy/log/development.log +460 -0
  59. data/spec/dummy/log/test.log +11533 -0
  60. data/spec/dummy/public/404.html +67 -0
  61. data/spec/dummy/public/422.html +67 -0
  62. data/spec/dummy/public/500.html +66 -0
  63. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  64. data/spec/dummy/public/apple-touch-icon.png +0 -0
  65. data/spec/dummy/public/favicon.ico +0 -0
  66. data/spec/helpers/markup_attributes_helper_spec.rb +170 -0
  67. data/spec/rails_helper.rb +62 -0
  68. data/spec/spec_helper.rb +96 -0
  69. data/spec/support/html_examples.rb +26 -0
  70. data/spec/support/matchers.rb +17 -0
  71. data/spec/support/textile_examples.rb +50 -0
  72. metadata +288 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97c6b8cec1b64b794fac504e4893679db9449395
4
+ data.tar.gz: 20456a12c564af69e167736e4ffcf92422995b01
5
+ SHA512:
6
+ metadata.gz: 654d8ed332adf3308ae8905defccaa7f7eb3f12d854bb1650f01af28c3c31c6c71aeb308cdaf61148d0b64623e0dba5551ef127285c2e6f9db4145633fd2f699
7
+ data.tar.gz: 732047395d4b1d68e81422482dcb235c396865441be46157d1073b4c279d953552f9651dde7b8a7f527fc828f494d80e5eb8bf0f4d1cb5f9499b69690159c425
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2019 James Adam
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,100 @@
1
+ # MarkupAttributes
2
+ A simple Rails engine for cleanly handling Textile/Markdown markup in ActiveRecord attributes.
3
+
4
+ Using this engine, we can define a particular attribute as containing markup, with constraints around
5
+ which markup rules and tags we want to support, and then render that attribute value to HTML
6
+ consistently throughout the rest of the application.
7
+
8
+ Rather than adding any HTML generation into the model itself, this works by attaching metadata
9
+ to the model, which can then be consumed by a helper when the attribute is used in views.
10
+
11
+ In the future, this will expand to also handle Markdown, Github-Flavoured Markdown and potentially
12
+ any other markup language; the underlying mechanism is markup-agnostic, and others can easily
13
+ be added.
14
+
15
+ ## Usage
16
+ Once you've added this gem to your application, you can enable it on a per-model basis by
17
+ extending the model class with the {#MarkupAttributes} module, and then declaring one or more
18
+ attributes as having textile:
19
+
20
+ class Post < ApplicationRecord
21
+ extend MarkupAttributes
22
+
23
+ textile_attribute :title, :description
24
+ end
25
+
26
+ You can then deal with the model as with any other ActiveRecord subclass; the attributes
27
+ can be treated as simple strings:
28
+
29
+ post = Post.create(title: 'My _cool_ post', description: 'A post about *stuff*')
30
+ post.title # => 'My _cool_ post'
31
+ post.description # => 'A post about *stuff*'
32
+
33
+ When you want to render the markup in a view, use the `render_markup` helper method:
34
+
35
+ <h1><%= render_markup post.title %></h1>
36
+ <p><%= render_markup post.description %></p>
37
+
38
+ which will produce the HTML
39
+
40
+ <h1>My <em>cool</em> post</h1>
41
+ <p>A post about <strong>stuff</strong></p>
42
+
43
+
44
+ ### Markup constraints
45
+
46
+ The main benefit of this gem is that it allows you to define _constraints_ about what markup
47
+ an attribute should support in a single place, and have those rules be applied consistently
48
+ wherever the content is rendered. We do this using the `:allow` and `:deny` options to
49
+ `textile_attribute`.
50
+
51
+ class Post < ApplicationRecord
52
+ extend MarkupAttributes
53
+
54
+ textile_attribute :title, allow: :emphasis
55
+ end
56
+
57
+ If any `:allow` options are set, anything missing from that option is assumed to be denied, and
58
+ will be removed from the rendered markup. So, anywhere we try to render the title markup now,
59
+ these rules will be respected:
60
+
61
+ <% post = Post.new(title: '"Link":http://example.com this _up_') %>
62
+ <%= render_markup post.title %>
63
+
64
+ produces
65
+
66
+ Link this <em>up</em>
67
+
68
+ Because we didn't allow links, that aspect of the markup is removed.
69
+
70
+ We can include multiple allowed markup types:
71
+
72
+ textile_attribute :title, allow: [:emphasis, :links, :images]
73
+
74
+ or, we can allow all markup and then explicitly deny certain types:
75
+
76
+ textile_attribute :title, deny: :images
77
+
78
+
79
+ ## Installation
80
+ Add this line to your application's Gemfile:
81
+
82
+ ```ruby
83
+ gem 'markup_attributes'
84
+ ```
85
+
86
+ And then execute:
87
+ ```bash
88
+ $ bundle
89
+ ```
90
+
91
+ Or install it yourself as:
92
+ ```bash
93
+ $ gem install markup_attributes
94
+ ```
95
+
96
+ ## Contributing
97
+ Contribution directions go here.
98
+
99
+ ## License
100
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'yard'
8
+ YARD::Rake::YardocTask.new(:doc) do |t|
9
+ t.files = ['app/**/*.rb', 'lib/**/*.rb', '-', 'README.md']
10
+ t.options = ['--no-private']
11
+ end
12
+
13
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
14
+ load 'rails/tasks/engine.rake'
15
+
16
+ load 'rails/tasks/statistics.rake'
17
+
18
+ require 'bundler/gem_tasks'
19
+
20
+ if defined? RSpec
21
+ task(:spec).clear
22
+ RSpec::Core::RakeTask.new(:spec) do |t|
23
+ t.verbose = false
24
+ end
25
+ end
26
+
27
+ task default: :spec
@@ -0,0 +1,66 @@
1
+ # The top-level Rails helper which enables consistent rendering of markup attributes.
2
+ #
3
+ # Rails will make this automatically available in your views; you may need to explicitly
4
+ # include it in other places (like serializers).
5
+ #
6
+ # This helper exposes a single method: +render_markup+
7
+ module MarkupAttributesHelper
8
+
9
+ # Given an attribute, returned an HTML-safe, rendered version of the content
10
+ # in that attribute, rendered according to the markup options defined in the model.
11
+ #
12
+ # If the passed attribute has not been configured as a markup attribute, it will be
13
+ # returned without performing any rendering at all. Th ft ft
14
+ #
15
+ # @param markup_attribute [String] the attribute to render. If this is an attribute that
16
+ # has not been configured as a markup attribute, it will be returned without any rendering.
17
+ # @example rendering an attribute from a model
18
+ # # Given this model exists somewhere, with `title` as a markup attribute:
19
+ # # post = Post.new(title: '"This":http://example.com is _great_')
20
+ #
21
+ # render_markup(post.title) # => '<a href="http://example.com" rel="nofollow">This</a> is <em>great</em>'
22
+ def render_markup(markup_attribute)
23
+ return markup_attribute if markup_attribute.blank?
24
+
25
+ if markup_attribute.respond_to?(:markup_options)
26
+ options = markup_attribute.markup_options
27
+
28
+ html = case options[:markup]
29
+ when :textile
30
+ require 'redcloth'
31
+ RedCloth.new(sanitize(markup_attribute), [:no_span_caps]).to_html
32
+ else
33
+ raise "unknown markup attribute type: #{options[:markup]}"
34
+ end
35
+
36
+ cleaned_html = clean_rendered_markup(html, options)
37
+ cleaned_html.html_safe
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def clean_rendered_markup(html, options)
44
+ cleaned_html = if options[:allow] == [:all]
45
+ denied_tags = tags_from_tag_types(*options[:deny])
46
+ allowed_tags = Rails::Html::WhiteListSanitizer.allowed_tags.reject { |tag| denied_tags.include?(tag.to_s) }
47
+ whitelisted_html = Rails::Html::WhiteListSanitizer.new.sanitize(html, tags: allowed_tags).strip
48
+ whitelisted_html
49
+ else
50
+ allowed_tags = tags_from_tag_types(*options[:allow])
51
+ cleaned_html = Rails::Html::WhiteListSanitizer.new.sanitize(html, tags: allowed_tags).strip
52
+ cleaned_html = Loofah.scrub_fragment(cleaned_html, :nofollow).to_html if options[:allow].include?(:links)
53
+ cleaned_html
54
+ end
55
+
56
+ cleaned_html
57
+ end
58
+
59
+ def tags_from_tag_types(*tag_types)
60
+ tags = []
61
+ tags += %w(i em) if tag_types.include?(:emphasis)
62
+ tags += %w(a) if tag_types.include?(:links)
63
+ tags += %w(img) if tag_types.include?(:images)
64
+ tags
65
+ end
66
+ end
@@ -0,0 +1,5 @@
1
+ module MarkupAttributes
2
+ # @private
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module MarkupAttributes
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,137 @@
1
+ require "markup_attributes/engine"
2
+
3
+ # The main behaviour for defining markup attributes
4
+ #
5
+ # To enable this for your models, either extend it directly into one or more models,
6
+ # or extend it into `ApplicationRecord` to include it everywhere
7
+ #
8
+ # == Markup constraints
9
+ # Markup content typically comes from users of the app, and as with any user-generated
10
+ # content, we probably can't allow them to insert any old HTML into our rendered pages.
11
+ #
12
+ # The main benefit of this approach is that it allows us to declare constraints on
13
+ # the types of markup we want to deal with in a single place, but without coupling
14
+ # rendering logic into the model itself.
15
+ #
16
+ # Those constraints are grouped into certain types of elements:
17
+ #
18
+ # Emphasis (:emphasis):: allow `i` and `em` tags.
19
+ # Links (:links):: allow `a` tags, but mark them as `nofollow` so that they are not useful
20
+ # for spammers.
21
+ # Images (:images):: allow `img` tags.
22
+ #
23
+ # == Automatic sanitisation
24
+ #
25
+ # All the HTML generated is automatically run through Rails' own sanitisation mechanism,
26
+ # which means that things like `<script>alert();</script>` will automatically either
27
+ # be sanitised into a non-running piece of content, or entirely removed, depending on
28
+ # the options given.
29
+ #
30
+ # @example a simple model declaring textile attributes
31
+ # class Post < ApplicationRecord
32
+ # extend MarkupAttributes
33
+ #
34
+ # textile_attribute :title, :description, allow: [:emphasis, :images]
35
+ #
36
+ # # ...
37
+ # end
38
+ module MarkupAttributes
39
+ # A subclass of string which the attributes are cast into by ActiveRecord
40
+ # @private
41
+ class MarkupString < String
42
+ attr_accessor :markup_options
43
+ end
44
+
45
+ # The type used by ActiveRecord's attributes API
46
+ # @private
47
+ class MarkupType < ActiveRecord::Type::String
48
+ def self.inspect
49
+ "<MarkupType [#{markup_options}]>"
50
+ end
51
+
52
+ def markup_options
53
+ self.class.markup_options
54
+ end
55
+
56
+ def cast(value)
57
+ if value.is_a?(String) || value.is_a?(MarkupString)
58
+ MarkupString.new(value).tap { |s| s.markup_options = self.markup_options }
59
+ else
60
+ super
61
+ end
62
+ end
63
+ end
64
+
65
+ ActiveRecord::Type.register(:markup, MarkupType)
66
+
67
+ # Declare one or more attributes as containing Textile markup.
68
+ # @param (see #markup_attribute)
69
+ # @example An attribute which only supports Textile emphasis and links
70
+ # textile_attribute :title, allow: [:emphasis, :links]
71
+ # @example An attribute which supports everything except images
72
+ # textile_attribute :title, deny: [:images]
73
+ def textile_attribute(*attribute_names, **options)
74
+ markup_attribute(*attribute_names, **options.merge(markup: :textile))
75
+ end
76
+
77
+ # Declare one or more attributes as containing Markdown markup.
78
+ # @param (see #markup_attribute)
79
+ def markdown_attribute(*attribute_names, **options)
80
+ markup_attribute(*attribute_names, **options.merge(markup: :markdown))
81
+ end
82
+
83
+ # Declare one or more attributes as containing markup content
84
+ #
85
+ # == Markup types
86
+ # The following types can be provided in either the +:allow+ or +:deny+ options:
87
+ # :emphasis:: +i+ and +em+ tags
88
+ # :links:: +a+ tags (will all have +rel=nofollow+ automatically set)
89
+ # :images:: +img+ tags
90
+ #
91
+ # @param attribute_names [Symbol, Array<Symbol>] One or more attribute names to mark as containing markup
92
+ # @param options [Hash<Symbol=>Symbol>, Hash<Symbol=>Array<Symbol>>] Options to be used when rendering this/these attributes
93
+ # @option options [Symbol] :markup The markup engine to use, either +:textile+ or +:markdown+. If you use either of
94
+ # +textile_attribute+ or +markdown_attribute+, wrapper methods, this will be set automatically.
95
+ # @option options [Symbol, Array<Symbol>] :allow Which types of markup to allow (any not included are implicity denied)
96
+ # @option options [Symbol, Array<symbol>] :deny Which types of markup to deny (any not included are implicity allowed)
97
+ def markup_attribute(*attribute_names, **options)
98
+ raise "must define :markup option" unless options[:markup]
99
+ options.deep_symbolize_keys!
100
+ options[:allow] = Array.wrap(options[:allow] || :all).map(&:to_sym)
101
+ options[:deny] = Array.wrap(options[:deny]).map(&:to_sym)
102
+ options.freeze
103
+
104
+ attribute_registry_type = get_type_for(options)
105
+
106
+ attribute_names.each do |attribute_name|
107
+ if respond_to?(:translates?) && translates? && translated_attribute_names.include?(attribute_name)
108
+ translation_class.attribute attribute_name, attribute_registry_type
109
+ else
110
+ attribute attribute_name, attribute_registry_type
111
+ end
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ MARKUP_TYPES_REGISTRY = {}
118
+
119
+ def get_type_for(options)
120
+ allow_keys = options[:allow].map { |x| "+#{x}" }
121
+ deny_keys = options[:deny].map { |x| "-#{x}" }
122
+ type_key = [options[:markup],(allow_keys + deny_keys).sort.join].join('=>').to_sym
123
+ MARKUP_TYPES_REGISTRY.fetch(type_key) do
124
+ klass = eval <<-TYPE_CLASS
125
+ Class.new(MarkupType) do
126
+ def self.markup_options
127
+ #{options.inspect}
128
+ end
129
+ end
130
+ TYPE_CLASS
131
+ ActiveRecord::Type.register(type_key, klass)
132
+ MARKUP_TYPES_REGISTRY[type_key] = klass
133
+ klass
134
+ end
135
+ type_key
136
+ end
137
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :markup_attributes do
3
+ # # Task goes here
4
+ # end
@@ -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_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,2 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: 'from@example.com'
3
+ layout 'mailer'
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,3 @@
1
+ class BasicModel < ApplicationRecord
2
+ extend MarkupAttributes
3
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag 'application', media: 'all' %>
9
+ </head>
10
+
11
+ <body>
12
+ <%= yield %>
13
+ </body>
14
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../config/application', __dir__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ include FileUtils
4
+
5
+ # path to your application root.
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ chdir APP_ROOT do
13
+ # This script is a starting point to setup your application.
14
+ # Add necessary setup steps to this file.
15
+
16
+ puts '== Installing dependencies =='
17
+ system! 'gem install bundler --conservative'
18
+ system('bundle check') || system!('bundle install')
19
+
20
+ # puts "\n== Copying sample files =="
21
+ # unless File.exist?('config/database.yml')
22
+ # cp 'config/database.yml.sample', 'config/database.yml'
23
+ # end
24
+
25
+ puts "\n== Preparing database =="
26
+ system! 'bin/rails db:setup'
27
+
28
+ puts "\n== Removing old logs and tempfiles =="
29
+ system! 'bin/rails log:clear tmp:clear'
30
+
31
+ puts "\n== Restarting application server =="
32
+ system! 'bin/rails restart'
33
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ include FileUtils
4
+
5
+ # path to your application root.
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ chdir APP_ROOT do
13
+ # This script is a way to update your development environment automatically.
14
+ # Add necessary update steps to this file.
15
+
16
+ puts '== Installing dependencies =='
17
+ system! 'gem install bundler --conservative'
18
+ system('bundle check') || system!('bundle install')
19
+
20
+ puts "\n== Updating database =="
21
+ system! 'bin/rails db:migrate'
22
+
23
+ puts "\n== Removing old logs and tempfiles =="
24
+ system! 'bin/rails log:clear tmp:clear'
25
+
26
+ puts "\n== Restarting application server =="
27
+ system! 'bin/rails restart'
28
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'boot'
2
+
3
+ require "rails"
4
+ # Pick the frameworks you want:
5
+ require "active_model/railtie"
6
+ require "active_record/railtie"
7
+ require "action_controller/railtie"
8
+ require "action_view/railtie"
9
+
10
+ Bundler.require(*Rails.groups)
11
+ require "markup_attributes"
12
+ require 'globalize'
13
+
14
+
15
+ module Dummy
16
+ class Application < Rails::Application
17
+ # Initialize configuration defaults for originally generated Rails version.
18
+ config.load_defaults 5.2
19
+
20
+ config.i18n.available_locales = ['en-US', 'fr-FR']
21
+ config.i18n.default_locale = 'en-US'
22
+
23
+ # Settings in config/environments/* take precedence over those specified here.
24
+ # Application configuration can go into files in config/initializers
25
+ # -- all .rb files in that directory are automatically loaded after loading
26
+ # the framework and any gems in your application.
27
+ end
28
+ end
29
+
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
3
+
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
@@ -0,0 +1,10 @@
1
+ development:
2
+ adapter: async
3
+
4
+ test:
5
+ adapter: async
6
+
7
+ production:
8
+ adapter: redis
9
+ url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10
+ channel_prefix: dummy_production
@@ -0,0 +1,14 @@
1
+ default: &default
2
+ adapter: sqlite3
3
+ encoding: unicode
4
+ # For details on connection pooling, see Rails configuration guide
5
+ # http://guides.rubyonrails.org/configuring.html#database-pooling
6
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
7
+
8
+ development:
9
+ <<: *default
10
+ database: db/dummy_development.sqlite3
11
+
12
+ test:
13
+ <<: *default
14
+ database: db/dummy_test.sqlite3
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require_relative 'application'
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!