action_mailer_kafka 0.1.0
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 +7 -0
- data/.circleci/config.yml +158 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/.rubocop.yml +64 -0
- data/Appraisals +21 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -0
- data/LICENSE.md +23 -0
- data/README.md +138 -0
- data/Rakefile +6 -0
- data/action_mailer_kafka.gemspec +52 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example/.gitignore +21 -0
- data/example/Gemfile +39 -0
- data/example/README.rdoc +10 -0
- data/example/Rakefile +6 -0
- data/example/app/assets/images/.keep +0 -0
- data/example/app/assets/javascripts/application.js +16 -0
- data/example/app/assets/javascripts/users.js.coffee +3 -0
- data/example/app/assets/stylesheets/application.css +15 -0
- data/example/app/assets/stylesheets/scaffolds.css.scss +69 -0
- data/example/app/assets/stylesheets/users.css.scss +3 -0
- data/example/app/controllers/application_controller.rb +5 -0
- data/example/app/controllers/concerns/.keep +0 -0
- data/example/app/controllers/users_controller.rb +82 -0
- data/example/app/helpers/application_helper.rb +2 -0
- data/example/app/helpers/users_helper.rb +2 -0
- data/example/app/jobs/send_email_job.rb +8 -0
- data/example/app/mailers/.keep +0 -0
- data/example/app/mailers/example_mailer.rb +6 -0
- data/example/app/models/.keep +0 -0
- data/example/app/models/concerns/.keep +0 -0
- data/example/app/models/user.rb +2 -0
- data/example/app/views/example_mailer/sample_email.html.erb +398 -0
- data/example/app/views/example_mailer/sample_email.text.erb +2 -0
- data/example/app/views/layouts/application.html.erb +14 -0
- data/example/app/views/users/_form.html.erb +25 -0
- data/example/app/views/users/edit.html.erb +6 -0
- data/example/app/views/users/index.html.erb +27 -0
- data/example/app/views/users/index.json.jbuilder +4 -0
- data/example/app/views/users/new.html.erb +5 -0
- data/example/app/views/users/show.html.erb +14 -0
- data/example/app/views/users/show.json.jbuilder +1 -0
- data/example/config/application.rb +23 -0
- data/example/config/boot.rb +4 -0
- data/example/config/database.yml +11 -0
- data/example/config/environment.rb +5 -0
- data/example/config/environments/development.rb +43 -0
- data/example/config/environments/production.rb +105 -0
- data/example/config/environments/test.rb +39 -0
- data/example/config/initializers/backtrace_silencers.rb +7 -0
- data/example/config/initializers/cookies_serializer.rb +3 -0
- data/example/config/initializers/filter_parameter_logging.rb +4 -0
- data/example/config/initializers/inflections.rb +16 -0
- data/example/config/initializers/mime_types.rb +4 -0
- data/example/config/initializers/session_store.rb +3 -0
- data/example/config/initializers/wrap_parameters.rb +14 -0
- data/example/config/locales/en.yml +23 -0
- data/example/config/routes.rb +4 -0
- data/example/config/secrets.yml +22 -0
- data/example/config.ru +4 -0
- data/example/db/migrate/20141111080045_create_users.rb +10 -0
- data/example/db/migrate/20141115060216_create_delayed_jobs.rb +22 -0
- data/example/db/schema.rb +40 -0
- data/example/db/seeds.rb +7 -0
- data/example/public/404.html +67 -0
- data/example/public/422.html +67 -0
- data/example/public/500.html +66 -0
- data/example/public/favicon.ico +0 -0
- data/example/public/robots.txt +5 -0
- data/example/vendor/assets/javascripts/.keep +0 -0
- data/example/vendor/assets/stylesheets/.keep +0 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/mail_2_5.gemfile +7 -0
- data/gemfiles/mail_2_6.gemfile +7 -0
- data/gemfiles/mail_2_7.gemfile +7 -0
- data/gemfiles/rails_4.gemfile +7 -0
- data/gemfiles/rails_5.gemfile +7 -0
- data/lib/action_mailer_kafka/delivery_method.rb +139 -0
- data/lib/action_mailer_kafka/error.rb +22 -0
- data/lib/action_mailer_kafka/railtie.rb +7 -0
- data/lib/action_mailer_kafka/version.rb +3 -0
- data/lib/action_mailer_kafka.rb +10 -0
- data/logo.png +0 -0
- metadata +328 -0
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'action_mailer_kafka/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'action_mailer_kafka'
|
7
|
+
spec.version = ActionMailerKafka::VERSION
|
8
|
+
spec.authors = ['Luong Vo']
|
9
|
+
spec.email = ['vo.tran.thanh.luong@gmail.com']
|
10
|
+
spec.license = 'MIT'
|
11
|
+
spec.summary = 'Custom action mailer to send mails to Kafka message queue.'
|
12
|
+
spec.description = 'This gem defines a way for Rails service or other backends to \
|
13
|
+
define a mailer that sends email to our employemt hero mail service.'
|
14
|
+
spec.homepage = 'https://github.com/luong-komorebi/action-mailer-kafka/'
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
20
|
+
|
21
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
22
|
+
# spec.metadata['source_code_uri'] = "TODO: Put your gem's public repo URL here."
|
23
|
+
# spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
|
24
|
+
else
|
25
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
26
|
+
'public gem pushes.'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Specify which files should be added to the gem when it is released.
|
30
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
31
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
33
|
+
end
|
34
|
+
spec.bindir = 'exe'
|
35
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
36
|
+
spec.require_paths = ['lib']
|
37
|
+
|
38
|
+
spec.add_dependency 'mail'
|
39
|
+
spec.add_dependency 'ruby-kafka', '~> 0.7.6'
|
40
|
+
spec.add_development_dependency 'appraisal'
|
41
|
+
spec.add_development_dependency 'bundler'
|
42
|
+
spec.add_development_dependency 'byebug'
|
43
|
+
spec.add_development_dependency 'faraday'
|
44
|
+
spec.add_development_dependency 'rails'
|
45
|
+
spec.add_development_dependency 'rake'
|
46
|
+
spec.add_development_dependency 'rspec'
|
47
|
+
spec.add_development_dependency 'rspec-json_expectations'
|
48
|
+
spec.add_development_dependency 'rubocop'
|
49
|
+
spec.add_development_dependency 'rubocop-rspec'
|
50
|
+
spec.add_development_dependency 'rubycritic'
|
51
|
+
spec.add_development_dependency 'simplecov'
|
52
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "action_mailer_kafka"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/example/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
12
|
+
/db/*.sqlite3-journal
|
13
|
+
|
14
|
+
# Ignore all logfiles and tempfiles.
|
15
|
+
/log/*.log
|
16
|
+
/tmp
|
17
|
+
|
18
|
+
# Ignore application configuration
|
19
|
+
/config/application.yml
|
20
|
+
|
21
|
+
/Gemfile.lock
|
data/example/Gemfile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'byebug'
|
4
|
+
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
5
|
+
gem 'rails'
|
6
|
+
gem 'pg'
|
7
|
+
# Use SCSS for stylesheets
|
8
|
+
# gem 'sass-rails', '~> 4.0.3'
|
9
|
+
# Use Uglifier as compressor for JavaScript assets
|
10
|
+
gem 'uglifier'
|
11
|
+
# Use CoffeeScript for .js.coffee assets and view
|
12
|
+
gem 'coffee-rails'
|
13
|
+
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
14
|
+
# gem 'therubyracer', platforms: :ruby
|
15
|
+
|
16
|
+
# Use jquery as the JavaScript library
|
17
|
+
gem 'jquery-rails'
|
18
|
+
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
19
|
+
gem 'turbolinks'
|
20
|
+
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
21
|
+
gem 'jbuilder'
|
22
|
+
|
23
|
+
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
|
24
|
+
gem 'spring', group: :development
|
25
|
+
|
26
|
+
# Use ActiveModel has_secure_password
|
27
|
+
# gem 'bcrypt', '~> 3.1.7'
|
28
|
+
|
29
|
+
# Use unicorn as the app server
|
30
|
+
# gem 'unicorn'
|
31
|
+
|
32
|
+
# Use Capistrano for deployment
|
33
|
+
# gem 'capistrano-rails', group: :development
|
34
|
+
|
35
|
+
# Use debugger
|
36
|
+
# gem 'debugger', group: [:development, :test]
|
37
|
+
gem "figaro"
|
38
|
+
gem 'delayed_job_active_record'
|
39
|
+
gem 'action_mailer_kafka', path: '../'
|
data/example/README.rdoc
ADDED
data/example/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require turbolinks
|
16
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,69 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #fff;
|
3
|
+
color: #333;
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
5
|
+
font-size: 13px;
|
6
|
+
line-height: 18px;
|
7
|
+
}
|
8
|
+
|
9
|
+
p, ol, ul, td {
|
10
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
11
|
+
font-size: 13px;
|
12
|
+
line-height: 18px;
|
13
|
+
}
|
14
|
+
|
15
|
+
pre {
|
16
|
+
background-color: #eee;
|
17
|
+
padding: 10px;
|
18
|
+
font-size: 11px;
|
19
|
+
}
|
20
|
+
|
21
|
+
a {
|
22
|
+
color: #000;
|
23
|
+
&:visited {
|
24
|
+
color: #666;
|
25
|
+
}
|
26
|
+
&:hover {
|
27
|
+
color: #fff;
|
28
|
+
background-color: #000;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
div {
|
33
|
+
&.field, &.actions {
|
34
|
+
margin-bottom: 10px;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
#notice {
|
39
|
+
color: green;
|
40
|
+
}
|
41
|
+
|
42
|
+
.field_with_errors {
|
43
|
+
padding: 2px;
|
44
|
+
background-color: red;
|
45
|
+
display: table;
|
46
|
+
}
|
47
|
+
|
48
|
+
#error_explanation {
|
49
|
+
width: 450px;
|
50
|
+
border: 2px solid red;
|
51
|
+
padding: 7px;
|
52
|
+
padding-bottom: 0;
|
53
|
+
margin-bottom: 20px;
|
54
|
+
background-color: #f0f0f0;
|
55
|
+
h2 {
|
56
|
+
text-align: left;
|
57
|
+
font-weight: bold;
|
58
|
+
padding: 5px 5px 5px 15px;
|
59
|
+
font-size: 12px;
|
60
|
+
margin: -7px;
|
61
|
+
margin-bottom: 0px;
|
62
|
+
background-color: #c00;
|
63
|
+
color: #fff;
|
64
|
+
}
|
65
|
+
ul li {
|
66
|
+
font-size: 12px;
|
67
|
+
list-style: square;
|
68
|
+
}
|
69
|
+
}
|
File without changes
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
before_action :set_user, only: [:show, :edit, :update, :destroy]
|
3
|
+
|
4
|
+
# GET /users
|
5
|
+
# GET /users.json
|
6
|
+
def index
|
7
|
+
@users = User.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /users/1
|
11
|
+
# GET /users/1.json
|
12
|
+
def show
|
13
|
+
end
|
14
|
+
|
15
|
+
# GET /users/new
|
16
|
+
def new
|
17
|
+
@user = User.new
|
18
|
+
end
|
19
|
+
|
20
|
+
# GET /users/1/edit
|
21
|
+
def edit
|
22
|
+
end
|
23
|
+
|
24
|
+
# POST /users
|
25
|
+
# POST /users.json
|
26
|
+
def create
|
27
|
+
@user = User.new(user_params)
|
28
|
+
|
29
|
+
respond_to do |format|
|
30
|
+
if @user.save
|
31
|
+
|
32
|
+
# Sends email to user when user is created.
|
33
|
+
# To send emails without Action Job
|
34
|
+
ExampleMailer.sample_email(@user).deliver_now
|
35
|
+
|
36
|
+
# To send emails using Action Jobs
|
37
|
+
# SendEmailJob.set(wait: 10.seconds).perform_later(@user)
|
38
|
+
|
39
|
+
format.html { redirect_to @user, notice: 'User was successfully created.' }
|
40
|
+
format.json { render :show, status: :created, location: @user }
|
41
|
+
else
|
42
|
+
format.html { render :new }
|
43
|
+
format.json { render json: @user.errors, status: :unprocessable_entity }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# PATCH/PUT /users/1
|
49
|
+
# PATCH/PUT /users/1.json
|
50
|
+
def update
|
51
|
+
respond_to do |format|
|
52
|
+
if @user.update(user_params)
|
53
|
+
format.html { redirect_to @user, notice: 'User was successfully updated.' }
|
54
|
+
format.json { render :show, status: :ok, location: @user }
|
55
|
+
else
|
56
|
+
format.html { render :edit }
|
57
|
+
format.json { render json: @user.errors, status: :unprocessable_entity }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# DELETE /users/1
|
63
|
+
# DELETE /users/1.json
|
64
|
+
def destroy
|
65
|
+
@user.destroy
|
66
|
+
respond_to do |format|
|
67
|
+
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
|
68
|
+
format.json { head :no_content }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
# Use callbacks to share common setup or constraints between actions.
|
74
|
+
def set_user
|
75
|
+
@user = User.find(params[:id])
|
76
|
+
end
|
77
|
+
|
78
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
79
|
+
def user_params
|
80
|
+
params.require(:user).permit(:name, :email)
|
81
|
+
end
|
82
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,398 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta name="viewport" content="width=device-width" />
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
+
<title>Simple Transactional Email</title>
|
7
|
+
<style>
|
8
|
+
/* -------------------------------------
|
9
|
+
GLOBAL RESETS
|
10
|
+
------------------------------------- */
|
11
|
+
|
12
|
+
/*All the styling goes here*/
|
13
|
+
|
14
|
+
img {
|
15
|
+
border: none;
|
16
|
+
-ms-interpolation-mode: bicubic;
|
17
|
+
max-width: 100%;
|
18
|
+
}
|
19
|
+
|
20
|
+
body {
|
21
|
+
background-color: #f6f6f6;
|
22
|
+
font-family: sans-serif;
|
23
|
+
-webkit-font-smoothing: antialiased;
|
24
|
+
font-size: 14px;
|
25
|
+
line-height: 1.4;
|
26
|
+
margin: 0;
|
27
|
+
padding: 0;
|
28
|
+
-ms-text-size-adjust: 100%;
|
29
|
+
-webkit-text-size-adjust: 100%;
|
30
|
+
}
|
31
|
+
|
32
|
+
table {
|
33
|
+
border-collapse: separate;
|
34
|
+
mso-table-lspace: 0pt;
|
35
|
+
mso-table-rspace: 0pt;
|
36
|
+
width: 100%; }
|
37
|
+
table td {
|
38
|
+
font-family: sans-serif;
|
39
|
+
font-size: 14px;
|
40
|
+
vertical-align: top;
|
41
|
+
}
|
42
|
+
|
43
|
+
/* -------------------------------------
|
44
|
+
BODY & CONTAINER
|
45
|
+
------------------------------------- */
|
46
|
+
|
47
|
+
.body {
|
48
|
+
background-color: #f6f6f6;
|
49
|
+
width: 100%;
|
50
|
+
}
|
51
|
+
|
52
|
+
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
|
53
|
+
.container {
|
54
|
+
display: block;
|
55
|
+
margin: 0 auto !important;
|
56
|
+
/* makes it centered */
|
57
|
+
max-width: 580px;
|
58
|
+
padding: 10px;
|
59
|
+
width: 580px;
|
60
|
+
}
|
61
|
+
|
62
|
+
/* This should also be a block element, so that it will fill 100% of the .container */
|
63
|
+
.content {
|
64
|
+
box-sizing: border-box;
|
65
|
+
display: block;
|
66
|
+
margin: 0 auto;
|
67
|
+
max-width: 580px;
|
68
|
+
padding: 10px;
|
69
|
+
}
|
70
|
+
|
71
|
+
/* -------------------------------------
|
72
|
+
HEADER, FOOTER, MAIN
|
73
|
+
------------------------------------- */
|
74
|
+
.main {
|
75
|
+
background: #ffffff;
|
76
|
+
border-radius: 3px;
|
77
|
+
width: 100%;
|
78
|
+
}
|
79
|
+
|
80
|
+
.wrapper {
|
81
|
+
box-sizing: border-box;
|
82
|
+
padding: 20px;
|
83
|
+
}
|
84
|
+
|
85
|
+
.content-block {
|
86
|
+
padding-bottom: 10px;
|
87
|
+
padding-top: 10px;
|
88
|
+
}
|
89
|
+
|
90
|
+
.footer {
|
91
|
+
clear: both;
|
92
|
+
margin-top: 10px;
|
93
|
+
text-align: center;
|
94
|
+
width: 100%;
|
95
|
+
}
|
96
|
+
.footer td,
|
97
|
+
.footer p,
|
98
|
+
.footer span,
|
99
|
+
.footer a {
|
100
|
+
color: #999999;
|
101
|
+
font-size: 12px;
|
102
|
+
text-align: center;
|
103
|
+
}
|
104
|
+
|
105
|
+
/* -------------------------------------
|
106
|
+
TYPOGRAPHY
|
107
|
+
------------------------------------- */
|
108
|
+
h1,
|
109
|
+
h2,
|
110
|
+
h3,
|
111
|
+
h4 {
|
112
|
+
color: #000000;
|
113
|
+
font-family: sans-serif;
|
114
|
+
font-weight: 400;
|
115
|
+
line-height: 1.4;
|
116
|
+
margin: 0;
|
117
|
+
margin-bottom: 30px;
|
118
|
+
}
|
119
|
+
|
120
|
+
h1 {
|
121
|
+
font-size: 35px;
|
122
|
+
font-weight: 300;
|
123
|
+
text-align: center;
|
124
|
+
text-transform: capitalize;
|
125
|
+
}
|
126
|
+
|
127
|
+
p,
|
128
|
+
ul,
|
129
|
+
ol {
|
130
|
+
font-family: sans-serif;
|
131
|
+
font-size: 14px;
|
132
|
+
font-weight: normal;
|
133
|
+
margin: 0;
|
134
|
+
margin-bottom: 15px;
|
135
|
+
}
|
136
|
+
p li,
|
137
|
+
ul li,
|
138
|
+
ol li {
|
139
|
+
list-style-position: inside;
|
140
|
+
margin-left: 5px;
|
141
|
+
}
|
142
|
+
|
143
|
+
a {
|
144
|
+
color: #3498db;
|
145
|
+
text-decoration: underline;
|
146
|
+
}
|
147
|
+
|
148
|
+
/* -------------------------------------
|
149
|
+
BUTTONS
|
150
|
+
------------------------------------- */
|
151
|
+
.btn {
|
152
|
+
box-sizing: border-box;
|
153
|
+
width: 100%; }
|
154
|
+
.btn > tbody > tr > td {
|
155
|
+
padding-bottom: 15px; }
|
156
|
+
.btn table {
|
157
|
+
width: auto;
|
158
|
+
}
|
159
|
+
.btn table td {
|
160
|
+
background-color: #ffffff;
|
161
|
+
border-radius: 5px;
|
162
|
+
text-align: center;
|
163
|
+
}
|
164
|
+
.btn a {
|
165
|
+
background-color: #ffffff;
|
166
|
+
border: solid 1px #3498db;
|
167
|
+
border-radius: 5px;
|
168
|
+
box-sizing: border-box;
|
169
|
+
color: #3498db;
|
170
|
+
cursor: pointer;
|
171
|
+
display: inline-block;
|
172
|
+
font-size: 14px;
|
173
|
+
font-weight: bold;
|
174
|
+
margin: 0;
|
175
|
+
padding: 12px 25px;
|
176
|
+
text-decoration: none;
|
177
|
+
text-transform: capitalize;
|
178
|
+
}
|
179
|
+
|
180
|
+
.btn-primary table td {
|
181
|
+
background-color: #3498db;
|
182
|
+
}
|
183
|
+
|
184
|
+
.btn-primary a {
|
185
|
+
background-color: #3498db;
|
186
|
+
border-color: #3498db;
|
187
|
+
color: #ffffff;
|
188
|
+
}
|
189
|
+
|
190
|
+
/* -------------------------------------
|
191
|
+
OTHER STYLES THAT MIGHT BE USEFUL
|
192
|
+
------------------------------------- */
|
193
|
+
.last {
|
194
|
+
margin-bottom: 0;
|
195
|
+
}
|
196
|
+
|
197
|
+
.first {
|
198
|
+
margin-top: 0;
|
199
|
+
}
|
200
|
+
|
201
|
+
.align-center {
|
202
|
+
text-align: center;
|
203
|
+
}
|
204
|
+
|
205
|
+
.align-right {
|
206
|
+
text-align: right;
|
207
|
+
}
|
208
|
+
|
209
|
+
.align-left {
|
210
|
+
text-align: left;
|
211
|
+
}
|
212
|
+
|
213
|
+
.clear {
|
214
|
+
clear: both;
|
215
|
+
}
|
216
|
+
|
217
|
+
.mt0 {
|
218
|
+
margin-top: 0;
|
219
|
+
}
|
220
|
+
|
221
|
+
.mb0 {
|
222
|
+
margin-bottom: 0;
|
223
|
+
}
|
224
|
+
|
225
|
+
.preheader {
|
226
|
+
color: transparent;
|
227
|
+
display: none;
|
228
|
+
height: 0;
|
229
|
+
max-height: 0;
|
230
|
+
max-width: 0;
|
231
|
+
opacity: 0;
|
232
|
+
overflow: hidden;
|
233
|
+
mso-hide: all;
|
234
|
+
visibility: hidden;
|
235
|
+
width: 0;
|
236
|
+
}
|
237
|
+
|
238
|
+
.powered-by a {
|
239
|
+
text-decoration: none;
|
240
|
+
}
|
241
|
+
|
242
|
+
hr {
|
243
|
+
border: 0;
|
244
|
+
border-bottom: 1px solid #f6f6f6;
|
245
|
+
margin: 20px 0;
|
246
|
+
}
|
247
|
+
|
248
|
+
/* -------------------------------------
|
249
|
+
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
250
|
+
------------------------------------- */
|
251
|
+
@media only screen and (max-width: 620px) {
|
252
|
+
table[class=body] h1 {
|
253
|
+
font-size: 28px !important;
|
254
|
+
margin-bottom: 10px !important;
|
255
|
+
}
|
256
|
+
table[class=body] p,
|
257
|
+
table[class=body] ul,
|
258
|
+
table[class=body] ol,
|
259
|
+
table[class=body] td,
|
260
|
+
table[class=body] span,
|
261
|
+
table[class=body] a {
|
262
|
+
font-size: 16px !important;
|
263
|
+
}
|
264
|
+
table[class=body] .wrapper,
|
265
|
+
table[class=body] .article {
|
266
|
+
padding: 10px !important;
|
267
|
+
}
|
268
|
+
table[class=body] .content {
|
269
|
+
padding: 0 !important;
|
270
|
+
}
|
271
|
+
table[class=body] .container {
|
272
|
+
padding: 0 !important;
|
273
|
+
width: 100% !important;
|
274
|
+
}
|
275
|
+
table[class=body] .main {
|
276
|
+
border-left-width: 0 !important;
|
277
|
+
border-radius: 0 !important;
|
278
|
+
border-right-width: 0 !important;
|
279
|
+
}
|
280
|
+
table[class=body] .btn table {
|
281
|
+
width: 100% !important;
|
282
|
+
}
|
283
|
+
table[class=body] .btn a {
|
284
|
+
width: 100% !important;
|
285
|
+
}
|
286
|
+
table[class=body] .img-responsive {
|
287
|
+
height: auto !important;
|
288
|
+
max-width: 100% !important;
|
289
|
+
width: auto !important;
|
290
|
+
}
|
291
|
+
}
|
292
|
+
|
293
|
+
/* -------------------------------------
|
294
|
+
PRESERVE THESE STYLES IN THE HEAD
|
295
|
+
------------------------------------- */
|
296
|
+
@media all {
|
297
|
+
.ExternalClass {
|
298
|
+
width: 100%;
|
299
|
+
}
|
300
|
+
.ExternalClass,
|
301
|
+
.ExternalClass p,
|
302
|
+
.ExternalClass span,
|
303
|
+
.ExternalClass font,
|
304
|
+
.ExternalClass td,
|
305
|
+
.ExternalClass div {
|
306
|
+
line-height: 100%;
|
307
|
+
}
|
308
|
+
.apple-link a {
|
309
|
+
color: inherit !important;
|
310
|
+
font-family: inherit !important;
|
311
|
+
font-size: inherit !important;
|
312
|
+
font-weight: inherit !important;
|
313
|
+
line-height: inherit !important;
|
314
|
+
text-decoration: none !important;
|
315
|
+
}
|
316
|
+
.btn-primary table td:hover {
|
317
|
+
background-color: #34495e !important;
|
318
|
+
}
|
319
|
+
.btn-primary a:hover {
|
320
|
+
background-color: #34495e !important;
|
321
|
+
border-color: #34495e !important;
|
322
|
+
}
|
323
|
+
}
|
324
|
+
|
325
|
+
</style>
|
326
|
+
</head>
|
327
|
+
<body class="">
|
328
|
+
<span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
|
329
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
|
330
|
+
<tr>
|
331
|
+
<td> </td>
|
332
|
+
<td class="container">
|
333
|
+
<div class="content">
|
334
|
+
|
335
|
+
<!-- START CENTERED WHITE CONTAINER -->
|
336
|
+
<table role="presentation" class="main">
|
337
|
+
|
338
|
+
<!-- START MAIN CONTENT AREA -->
|
339
|
+
<tr>
|
340
|
+
<td class="wrapper">
|
341
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
342
|
+
<tr>
|
343
|
+
<td>
|
344
|
+
<p>Hi there,</p>
|
345
|
+
<p>Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it.</p>
|
346
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
|
347
|
+
<tbody>
|
348
|
+
<tr>
|
349
|
+
<td align="left">
|
350
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
351
|
+
<tbody>
|
352
|
+
<tr>
|
353
|
+
<td> <a href="http://htmlemail.io" target="_blank">Call To Action</a> </td>
|
354
|
+
</tr>
|
355
|
+
</tbody>
|
356
|
+
</table>
|
357
|
+
</td>
|
358
|
+
</tr>
|
359
|
+
</tbody>
|
360
|
+
</table>
|
361
|
+
<p>This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions.</p>
|
362
|
+
<p>Good luck! Hope it works.</p>
|
363
|
+
</td>
|
364
|
+
</tr>
|
365
|
+
</table>
|
366
|
+
</td>
|
367
|
+
</tr>
|
368
|
+
|
369
|
+
<!-- END MAIN CONTENT AREA -->
|
370
|
+
</table>
|
371
|
+
<!-- END CENTERED WHITE CONTAINER -->
|
372
|
+
|
373
|
+
<!-- START FOOTER -->
|
374
|
+
<div class="footer">
|
375
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
376
|
+
<tr>
|
377
|
+
<td class="content-block">
|
378
|
+
<span class="apple-link">Company Inc, 3 Abbey Road, San Francisco CA 94102</span>
|
379
|
+
<br> Don't like these emails? <a href="http://i.imgur.com/CScmqnj.gif">Unsubscribe</a>.
|
380
|
+
</td>
|
381
|
+
</tr>
|
382
|
+
<tr>
|
383
|
+
<td class="content-block powered-by">
|
384
|
+
Powered by <a href="http://htmlemail.io">HTMLemail</a>.
|
385
|
+
</td>
|
386
|
+
</tr>
|
387
|
+
</table>
|
388
|
+
</div>
|
389
|
+
<!-- END FOOTER -->
|
390
|
+
|
391
|
+
</div>
|
392
|
+
</td>
|
393
|
+
<td> </td>
|
394
|
+
</tr>
|
395
|
+
</table>
|
396
|
+
</body>
|
397
|
+
</html>
|
398
|
+
|