actionmailer-markdown 0.2.0 → 0.4.2
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 +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.rubocop.yml +21 -0
- data/Gemfile +3 -1
- data/README.md +52 -19
- data/Rakefile +16 -6
- data/actionmailer-markdown.gemspec +29 -19
- data/lib/action_mailer/markdown/ext.rb +9 -5
- data/lib/action_mailer/markdown/renderer/text.rb +23 -16
- data/lib/action_mailer/markdown/renderer.rb +6 -3
- data/lib/action_mailer/markdown/resolver.rb +25 -9
- data/lib/action_mailer/markdown/template_handler.rb +27 -6
- data/lib/action_mailer/markdown/version.rb +3 -1
- data/lib/action_mailer/markdown.rb +11 -9
- data/lib/actionmailer-markdown.rb +3 -1
- metadata +80 -23
- data/.travis.yml +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a044ca81f7b847e07a7f2287837a5ee6fb7b077a7ea4b3c91fa06234380b1188
|
|
4
|
+
data.tar.gz: fcedeba702d82d424fd45a23c0c7cc8a83efe4df13f93238968fb277e393fae3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc09a724f76c74741e55d43247491d61dcf7738564c58d6b939ca815935bb75057adb9560b3b74b018734ed8d099f546111c6369ace5cf74b1ecf5faa6d06a6d
|
|
7
|
+
data.tar.gz: 97bd392bca74d202d65cab66260704ba18206adb880d637ba20998cda0093d16ade2d0a1b604756f53a2423fe1b657bb33adabe9369b4b1d393c8e5d36fcfeda
|
data/.github/FUNDING.yml
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
inherit_gem:
|
|
3
|
+
rubocop-fnando: .rubocop.yml
|
|
4
|
+
|
|
5
|
+
AllCops:
|
|
6
|
+
TargetRubyVersion: 2.7
|
|
7
|
+
NewCops: enable
|
|
8
|
+
|
|
9
|
+
Layout/LineLength:
|
|
10
|
+
Enabled: false
|
|
11
|
+
|
|
12
|
+
Metrics:
|
|
13
|
+
Enabled: false
|
|
14
|
+
|
|
15
|
+
Naming/FileName:
|
|
16
|
+
Exclude:
|
|
17
|
+
- lib/actionmailer-markdown.rb
|
|
18
|
+
|
|
19
|
+
Style/OpenStructUse:
|
|
20
|
+
Exclude:
|
|
21
|
+
- test/**/*.rb
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# ActionMailer::Markdown
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.org/fnando/actionmailer-markdown)
|
|
4
|
+
[](https://codeclimate.com/github/fnando/actionmailer-markdown)
|
|
5
|
+
[](https://codeclimate.com/github/fnando/actionmailer-markdown/coverage)
|
|
6
|
+
[](https://rubygems.org/gems/actionmailer-markdown)
|
|
7
|
+
[](https://rubygems.org/gems/actionmailer-markdown)
|
|
4
8
|
|
|
5
9
|
A different take on using ActionMailer, Markdown and I18n.
|
|
6
10
|
|
|
@@ -22,7 +26,9 @@ Or install it yourself as:
|
|
|
22
26
|
|
|
23
27
|
## Usage
|
|
24
28
|
|
|
25
|
-
Imagine that you have a mail named `UserMailer#welcome`. Instead of manually
|
|
29
|
+
Imagine that you have a mail named `UserMailer#welcome`. Instead of manually
|
|
30
|
+
defining your subjects like the following, you can create the subject by
|
|
31
|
+
defining the `user_mailer.welcome.subject` translation.
|
|
26
32
|
|
|
27
33
|
```ruby
|
|
28
34
|
# app/mailers/user_mailer.rb
|
|
@@ -41,7 +47,9 @@ en:
|
|
|
41
47
|
subject: Welcome to my app
|
|
42
48
|
```
|
|
43
49
|
|
|
44
|
-
Since I really like defining everything I can in I18n files, I always extend
|
|
50
|
+
Since I really like defining everything I can in I18n files, I always extend
|
|
51
|
+
this behavior to the message's body, through the `user_mailer.welcome.body`
|
|
52
|
+
translation.
|
|
45
53
|
|
|
46
54
|
```yaml
|
|
47
55
|
# config/locales/en.yml
|
|
@@ -56,7 +64,8 @@ en:
|
|
|
56
64
|
Myapp team
|
|
57
65
|
```
|
|
58
66
|
|
|
59
|
-
Did you notice that `|`? That allows YAML strings to be multiline. And on your
|
|
67
|
+
Did you notice that `|`? That allows YAML strings to be multiline. And on your
|
|
68
|
+
e-mail class you can do something like this:
|
|
60
69
|
|
|
61
70
|
```ruby
|
|
62
71
|
# app/mailers/user_mailer.rb
|
|
@@ -67,7 +76,8 @@ class UserMailer < ApplicationMailer
|
|
|
67
76
|
end
|
|
68
77
|
```
|
|
69
78
|
|
|
70
|
-
And if you want to render HTML and text-plain from this string, you may have to
|
|
79
|
+
And if you want to render HTML and text-plain from this string, you may have to
|
|
80
|
+
do something like this (Markdown class not shown).
|
|
71
81
|
|
|
72
82
|
```ruby
|
|
73
83
|
# app/mailers/user_mailer.rb
|
|
@@ -83,7 +93,8 @@ class UserMailer < ApplicationMailer
|
|
|
83
93
|
end
|
|
84
94
|
```
|
|
85
95
|
|
|
86
|
-
This idea is really nice, but you have too much things to deal with. Not
|
|
96
|
+
This idea is really nice, but you have too much things to deal with. Not
|
|
97
|
+
anymore!
|
|
87
98
|
|
|
88
99
|
With ActionMailer::Markdown you can just define your mailer action like this:
|
|
89
100
|
|
|
@@ -96,17 +107,20 @@ class UserMailer < ApplicationMailer
|
|
|
96
107
|
end
|
|
97
108
|
```
|
|
98
109
|
|
|
99
|
-
That's right! This gem automatically uses `user_mailer.welcome.{subject,body}`
|
|
110
|
+
That's right! This gem automatically uses `user_mailer.welcome.{subject,body}`
|
|
111
|
+
from your translation files. And the best part: it evens supports Markdown.
|
|
100
112
|
|
|
101
113
|
### Passing variables
|
|
102
114
|
|
|
103
|
-
You're likely to pass in variables to your messages. To do this, just define
|
|
115
|
+
You're likely to pass in variables to your messages. To do this, just define
|
|
116
|
+
instance variables. Imagine you want to parse the user's name on your subject
|
|
117
|
+
and message. Let's suppose you have your translation file defined like this:
|
|
104
118
|
|
|
105
119
|
```yaml
|
|
106
120
|
en:
|
|
107
121
|
user_mailer:
|
|
108
122
|
welcome:
|
|
109
|
-
subject:
|
|
123
|
+
subject: "Welcome to Myapp, %{name}"
|
|
110
124
|
body: |
|
|
111
125
|
Hello, %{name}. And welcome to Myapp.
|
|
112
126
|
```
|
|
@@ -152,7 +166,8 @@ en:
|
|
|
152
166
|
Myapp team
|
|
153
167
|
```
|
|
154
168
|
|
|
155
|
-
You may be wondering what happens with the mail's text part. Don't worry!
|
|
169
|
+
You may be wondering what happens with the mail's text part. Don't worry!
|
|
170
|
+
ActionMailer::Markdown will take care of that. That message will be rendered as:
|
|
156
171
|
|
|
157
172
|
```text
|
|
158
173
|
Hello, John!
|
|
@@ -168,11 +183,16 @@ Myapp team
|
|
|
168
183
|
|
|
169
184
|
Lists and other elements are also exported to a more friendly text version.
|
|
170
185
|
|
|
171
|
-
**PROTIP:** Use [i18n-dot_lookup](https://github.com/fnando/i18n-dot_lookup) if
|
|
186
|
+
**PROTIP:** Use [i18n-dot_lookup](https://github.com/fnando/i18n-dot_lookup) if
|
|
187
|
+
you want to access properties from an object, like `%{user.name}`
|
|
172
188
|
|
|
173
189
|
### Replacing the Markdown engine
|
|
174
190
|
|
|
175
|
-
[redcarpet](https://github.com/vmg/redcarpet) is the default Markdown parser.
|
|
191
|
+
[redcarpet](https://github.com/vmg/redcarpet) is the default Markdown parser.
|
|
192
|
+
You may want to specify different options or even switch out to a different
|
|
193
|
+
Markdown library. All you have to do is defining a processor that responds to
|
|
194
|
+
`.call`. Let's say you want to use [kramdown](http://kramdown.gettalong.org/) as
|
|
195
|
+
your Markdown engine.
|
|
176
196
|
|
|
177
197
|
```ruby
|
|
178
198
|
ActionMailer::Markdown.processor = -> text { Kramdown::Document.new(text).to_html }
|
|
@@ -180,23 +200,36 @@ ActionMailer::Markdown.processor = -> text { Kramdown::Document.new(text).to_htm
|
|
|
180
200
|
|
|
181
201
|
### Falling back to ActionMailer's default behavior
|
|
182
202
|
|
|
183
|
-
You can use templates if you want. Just don't define the `.body` part of your
|
|
203
|
+
You can use templates if you want. Just don't define the `.body` part of your
|
|
204
|
+
translation. Also, if you pass a block to the `mail()` method, it will skip this
|
|
205
|
+
functionally completely.
|
|
184
206
|
|
|
185
207
|
### Using markdown files
|
|
186
208
|
|
|
187
|
-
If you want to use Markdown files instead of I18n translations, this gem is not
|
|
209
|
+
If you want to use Markdown files instead of I18n translations, this gem is not
|
|
210
|
+
for you. Consider using [maildown](https://github.com/schneems/maildown) or
|
|
211
|
+
[markerb](https://github.com/plataformatec/markerb).
|
|
188
212
|
|
|
189
213
|
## Development
|
|
190
214
|
|
|
191
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
215
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
216
|
+
`rake test` to run the tests. You can also run `bin/console` for an interactive
|
|
217
|
+
prompt that will allow you to experiment.
|
|
192
218
|
|
|
193
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
219
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
220
|
+
release a new version, update the version number in `version.rb`, and then run
|
|
221
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
|
222
|
+
git commits and tags, and push the `.gem` file to
|
|
223
|
+
[rubygems.org](https://rubygems.org).
|
|
194
224
|
|
|
195
225
|
## Contributing
|
|
196
226
|
|
|
197
|
-
Bug reports and pull requests are welcome on GitHub at
|
|
198
|
-
|
|
227
|
+
Bug reports and pull requests are welcome on GitHub at
|
|
228
|
+
https://github.com/fnando/actionmailer-markdown. This project is intended to be
|
|
229
|
+
a safe, welcoming space for collaboration, and contributors are expected to
|
|
230
|
+
adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
|
199
231
|
|
|
200
232
|
## License
|
|
201
233
|
|
|
202
|
-
The gem is available as open source under the terms of the
|
|
234
|
+
The gem is available as open source under the terms of the
|
|
235
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "bundler/gem_tasks"
|
|
5
|
+
require "rake/testtask"
|
|
6
|
+
require "rubocop/rake_task"
|
|
7
|
+
|
|
8
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
|
9
|
+
t.options << "--config"
|
|
10
|
+
t.options << File.expand_path(".rubocop.yml", __dir__)
|
|
11
|
+
end
|
|
3
12
|
|
|
4
13
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.libs <<
|
|
6
|
-
t.libs <<
|
|
7
|
-
t.test_files = FileList[
|
|
14
|
+
t.libs << "test"
|
|
15
|
+
t.libs << "lib"
|
|
16
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
|
17
|
+
t.warning = false
|
|
8
18
|
end
|
|
9
19
|
|
|
10
|
-
task :
|
|
20
|
+
task default: %i[test rubocop]
|
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "./lib/action_mailer/markdown/version"
|
|
2
4
|
|
|
3
5
|
Gem::Specification.new do |spec|
|
|
4
|
-
spec.name =
|
|
6
|
+
spec.name = "actionmailer-markdown"
|
|
5
7
|
spec.version = ActionMailer::Markdown::VERSION
|
|
6
|
-
spec.authors = [
|
|
7
|
-
spec.email = [
|
|
8
|
-
spec.summary =
|
|
8
|
+
spec.authors = ["Nando Vieira"]
|
|
9
|
+
spec.email = ["fnando.vieira@gmail.com"]
|
|
10
|
+
spec.summary = "A different take on using ActionMailer, Markdown and I18n."
|
|
9
11
|
spec.description = spec.summary
|
|
10
|
-
spec.homepage =
|
|
11
|
-
spec.license =
|
|
12
|
+
spec.homepage = "https://github.com/fnando/actionmailer-markdown"
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
|
12
15
|
|
|
13
|
-
spec.files = `git ls-files -z`.split("\x0").reject {
|
|
14
|
-
spec.executables = spec.files.grep(%r{^exe/}) {
|
|
15
|
-
spec.require_paths = [
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(test|spec|features)/}) }
|
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) {|f| File.basename(f) }
|
|
18
|
+
spec.require_paths = ["lib"]
|
|
16
19
|
|
|
17
|
-
spec.add_dependency
|
|
18
|
-
spec.add_dependency
|
|
20
|
+
spec.add_dependency "actionmailer"
|
|
21
|
+
spec.add_dependency "redcarpet"
|
|
19
22
|
|
|
20
|
-
spec.add_development_dependency
|
|
21
|
-
spec.add_development_dependency
|
|
22
|
-
spec.add_development_dependency
|
|
23
|
-
spec.add_development_dependency
|
|
24
|
-
spec.add_development_dependency
|
|
25
|
-
spec.add_development_dependency
|
|
26
|
-
spec.add_development_dependency
|
|
23
|
+
spec.add_development_dependency "bundler"
|
|
24
|
+
spec.add_development_dependency "kramdown"
|
|
25
|
+
spec.add_development_dependency "minitest"
|
|
26
|
+
spec.add_development_dependency "minitest-utils"
|
|
27
|
+
spec.add_development_dependency "pry-meta"
|
|
28
|
+
spec.add_development_dependency "rails"
|
|
29
|
+
spec.add_development_dependency "rake"
|
|
30
|
+
spec.add_development_dependency "rubocop"
|
|
31
|
+
spec.add_development_dependency "rubocop-fnando"
|
|
32
|
+
spec.add_development_dependency "simplecov"
|
|
33
|
+
spec.add_development_dependency "simplecov-console"
|
|
34
|
+
spec.metadata = {
|
|
35
|
+
"rubygems_mfa_required" => "true"
|
|
36
|
+
}
|
|
27
37
|
end
|
|
@@ -1,28 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
ActionMailer::Base.class_eval do
|
|
2
4
|
mail_method = instance_method(:mail)
|
|
3
5
|
|
|
4
6
|
define_method(:mail) do |headers = {}, &block|
|
|
5
7
|
options = variables_set_by_user
|
|
6
|
-
subject = get_translation_for(
|
|
8
|
+
subject = get_translation_for("subject", options)
|
|
7
9
|
headers[:subject] ||= subject
|
|
8
|
-
|
|
10
|
+
headers[:locals] = {a: 1}
|
|
11
|
+
mail_method.bind_call(self, headers, &block)
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
def get_translation_for(key, options)
|
|
12
|
-
I18n.t(key, options.merge(scope: [mailer_scope, action_name], raise: true))
|
|
15
|
+
I18n.t(key, **options.merge(scope: [mailer_scope, action_name], raise: true))
|
|
13
16
|
rescue I18n::MissingTranslationData
|
|
14
17
|
nil
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def variables_set_by_user
|
|
18
21
|
instance_variables.each_with_object({}) do |name, buffer|
|
|
19
|
-
next if
|
|
22
|
+
next if /^@_/.match?(name)
|
|
23
|
+
|
|
20
24
|
name = name.to_s[/^@(.*?)$/, 1]
|
|
21
25
|
buffer[name.to_sym] = instance_variable_get("@#{name}")
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
def mailer_scope
|
|
26
|
-
self.class.mailer_name.tr(
|
|
30
|
+
self.class.mailer_name.tr("/", ".")
|
|
27
31
|
end
|
|
28
32
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionMailer
|
|
2
4
|
module Markdown
|
|
3
5
|
class Renderer
|
|
@@ -10,7 +12,7 @@ module ActionMailer
|
|
|
10
12
|
|
|
11
13
|
def initialize(source)
|
|
12
14
|
@source = source
|
|
13
|
-
@root = Nokogiri::HTML(Markdown.html(source)).css(
|
|
15
|
+
@root = Nokogiri::HTML(Markdown.html(source)).css("body")
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def extract
|
|
@@ -25,32 +27,33 @@ module ActionMailer
|
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def process_code
|
|
28
|
-
root.css(
|
|
29
|
-
next if code.parent.name ==
|
|
30
|
+
root.css("code").each do |code|
|
|
31
|
+
next if code.parent.name == "pre"
|
|
32
|
+
|
|
30
33
|
code.content = "`#{code.content}`"
|
|
31
34
|
end
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def process_hr
|
|
35
|
-
root.css(
|
|
38
|
+
root.css("hr").each(&:remove)
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
def process_h1
|
|
39
|
-
root.css(
|
|
40
|
-
heading.content =
|
|
42
|
+
root.css("h1").each do |heading|
|
|
43
|
+
heading.content = build_heading(heading.text, "=")
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
def process_h2
|
|
45
|
-
root.css(
|
|
46
|
-
heading.content = "\n#{heading.text
|
|
48
|
+
root.css("h2").each do |heading|
|
|
49
|
+
heading.content = "\n#{build_heading(heading.text, '-')}"
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def process_lists
|
|
51
|
-
root.css(
|
|
52
|
-
list.css(
|
|
53
|
-
prefix = (list.name ==
|
|
54
|
+
root.css("ol, ul").each do |list|
|
|
55
|
+
list.css("li").to_enum(:each).with_index(1) do |item, index|
|
|
56
|
+
prefix = (list.name == "ol" ? "#{index}." : "-")
|
|
54
57
|
item.content = "#{prefix} #{item.text}"
|
|
55
58
|
end
|
|
56
59
|
end
|
|
@@ -59,12 +62,12 @@ module ActionMailer
|
|
|
59
62
|
def process_links
|
|
60
63
|
links = []
|
|
61
64
|
|
|
62
|
-
root.css(
|
|
63
|
-
href = link[
|
|
65
|
+
root.css("a").each do |link|
|
|
66
|
+
href = link["href"]
|
|
64
67
|
|
|
65
|
-
if href.starts_with?(
|
|
66
|
-
link.content = href.sub(
|
|
67
|
-
elsif link.content.match(%r
|
|
68
|
+
if href.starts_with?("mailto:")
|
|
69
|
+
link.content = href.sub("mailto:", "")
|
|
70
|
+
elsif link.content.match?(%r{^(?!\w+://)})
|
|
68
71
|
links << href unless links.include?(href)
|
|
69
72
|
index = links.index(href) + 1
|
|
70
73
|
link.content = "#{link.content}[#{index}]"
|
|
@@ -76,6 +79,10 @@ module ActionMailer
|
|
|
76
79
|
|
|
77
80
|
root << node
|
|
78
81
|
end
|
|
82
|
+
|
|
83
|
+
private def build_heading(text, separator)
|
|
84
|
+
"#{text}\n#{separator * text.size}"
|
|
85
|
+
end
|
|
79
86
|
end
|
|
80
87
|
end
|
|
81
88
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionMailer
|
|
2
4
|
module Markdown
|
|
3
5
|
class Renderer < Redcarpet::Render::HTML
|
|
@@ -11,7 +13,8 @@ module ActionMailer
|
|
|
11
13
|
|
|
12
14
|
renderer = Renderer.new(hard_wrap: true, safe_links_only: true)
|
|
13
15
|
|
|
14
|
-
markdown_engine = Redcarpet::Markdown.new(
|
|
16
|
+
markdown_engine = Redcarpet::Markdown.new(
|
|
17
|
+
renderer,
|
|
15
18
|
tables: true,
|
|
16
19
|
footnotes: true,
|
|
17
20
|
space_after_headers: true,
|
|
@@ -20,9 +23,9 @@ module ActionMailer
|
|
|
20
23
|
strikethrough: true,
|
|
21
24
|
autolink: true,
|
|
22
25
|
no_intra_emphasis: true
|
|
23
|
-
|
|
26
|
+
)
|
|
24
27
|
|
|
25
|
-
self.default_processor = ->
|
|
28
|
+
self.default_processor = ->(text) { markdown_engine.render(text) }
|
|
26
29
|
self.processor = default_processor
|
|
27
30
|
|
|
28
31
|
def self.html(text)
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionMailer
|
|
2
4
|
module Markdown
|
|
3
5
|
class Resolver < ActionView::Resolver
|
|
4
6
|
FORMAT_TO_EXTENSION = {
|
|
5
7
|
text: :mdt,
|
|
6
8
|
html: :md
|
|
7
|
-
}
|
|
9
|
+
}.freeze
|
|
8
10
|
|
|
9
|
-
def find_templates(
|
|
11
|
+
def find_templates(
|
|
12
|
+
name,
|
|
13
|
+
prefix,
|
|
14
|
+
_partial,
|
|
15
|
+
details,
|
|
16
|
+
_outside_app_allowed = false # rubocop:disable Style/OptionalBooleanParameter
|
|
17
|
+
)
|
|
10
18
|
contents = find_contents(name, prefix, details)
|
|
11
19
|
return [] unless contents
|
|
12
20
|
|
|
@@ -18,9 +26,13 @@ module ActionMailer
|
|
|
18
26
|
end
|
|
19
27
|
|
|
20
28
|
def build_template(path, contents, identifier, format)
|
|
21
|
-
ActionView::Template.new(
|
|
29
|
+
ActionView::Template.new(
|
|
30
|
+
contents,
|
|
31
|
+
identifier,
|
|
32
|
+
handler_for(format),
|
|
22
33
|
virtual_path: path,
|
|
23
|
-
format: format
|
|
34
|
+
format: format,
|
|
35
|
+
locals: []
|
|
24
36
|
)
|
|
25
37
|
end
|
|
26
38
|
|
|
@@ -33,12 +45,16 @@ module ActionMailer
|
|
|
33
45
|
"#{prefix}/#{name}"
|
|
34
46
|
end
|
|
35
47
|
|
|
36
|
-
def
|
|
37
|
-
|
|
48
|
+
def translations
|
|
49
|
+
I18n.backend.initialize unless I18n.backend.initialized?
|
|
50
|
+
I18n.backend.send(:translations)
|
|
51
|
+
end
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
def find_contents(name, prefix, details)
|
|
54
|
+
[details[:locale].try(:first) || I18n.locale, prefix, name, :body]
|
|
55
|
+
.reduce(translations) do |buffer, key|
|
|
56
|
+
buffer && buffer[key.to_sym]
|
|
57
|
+
end
|
|
42
58
|
end
|
|
43
59
|
end
|
|
44
60
|
end
|
|
@@ -1,31 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionMailer
|
|
2
4
|
module Markdown
|
|
3
5
|
module TemplateHandler
|
|
4
|
-
UNDERSCORE =
|
|
6
|
+
UNDERSCORE = "_"
|
|
7
|
+
OBJECT_ATTRIBUTE_MATCHER = /%\{([a-z0-9_]+\.[a-z0-9_]+)\}/i.freeze
|
|
5
8
|
|
|
6
9
|
def self.render(template, context, format)
|
|
7
|
-
|
|
10
|
+
variables = expand_variables(template, extract_variables(context))
|
|
11
|
+
source = template.rstrip % variables
|
|
8
12
|
ActionMailer::Markdown.public_send(format, source)
|
|
9
13
|
end
|
|
10
14
|
|
|
15
|
+
def self.expand_variables(template, variables)
|
|
16
|
+
template
|
|
17
|
+
.scan(OBJECT_ATTRIBUTE_MATCHER)
|
|
18
|
+
.map(&:first)
|
|
19
|
+
.each_with_object(variables) do |match, buffer|
|
|
20
|
+
target, attribute = match.split(".")
|
|
21
|
+
buffer[match.to_sym] = variables[target.to_sym].public_send(attribute)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
11
25
|
def self.extract_variables(context)
|
|
12
26
|
context
|
|
13
27
|
.instance_variable_get(:@_assigns)
|
|
14
28
|
.each_with_object({}) do |(name, value), buffer|
|
|
15
29
|
next if name.start_with?(UNDERSCORE)
|
|
30
|
+
|
|
16
31
|
buffer[name.to_sym] = value
|
|
17
32
|
end
|
|
18
33
|
end
|
|
19
34
|
|
|
20
35
|
class Text
|
|
21
|
-
def self.call(template)
|
|
22
|
-
%[
|
|
36
|
+
def self.call(template, _source = nil)
|
|
37
|
+
%[
|
|
38
|
+
ActionMailer::Markdown::TemplateHandler
|
|
39
|
+
.render(#{template.source.inspect}, self, :text)
|
|
40
|
+
]
|
|
23
41
|
end
|
|
24
42
|
end
|
|
25
43
|
|
|
26
44
|
class HTML
|
|
27
|
-
def self.call(template)
|
|
28
|
-
%[
|
|
45
|
+
def self.call(template, _source = nil)
|
|
46
|
+
%[
|
|
47
|
+
ActionMailer::Markdown::TemplateHandler
|
|
48
|
+
.render(#{template.source.inspect}, self, :html)
|
|
49
|
+
]
|
|
29
50
|
end
|
|
30
51
|
end
|
|
31
52
|
end
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionMailer
|
|
2
4
|
module Markdown
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
5
|
+
require "action_mailer"
|
|
6
|
+
require "action_view"
|
|
7
|
+
require "redcarpet"
|
|
6
8
|
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
require
|
|
9
|
+
require "action_mailer/markdown/version"
|
|
10
|
+
require "action_mailer/markdown/resolver"
|
|
11
|
+
require "action_mailer/markdown/ext"
|
|
12
|
+
require "action_mailer/markdown/renderer"
|
|
13
|
+
require "action_mailer/markdown/renderer/text"
|
|
14
|
+
require "action_mailer/markdown/template_handler"
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: actionmailer-markdown
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nando Vieira
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-12-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionmailer
|
|
@@ -42,30 +42,72 @@ dependencies:
|
|
|
42
42
|
name: bundler
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- - "
|
|
45
|
+
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- - "
|
|
52
|
+
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
56
|
+
name: kramdown
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: minitest
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
58
72
|
requirements:
|
|
59
|
-
- - "
|
|
73
|
+
- - ">="
|
|
60
74
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
75
|
+
version: '0'
|
|
62
76
|
type: :development
|
|
63
77
|
prerelease: false
|
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
79
|
requirements:
|
|
66
|
-
- - "
|
|
80
|
+
- - ">="
|
|
67
81
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: minitest-utils
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: pry-meta
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
69
111
|
- !ruby/object:Gem::Dependency
|
|
70
112
|
name: rails
|
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -81,7 +123,7 @@ dependencies:
|
|
|
81
123
|
- !ruby/object:Gem::Version
|
|
82
124
|
version: '0'
|
|
83
125
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
126
|
+
name: rake
|
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
|
86
128
|
requirements:
|
|
87
129
|
- - ">="
|
|
@@ -95,7 +137,7 @@ dependencies:
|
|
|
95
137
|
- !ruby/object:Gem::Version
|
|
96
138
|
version: '0'
|
|
97
139
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
140
|
+
name: rubocop
|
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
|
100
142
|
requirements:
|
|
101
143
|
- - ">="
|
|
@@ -109,7 +151,7 @@ dependencies:
|
|
|
109
151
|
- !ruby/object:Gem::Version
|
|
110
152
|
version: '0'
|
|
111
153
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
154
|
+
name: rubocop-fnando
|
|
113
155
|
requirement: !ruby/object:Gem::Requirement
|
|
114
156
|
requirements:
|
|
115
157
|
- - ">="
|
|
@@ -123,7 +165,21 @@ dependencies:
|
|
|
123
165
|
- !ruby/object:Gem::Version
|
|
124
166
|
version: '0'
|
|
125
167
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
168
|
+
name: simplecov
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '0'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: simplecov-console
|
|
127
183
|
requirement: !ruby/object:Gem::Requirement
|
|
128
184
|
requirements:
|
|
129
185
|
- - ">="
|
|
@@ -143,8 +199,9 @@ executables: []
|
|
|
143
199
|
extensions: []
|
|
144
200
|
extra_rdoc_files: []
|
|
145
201
|
files:
|
|
202
|
+
- ".github/FUNDING.yml"
|
|
146
203
|
- ".gitignore"
|
|
147
|
-
- ".
|
|
204
|
+
- ".rubocop.yml"
|
|
148
205
|
- CODE_OF_CONDUCT.md
|
|
149
206
|
- Gemfile
|
|
150
207
|
- LICENSE.txt
|
|
@@ -164,8 +221,9 @@ files:
|
|
|
164
221
|
homepage: https://github.com/fnando/actionmailer-markdown
|
|
165
222
|
licenses:
|
|
166
223
|
- MIT
|
|
167
|
-
metadata:
|
|
168
|
-
|
|
224
|
+
metadata:
|
|
225
|
+
rubygems_mfa_required: 'true'
|
|
226
|
+
post_install_message:
|
|
169
227
|
rdoc_options: []
|
|
170
228
|
require_paths:
|
|
171
229
|
- lib
|
|
@@ -173,16 +231,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
173
231
|
requirements:
|
|
174
232
|
- - ">="
|
|
175
233
|
- !ruby/object:Gem::Version
|
|
176
|
-
version:
|
|
234
|
+
version: 2.7.0
|
|
177
235
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
236
|
requirements:
|
|
179
237
|
- - ">="
|
|
180
238
|
- !ruby/object:Gem::Version
|
|
181
239
|
version: '0'
|
|
182
240
|
requirements: []
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
signing_key:
|
|
241
|
+
rubygems_version: 3.2.32
|
|
242
|
+
signing_key:
|
|
186
243
|
specification_version: 4
|
|
187
244
|
summary: A different take on using ActionMailer, Markdown and I18n.
|
|
188
245
|
test_files: []
|