diff --git a/README.md b/README.md
index 01ffab34..39db1208 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ Potassium Rails apps includes the following gems and technologies:
- [Tzinfo-Data](https://github.com/tzinfo/tzinfo-data) for updating timezone information
- [Faker](https://github.com/stympy/faker) for creating development data
- [Scout](https://github.com/scoutapp/scout_apm_ruby) for monitoring performance
+- [Mjml](https://github.com/sighmon/mjml-rails) for mails style
The following optional integrations are also added:
diff --git a/lib/potassium/assets/app/mailers/application_mailer.rb b/lib/potassium/assets/app/mailers/application_mailer.rb
index d8bd387b..474c7b92 100644
--- a/lib/potassium/assets/app/mailers/application_mailer.rb
+++ b/lib/potassium/assets/app/mailers/application_mailer.rb
@@ -1,3 +1,3 @@
class ApplicationMailer < ActionMailer::Base
- layout 'mailer'
+ layout 'default_mail'
end
diff --git a/lib/potassium/assets/app/mailers/example_mailer.rb b/lib/potassium/assets/app/mailers/example_mailer.rb
new file mode 100644
index 00000000..4a19707c
--- /dev/null
+++ b/lib/potassium/assets/app/mailers/example_mailer.rb
@@ -0,0 +1,6 @@
+class ExampleMailer < ApplicationMailer
+ def example_mail
+ @email = params[:email]
+ mail(from: 'admin@example.com', to: @email, subject: 'Welcome to Potassium')
+ end
+end
diff --git a/lib/potassium/assets/app/views/example_mailer/example_mail.html.mjml b/lib/potassium/assets/app/views/example_mailer/example_mail.html.mjml
new file mode 100644
index 00000000..b6b01a3d
--- /dev/null
+++ b/lib/potassium/assets/app/views/example_mailer/example_mail.html.mjml
@@ -0,0 +1,7 @@
+
+
+
+ Hello <%= @email %>, welcome to Potassium
+
+
+
diff --git a/lib/potassium/assets/app/views/layouts/default_mail.html.mjml b/lib/potassium/assets/app/views/layouts/default_mail.html.mjml
new file mode 100644
index 00000000..3d466077
--- /dev/null
+++ b/lib/potassium/assets/app/views/layouts/default_mail.html.mjml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ .body-section {
+ -webkit-box-shadow: 1px 4px 11px 0px rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: 1px 4px 11px 0px rgba(0, 0, 0, 0.15);
+ box-shadow: 1px 4px 11px 0px rgba(0, 0, 0, 0.15);
+ }
+
+
+ .text-link {
+ color: #5e6ebf
+ }
+
+
+ .footer-link {
+ color: #888888
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= yield %>
+
+
+
+
+
+
+
+
diff --git a/lib/potassium/assets/config/mailer.rb.erb b/lib/potassium/assets/config/mailer.rb.erb
index 3a3b2927..3badab43 100644
--- a/lib/potassium/assets/config/mailer.rb.erb
+++ b/lib/potassium/assets/config/mailer.rb.erb
@@ -7,8 +7,6 @@ Rails.application.config.action_mailer.default_url_options = {
}
Rails.application.config.action_mailer.default_options = { from: ENV['DEFAULT_EMAIL_ADDRESS'] }
-ASSET_HOST = ENV.fetch("ASSET_HOST", ENV.fetch("APPLICATION_HOST"))
-Rails.application.config.action_mailer.asset_host = ASSET_HOST
if ENV["EMAIL_RECIPIENTS"].present?
Mail.register_interceptor RecipientInterceptor.new(
diff --git a/lib/potassium/assets/public/mails/platanus-logo.png b/lib/potassium/assets/public/mails/platanus-logo.png
new file mode 100644
index 00000000..0864c69e
Binary files /dev/null and b/lib/potassium/assets/public/mails/platanus-logo.png differ
diff --git a/lib/potassium/recipes/mailer.rb b/lib/potassium/recipes/mailer.rb
index 47dcbbfb..9d7cb561 100644
--- a/lib/potassium/recipes/mailer.rb
+++ b/lib/potassium/recipes/mailer.rb
@@ -63,20 +63,32 @@ def dependencies(service)
gather_gem 'recipient_interceptor'
end
+ def config_environments
+ gsub_file 'config/environments/production.rb', /$\s*config.action_mailer.*/, ''
+ asset_host_dev = <<~RUBY
+ config.action_mailer.asset_host = "http://\#{ENV.fetch('APPLICATION_HOST')}"
+ RUBY
+ application asset_host_dev, env: "development"
+ asset_host_prod = <<~RUBY
+ config.action_mailer.asset_host = "https://\#{ENV.fetch('APPLICATION_HOST')}"
+ RUBY
+ application asset_host_prod, env: "production"
+ mailer_config = <<~RUBY
+ require Rails.root.join("config", "mailer")
+ RUBY
+
+ prepend_file "config/environments/production.rb", mailer_config
+ end
+
def config(service)
template "../assets/config/mailer.rb.erb", 'config/mailer.rb'
- gsub_file 'config/environments/production.rb', /$\s*config.action_mailer.*/, ''
+
append_to_file '.env.development', "APPLICATION_HOST=localhost:3000\n"
append_to_file '.env.development', "EMAIL_RECIPIENTS=\n"
- mailer_config =
- <<~RUBY
- require Rails.root.join("config", "mailer")
- RUBY
-
- prepend_file "config/environments/production.rb", mailer_config
- copy_file '../assets/app/mailers/application_mailer.rb', 'app/mailers/application_mailer.rb', force: true
-
+ copy_file '../assets/app/mailers/application_mailer.rb', 'app/mailers/application_mailer.rb',
+ force: true
+ config_environments
send(service[:name])
end
@@ -88,7 +100,7 @@ def sendgrid
}
RUBY
inject_into_file 'config/mailer.rb', sendgrid_settings,
- after: "Rails.application.config.action_mailer.delivery_method = :sendgrid\n"
+ after: "Rails.application.config.action_mailer.delivery_method = :sendgrid\n"
sendgrid_dev_settings = <<~RUBY
Rails.application.config.action_mailer.sendgrid_dev_settings = {
api_key: ENV['SENDGRID_API_KEY']
diff --git a/lib/potassium/recipes/mjml.rb b/lib/potassium/recipes/mjml.rb
new file mode 100644
index 00000000..81f1504b
--- /dev/null
+++ b/lib/potassium/recipes/mjml.rb
@@ -0,0 +1,31 @@
+class Recipes::Mjml < Rails::AppBuilder
+ def create
+ return if get(:email_service).to_s.downcase.to_sym == :none
+
+ gather_gem 'mjml-rails'
+ after(:gem_install) do
+ run 'bin/yarn add mjml'
+ mjml_config
+ end
+ end
+
+ def installed?
+ gem_exists?(/mjml-rails/)
+ end
+
+ def install
+ create
+ end
+end
+
+private
+
+def mjml_config
+ copy_file '../assets/app/views/layouts/default_mail.html.mjml',
+ 'app/views/layouts/default_mail.html.mjml', force: true
+ copy_file '../assets/app/mailers/example_mailer.rb', 'app/mailers/example_mailer.rb', force: true
+ copy_file '../assets/app/views/example_mailer/example_mail.html.mjml',
+ 'app/views/example_mailer/example_mail.html.mjml', force: true
+ copy_file '../assets/public/mails/platanus-logo.png',
+ 'public/mails/platanus-logo.png', force: true
+end
diff --git a/lib/potassium/templates/application.rb b/lib/potassium/templates/application.rb
index 27399f15..8358ba37 100644
--- a/lib/potassium/templates/application.rb
+++ b/lib/potassium/templates/application.rb
@@ -81,6 +81,7 @@
create :admin
create :vue_admin
create :google_tag_manager
+ create :mjml
end
info "Gathered enough information. Applying the template. Wait a minute."
diff --git a/spec/features/mailer_spec.rb b/spec/features/mailer_spec.rb
index eb49f5fa..cc3681e1 100644
--- a/spec/features/mailer_spec.rb
+++ b/spec/features/mailer_spec.rb
@@ -1,58 +1,104 @@
+# rubocop:disable Rspec/MultipleMemoizedHelpers
require "spec_helper"
RSpec.describe "Mailer" do
let(:gemfile) { IO.read("#{project_path}/Gemfile") }
- let(:mailer_config) { IO.read("#{project_path}/config/mailer.rb") }
+ let(:env) { IO.read("#{project_path}/.env.development") }
let(:dev_config) { IO.read("#{project_path}/config/environments/development.rb") }
- let(:sidekiq_config) { IO.read("#{project_path}/config/sidekiq.yml") }
+ let(:prod_config) { IO.read("#{project_path}/config/environments/production.rb") }
+ let(:asset_host_dev) do
+ <<~RUBY
+ config.action_mailer.asset_host = "http://\#{ENV.fetch('APPLICATION_HOST')}"
+ RUBY
+ end
+ let(:asset_host_prod) do
+ <<~RUBY
+ config.action_mailer.asset_host = "https://\#{ENV.fetch('APPLICATION_HOST')}"
+ RUBY
+ end
+ let(:mailer_config_text) do
+ <<~RUBY
+ require Rails.root.join("config", "mailer")
+ RUBY
+ end
before(:all) { drop_dummy_database }
- context "when selecting sendgrid as mailer" do
- before(:all) do
- remove_project_directory
- create_dummy_project("email_service" => "sendgrid")
- end
+ describe 'with mailer' do
+ let(:mailer_config) { IO.read("#{project_path}/config/mailer.rb") }
+ let(:sidekiq_config) { IO.read("#{project_path}/config/sidekiq.yml") }
+
+ context "when selecting sendgrid as mailer" do
+ before(:all) do
+ remove_project_directory
+ create_dummy_project("email_service" => "sendgrid")
+ end
+
+ it_behaves_like "name"
+ it { expect(gemfile).to include("send_grid_mailer") }
- it { expect(gemfile).to include("send_grid_mailer") }
+ it "adds configuration to mailer.rb" do
+ expect(mailer_config).to include("delivery_method = :sendgrid")
+ expect(mailer_config).to include("sendgrid_settings = {")
+ expect(mailer_config).to include("api_key: ENV['SENDGRID_API_KEY']")
+ end
- it "adds configuration to mailer.rb" do
- expect(mailer_config).to include("delivery_method = :sendgrid")
- expect(mailer_config).to include("sendgrid_settings = {")
- expect(mailer_config).to include("api_key: ENV['SENDGRID_API_KEY']")
+ it "adds configuration to development.rb" do
+ expect(dev_config).to include("delivery_method = :sendgrid_dev")
+ expect(dev_config).to include("sendgrid_dev_settings = {")
+ expect(dev_config).to include("api_key: ENV['SENDGRID_API_KEY']")
+ end
+
+ it "adds configuration to production" do
+ expect(prod_config).to include(mailer_config_text)
+ expect(prod_config).to include(asset_host_prod)
+ end
end
- it "adds configuration to development.rb" do
- expect(dev_config).to include("delivery_method = :sendgrid_dev")
- expect(dev_config).to include("sendgrid_dev_settings = {")
- expect(dev_config).to include("api_key: ENV['SENDGRID_API_KEY']")
+ context "when selecting aws_ses as mailer" do
+ before(:all) do
+ remove_project_directory
+ create_dummy_project("email_service" => "aws_ses")
+ end
+
+ it_behaves_like "name"
+ it { expect(gemfile).to include("aws-sdk-rails") }
+ it { expect(gemfile).to include("letter_opener") }
+ it { expect(mailer_config).to include("delivery_method = :aws_sdk") }
+ it { expect(dev_config).to include("delivery_method = :letter_opener") }
end
- it { expect(sidekiq_config).to include("- mailers") }
+ context "when selecting a mailer and sidekiq" do
+ before :all do
+ drop_dummy_database
+ remove_project_directory
+ create_dummy_project(
+ "background_processor" => true, "email_service" => 'sendgrid'
+ )
+ end
+
+ it { expect(sidekiq_config).to include("- mailers") }
+ end
end
- context "when selecting aws_ses as mailer" do
+ context "when there is no mailer" do
before(:all) do
remove_project_directory
- create_dummy_project("email_service" => "aws_ses")
+ create_dummy_project
end
- it { expect(gemfile).to include("aws-sdk-rails") }
- it { expect(gemfile).to include("letter_opener") }
- it { expect(mailer_config).to include("delivery_method = :aws_sdk") }
- it { expect(dev_config).to include("delivery_method = :letter_opener") }
- it { expect(sidekiq_config).to include("- mailers") }
- end
+ it { expect(gemfile).not_to include("letter_opener") }
+ it { expect(File.exists?("#{project_path}/config/mailer.rb")).to eq(false) }
+ it { expect(env).not_to include("EMAIL_RECIPIENTS") }
- context "when selecting a mailer and sidekiq" do
- before :all do
- drop_dummy_database
- remove_project_directory
- create_dummy_project(
- "background_processor" => true, "email_service" => 'sendgrid'
- )
+ it "adds configuration to development" do
+ expect(dev_config).not_to include(asset_host_dev)
+ expect(dev_config).not_to include("delivery_method")
end
- it { expect(sidekiq_config).to include("- mailers") }
+ it "adds configuration to production" do
+ expect(prod_config).not_to include(mailer_config_text)
+ expect(prod_config).not_to include(asset_host_prod)
+ end
end
end
diff --git a/spec/features/mjml_spec.rb b/spec/features/mjml_spec.rb
new file mode 100644
index 00000000..2289fe41
--- /dev/null
+++ b/spec/features/mjml_spec.rb
@@ -0,0 +1,53 @@
+require "spec_helper"
+
+RSpec.describe "Mjml" do
+ let(:gemfile) { IO.read("#{project_path}/Gemfile") }
+ let(:mailer_config) { IO.read("#{project_path}/config/mailer.rb") }
+ let(:dev_config) { IO.read("#{project_path}/config/environments/development.rb") }
+ let(:sidekiq_config) { IO.read("#{project_path}/config/sidekiq.yml") }
+ let(:yarn_lock) { IO.read("#{project_path}/yarn.lock") }
+
+ before(:all) { drop_dummy_database }
+
+ context "when selecting a mailer" do
+ before(:all) do
+ remove_project_directory
+ create_dummy_project("email_service" => "sendgrid")
+ end
+
+ it 'adds gems and packages' do
+ expect(yarn_lock).to include("mjml")
+ expect(gemfile).to include("mjml-rails")
+ end
+
+ it 'creates example mailer' do
+ expect(File.exists?("#{project_path}/app/views/layouts/default_mail.html.mjml")).to eq(true)
+ expect(File.exists?("#{project_path}/app/mailers/example_mailer.rb")).to eq(true)
+ expect(File.exists?("#{project_path}/app/views/example_mailer/example_mail.html.mjml"))
+ .to eq(true)
+ expect(File.exists?("#{project_path}/public/mails/platanus-logo.png")).to eq(true)
+ end
+ end
+
+ context "when there is no mailer selected" do
+ before(:all) do
+ remove_project_directory
+ create_dummy_project
+ end
+
+ it 'adds gems and packages' do
+ expect(yarn_lock).not_to include("mjml")
+ expect(gemfile).not_to include("mjml-rails")
+ end
+
+ it 'creates example mailer' do
+ expect(File.exists?("#{project_path}/app/views/layouts/default_mail.html.mjml"))
+ .not_to eq(true)
+ expect(File.exists?("#{project_path}/app/mailers/example_mailer.rb"))
+ .not_to eq(true)
+ expect(File.exists?("#{project_path}/app/views/example_mailer/example_mail.html.mjml"))
+ .not_to eq(true)
+ expect(File.exists?("#{project_path}/public/mails/platanus-logo.png")).not_to eq(true)
+ end
+ end
+end
diff --git a/spec/support/shared_examples.rb b/spec/support/shared_examples.rb
new file mode 100644
index 00000000..4828e4e4
--- /dev/null
+++ b/spec/support/shared_examples.rb
@@ -0,0 +1,5 @@
+RSpec.shared_examples "name" do
+ it { expect(sidekiq_config).to include("- mailers") }
+ it { expect(env).to include("EMAIL_RECIPIENTS") }
+ it { expect(dev_config).to include(asset_host_dev) }
+end