simple_email_preview 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +7 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +162 -0
  5. data/Rakefile +62 -0
  6. data/app/assets/images/simple_email_preview/favicon.png +0 -0
  7. data/app/assets/javascripts/simple_email_preview/application.js +1 -0
  8. data/app/assets/stylesheets/simple_email_preview/_bootstrap3.sass +68 -0
  9. data/app/assets/stylesheets/simple_email_preview/_default.sass +230 -0
  10. data/app/assets/stylesheets/simple_email_preview/application.scss +10 -0
  11. data/app/controllers/simple_email_preview/application_controller.rb +19 -0
  12. data/app/controllers/simple_email_preview/emails_controller.rb +194 -0
  13. data/app/helpers/simple_email_preview/emails_helper.rb +85 -0
  14. data/app/models/simple_email_preview/preview.rb +86 -0
  15. data/app/presenters/simple_email_preview/preview_list_presenter.rb +38 -0
  16. data/app/views/layouts/simple_email_preview/_flash_notices.html.erb +7 -0
  17. data/app/views/layouts/simple_email_preview/application.html.erb +16 -0
  18. data/app/views/layouts/simple_email_preview/email.html.erb +30 -0
  19. data/app/views/simple_email_preview/emails/_email_iframe.html.erb +88 -0
  20. data/app/views/simple_email_preview/emails/_format_nav.html.erb +4 -0
  21. data/app/views/simple_email_preview/emails/_headers.html.erb +10 -0
  22. data/app/views/simple_email_preview/emails/_headers_and_nav.html.erb +12 -0
  23. data/app/views/simple_email_preview/emails/_i18n_nav.html.erb +3 -0
  24. data/app/views/simple_email_preview/emails/_nav.html.erb +18 -0
  25. data/app/views/simple_email_preview/emails/_send_form.html.erb +11 -0
  26. data/app/views/simple_email_preview/emails/index.html.erb +36 -0
  27. data/app/views/simple_email_preview/emails/show.html.erb +23 -0
  28. data/config/i18n-tasks.yml +10 -0
  29. data/config/initializers/simple_email_preview.rb +14 -0
  30. data/config/locales/de.yml +47 -0
  31. data/config/locales/en.yml +47 -0
  32. data/config/locales/es.yml +47 -0
  33. data/config/locales/ja.yml +47 -0
  34. data/config/locales/ru.yml +51 -0
  35. data/config/routes.rb +23 -0
  36. data/lib/generators/simple_email_preview/install_generator.rb +17 -0
  37. data/lib/generators/simple_email_preview/update_previews_generator.rb +45 -0
  38. data/lib/simple_email_preview.rb +105 -0
  39. data/lib/simple_email_preview/delivery_handler.rb +15 -0
  40. data/lib/simple_email_preview/engine.rb +14 -0
  41. data/lib/simple_email_preview/main_app_route_delegator.rb +20 -0
  42. data/lib/simple_email_preview/version.rb +3 -0
  43. data/lib/simple_email_preview/view_hooks.rb +102 -0
  44. metadata +231 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1e73087223247d26b230fcf9056c82b9758e62e60790454ac618d6ef317b2e4c
4
+ data.tar.gz: 3eca396535a17023a829bd85847704a9403db5b42c2f1e0806fc4d420dacf50d
5
+ SHA512:
6
+ metadata.gz: 1816d19dc6c4b1f1909d91d622e98620af0a5c0a76880d1564e8f1f5372ede65d5380fbe148972be19165d335bff9476bfa8684b8fdc14e947b0a016809aeecf
7
+ data.tar.gz: 6e2997d6474618938140a10d1a8ee0a3c1f5994511916eccfdf9e39a205ab3e628f87f42790dec4c6935d503df3ecf5443908f3cdc2d06209d9a2853c970193d
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rails'
6
+
7
+ eval_gemfile './shared.gemfile'
@@ -0,0 +1,20 @@
1
+ Copyright 2012-2013
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,162 @@
1
+ # Simple Email Preview
2
+ Preview email in the browser with this Rails engine. Compatible with Rails 4.2+.
3
+
4
+ *This gem base on [rails_email_preview](https://github.com/glebm/rails_email_preview), but prune for simple purpose (just preview)*
5
+
6
+ ## Installation
7
+
8
+ Add [![Gem Version][gem-badge]][gem] to Gemfile:
9
+
10
+ ```ruby
11
+ gem 'simple_email_preview', '~> 1.0.0'
12
+ ```
13
+
14
+ Add an initializer and the routes:
15
+
16
+ ```console
17
+ $ rails g simple_email_preview:install
18
+ ```
19
+
20
+ Generate preview classes and method stubs in app/mailer_previews/
21
+
22
+ ```console
23
+ $ rails g simple_email_preview:update_previews
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ The last generator above will add a stub for each of your emails, then you populate the stubs with mock data:
29
+
30
+ ```ruby
31
+ # app/mailer_previews/user_mailer_preview.rb:
32
+ class UserMailerPreview
33
+ # preview methods should return Mail objects, e.g.:
34
+ def invitation
35
+ UserMailer.invitation mock_user('Alice'), mock_user('Bob')
36
+ end
37
+
38
+ def welcome
39
+ UserMailer.welcome mock_user
40
+ end
41
+
42
+ private
43
+ # You can put all your mock helpers in a module
44
+ # or you can use your factories, just make sure you are not creating anything
45
+ def mock_user(name = 'Me')
46
+ fake_id User.new(name: name, email: "user#{rand 100}@test.com")
47
+ end
48
+
49
+ def fake_id(obj)
50
+ # overrides the method on just this object
51
+ obj.define_singleton_method(:id) { 123 + rand(100) }
52
+ obj
53
+ end
54
+ end
55
+ ```
56
+
57
+ ### Parameters as instance variables
58
+
59
+ All parameters in the search query will be available to the preview class as instance variables.
60
+ For example, if URL to mailer preview looks like:
61
+
62
+ /emails/user_mailer_preview-welcome?**user_id=1**
63
+
64
+ The method `welcome` in `UserMailerPreview` have a `@user_id` instance variable defined:
65
+
66
+ ```ruby
67
+ class UserMailerPreview
68
+ def welcome
69
+ user = @user_id ? User.find(@user_id) : mock_user
70
+ UserMailer.welcome(user)
71
+ end
72
+ end
73
+ ```
74
+
75
+ Now you can preview or send the welcome email to a specific user.
76
+
77
+ ### Routing
78
+
79
+ You can access REP urls like this:
80
+
81
+ ```ruby
82
+ # engine root:
83
+ simple_email_preview.rep_root_url
84
+ # list of emails (same as root):
85
+ simple_email_preview.rep_emails_url
86
+ # email show:
87
+ simple_email_preview.rep_email_url('user_mailer-welcome')
88
+ ```
89
+
90
+
91
+ ### Views
92
+
93
+ By default REP views will render inside its own layout.
94
+
95
+ To render all REP views inside your app layout, first set the layout to use in the initializer:
96
+
97
+ ```ruby
98
+ Rails.application.config.to_prepare do
99
+ # Use admin layout with REP (this will also make app routes accessible within REP):
100
+ SimpleEmailPreview.layout = 'admin'
101
+ end
102
+ ```
103
+
104
+ Then, import REP styles into your `application.css.scss`:
105
+
106
+ ```scss
107
+ @import "simple_email_preview/application";
108
+ ```
109
+
110
+ Alternatively, if you are using Bootstrap 3, `@import "simple_email_preview/bootstrap3"`, and add the following
111
+ to the initializer:
112
+
113
+ ```ruby
114
+ config.style.merge!(
115
+ btn_active_class_modifier: 'active',
116
+ btn_danger_class: 'btn btn-danger',
117
+ btn_default_class: 'btn btn-default',
118
+ btn_group_class: 'btn-group btn-group-sm',
119
+ btn_primary_class: 'btn btn-primary',
120
+ form_control_class: 'form-control',
121
+ list_group_class: 'list-group',
122
+ list_group_item_class: 'list-group-item',
123
+ row_class: 'row',
124
+ )
125
+ ```
126
+
127
+ You can also override any individual view by placing a file with the same path in your project's `app/views`,
128
+ e.g. `app/views/simple_email_preview/emails/index.html.slim`.
129
+
130
+ #### Hooks
131
+
132
+ You can add content around or replacing REP UI elements by registering view hooks in the initializer:
133
+
134
+ ```ruby
135
+ # Pass position (before, after, or replace) and render arguments:
136
+ SimpleEmailPreview.view_hooks.add_render :list, :before, partial: 'shared/hello'
137
+
138
+ # Pass hook id and position (before, after, or replace):
139
+ SimpleEmailPreview.view_hooks.add :headers_content, :after do |mail:, preview:|
140
+ raw "<dt>ID</dt><dd>#{h mail.header['X-APP-EMAIL-ID']}</dd>"
141
+ end
142
+ ```
143
+
144
+ All of the available hooks can be found [here](/lib/simple_email_preview/view_hooks.rb#L10).
145
+
146
+
147
+
148
+ ## Development
149
+
150
+ Run the tests:
151
+
152
+ ```console
153
+ $ rspec
154
+ ```
155
+
156
+ Start a development web server on [localhost:9292](http://localhost:9292):
157
+
158
+ ```console
159
+ $ rake dev
160
+ ```
161
+
162
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,62 @@
1
+
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ # Load dummy app tasks
9
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
10
+ load 'rails/tasks/engine.rake'
11
+
12
+ Bundler::GemHelper.install_tasks
13
+
14
+ require 'rspec/core/rake_task'
15
+ RSpec::Core::RakeTask.new(:spec)
16
+
17
+ task default: :spec
18
+
19
+ desc 'Start development web server'
20
+ task :dev do
21
+ host = '0.0.0.0'
22
+ port = ENV['PORT'] || 9292
23
+ ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'development'
24
+ Dir.chdir 'spec/dummy'
25
+
26
+ Rack::Server.start(
27
+ environment: 'development',
28
+ Host: host,
29
+ Port: port,
30
+ config: 'config.ru'
31
+ )
32
+ end
33
+
34
+ desc 'Test all Gemfiles from spec/*.gemfile'
35
+ task :test_all_gemfiles do
36
+ require 'pty'
37
+ require 'shellwords'
38
+ cmd = 'bundle install --quiet && bundle exec rake --trace'
39
+ statuses = Dir.glob('./spec/gemfiles/*{[!.lock]}').map do |gemfile|
40
+ Bundler.with_clean_env do
41
+ env = { 'BUNDLE_GEMFILE' => gemfile }
42
+ warn "Testing #{File.basename(gemfile)}:\n export #{env.map { |k, v| "#{k}=#{Shellwords.escape v}" } * ' '}; #{cmd}"
43
+ PTY.spawn(env, cmd) do |r, _w, pid|
44
+ begin
45
+ r.each_line { |l| puts l }
46
+ rescue Errno::EIO
47
+ # Errno:EIO error means that the process has finished giving output.
48
+ ensure
49
+ ::Process.wait pid
50
+ end
51
+ end
52
+ [$CHILD_STATUS && $CHILD_STATUS.exitstatus == 0, gemfile]
53
+ end
54
+ end
55
+ failed_gemfiles = statuses.reject(&:first).map { |(_status, gemfile)| gemfile }
56
+ if failed_gemfiles.empty?
57
+ warn "✓ Tests pass with all #{statuses.size} gemfiles"
58
+ else
59
+ warn "❌ FAILING (#{failed_gemfiles.size} / #{statuses.size})\n#{failed_gemfiles * "\n"}"
60
+ exit 1
61
+ end
62
+ end
@@ -0,0 +1 @@
1
+ //= require turbolinks
@@ -0,0 +1,68 @@
1
+ // Bootstrap 3 theme for Rails Email Preview
2
+
3
+ .rep--email-headers
4
+ @extend .col-md-8
5
+
6
+ .rep--email-nav-container
7
+ @extend .col-md-4
8
+
9
+ .rep--email-list-half
10
+ @extend .col-md-6
11
+
12
+ .rep--headers-list
13
+ dt
14
+ color: $gray-dark
15
+ @media (min-width: $screen-sm-min)
16
+ float: left
17
+ clear: left
18
+ margin-right: 0.45em
19
+ text-align: right
20
+ width: 100px
21
+ &::after
22
+ content: ":"
23
+ dd
24
+ width: auto
25
+ margin-left: 0
26
+ margin-bottom: 0.3em
27
+
28
+ .rep--email-options
29
+ text-align: right
30
+
31
+ .rep--breadcrumbs
32
+ @extend .breadcrumb
33
+
34
+ .rep--breadcrumbs__breadcrumb-active
35
+ color: $breadcrumb-active-color
36
+
37
+ .rep--panel
38
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .125)
39
+ padding: 15px
40
+ margin-bottom: 20px
41
+
42
+ .rep--send-to-form
43
+ display: block
44
+ white-space: nowrap
45
+ padding-bottom: 4px
46
+ button, [type="email"]
47
+ display: inline-block
48
+ &:focus, &:active
49
+ z-index: 2
50
+ button
51
+ line-height: 1.3
52
+ border-top-right-radius: 0
53
+ border-bottom-right-radius: 0
54
+ [type="email"]
55
+ max-width: 140px
56
+ border-top-left-radius: 0
57
+ border-bottom-left-radius: 0
58
+
59
+ .rep--footer
60
+ text-align: center
61
+ color: $state-info-text
62
+
63
+ .rep--email-headers
64
+ +make-sm-column(8)
65
+ .rep--email-nav-container
66
+ +make-sm-column(4)
67
+ .rep--email-list-half
68
+ +make-sm-column(6)
@@ -0,0 +1,230 @@
1
+ // A standalone theme for Rails Email Preview
2
+
3
+ $rep-brand-color: #4a90e2 !default
4
+ $rep-link-color: $rep-brand-color !default
5
+ $rep-gray: #818a91 !default
6
+ $rep-gray-light: #dedede !default
7
+ $rep-gray-lighter: #f1f3f4 !default
8
+
9
+ $rep-breadcrumb-bg: $rep-gray-lighter !default
10
+
11
+ $rep-grid-gutter: 30px !default
12
+ $rep-grid-breakpoint-sm: 768px !default
13
+ $rep-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default
14
+ $rep-font-size-nav: 1.15em !default
15
+ $rep-text-color: rgba(black, 0.87) !default
16
+ $rep-text-color-secondary: #263238 !default
17
+
18
+ =rep--media-sm-plus
19
+ @media (min-width: $rep-grid-breakpoint-sm)
20
+ @content
21
+
22
+ =clearfix
23
+ &::after
24
+ content: ""
25
+ display: table
26
+ clear: both
27
+
28
+ %rep--link
29
+ color: $rep-link-color
30
+ text-decoration: none
31
+ transition: color 0.1s linear
32
+ &:active, &:focus, &:hover
33
+ color: darken($rep-link-color, 15%)
34
+ &:active
35
+ outline: none
36
+ &:focus
37
+ outline: thin dotted
38
+ outline: 5px auto -webkit-focus-ring-color
39
+ outline-offset: -2px
40
+
41
+ %rep--hr
42
+ margin-top: 20px
43
+ margin-bottom: 20px
44
+ border: 0
45
+ border-top: 1px solid $rep-gray-lighter
46
+
47
+ .rep--main-container
48
+ box-sizing: border-box
49
+ color: $rep-text-color
50
+ font-family: $rep-font-family
51
+ *, *::before, *::after
52
+ box-sizing: inherit
53
+ a
54
+ @extend %rep--link
55
+ hr
56
+ @extend %rep--hr
57
+
58
+ .rep--row
59
+ margin-left: ($rep-grid-gutter / -2)
60
+ margin-right: ($rep-grid-gutter / -2)
61
+ +clearfix
62
+
63
+ %rep--row__col
64
+ position: relative
65
+ min-height: 1px
66
+ padding-right: ($rep-grid-gutter / 2)
67
+ padding-left: ($rep-grid-gutter / 2)
68
+
69
+ @each $col in (4, 6, 8)
70
+ %rep--row__col-#{$col}
71
+ @extend %rep--row__col
72
+ +rep--media-sm-plus
73
+ float: left
74
+ width: percentage($col / 12)
75
+
76
+ .rep--email-headers
77
+ @extend %rep--row__col-8
78
+
79
+ .rep--email-nav-container
80
+ @extend %rep--row__col-4
81
+
82
+ .rep--email-list-half
83
+ @extend %rep--row__col-6
84
+
85
+ .rep--breadcrumbs
86
+ padding: 0.75rem 1rem
87
+ margin-bottom: 1rem
88
+ font-size: $rep-font-size-nav
89
+ list-style: none
90
+ background-color: $rep-breadcrumb-bg
91
+ .rep--breadcrumbs__breadcrumb
92
+ display: inline-block
93
+ + ::before
94
+ display: inline-block
95
+ padding: 0 0.5em
96
+ color: $rep-gray-light
97
+ content: "/"
98
+ .rep--breadcrumbs__breadcrumb-active
99
+ display: inline-block
100
+
101
+ .rep--headers-list
102
+ margin: 0
103
+ dt
104
+ color: $rep-text-color-secondary
105
+ font-weight: bold
106
+ +rep--media-sm-plus
107
+ float: left
108
+ clear: left
109
+ margin-right: 0.4em
110
+ text-align: right
111
+ width: 6em
112
+ dd
113
+ width: auto
114
+ margin-left: 0
115
+ margin-bottom: 0.2em
116
+
117
+ .rep--btn
118
+ appearance: none
119
+ -webkit-font-smoothing: antialiased
120
+ border: 1px solid
121
+ cursor: pointer
122
+ display: inline-block
123
+ font-weight: 600
124
+ padding: 0.75em 1em
125
+ text-decoration: none
126
+ user-select: none
127
+ vertical-align: middle
128
+ text-align: center
129
+ white-space: nowrap
130
+ transition: all .2s ease-in-out
131
+ &:active, &.rep--btn-active
132
+ background-image: none
133
+ outline: 0
134
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
135
+ &:focus
136
+ outline: none
137
+
138
+ =rep--btn($color, $background, $border-color: darken($background, 5%))
139
+ color: $color
140
+ background: $background
141
+ border-color: $border-color
142
+ &:hover
143
+ background: darken($background, 10%)
144
+ border-color: darken($border-color, 12%)
145
+ &:focus
146
+ box-shadow: 0 0 3px $background
147
+ background-color: darken($background, 17%)
148
+ border-color: darken($border-color, 25%)
149
+
150
+ .rep--btn-default
151
+ +rep--btn(#111, $rep-gray-lighter)
152
+
153
+ .rep--btn-primary
154
+ +rep--btn(#fff, $rep-brand-color)
155
+
156
+ .rep--btn-danger
157
+ +rep--btn(#fff, #d9534f)
158
+
159
+ .rep--btn-group
160
+ .rep--btn + .rep--btn
161
+ margin-left: -1px
162
+ .rep--btn
163
+ z-index: 1
164
+ &.rep--btn-active
165
+ z-index: 2
166
+ &:focus, &:hover
167
+ z-index: 3
168
+
169
+ .rep--list-group
170
+ font-size: $rep-font-size-nav
171
+
172
+ .rep--list-group__item
173
+ display: block
174
+ padding: 1rem 1.5rem
175
+ &:hover
176
+ background-color: $rep-gray-lighter
177
+ transition: background-color ease-in-out 0.15s, background-color ease-in-out 0.15s
178
+ + .rep--list-group__item
179
+ border-top: 1px solid $rep-gray-light
180
+
181
+ .rep--panel
182
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .125)
183
+ padding: 1.25rem
184
+ margin-bottom: 1rem
185
+
186
+ .rep--email-options
187
+ font-size: 0.875rem
188
+ text-align: left
189
+ p
190
+ margin-top: 0
191
+ +rep--media-sm-plus
192
+ text-align: right
193
+
194
+ .rep--send-to-form
195
+ display: block
196
+ white-space: nowrap
197
+ padding-bottom: 4px
198
+ button, [type="email"]
199
+ display: inline-block
200
+ &:focus, &:active
201
+ z-index: 2
202
+ button
203
+ line-height: 1.25
204
+ padding: 0.5rem
205
+ [type="email"]
206
+ max-width: 135px
207
+ padding: 0.5rem
208
+ border-top-left-radius: 0
209
+ border-bottom-left-radius: 0
210
+
211
+ .rep--form-control
212
+ padding: 0.5rem 0.75rem
213
+ line-height: 1.25
214
+ background-image: none
215
+ background-clip: padding-box
216
+ border: 1px solid rgba(0, 0, 0, 0.15)
217
+ border-radius: 0.25rem
218
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
219
+ transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s
220
+ &::placeholder
221
+ color: #999
222
+ opacity: 1
223
+ &:focus
224
+ border-color: lighten($rep-brand-color, 20%)
225
+ outline: none
226
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)
227
+
228
+ .rep--footer
229
+ text-align: center
230
+ color: $rep-gray