nisetegami 0.4.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.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ ## Nisetegami
2
+
3
+
4
+
5
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError
11
+ require 'rdoc/rdoc'
12
+ require 'rake/rdoctask'
13
+ RDoc::Task = Rake::RDocTask
14
+ end
15
+
16
+ RDoc::Task.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Nisetegami'
19
+ rdoc.options << '--line-numbers'
20
+ rdoc.rdoc_files.include('README.rdoc')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ Bundler::GemHelper.install_tasks
25
+
26
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
27
+ load 'rails/tasks/engine.rake'
28
+
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ desc 'Default: Run all specs.'
35
+ task default: :spec
@@ -0,0 +1,157 @@
1
+ class Nisetegami::Template < ActiveRecord::Base
2
+
3
+ self.table_name = :nisetegami_templates
4
+
5
+ ## constants
6
+
7
+ CONTENT = [:subject, :body_html, :body_text]
8
+ HEADERS = [:cc, :bcc, :reply_to, :from]
9
+
10
+ ## scopes
11
+
12
+ scope :by_mailer, ->(mailer){ where(mailer: mailer.respond_to?(:name) ? mailer.name : mailer) }
13
+ scope :by_action, ->(action){ where(action: action) }
14
+ scope :by_layout, ->(layout){ where(layout: layout) }
15
+ scope :enabled, where(enabled: true)
16
+ scope :disabled, where(enabled: false)
17
+ scope :html, where(only_text: false)
18
+ scope :text, where(only_text: true)
19
+
20
+ ## validations
21
+ email_re = '[-a-z0-9_+\.]+@([-a-z0-9]+\.)+[a-z0-9]{2,}'
22
+ address_re = "(?:[^<@]+\\s+<#{email_re}>|#{email_re})"
23
+ addresses_re = /^#{address_re}(?:\s*,\s*#{address_re})*$/i
24
+ validates_format_of :from, :reply_to, :cc, :bcc, with: addresses_re, allow_blank: true
25
+ validate :subject, :body_text, :layout_text, :name, presence: true
26
+ validate :body_html, :layout_html, presence: true, unless: :only_text?
27
+ validate :check_template_syntax
28
+ validate :check_mailer
29
+
30
+ ## class-methods
31
+
32
+ # Accepts an instance of the ActionMailer::Base subclass
33
+ # and attempts to find associated template using
34
+ # name and action_name of the mailer.
35
+ def self.lookup(mailer_instance)
36
+ relation.where(mailer: mailer_instance.class.name, action: mailer_instance.action_name).first
37
+ end
38
+
39
+ public
40
+
41
+ def layout_html_path
42
+ layout_html && File.join(Nisetegami.layouts_path, layout_html)
43
+ end
44
+
45
+ def layout_text_path
46
+ layout_text && File.join(Nisetegami.layouts_path, layout_text)
47
+ end
48
+
49
+ # Returns a mapping for +self+, as a Hash.
50
+ def mapping
51
+ @_mapping ||= ::Nisetegami.mapping.lookup(mailer, action)
52
+ end
53
+
54
+ # Returns a list of variables for +self+,
55
+ # using a Nisetegami::Mapping definitions.
56
+ def variable_names
57
+ @_variable_names ||= mapping.keys
58
+ end
59
+
60
+ def variable_mapping
61
+ @_variable_mapping ||= begin
62
+ mapping.each_with_object([]) do |(variable, thing), array|
63
+ # @todo: store variable_mapping in mapping instead of classes [?]
64
+ meths = Nisetegami::Utils.liquid_methods_for(Nisetegami.cast[thing])
65
+ array << (meths.blank? ? variable.to_sym : { variable.to_sym => meths })
66
+ end
67
+ end
68
+ end
69
+
70
+ def mailer
71
+ @_mailer ||= self[:mailer].constantize
72
+ rescue NameError
73
+ end
74
+
75
+ CONTENT.each do |attribute|
76
+ define_method "#{attribute}=" do |raw|
77
+ self[attribute] = raw.blank? ? nil : raw
78
+ instance_variable_set("@#{attribute}_template", nil)
79
+ end
80
+
81
+ define_method "render_#{attribute}" do |variables|
82
+ return nil unless self[attribute]
83
+ # do not parse invalid templates
84
+ if instance_variable_get("@#{attribute}_template").nil?
85
+ instance_variable_set("@#{attribute}_template", try_parse_template(attribute))
86
+ end
87
+ instance_variable_get("@#{attribute}_template") \
88
+ .try(:render, variables.stringify_keys.select { |k, v| k.in?(variable_names) })
89
+ end
90
+ end
91
+
92
+ def headers(variables = {})
93
+ options = { subject: render_subject(variables) }
94
+ options[:css] = associated_stylesheets unless only_text?
95
+ HEADERS.each { |header| options[header] = self[header] unless self[header].blank? }
96
+ options
97
+ end
98
+
99
+ def message(recipient, variables)
100
+ return nil unless valid?
101
+ mailer.testing(action, recipient, variables)
102
+ end
103
+
104
+ private
105
+
106
+ def associated_stylesheets
107
+ @@asset_provider ||= Nisetegami::AssetProvider.new(Roadie.current_provider.prefix)
108
+ stylesheets = [:default]
109
+ stylesheets << layout_html unless layout_html.blank?
110
+ stylesheets.map! { |s| File.join('nisetegami', s.to_s) }
111
+ stylesheets.select { |s| @@asset_provider.exists?(s) }
112
+ end
113
+
114
+ def check_mailer
115
+ errors.add(:mailer, :undefined) if !mailer || !mailer.ancestors.include?(ActionMailer::Base)
116
+ errors.add(:action, :undefined) if mailer && !mailer.action_methods.include?(action.to_s)
117
+ end
118
+
119
+ def check_template_syntax
120
+ CONTENT.each { |attribute| try_parse_template(attribute) }
121
+ end
122
+
123
+ def try_parse_template(attribute)
124
+ Liquid::Template.parse(self[attribute])
125
+ rescue Liquid::SyntaxError => error
126
+ errors.add(attribute, :liquid_syntax_error, message: error.message)
127
+ false
128
+ end
129
+
130
+ end
131
+
132
+ # == Schema Information
133
+ #
134
+ # Table name: nisetegami_templates
135
+ #
136
+ # id :integer not null, primary key
137
+ # mailer :string(255)
138
+ # action :string(255)
139
+ # name :string(255)
140
+ # from :string(255)
141
+ # cc :string(255)
142
+ # bcc :string(255)
143
+ # reply_to :string(255)
144
+ # subject :text
145
+ # body_text :text
146
+ # body_html :text
147
+ # layout_text :string(255)
148
+ # layout_html :string(255)
149
+ # enabled :boolean default(FALSE), not null
150
+ # created_at :datetime not null
151
+ # updated_at :datetime not null
152
+ #
153
+ # Indexes
154
+ #
155
+ # index_nisetegami_templates_on_mailer_and_action (mailer,action) UNIQUE
156
+ #
157
+
@@ -0,0 +1,35 @@
1
+ class CreateNisetegamiTemplates < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :nisetegami_templates do |t|
4
+
5
+ ## mapping
6
+ t.string :mailer # EG: "TestMailer"
7
+ t.string :action # EG: "simple"
8
+ t.string :name # results in "TestMailer#simple"
9
+
10
+ ## headers
11
+ t.string :from
12
+ t.string :cc
13
+ t.string :bcc
14
+ t.string :reply_to
15
+
16
+ ## content
17
+ t.text :subject
18
+ t.text :body_text
19
+ t.text :body_html
20
+ t.text :layout_text
21
+ t.text :layout_html
22
+
23
+ ## controls
24
+ t.boolean :enabled, null: false, default: false
25
+ t.boolean :only_text, null: false, default: true
26
+
27
+ t.timestamps
28
+ end
29
+ add_index :nisetegami_templates, [:mailer, :action], unique: true
30
+ end
31
+
32
+ def self.down
33
+ drop_table :nisetegami_templates
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ class Nisetegami::TemplatesGenerator < Rails::Generators::Base
5
+ include Rails::Generators::Migration
6
+
7
+ source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
8
+
9
+ def self.next_migration_number(dirname)
10
+ if ActiveRecord::Base.timestamped_migrations
11
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
12
+ else
13
+ "%.3d" % (current_migration_number(dirname) + 1)
14
+ end
15
+ end
16
+
17
+ def create_migrations
18
+ Dir[File.join(self.class.source_root, 'migrations/*.rb')].sort.each do |template|
19
+ basename = File.basename(template).gsub(/^\d+_/, '')
20
+ if self.class.migration_exists?(File.join(Rails.root, 'db/migrate'), basename.sub(/\.rb$/, '')).blank?
21
+ migration_template template, "db/migrate/#{basename}"
22
+ sleep 1
23
+ end
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,77 @@
1
+ module Nisetegami
2
+ module ActionMailerExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ append_view_path ARTemplateResolver.instance
7
+ append_view_path "#{Rails.root}/app/views/nisetegami"
8
+ alias_method_chain :collect_responses_and_parts_order, :required_parts_order
9
+ alias_method_chain :mail, :template
10
+ alias_method_chain :render, :layout
11
+ end
12
+
13
+ module ClassMethods
14
+ def testing(action, recipient, variables)
15
+ new.testing do |instance|
16
+ instance.action_name = action.to_s
17
+ variables.each { |k, v| instance.instance_variable_set("@#{k}", v) }
18
+ instance.mail to: recipient
19
+ end
20
+ end
21
+ end
22
+
23
+ def render_with_layout(*args, &block)
24
+ options = args.first
25
+ if !options[:layout] && @_ar_template
26
+ format = options[:template].identifier.split('.').last
27
+ options[:layout] = @_ar_template.send("layout_#{format}")
28
+ end
29
+ render_without_layout(*args, &block)
30
+ end
31
+
32
+ def mail_with_template(headers = {}, &block)
33
+ # maybe there is better way? - do not want to do query it (despite cache is used) for second time
34
+ @_ar_template = Template.by_mailer(self.class).by_action(action_name).first
35
+ if @_ar_template
36
+ self.action_name ||= @_ar_template.action.to_s
37
+ # think about this ugly shit
38
+ vars = instance_variables.inject({}) do |hsh, var|
39
+ unless var =~ /@_/
40
+ template_var = instance_variable_get(var)
41
+ template_var = begin
42
+ instance_variable_set(var, "#{template_var.class}Decorator".constantize.decorate(template_var))
43
+ rescue NameError
44
+ template_var
45
+ end
46
+ hsh[var[1..-1].to_sym] = template_var
47
+ end
48
+ hsh
49
+ end
50
+ headers.reverse_merge!(@_ar_template.headers(vars))
51
+ end
52
+ mail_without_template(headers, &block).tap do |m|
53
+ m.perform_deliveries = testing? || !@_ar_template || @_ar_template.enabled
54
+ m.body = nil unless m.perform_deliveries # better to remove corresponding specs??
55
+ end
56
+ end
57
+
58
+ def testing(&block)
59
+ @_testing_was, @_testing = @_testing, true
60
+ yield self
61
+ ensure
62
+ @_testing = @_testing_was
63
+ end
64
+
65
+ protected
66
+
67
+ def testing?
68
+ !!@_testing
69
+ end
70
+
71
+ def collect_responses_and_parts_order_with_required_parts_order(headers)
72
+ responses, parts_order = collect_responses_and_parts_order_without_required_parts_order(headers)
73
+ [responses, parts_order || responses.map { |r| r[:content_type] }]
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,24 @@
1
+ require 'singleton'
2
+
3
+ class Nisetegami::ARTemplateResolver < ActionView::Resolver
4
+
5
+ include Singleton
6
+
7
+ def find_templates(name, prefix, partial, details)
8
+ Nisetegami::Template.by_mailer(prefix.classify).by_action(name).map do |record|
9
+ formats = [:text]
10
+ formats.unshift(:html) unless record.only_text?
11
+ formats.map do |format|
12
+ source = record.send("body_#{format}")
13
+ identifier = "Nisetegami::Template.#{record.id}.#{format}"
14
+ handler = ActionView::Template.registered_template_handler(:liquid)
15
+ details = {
16
+ format: Mime[format],
17
+ virtual_path: "#{record.mailer.to_s.underscore}/#{record.action}",
18
+ updated_at: record.updated_at
19
+ }
20
+ ActionView::Template.new(source, identifier, handler, details)
21
+ end
22
+ end.flatten
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module Nisetegami
2
+ class AssetProvider < Roadie::AssetPipelineProvider
3
+
4
+ def exists?(name)
5
+ !asset_file(name).nil?
6
+ end
7
+
8
+ def asset_file(name)
9
+ basename = remove_prefix(name)
10
+ assets[basename]
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ require 'nisetegami'
2
+
3
+ module Nisetegami
4
+ class Engine < Rails::Engine
5
+ isolate_namespace Nisetegami
6
+
7
+ initializer 'nisetegami.action_mailer' do |app|
8
+ ActiveSupport.on_load :action_mailer do
9
+ include Nisetegami::ActionMailerExtensions
10
+ end
11
+ end
12
+
13
+ config.before_initialize do
14
+ Nisetegami.class_variable_set(:@@layouts_path, Rails.root.join('app/views/nisetegami/layouts').to_s)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module Nisetegami
2
+ module Exceptions
3
+
4
+ class Error < StandardError
5
+ end
6
+
7
+ class UnknownActionError < Error
8
+ def initialize(mailer, action)
9
+ @action = "#{mailer}##{action}"
10
+ end
11
+ def message
12
+ "Action #{@action} does not exist. You should define it first."
13
+ end
14
+ end
15
+
16
+ class MissingTemplateError < Error
17
+ def initialize(mailer_instance)
18
+ @action = "#{mailer_instance.class.name}##{mailer_instance.action_name}"
19
+ end
20
+ def message
21
+ "Template for #{@action} not found. " \
22
+ "You should define it manually or use Nisetegami.populate!"
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ class ActionView::Template::Handlers::Liquid
2
+
3
+ def self.call(template)
4
+ "ActionView::Template::Handlers::Liquid.new(self).render(#{template.source.inspect}, local_assigns)"
5
+ end
6
+
7
+ def initialize(view)
8
+ @view = view
9
+ end
10
+
11
+ def render(template, local_assigns = {})
12
+ assigns = @view.assigns
13
+ assigns["content_for_layout"] = @view.content_for(:layout) if @view.content_for?(:layout)
14
+ assigns.merge!(local_assigns.stringify_keys)
15
+
16
+ controller = @view.controller
17
+ filters = if controller.respond_to?(:liquid_filters, true)
18
+ controller.send(:liquid_filters)
19
+ elsif controller.respond_to?(:master_helper_module)
20
+ [controller.master_helper_module]
21
+ else
22
+ [controller._helpers]
23
+ end
24
+
25
+ liquid = Liquid::Template.parse(template)
26
+ liquid.render(assigns, filters: filters, registers: { action_view: @view, controller: @view.controller })
27
+ end
28
+
29
+ def compilable?
30
+ false
31
+ end
32
+ end
33
+
34
+ ActionView::Template.register_template_handler :liquid, ActionView::Template::Handlers::Liquid
@@ -0,0 +1,73 @@
1
+ module Nisetegami
2
+ class Mapping
3
+ attr_reader :mailers
4
+
5
+ SEPARATOR = "#"
6
+
7
+ def initialize
8
+ @mailers = Set.new
9
+ @mapping = {}
10
+ end
11
+
12
+ def register(mailer, action, *locals)
13
+ mailer = mailer.to_s.classify
14
+ unless action_exists?(mailer, action)
15
+ raise Exceptions::UnknownActionError.new(mailer, action)
16
+ end
17
+ @mapping["#{mailer}#{SEPARATOR}#{action}"] = prepare_locals(*locals)
18
+ @mailers << mailer
19
+ end
20
+
21
+ def lookup(mailer, action)
22
+ @mapping["#{mailer}#{SEPARATOR}#{action}"] || {}
23
+ end
24
+
25
+ def populate!
26
+ Nisetegami::Template.find_each { |template| template.destroy unless action_exists?(template[:mailer], template.action) }
27
+
28
+ @mapping.each do |route, locals|
29
+ mailer, action = route.split(SEPARATOR, 2)
30
+ next unless can_populate?(mailer, action)
31
+ variables = expand_locals(*locals).map{ |v| "{{ #{v} }}" }.join(", ")
32
+
33
+ Nisetegami::Template.create!(
34
+ subject: "Subject",
35
+ body_text: "You can use following variables: #{variables}. Format: text.",
36
+ body_html: "You can use following variables: #{variables}. Format: html.",
37
+ name: route,
38
+ mailer: mailer,
39
+ action: action,
40
+ enabled: false
41
+ )
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def expand_locals(*locals)
48
+ locals.each_with_object([]) do |(v, thing), array|
49
+ meths = Nisetegami::Utils.liquid_methods_for(Nisetegami.cast[thing])
50
+ array << (meths.blank? ? v : meths.map { |m| "#{v}.#{m}" })
51
+ end.flatten
52
+ end
53
+
54
+ def prepare_locals(*locals)
55
+ options = locals.extract_options!
56
+ # need to call tableize because of the bug in classify method ('master_class'.classify => 'MasterClas')
57
+ locals.each_with_object({}) { |v, hsh| hsh[v.to_s] = v.to_s.tableize.classify }.merge(options.stringify_keys)
58
+ end
59
+
60
+ def can_populate?(mailer, action)
61
+ action_exists?(mailer, action) && !Nisetegami::Template.where(mailer: mailer, action: action).exists?
62
+ end
63
+
64
+ def action_exists?(mailer, action)
65
+ klass = mailer.constantize
66
+ klass.ancestors.include?(ActionMailer::Base) &&
67
+ klass.action_methods.include?(action.to_s)
68
+ rescue NameError
69
+ false
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ if defined?(::FactoryGirl)
2
+
3
+ FactoryGirl.define do
4
+ factory :simple_nisetegami_template, class: 'Nisetegami::Template' do
5
+
6
+ mailer "Nisetegami::TestMailer"
7
+ sequence(:action) { |n| "simple_#{n}" }
8
+
9
+ subject "The quick brown {{ fox }} jumps over the lazy {{ dog }}."
10
+ body_text "The quick brown {{ fox }} jumps over the lazy {{ dog }}."
11
+ body_html "The quick brown {{ fox }} jumps over the lazy {{ dog }}."
12
+ layout_text "default"
13
+ layout_html "default"
14
+
15
+ after(:build) do |template|
16
+ Nisetegami::TestMailer.action_methods << template.action.to_sym
17
+ Nisetegami::TestMailer.send :alias_method, template.action.to_sym, :simple
18
+ Nisetegami.configure { |c| c.register template[:mailer], template.action, fox: 'String', dog: 'String' }
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ class Nisetegami::TestMailer < ActionMailer::Base
2
+ def simple(fox, dog)
3
+ @fox = fox
4
+ @dog = dog
5
+ mail to: 'user@example.com'
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ Dir[File.expand_path('../test/*.rb', __FILE__)].each { |f| require f }
@@ -0,0 +1,15 @@
1
+ module Nisetegami
2
+ module Utils
3
+ module_function
4
+
5
+ def liquid_methods_for(thing)
6
+ return nil unless thing.const_defined?('LiquidDropClass')
7
+ thing::LiquidDropClass.public_instance_methods(false)
8
+ end
9
+
10
+ def filenames(path, format)
11
+ Dir[File.join(path, "*.#{format}.*")].map { |file| File.basename(file).sub(/\.#{format}#{File.extname(file)}$/, "") }.uniq
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Nisetegami
2
+ VERSION = "0.4.0"
3
+ end
data/lib/nisetegami.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'roadie'
2
+ require 'liquid'
3
+
4
+ require 'nisetegami/action_mailer_extensions'
5
+ require 'nisetegami/liquid_template_handler'
6
+ require 'nisetegami/ar_template_resolver'
7
+ require 'nisetegami/asset_provider'
8
+ require 'nisetegami/exceptions'
9
+ require 'nisetegami/mapping'
10
+ require 'nisetegami/utils'
11
+ require 'nisetegami/engine'
12
+
13
+ module Nisetegami
14
+
15
+ mattr_reader :layouts_path
16
+
17
+ mattr_reader :mapping
18
+ @@mapping = Nisetegami::Mapping.new
19
+
20
+ def self.configure
21
+ yield self
22
+ end
23
+
24
+ # optional block to cast a thing (String, Symbol)
25
+ # into a class with liquid_methods
26
+ def self.cast(&block)
27
+ @@cast ||= ->(thing){ defined?(thing) == 'constant' ? thing : thing.to_s.constantize }
28
+ block_given? ? @@cast = block : @@cast
29
+ end
30
+
31
+ def self.register(*args)
32
+ @@mapping.register(*args)
33
+ end
34
+
35
+ def self.populate!
36
+ @@mapping.populate!
37
+ end
38
+
39
+ class << self
40
+ %w(text html).each do |format|
41
+ define_method("#{format}_layouts") do
42
+ # cache result in class variable unless in development
43
+ instance_variable_get(:"@#{format}_layouts") || Nisetegami::Utils.filenames(Nisetegami.layouts_path, format).tap do |layouts|
44
+ instance_variable_set(:"@#{format}_layouts", layouts) unless Rails.env.development?
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :nisetegami do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nisetegami
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Denis Lifanov
9
+ - Dmitry Afanasyev
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-11-05 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '3.2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '3.2'
31
+ - !ruby/object:Gem::Dependency
32
+ name: roadie
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: 2.3.1
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: 2.3.1
47
+ - !ruby/object:Gem::Dependency
48
+ name: liquid
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: sqlite3
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rails
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: '3.2'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '3.2'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rspec
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-rails
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: factory_girl_rails
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: pry-debugger
145
+ requirement: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ description: ActiveRecord/Liquid-based mail templates, incl. CSS-processing.
160
+ email:
161
+ - inadsence@gmail.com
162
+ - dimarzio1986@gmail.com
163
+ executables: []
164
+ extensions: []
165
+ extra_rdoc_files: []
166
+ files:
167
+ - app/models/nisetegami/template.rb
168
+ - lib/generators/nisetegami/templates/migrations/001_create_nisetegami_templates.rb
169
+ - lib/generators/nisetegami/templates_generator.rb
170
+ - lib/nisetegami/action_mailer_extensions.rb
171
+ - lib/nisetegami/ar_template_resolver.rb
172
+ - lib/nisetegami/asset_provider.rb
173
+ - lib/nisetegami/engine.rb
174
+ - lib/nisetegami/exceptions.rb
175
+ - lib/nisetegami/liquid_template_handler.rb
176
+ - lib/nisetegami/mapping.rb
177
+ - lib/nisetegami/test/factories.rb
178
+ - lib/nisetegami/test/test_mailer.rb
179
+ - lib/nisetegami/test.rb
180
+ - lib/nisetegami/utils.rb
181
+ - lib/nisetegami/version.rb
182
+ - lib/nisetegami.rb
183
+ - lib/tasks/nisetegami_tasks.rake
184
+ - MIT-LICENSE
185
+ - Rakefile
186
+ - README.md
187
+ homepage: https://github.com/icrowley/nisetegami
188
+ licenses: []
189
+ post_install_message:
190
+ rdoc_options: []
191
+ require_paths:
192
+ - lib
193
+ required_ruby_version: !ruby/object:Gem::Requirement
194
+ none: false
195
+ requirements:
196
+ - - ! '>='
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ required_rubygems_version: !ruby/object:Gem::Requirement
200
+ none: false
201
+ requirements:
202
+ - - ! '>='
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ requirements: []
206
+ rubyforge_project:
207
+ rubygems_version: 1.8.24
208
+ signing_key:
209
+ specification_version: 3
210
+ summary: ActiveRecord/Liquid-based mail templates, incl. CSS-processing.
211
+ test_files: []
212
+ has_rdoc: