effective_email_templates 0.2.8
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/MIT-LICENSE +20 -0
- data/README.md +195 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/effective_email_templates.js +1 -0
- data/app/assets/stylesheets/effective_email_templates.css.scss +1 -0
- data/app/controllers/admin/email_templates_controller.rb +63 -0
- data/app/errors/effective/access_denied.rb +18 -0
- data/app/helpers/effective_email_templates_helper.rb +19 -0
- data/app/mailers/effective/email_template_mailer.rb +14 -0
- data/app/models/effective/datatables/email_templates.rb +22 -0
- data/app/models/effective/email_template.rb +55 -0
- data/app/views/admin/email_templates/_actions.html.haml +2 -0
- data/app/views/admin/email_templates/_form.html.haml +9 -0
- data/app/views/admin/email_templates/edit.html.haml +3 -0
- data/app/views/admin/email_templates/index.html.haml +3 -0
- data/app/views/effective/email_template_mailer/templated_email.html.haml +1 -0
- data/config/routes.rb +11 -0
- data/db/migrate/01_create_effective_email_templates.rb.erb +20 -0
- data/lib/effective/liquid_mailer.rb +12 -0
- data/lib/effective_email_templates.rb +33 -0
- data/lib/effective_email_templates/email_view_template.rb +29 -0
- data/lib/effective_email_templates/engine.rb +27 -0
- data/lib/effective_email_templates/liquid_resolver.rb +46 -0
- data/lib/effective_email_templates/template_importer.rb +46 -0
- data/lib/effective_email_templates/version.rb +3 -0
- data/lib/generators/effective_email_templates/install_generator.rb +32 -0
- data/lib/generators/templates/README +1 -0
- data/lib/generators/templates/effective_email_templates.rb +51 -0
- data/lib/tasks/effective_email_templates/import_default_views.rake +5 -0
- data/spec/controllers/admin/email_templates_controller_spec.rb +60 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/welcome_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/liquid_resolved_mailer.rb +9 -0
- data/spec/dummy/app/mailers/user_liquid_mailer.rb +10 -0
- data/spec/dummy/app/models/user.rb +15 -0
- data/spec/dummy/app/views/layouts/application.html.erb +17 -0
- data/spec/dummy/app/views/user_liquid/after_create_user.liquid +7 -0
- data/spec/dummy/app/views/welcome/index.html.haml +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +78 -0
- data/spec/dummy/config/environments/test.rb +40 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/devise.rb +259 -0
- data/spec/dummy/config/initializers/effective_email_templates.rb +51 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/devise.en.yml +60 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +57 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/migrate/20141126222940_devise_create_users.rb +42 -0
- data/spec/dummy/db/migrate/20141126222941_create_effective_email_templates.rb +20 -0
- data/spec/dummy/db/schema.rb +46 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/effective_email_templates_spec.rb +35 -0
- data/spec/factories/email_template.rb +12 -0
- data/spec/factories/user.rb +16 -0
- data/spec/factory_spec.rb +10 -0
- data/spec/lib/effective_email_templates/template_importer_spec.rb +44 -0
- data/spec/mailers/liquid_resolved_mailer_spec.rb +38 -0
- data/spec/models/email_template_spec.rb +61 -0
- data/spec/models/user_spec.rb +10 -0
- data/spec/sanity_spec.rb +7 -0
- data/spec/spec_helper.rb +26 -0
- metadata +353 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= @body
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Rails.application.routes.draw do
|
|
2
|
+
mount EffectiveEmailTemplates::Engine => '/', :as => 'effective_email_templates'
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
EffectiveEmailTemplates::Engine.routes.draw do
|
|
6
|
+
if defined?(EffectiveDatatables)
|
|
7
|
+
namespace :admin do
|
|
8
|
+
resources :email_templates, only: [:index, :edit, :update]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateEffectiveEmailTemplates < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table <%= @email_templates_table_name %> do |t|
|
|
4
|
+
t.string :subject
|
|
5
|
+
t.string :from
|
|
6
|
+
t.string :bcc
|
|
7
|
+
t.string :cc
|
|
8
|
+
t.string :slug, :null => false
|
|
9
|
+
t.text :body, :null => false
|
|
10
|
+
t.text :template, :null => false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
add_index <%= @email_templates_table_name %>, :slug
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.down
|
|
17
|
+
drop_table <%= @email_templates_table_name %>
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Effective
|
|
2
|
+
class LiquidMailer < ::ActionMailer::Base
|
|
3
|
+
def mail(headers = {}, &block)
|
|
4
|
+
# this be dangerous and requires ruby 2.0+
|
|
5
|
+
mail_method = caller_locations(1,1)[0].label
|
|
6
|
+
email_template = EffectiveEmailTemplates.get(mail_method)
|
|
7
|
+
headers = headers.merge(email_template.mail_options)
|
|
8
|
+
super(headers, &block)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "effective_email_templates/engine"
|
|
2
|
+
require "effective_email_templates/liquid_resolver"
|
|
3
|
+
require "effective_email_templates/email_view_template"
|
|
4
|
+
require "effective_email_templates/template_importer"
|
|
5
|
+
require "effective_email_templates/version"
|
|
6
|
+
|
|
7
|
+
require "effective/liquid_mailer"
|
|
8
|
+
Effective::LiquidMailer.send(:append_view_path, EffectiveEmailTemplates::LiquidResolver.new)
|
|
9
|
+
|
|
10
|
+
module EffectiveEmailTemplates
|
|
11
|
+
|
|
12
|
+
mattr_accessor :email_templates_table_name
|
|
13
|
+
mattr_accessor :authorization_method
|
|
14
|
+
mattr_accessor :simple_form_options
|
|
15
|
+
mattr_accessor :layout
|
|
16
|
+
|
|
17
|
+
def self.setup
|
|
18
|
+
yield self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.authorized?(controller, action, resource)
|
|
22
|
+
if authorization_method.respond_to?(:call) || authorization_method.kind_of?(Symbol)
|
|
23
|
+
raise Effective::AccessDenied.new() unless (controller || self).instance_exec(controller, action, resource, &authorization_method)
|
|
24
|
+
end
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.get(slug)
|
|
29
|
+
Effective::EmailTemplate.find_by_slug(slug) || Effective::EmailTemplate.new(slug: slug)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module EffectiveEmailTemplates
|
|
2
|
+
class EmailViewTemplate
|
|
3
|
+
def initialize( effective_email_template )
|
|
4
|
+
@effective_email_template = effective_email_template
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
attr_accessor :locals
|
|
8
|
+
attr_reader :effective_email_template
|
|
9
|
+
|
|
10
|
+
def render(view, locals, buffer=nil, &block)
|
|
11
|
+
# The view object here is an anonymous view object (it has a class
|
|
12
|
+
# of Class). It has all of the view helper methods inside of it.
|
|
13
|
+
effective_email_template.render(view.assigns['to_liquid'])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def formats
|
|
17
|
+
[:html]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def identifier
|
|
21
|
+
effective_email_template.slug
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def type
|
|
25
|
+
formats.first
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module EffectiveEmailTemplates
|
|
2
|
+
class Engine < ::Rails::Engine
|
|
3
|
+
engine_name 'effective_email_templates'
|
|
4
|
+
|
|
5
|
+
# Include Helpers to base application
|
|
6
|
+
initializer 'effective_email_templates.action_controller' do |app|
|
|
7
|
+
ActiveSupport.on_load :action_controller do
|
|
8
|
+
helper EffectiveEmailTemplatesHelper
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Include acts_as_email_templatable concern and allow any ActiveRecord object to call it
|
|
13
|
+
initializer 'effective_email_templates.active_record' do |app|
|
|
14
|
+
ActiveSupport.on_load :active_record do
|
|
15
|
+
# If you write a concern at all, it should be registered here
|
|
16
|
+
#ActiveRecord::Base.extend(ActsAsAddressable::ActiveRecord)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Set up our default configuration options.
|
|
21
|
+
initializer "effective_email_templates.defaults", :before => :load_config_initializers do |app|
|
|
22
|
+
eval File.read("#{config.root}/lib/generators/templates/effective_email_templates.rb")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module EffectiveEmailTemplates
|
|
2
|
+
class LiquidResolver < ::ActionView::Resolver
|
|
3
|
+
|
|
4
|
+
attr_reader :name, :prefix
|
|
5
|
+
alias_method :slug, :name
|
|
6
|
+
|
|
7
|
+
def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
|
|
8
|
+
# key is used for caching which we won't do since
|
|
9
|
+
# these templates can be updated at any time by
|
|
10
|
+
# an admin. TODO: expire the resolver's cache when
|
|
11
|
+
# a template is updated rather than skip caching
|
|
12
|
+
@name = name
|
|
13
|
+
@prefix = prefix
|
|
14
|
+
|
|
15
|
+
return [] unless liquid_mailer?
|
|
16
|
+
|
|
17
|
+
templates = collect_view_templates
|
|
18
|
+
decorate(templates, [name, prefix, partial], details, locals)
|
|
19
|
+
templates
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# Ensures all the resolver information is set in the template.
|
|
25
|
+
def decorate(templates, path_info, details, locals)
|
|
26
|
+
templates.each do |t|
|
|
27
|
+
t.locals = locals
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def collect_view_templates
|
|
32
|
+
effective_email_templates.map do |eet|
|
|
33
|
+
EmailViewTemplate.new(eet)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def effective_email_templates
|
|
38
|
+
Array.wrap(Effective::EmailTemplate.find_by_slug(slug))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def liquid_mailer?
|
|
42
|
+
prefix =~ /liquid/
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module EffectiveEmailTemplates
|
|
2
|
+
class TemplateImporter
|
|
3
|
+
def self.invoke(importer = new)
|
|
4
|
+
importer.invoke
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def invoke
|
|
8
|
+
Dir[Rails.root.join('app', 'views', '**', '*.liquid')].each do |liquid_template_filepath|
|
|
9
|
+
slug = File.basename(liquid_template_filepath, '.liquid')
|
|
10
|
+
next if Effective::EmailTemplate.where(slug: slug).present?
|
|
11
|
+
|
|
12
|
+
template = Effective::EmailTemplate.new(slug: slug)
|
|
13
|
+
|
|
14
|
+
file = File.new(liquid_template_filepath, "r")
|
|
15
|
+
template = add_template_meta(file, template)
|
|
16
|
+
template.body = extract_template_body(file)
|
|
17
|
+
template.save
|
|
18
|
+
print_errors(template, liquid_template_filepath) unless template.valid?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def add_template_meta(file, template)
|
|
25
|
+
template.attributes = File.open(file) do |f|
|
|
26
|
+
attr = YAML::load(f)
|
|
27
|
+
attr.is_a?(Hash) ? attr : {}
|
|
28
|
+
end
|
|
29
|
+
template
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def extract_template_body file
|
|
33
|
+
contents = file.read
|
|
34
|
+
return unless match = contents.match(/(---+(.|\n)+---+)/)
|
|
35
|
+
contents.gsub(match[1], '').strip
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def print_errors(template, liquid_template_filepath)
|
|
39
|
+
puts "ERROR -- There was one or more validation errors while uploading:"
|
|
40
|
+
puts " Email Template: #{liquid_template_filepath}"
|
|
41
|
+
template.errors.each do |attribute, error|
|
|
42
|
+
puts " -> #{attribute} #{error}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module EffectiveEmailTemplates
|
|
2
|
+
module Generators
|
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
|
4
|
+
include Rails::Generators::Migration
|
|
5
|
+
|
|
6
|
+
desc "Creates an EffectiveEmailTemplates initializer in your application."
|
|
7
|
+
|
|
8
|
+
source_root File.expand_path("../../templates", __FILE__)
|
|
9
|
+
|
|
10
|
+
def self.next_migration_number(dirname)
|
|
11
|
+
if not ActiveRecord::Base.timestamped_migrations
|
|
12
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
|
13
|
+
else
|
|
14
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def copy_initializer
|
|
19
|
+
template "effective_email_templates.rb", "config/initializers/effective_email_templates.rb"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create_migration_file
|
|
23
|
+
@email_templates_table_name = ':' + EffectiveEmailTemplates.email_templates_table_name.to_s
|
|
24
|
+
migration_template '../../../db/migrate/01_create_effective_email_templates.rb.erb', 'db/migrate/create_effective_email_templates.rb'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def show_readme
|
|
28
|
+
readme "README" if behavior == :invoke
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Thanks for using EffectiveEmailTemplates
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
EffectiveEmailTemplates.setup do |config|
|
|
2
|
+
# Database table name to store email_templates in. Default is :email_templates
|
|
3
|
+
config.email_templates_table_name = :email_templates
|
|
4
|
+
|
|
5
|
+
# SimpleForm Options
|
|
6
|
+
# This Hash of options will be passed into any simple_form_for() calls
|
|
7
|
+
config.simple_form_options = {}
|
|
8
|
+
|
|
9
|
+
# config.simple_form_options = {
|
|
10
|
+
# :html => {:class => 'form-horizontal'},
|
|
11
|
+
# :wrapper => :horizontal_form,
|
|
12
|
+
# :wrapper_mappings => {
|
|
13
|
+
# :boolean => :horizontal_boolean,
|
|
14
|
+
# :check_boxes => :horizontal_radio_and_checkboxes,
|
|
15
|
+
# :radio_buttons => :horizontal_radio_and_checkboxes
|
|
16
|
+
# }
|
|
17
|
+
# }
|
|
18
|
+
|
|
19
|
+
# Layout Settings
|
|
20
|
+
# Configure the Layout per controller, or all at once
|
|
21
|
+
|
|
22
|
+
# config.layout = 'application' # All EffectiveEmailTemplates controllers will use this layout
|
|
23
|
+
config.layout = {
|
|
24
|
+
:email_templates => 'application',
|
|
25
|
+
:admin_email_templates => 'application'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Authorization Method
|
|
30
|
+
#
|
|
31
|
+
# This method is called by all controller actions with the appropriate action and resource
|
|
32
|
+
# If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
|
|
33
|
+
#
|
|
34
|
+
# Use via Proc (and with CanCan):
|
|
35
|
+
# config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
|
|
36
|
+
#
|
|
37
|
+
# Use via custom method:
|
|
38
|
+
# config.authorization_method = :my_authorization_method
|
|
39
|
+
#
|
|
40
|
+
# And then in your application_controller.rb:
|
|
41
|
+
#
|
|
42
|
+
# def my_authorization_method(action, resource)
|
|
43
|
+
# current_user.is?(:admin)
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# Or disable the check completely:
|
|
47
|
+
# config.authorization_method = false
|
|
48
|
+
config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) } # CanCan gem
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Admin::EmailTemplatesController do
|
|
4
|
+
context "as an admin" do
|
|
5
|
+
before :each do
|
|
6
|
+
@admin = create(:admin)
|
|
7
|
+
sign_in @admin
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "#index" do
|
|
11
|
+
it 'opens' do
|
|
12
|
+
get :index, :use_route => :effective_email_templates
|
|
13
|
+
expect(response.status).to eq 200
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#new" do
|
|
18
|
+
it 'opens' do
|
|
19
|
+
get :new, :use_route => :effective_email_templates
|
|
20
|
+
expect(response.status).to eq 200
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#create" do
|
|
25
|
+
it 'creates an email template' do
|
|
26
|
+
expect{
|
|
27
|
+
post :create, effective_email_template: attributes_for(:email_template), :use_route => :effective_email_templates
|
|
28
|
+
}.to change(Effective::EmailTemplate,:count).by(1)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "member actions" do
|
|
33
|
+
before :each do
|
|
34
|
+
@email_template = create(:email_template)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "#edit" do
|
|
38
|
+
it 'opens' do
|
|
39
|
+
get :edit, :id => @email_template.id, :use_route => :effective_email_templates
|
|
40
|
+
expect(response.status).to eq 200
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "#update" do
|
|
45
|
+
it 'updates an email template' do
|
|
46
|
+
attributes = @email_template.attributes
|
|
47
|
+
old_from = @email_template.from
|
|
48
|
+
new_from = "gfssljewr@dsfa.com"
|
|
49
|
+
attributes["from"] = new_from
|
|
50
|
+
expect{
|
|
51
|
+
patch :update, id: @email_template.id, effective_email_template: attributes, :use_route => :effective_email_templates
|
|
52
|
+
@email_template.reload
|
|
53
|
+
}.to change(@email_template,:from)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
== README
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
|
4
|
+
application up and running.
|
|
5
|
+
|
|
6
|
+
Things you may want to cover:
|
|
7
|
+
|
|
8
|
+
* Ruby version
|
|
9
|
+
|
|
10
|
+
* System dependencies
|
|
11
|
+
|
|
12
|
+
* Configuration
|
|
13
|
+
|
|
14
|
+
* Database creation
|
|
15
|
+
|
|
16
|
+
* Database initialization
|
|
17
|
+
|
|
18
|
+
* How to run the test suite
|
|
19
|
+
|
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
|
21
|
+
|
|
22
|
+
* Deployment instructions
|
|
23
|
+
|
|
24
|
+
* ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
|
28
|
+
<tt>rake doc:app</tt>.
|