supermail 0.2.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5007ee69916bd3c91239105a78c65ac3fc6729adb206e914881166480cca8d63
4
- data.tar.gz: 903ba6a76b34ec3f64d8dc0f4bab2d8782a3ea90c727dbec5647d8e8b99a3376
3
+ metadata.gz: ab203ffd27a2af74aa3f64e1d0f82fda4263ee4c818072cabd6e9daa5e8afe73
4
+ data.tar.gz: 2ea834cd01184581f56de63a9e03a708e51c036e37536588bc3143014fe57277
5
5
  SHA512:
6
- metadata.gz: d696046239e5c7bbb875b291ca99fc2533127f72babac2991ace61520522dc095788506857c1b8cc56c91f74e5c5f24de9db88a3046421ea10e9a677ac6fb4c1
7
- data.tar.gz: c2e1303de634498310018e9edbecbb1f0718b545698f56b378d172b4a1fc11389d572ab35019a6bf419faf345b8554b27f95181f4c2ec4e4b0ddca4c81da6c78
6
+ metadata.gz: 71dd7876ad4759ab40022e6950366f9aad994cfe0e9cbd5f3baeba709de6b40ba4d804b8d864710a7138c9203273caaa61d67955cdaada57a2eb5f0496080a9d
7
+ data.tar.gz: 4d879602a5ba9fc46ea510428d9ab798f8fb9a0c0c4110b4c002d054737cf0816406cdac30f9edda02bc8640e93b84bc028df931f28516804c23597d2b623f12
data/README.md CHANGED
@@ -5,16 +5,16 @@ Organize emails with plain 'ol Ruby objects in a Rails application, like this:
5
5
  ```ruby
6
6
  # ./app/email/user/welcome.rb
7
7
  class User::WelcomeEmail < ApplicationEmail
8
- def initialize(person:)
9
- @person = person
8
+ def initialize(user:)
9
+ @user = user
10
10
  end
11
11
 
12
- def to = @person.email
12
+ def to = @user.email
13
13
  def subject = "Welcome to Beautiful Ruby"
14
14
  def body
15
15
  super do
16
16
  <<~_
17
- Hi #{@person.name},
17
+ Hi #{@user.name},
18
18
 
19
19
  You're going to learn a ton at https://beautifulruby.com.
20
20
  _
@@ -25,6 +25,13 @@ end
25
25
 
26
26
  Contrast that with rails ActionMailer, where you will spend 20 minutes trying to figure out how to send an email. I created this gem because I got tired of digging through Rails docs to understand how to intialize an email and send it. PORO's FTW!
27
27
 
28
+ ## Support this project
29
+
30
+ Learn how to build UI's out of Ruby classes and support this project by ordering the [Phlex on Rails video course](https://beautifulruby.com/phlex).
31
+
32
+ [![](https://immutable.terminalwire.com/hmM9jvv7yF89frBUfjikUfRmdUsTVZ8YvXc7OnnYoERXfLJLzDcj5dFM7qdfMG2bqQLuw633Zt1gl3O7z0zKmH6k8QmifN7z0kJo.png)](https://beautifulruby.com/phlex/forms/introduction)
33
+
34
+
28
35
  ## Installation
29
36
 
30
37
  Install the gem and add to the application's Gemfile by executing:
@@ -76,21 +83,21 @@ class User::WelcomeEmail < ApplicationEmail
76
83
  PLAIN
77
84
  end
78
85
  ```
79
-
86
+ You can customize the email by overriding the `to`, `from`, `subject`, and `body` methods.s
80
87
 
81
88
  ```ruby
82
89
  # ./app/email/user/welcome.rb
83
90
  class User::WelcomeEmail < ApplicationEmail
84
- def initialize(person:)
85
- @person = person
91
+ def initialize(user:)
92
+ @user = user
86
93
  end
87
94
 
88
- def to = @person.email
95
+ def to = @user.email
89
96
  def subject = "Welcome to the website"
90
97
  def body
91
98
  super do
92
99
  <<~_
93
- Hi #{@person.name},
100
+ Hi #{@user.name},
94
101
 
95
102
  Welcome to the website We're excited to have you on board.
96
103
  _
@@ -99,6 +106,8 @@ class User::WelcomeEmail < ApplicationEmail
99
106
  end
100
107
  ```
101
108
 
109
+ ### Send emails from the server
110
+
102
111
  Then, to send the email.
103
112
 
104
113
  ```ruby
@@ -113,6 +122,41 @@ User::Welcome.new(user: User.first).message.tap do
113
122
  end.deliver_now
114
123
  ```
115
124
 
125
+ ### Launch the user's email client
126
+
127
+ Supermail clases can be used to generate `mailto:` links with Rails helpers.
128
+
129
+ ```erb
130
+ <%= link_to Support::OrderEmail.new(
131
+ user: current_user,
132
+ order: @order
133
+ ).mail_to s%>
134
+ ```
135
+
136
+ This opens your users email client with prefilled information. A support email about an order might look like this:
137
+
138
+ ```ruby
139
+ class Support::OrderEmail < ApplicationEmail
140
+ def initialize(user:, order:)
141
+ @user = user
142
+ @order = order
143
+ end
144
+
145
+ def to = "support@example.com"
146
+ def from = @user.email
147
+ def subject = "Question about order #{@order.id}"
148
+ def body = <<~BODY
149
+ Hi Support,
150
+
151
+ I need help with my order #{@order.id}.
152
+
153
+ Thanks,
154
+
155
+ #{@user.name}
156
+ BODY
157
+ end
158
+ ```
159
+
116
160
  ## Development
117
161
 
118
162
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -3,23 +3,28 @@
3
3
  require 'rails/generators/named_base'
4
4
 
5
5
  module Supermail
6
- class EmailGenerator < Rails::Generators::NamedBase
6
+ class EmailGenerator < ::Rails::Generators::NamedBase
7
7
  source_root File.expand_path('templates', __dir__)
8
8
 
9
9
  desc "Generate a new email class"
10
10
 
11
11
  def create_email_file
12
- template 'email.rb', "app/emails/#{file_path}_email.rb"
12
+ template 'email.rb', "app/emails/#{file_path}.rb"
13
13
  end
14
14
 
15
15
  private
16
16
 
17
17
  def file_path
18
- name.underscore
18
+ "#{base_name.underscore}_email"
19
19
  end
20
20
 
21
21
  def class_name
22
- name.camelize
22
+ "#{base_name.camelize}Email"
23
+ end
24
+
25
+ def base_name
26
+ stripped = name.to_s.sub(/_?email\z/i, '')
27
+ stripped.empty? ? name : stripped
23
28
  end
24
29
  end
25
- end
30
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class <%= class_name %>Email < ApplicationEmail
3
+ class <%= class_name %> < ApplicationEmail
4
4
  def body = <<~PLAIN
5
5
 
6
6
  PLAIN
@@ -3,7 +3,7 @@
3
3
  require 'rails/generators/base'
4
4
 
5
5
  module Supermail
6
- class InstallGenerator < Rails::Generators::Base
6
+ class InstallGenerator < ::Rails::Generators::Base
7
7
  source_root File.expand_path('templates', __dir__)
8
8
 
9
9
  desc "Install Supermail in a Rails application"
@@ -16,4 +16,4 @@ module Supermail
16
16
  empty_directory 'app/emails'
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -1,4 +1,4 @@
1
- class ApplicationEmail < Supermail::Base
1
+ class ApplicationEmail < Supermail::Rails::Base
2
2
  def from = "website@example.com"
3
3
 
4
4
  def body
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Supermail
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
data/lib/supermail.rb CHANGED
@@ -1,30 +1,77 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "supermail/version"
4
- require 'action_mailer'
4
+ require "action_mailer"
5
+ require "erb"
5
6
 
6
7
  module Supermail
7
8
  class Error < StandardError; end
8
9
 
9
- class Base
10
- delegate :deliver, :deliver_now, :deliver_later, to: :message_delivery
10
+ module Rails
11
+ # This is a bizzare work around for a commit that broke https://github.com/rails/rails/commit/c594ba4ffdb016c7b2a22055f41dfb2c4409594d
12
+ # further proving the bewildering maze of indirection in Rails ActionMailer.
13
+ class Mailer < ActionMailer::Base
14
+ def mail(...)
15
+ super(...)
16
+ end
11
17
 
12
- def to = nil
13
- def from = nil
14
- def subject = nil
15
- def body = ""
16
-
17
- def message
18
- message_delivery.message
18
+ def self.message_delivery(**)
19
+ ActionMailer::MessageDelivery.new self, :mail, **
20
+ end
19
21
  end
20
22
 
21
- def message_delivery
22
- ActionMailer::Base.mail(to:, from:, subject:, body:)
23
+ class Base
24
+ delegate \
25
+ :deliver,
26
+ :deliver_now,
27
+ :deliver_later,
28
+ :message,
29
+ to: :message_delivery
30
+
31
+ def to = nil
32
+ def from = nil
33
+ def subject = nil
34
+ def cc = []
35
+ def bcc = []
36
+ def body = ""
37
+
38
+ # Generate a mailto: URL with appropriate escaping.
39
+ def mailto = MailTo.href(to:, from:, cc:, bcc:, subject:, body:)
40
+ alias :mail_to :mailto
41
+
42
+ private def message_delivery
43
+ Rails::Mailer.message_delivery(
44
+ to:,
45
+ from:,
46
+ cc:,
47
+ bcc:,
48
+ subject:,
49
+ body:
50
+ )
51
+ end
23
52
  end
24
53
  end
25
- end
26
54
 
27
- # Load generators only when Rails is available
28
- if defined?(::Rails)
29
- require 'rails'
55
+ module MailTo
56
+ extend self
57
+
58
+ def href(to:, **params)
59
+ q = query(**params)
60
+ q.empty? ? "mailto:#{to}" : "mailto:#{to}?#{q}"
61
+ end
62
+
63
+ def query(**params)
64
+ params
65
+ .compact # drop nils
66
+ .reject { |k, v| v.is_a?(Array) && v.empty? } # drop empty arrays
67
+ .map { |k, v| "#{k}=#{mailto_escape(v)}" }
68
+ .join("&")
69
+ end
70
+
71
+ private
72
+
73
+ def mailto_escape(str)
74
+ ERB::Util.url_encode(str.to_s).tr("+", "%20")
75
+ end
76
+ end
30
77
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: supermail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-09-26 00:00:00.000000000 Z
10
+ date: 2025-11-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: actionmailer