mjml-rails 4.3.0 → 4.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a65c2ff3a407479d78f77b8d513813d0f854686c2f9714166352eedde66e79f
4
- data.tar.gz: d8ae58fc1113e28391e18ba08c1f18c0de211ef86c205a3060bdec242a80717f
3
+ metadata.gz: a8610d3313ee8297b7ac411aa8f23b8c99a85cf41940db1798529d91193fb37d
4
+ data.tar.gz: c5099915099d3aeb6e050bf44b3cb81b8fe759686a06b85d61a197e65b7b4dfb
5
5
  SHA512:
6
- metadata.gz: 9193f72b9fd381b1cc6f6e92d035ca71c0f0efac8109e0e0ccb53ebb00f1ed7fcec081b867c1eaf8276ddad14740b6ce599dc43a529b4d53ac7e61cf4c3d0a4f
7
- data.tar.gz: 061b6315985c9e2e23fd1833a9ab2bf960842e01d4baaf24e1b502f7ad4411a6a5481ab71ef5aebc1fe73d535d022dd8d1c50f6939e47d06139b32837c34da99
6
+ metadata.gz: 717f6819381d9f925ce597f05288cfc6f3c07417e353de40561de9ddffc6ac48331e4877ed775818b7b3dbd3836c27e2347bafcbcc9c0247b467565e944911ab
7
+ data.tar.gz: ec6662022e6ed5f5e8b6732d61fa766de5af32dd57fcd43c508576bcb7f594b1f413b17452532fa4e7ee94b46d1c90427bb90e3cff1425ae39c05d46c38f371e
Binary file
data.tar.gz.sig CHANGED
@@ -1,3 +1,5 @@
1
- 1��p��$91s=XsT>�Dۙ�j�Sl
2
- u� ����}�:"h�:ƴ��r$��IĤN�f,��c|ԓ\�� ZG�����?`��x�I�)�B)����p$rb.>j��F�����t<�H���jk0��P�ڂ' �ikYB݂�[cuÐf�\7��>�Pl�V?ga37�?��>��F�nE�,]�J+z{�2T�{��d)��={�\a���|]Ѵ�jp�w��$��/P/ �*��X2��y7��_}��Tv.���5&�KQO��P�/�����iJ�mz]fJ��E��Oҋ0m���1�F�M��(QƐWu$/D�ȭ�B�tIz�
3
- c����m_��8u�B*�m ����]
1
+ &=V��߀��\�c�~ʻ�!_mAzߪϣRQ��!�bN�{8{Q�%����(���|�授2v
2
+ ���Z P������*��an��� Nj��LU
3
+ ���Y��QN\m5fm0��iw�����Ⱦ����a��NjgG-=�QK=�.�W -r��`���aX��7>�zwK~P.=i*��@A�E_���yoõ�
4
+ \�$W�P� ��O�q����G�hމ�p�E��pn��v f�m.�/|��
5
+ ��)|���f*��>�`k��"~v�u��e �x�]EFC��B({*�w��Q,rE�*Kg�w3�Ft�p���'���?���'f��<�!�PZՃO"
data/README.md CHANGED
@@ -34,7 +34,7 @@ And the partial:
34
34
 
35
35
  * Notice you can use ERB and partials inside the template.
36
36
 
37
- Your `user_mailer.rb` might look like this::
37
+ Your `user_mailer.rb` might look like this:
38
38
 
39
39
  ```ruby
40
40
  # ./app/mailers/user_mailer.rb
@@ -48,6 +48,10 @@ class UserMailer < ActionMailer::Base
48
48
  end
49
49
  ```
50
50
 
51
+ ## Example application
52
+
53
+ * [MJML with Rails 6](https://github.com/dyanagi/example_mjml_rails): Renders HTML emails with MJML layout, view, and partial.
54
+
51
55
  ## Installation
52
56
 
53
57
  Add it to your Gemfile.
@@ -62,13 +66,19 @@ Run the following command to install it:
62
66
  bundle install
63
67
  ```
64
68
 
65
- Install the MJML parser (optional -g to install it globally):
69
+ Add the MJML parser to your project with your favourite package manager:
66
70
 
67
71
  ```console
68
- npm install -g mjml
72
+ # with npm
73
+ npm install mjml
74
+
75
+ # with yarn
76
+ yarn add mjml
69
77
  ```
70
78
 
71
- Note that you'll need at least Node.js version 6 for MJML to function properly.
79
+ MJML-Rails falls back to a global installation of MJML but it is strongly recommended to add MJML directly to your project.
80
+
81
+ You'll need at least Node.js version 6 for MJML to function properly.
72
82
 
73
83
  If you're using ```:haml``` or any other Rails template language, create an initializer to set it up:
74
84
 
@@ -85,8 +95,10 @@ If there are configurations you'd like change:
85
95
  - render errors: defaults to `true` (errors raised)
86
96
  - minify: defaults to `false` (not minified)
87
97
  - beautify: defaults to `true` (beautified)
98
+ - validation_level: defaults to `soft` (MJML syntax validation)
88
99
 
89
100
  ```ruby
101
+ # config/initializers/mjml.rb
90
102
  Mjml.setup do |config|
91
103
  # set to `false` to ignore errors silently
92
104
  config.raise_render_exception = true
@@ -94,14 +106,16 @@ Mjml.setup do |config|
94
106
  # optimize the size of your email
95
107
  config.beautify = false
96
108
  config.minify = true
109
+ config.validation_level = "strict"
97
110
  end
98
111
  ```
99
112
 
100
113
  If you’d like to specify a different MJML binary to run other than `4.`:
101
114
 
102
115
  ```ruby
116
+ # config/initializers/mjml.rb
103
117
  Mjml.setup do |config|
104
- config.mjml_binary_version_supported = 3.3.5
118
+ config.mjml_binary_version_supported = "3.3.5"
105
119
  end
106
120
  # If you set a different MJML binary version, you need to re-discover the binary
107
121
  Mjml::BIN = Mjml.discover_mjml_bin
@@ -151,12 +165,14 @@ class MyMailer < ActionMailer::Base
151
165
  @recipient = user
152
166
 
153
167
  mail(to: user.email, from: "app@example.com") do |format|
154
- format.html
168
+ format.html # This will look for "default.html.erb" and then "default.html.mjml"
155
169
  end
156
170
  end
157
171
  end
158
172
  ```
159
173
 
174
+ Note: If `default.html.erb` exists, email will be rendered as ERB, and MJML tags will not be compiled.
175
+
160
176
  Email layout:
161
177
  ```html
162
178
  <!-- views/layouts/default.html.mjml -->
@@ -169,7 +185,7 @@ Email layout:
169
185
 
170
186
  Email view:
171
187
  ```html
172
- <!-- views/my_mailer/foo_bar.html.erb -->
188
+ <!-- views/my_mailer/foo_bar.html.mjml (or foo_bar.html.erb) -->
173
189
  <%= render partial: "to" %>
174
190
 
175
191
  <mj-section>
@@ -183,7 +199,7 @@ Email view:
183
199
 
184
200
  Email partial:
185
201
  ```html
186
- <!-- views/my_mailer/_to.html.erb -->
202
+ <!-- views/my_mailer/_to.html.mjml (or _to.html.erb) -->
187
203
  <mj-section>
188
204
  <mj-column>
189
205
  <mj-text>
@@ -251,7 +267,7 @@ Next you'll need to setup a `package.json` file in the root, something like this
251
267
  "test": "test"
252
268
  },
253
269
  "dependencies": {
254
- "mjml": "^4.0.0",
270
+ "mjml": "^4.0.0"
255
271
  },
256
272
  "repository": {
257
273
  "type": "git",
@@ -4,9 +4,10 @@ require "action_view/template"
4
4
  require "mjml/mjmltemplate"
5
5
  require "mjml/railtie"
6
6
  require "rubygems"
7
+ require "open3"
7
8
 
8
9
  module Mjml
9
- mattr_accessor :template_language, :raise_render_exception, :mjml_binary_version_supported, :mjml_binary_error_string, :beautify, :minify
10
+ mattr_accessor :template_language, :raise_render_exception, :mjml_binary_version_supported, :mjml_binary_error_string, :beautify, :minify, :validation_level
10
11
 
11
12
  @@template_language = :erb
12
13
  @@raise_render_exception = true
@@ -14,27 +15,54 @@ module Mjml
14
15
  @@mjml_binary_error_string = "Couldn't find the MJML #{Mjml.mjml_binary_version_supported} binary.. have you run $ npm install mjml?"
15
16
  @@beautify = true
16
17
  @@minify = false
18
+ @@validation_level = "soft"
17
19
 
18
20
  def self.check_version(bin)
19
- IO.popen([bin, '--version']) { |io| io.read.include?("mjml-core: #{Mjml.mjml_binary_version_supported}") }
20
- rescue
21
+ stdout, _, status = run_mjml('--version', mjml_bin: bin)
22
+ status.success? && stdout.include?("mjml-core: #{Mjml.mjml_binary_version_supported}")
23
+ rescue StandardError
21
24
  false
22
25
  end
23
26
 
27
+ def self.run_mjml(args, mjml_bin: nil)
28
+ mjml_bin ||= BIN
29
+
30
+ Open3.capture3("#{mjml_bin} #{args}")
31
+ end
32
+
24
33
  def self.discover_mjml_bin
25
- # Check for a global install of MJML binary
26
- mjml_bin = 'mjml'
27
- return mjml_bin if check_version(mjml_bin)
34
+ # Check for local install of MJML with yarn
35
+ yarn_bin = `which yarn`.chomp
36
+ if yarn_bin.present?
37
+ mjml_bin = "#{yarn_bin} run mjml"
38
+ return mjml_bin if check_version(mjml_bin)
39
+ end
40
+
41
+ # Check for a local install of MJML with npm
42
+ npm_bin = `which npm`.chomp
43
+ if npm_bin.present? && (installer_path = bin_path_from(npm_bin)).present?
44
+ mjml_bin = File.join(installer_path, 'mjml')
45
+ return mjml_bin if check_version(mjml_bin)
46
+ end
28
47
 
29
- # Check for a local install of MJML binary
30
- installer_path = (`npm bin` || `yarn bin`).chomp
31
- mjml_bin = File.join(installer_path, 'mjml')
32
- return mjml_bin if check_version(mjml_bin)
48
+ # Check for a global install of MJML
49
+ mjml_bin = `which mjml`.chomp
50
+ return mjml_bin if mjml_bin.present? && check_version(mjml_bin)
33
51
 
34
52
  puts Mjml.mjml_binary_error_string
35
53
  nil
36
54
  end
37
55
 
56
+ def self.bin_path_from(package_manager)
57
+ stdout, _, status = Open3.capture3("#{package_manager} bin")
58
+
59
+ return unless status.success?
60
+
61
+ stdout.chomp
62
+ rescue Errno::ENOENT # package manager is not installed
63
+ nil
64
+ end
65
+
38
66
  BIN = discover_mjml_bin
39
67
 
40
68
  class Handler
@@ -22,7 +22,7 @@ module Mjml
22
22
  file.write(input)
23
23
  file # return tempfile from block so #unlink works later
24
24
  end
25
- run(in_tmp_file.path, Mjml.beautify, Mjml.minify)
25
+ run(in_tmp_file.path, Mjml.beautify, Mjml.minify, Mjml.validation_level)
26
26
  rescue
27
27
  raise if Mjml.raise_render_exception
28
28
  ""
@@ -33,11 +33,11 @@ module Mjml
33
33
  # Exec mjml command
34
34
  #
35
35
  # @return [String] The result as string
36
- def run(in_tmp_file, beautify=true, minify=false)
36
+ def run(in_tmp_file, beautify=true, minify=false, validation_level="soft")
37
37
  Tempfile.create(["out", ".html"]) do |out_tmp_file|
38
- command = "#{mjml_bin} -r #{in_tmp_file} -o #{out_tmp_file.path} --config.beautify #{beautify} --config.minify #{minify}"
39
- _, _, stderr, _ = Open3.popen3(command)
40
- raise ParseError.new(stderr.read.chomp) unless stderr.eof?
38
+ command = "-r #{in_tmp_file} -o #{out_tmp_file.path} --config.beautify #{beautify} --config.minify #{minify} --config.validationLevel #{validation_level}"
39
+ _, stderr, _ = Mjml.run_mjml(command)
40
+ raise ParseError.new(stderr.chomp) unless stderr.blank?
41
41
  out_tmp_file.read
42
42
  end
43
43
  end
@@ -1,4 +1,4 @@
1
1
  module Mjml
2
2
  # Version number no longer matches MJML.io version
3
- VERSION = "4.3.0"
3
+ VERSION = "4.4.2"
4
4
  end
@@ -21,7 +21,8 @@ describe Mjml::Parser do
21
21
  end
22
22
 
23
23
  it 'raises exception' do
24
- -> { parser.render }.must_raise(custom_error_class, error.message)
24
+ err = expect { parser.render }.must_raise(custom_error_class)
25
+ expect(err.message).must_equal error.message
25
26
  end
26
27
  end
27
28
 
@@ -33,38 +34,43 @@ describe Mjml::Parser do
33
34
  end
34
35
 
35
36
  it 'returns empty string' do
36
- parser.render.must_equal ''
37
+ expect(parser.render).must_equal ''
37
38
  end
38
39
  end
39
40
  end
40
41
 
41
- describe 'can read beautify and minify configs' do
42
+ describe 'can read beautify, minify, and validation_level configs' do
42
43
  it 'use defaults if no config is set' do
43
- expect(Mjml.beautify).equal?(true);
44
- expect(Mjml.minify).equal?(false);
44
+ expect(Mjml.beautify).must_equal(true)
45
+ expect(Mjml.minify).must_equal(false)
46
+ expect(Mjml.validation_level).must_equal('soft')
45
47
  end
46
48
 
47
49
  it 'use setup config' do
48
50
  Mjml.setup do |config|
49
51
  config.beautify = false
50
52
  config.minify = true
53
+ config.validation_level = 'strict'
51
54
  end
52
55
 
53
- expect(Mjml.beautify).equal?(false);
54
- expect(Mjml.minify).equal?(true);
56
+ expect(Mjml.beautify).must_equal(false)
57
+ expect(Mjml.minify).must_equal(true)
58
+ expect(Mjml.validation_level).must_equal('strict')
59
+
60
+ Mjml.setup do |config|
61
+ config.beautify = true
62
+ config.minify = false
63
+ config.validation_level = 'soft'
64
+ end
55
65
  end
56
66
  end
57
67
  end
58
68
 
59
69
  describe '#run' do
60
- describe 'when shell command is failed' do
61
- let(:error) { 'shell error' }
62
- let(:stderr) { mock('stderr', eof?: false, read: error) }
63
-
64
- before { Open3.stubs(popen3: [nil, nil, stderr, nil]) }
65
-
70
+ describe 'when shell command failed' do
66
71
  it 'raises exception' do
67
- -> { parser.run "/tmp/input_file.mjml" }.must_raise(Mjml::Parser::ParseError, error)
72
+ err = expect { parser.run "/tmp/non_existent_file.mjml" }.must_raise(Mjml::Parser::ParseError)
73
+ expect(err.message).must_include 'Command line error'
68
74
  end
69
75
  end
70
76
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mjml-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Loffler
8
8
  - Steven Pickles
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - |
13
13
  -----BEGIN CERTIFICATE-----
14
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- wi2BnJUjakKmqlXl/NZjnFMKf5jjd5IbkguxNT6Yaaxx18aVmIpnoLWC4Ufgfnno
25
- n+TTW9lt+2XVf6BKw5A5HoKPy1YXkV5+ttaYRQIDAQABo3kwdzAJBgNVHRMEAjAA
26
- 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
- VR0RBBcwFYETc2lnaG1vbkBzaWdobW9uLmNvbTAeBgNVHRIEFzAVgRNzaWdobW9u
28
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 2QfUTBQZBmdkzXtFEAAJQVPa0X6iKxer4Na0dbjQciqf+5FrNBrct94To8eEEgqJ
36
- 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
36
+ DcQ7RSt1TU5eck6c
37
37
  -----END CERTIFICATE-----
38
- date: 2019-04-07 00:00:00.000000000 Z
38
+ date: 2020-11-27 00:00:00.000000000 Z
39
39
  dependencies: []
40
40
  description: Render MJML + ERb template views in Rails
41
41
  email: sighmon@sighmon.com
@@ -78,9 +78,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  requirements: []
81
- rubyforge_project:
82
- rubygems_version: 2.7.9
83
- signing_key:
81
+ rubygems_version: 3.1.4
82
+ signing_key:
84
83
  specification_version: 4
85
84
  summary: MJML + ERb templates
86
85
  test_files:
metadata.gz.sig CHANGED
Binary file