Permalink
Browse files

merge changes from grimen

  • Loading branch information...
2 parents 9e5163d + 4b9037b commit ea098c26e04d0a3dc673cc0603dff62d11cdc5e1 Thomas Kadauke committed Jan 6, 2010
View
@@ -0,0 +1,4 @@
+.DS_STORE
+*.tmproj
+pkg*
+coverage*
View
@@ -1,7 +1,8 @@
h2. For the impatient
Check out the demo application:
-*<code>http://opensource.imedo.de/htmlmail</code>*
+
+"http://opensource.imedo.de/htmlmail":http://opensource.imedo.de/htmlmail
Install the plugin:
*<code>script/plugin install git://github.com/imedo/awesome_email.git</code>*
@@ -66,15 +67,19 @@ Be sure to follow these simple conventions or otherwise awesome_emails's magic w
h2. Dependencies
-gems: rails 2.0.2, hpricot, csspool
+Gems:
+
+* "rails 2.0.1+":http://github.com/rails/rails
+* "nokogiri 1.3.3+":http://github.com/tenderlove/nokogiri
+* "csspool 2.0.0+":http://github.com/tenderlove/csspool
h2. Getting it, License and Patches
Get the complete source code through "http://github.com/imedo/awesome_email":http://github.com/imedo/awesome_email. License is MIT. That means that you can do whatever you want with the software, as long as the copyright statement stays intact. Please be a kind open source citizen, and give back your patches and extensions. Just fork the code on Github, and after you're done, send us a pull request. Thanks for your help!
h2. ToDo
-* More test coverage (as usual)
-* make it more flexible with view paths
-* rails 2.1 compatibility
+* More test coverage (as usual) - especially testing multiple rules (!)
+* Make it more flexible with view paths
+
Copyright (c) 2008 imedo GmbH, released under the MIT license
View
@@ -1,22 +1,50 @@
+require 'rubygems'
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
-desc 'Default: run unit tests.'
+NAME = "awesome_email"
+SUMMARY = %Q{Rails ActionMailer with HTML layouts, inline CSS and entity substitution.}
+HOMEPAGE = "http://github.com/grimen/#{NAME}/tree/master"
+AUTHORS = ["imedo GmbH"]
+EMAIL = "entwickler@imedo.de"
+SUPPORT_FILES = %w(README.textile)
+
+begin
+ gem 'technicalpickles-jeweler', '>= 1.2.1'
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = NAME
+ gem.summary = SUMMARY
+ gem.description = SUMMARY
+ gem.homepage = HOMEPAGE
+ gem.authors = AUTHORS
+ gem.email = EMAIL
+
+ gem.require_paths = %w{lib}
+ gem.files = SUPPORT_FILES << %w(MIT-LICENSE Rakefile) << Dir.glob(File.join('{lib,rails,test}', '**', '*'))
+ gem.executables = %w()
+ gem.extra_rdoc_files = %w{README.textile}
+ end
+rescue LoadError
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
+end
+
+desc %Q{Run unit tests for "#{NAME}".}
task :default => :test
-desc 'Test the awesome_email plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
+desc %Q{Run unit tests for "#{NAME}".}
+Rake::TestTask.new(:test) do |test|
+ test.libs << ['lib', 'test']
+ test.pattern = File.join('test', '**', '*_test.rb')
+ test.verbose = true
end
-desc 'Generate documentation for the awesome_email plugin.'
+desc %Q{Generate documentation for "#{NAME}".}
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'AwesomeEmail'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
+ rdoc.title = NAME
+ rdoc.options << '--line-numbers' << '--inline-source' << '--charset=UTF-8'
+ rdoc.rdoc_files.include(SUPPORT_FILES)
+ rdoc.rdoc_files.include(File.join('lib', '**', '*.rb'))
+end
View
@@ -0,0 +1 @@
+0.1.3
View
@@ -0,0 +1,50 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE
+# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{awesome_email}
+ s.version = "0.1.3"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["imedo GmbH"]
+ s.date = %q{2009-09-11}
+ s.description = %q{Rails ActionMailer with HTML layouts, inline CSS and entity substitution.}
+ s.email = %q{entwickler@imedo.de}
+ s.extra_rdoc_files = [
+ "README.textile"
+ ]
+ s.files = [
+ "MIT-LICENSE",
+ "README.textile",
+ "Rakefile",
+ "lib/awesome_email.rb",
+ "lib/awesome_email/convert_entities.rb",
+ "lib/awesome_email/helpers.rb",
+ "lib/awesome_email/inline_styles.rb",
+ "lib/awesome_email/layouts.rb",
+ "rails/init.rb",
+ "test/awesome_email_test.rb",
+ "test/test_helper.rb"
+ ]
+ s.homepage = %q{http://github.com/grimen/awesome_email/tree/master}
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_paths = ["lib"]
+ s.rubygems_version = %q{1.3.3}
+ s.summary = %q{Rails ActionMailer with HTML layouts, inline CSS and entity substitution.}
+ s.test_files = [
+ "test/awesome_email_test.rb",
+ "test/test_helper.rb"
+ ]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ else
+ end
+ else
+ end
+end
@@ -1,4 +1,4 @@
-require File.join(File.dirname(__FILE__), 'layouts.rb')
-require File.join(File.dirname(__FILE__), 'inline_styles.rb')
-require File.join(File.dirname(__FILE__), 'convert_entities.rb')
-require File.join(File.dirname(__FILE__), 'helpers.rb')
+require File.join(File.dirname(__FILE__), 'awesome_email', 'layouts.rb')
+require File.join(File.dirname(__FILE__), 'awesome_email', 'inline_styles.rb')
+require File.join(File.dirname(__FILE__), 'awesome_email', 'convert_entities.rb')
+require File.join(File.dirname(__FILE__), 'awesome_email', 'helpers.rb')
@@ -0,0 +1,55 @@
+# coding: utf-8
+$KCODE = 'u' unless RUBY_VERSION >= '1.9'
+
+module ActionMailer
+ module ConvertEntities
+
+ # Add more if replacements you need
+ UMLAUTS = {
+ 'ä' => '&auml;',
+ 'ö' => '&ouml;',
+ 'ü' => '&uuml;',
+ 'Ä' => '&Auml;',
+ 'Ö' => '&Ouml;',
+ 'Ü' => '&Uuml;',
+ 'ß' => '&szlig;'
+ }.freeze
+
+ module ClassMethods
+ # none
+ end
+
+ module InstanceMethods
+
+ # Replace all umlauts
+ # Add more if replacements you need them
+ def convert_to_entities(text)
+ text.gsub(/[#{UMLAUTS.keys.join}]/u) { |match| UMLAUTS[match] }
+ end
+
+ # Convert entities only when rendering html
+ def render_message_with_converted_entities(method_name, body)
+ message = render_message_without_converted_entities(method_name, body)
+ html_part?(method_name) ? convert_to_entities(message) : message
+ end
+
+ # Check if the part we are rendering is html
+ def html_part?(method_name)
+ method_name.to_s.gsub('.', '/') =~ /#{Mime::EXTENSION_LOOKUP['html']}/
+ end
+
+ end
+
+ def self.included(receiver)
+ receiver.class_eval do
+ extend ClassMethods
+ include InstanceMethods
+
+ alias_method_chain :render_message, :converted_entities
+ end
+ end
+
+ end
+end
+
+ActionMailer::Base.send :include, ActionMailer::ConvertEntities
@@ -0,0 +1,51 @@
+# coding: utf-8
+$KCODE = 'u' unless RUBY_VERSION >= '1.9'
+
+module AwesomeEmail
+ module Helpers
+
+ # helper methods for ActionView::Base
+ module Views
+
+ # prints the contents of a file to the page
+ # default file_name is 'html-mail.css'
+ def render_css_file(file_name = 'html-mail.css')
+ file_name = "#{file_name}.css" unless file_name.end_with?('.css')
+ relative_path = File.join('public', 'stylesheets', 'mails', file_name)
+ files = Dir.glob(File.join(RAILS_ROOT, '**', relative_path))
+ full_path = files.blank? ? File.join(RAILS_ROOT, relative_path) : files.first
+ File.read(full_path) rescue ''
+ end
+
+ # outputs style sheet information into the header of a webpage
+ # to link the stylesheet absolute, we have to pass in the server_url like: "http://localhost" or "https://localhost:3001"
+ def mail_header_styles(server_url, file_name)
+ return '' if file_name.blank?
+ %Q{<link rel="stylesheet" href="#{File.join(server_url, file_name)}" />\n<style type="text/css"><!-- #{render_css_file(file_name)} --></style>}
+ end
+
+ end
+
+ # helper methods for ActionMailer::Base
+ module Mailer
+
+ protected
+
+ # sets a few variables that ensure good delivery of the mail
+ def setup_multipart_mail
+ headers 'Content-transfer-encoding' => '8bit'
+ sent_on Time.now
+ content_type 'text/html'
+ end
+
+ end
+
+ end
+end
+
+ActionView::Base.class_eval do
+ include AwesomeEmail::Helpers::Views
+end
+ActionMailer::Base.class_eval do
+ include AwesomeEmail::Helpers::Mailer
+end
@@ -0,0 +1,92 @@
+# coding: utf-8
+$KCODE = 'u' unless RUBY_VERSION >= '1.9'
+
+require 'rubygems'
+
+gem 'nokogiri', '>= 1.3.3'
+gem 'csspool', '>= 2.0.0'
+
+require 'nokogiri'
+require 'csspool'
+
+module ActionMailer
+ module InlineStyles
+
+ STYLE_ATTR = (RUBY_VERSION >= '1.9') ? :style : 'style'
+
+ module ClassMethods
+ # none
+ end
+
+ module InstanceMethods
+
+ def inline(html)
+ css_doc = parse_css_doc(build_css_file_name_from_css_setting)
+ html_doc = parse_html_doc(html)
+ render_inline(css_doc, html_doc)
+ end
+
+ def render_message_with_inline_styles(method_name, body)
+ message = render_message_without_inline_styles(method_name, body)
+ return message if @css.blank?
+ inline(message)
+ end
+
+ protected
+
+ def render_inline(css_doc, html_doc)
+ css_doc.rule_sets.each do |rule_set|
+ inline_css = css_for_rule(rule_set)
+
+ html_doc.css(rule_set.selectors.first.to_s).each do |element|
+ element[STYLE_ATTR] = [inline_css, element[STYLE_ATTR]].compact.join('').strip
+ element[STYLE_ATTR] << ';' unless element[STYLE_ATTR] =~ /;$/
+ end
+ end
+ html_doc.to_html
+ end
+
+ def css_for_rule(rule_set)
+ rule_set.declarations.map do |declaration|
+ declaration.to_s.strip
+ end.join
+ end
+
+ def parse_html_doc(html)
+ html_doc = Nokogiri::HTML.parse(html)
+ end
+
+ def parse_css_doc(file_name)
+ css_doc = CSSPool.CSS(parse_css_from_file(file_name))
+ end
+
+ def parse_css_from_file(file_name)
+ files = Dir.glob(File.join(RAILS_ROOT, '**', file_name))
+ files.blank? ? '' : File.read(files.first)
+ end
+
+ def build_css_file_name_from_css_setting
+ @css.blank? ? '' : build_css_file_name(@css)
+ end
+
+ def build_css_file_name(css_name)
+ file_name = "#{css_name}.css"
+ Dir.glob(File.join(RAILS_ROOT, '**', file_name)).first || File.join(RAILS_ROOT, 'public', 'stylesheets', 'mails', file_name)
+ end
+
+ end
+
+ def self.included(receiver)
+ receiver.class_eval do
+ extend ClassMethods
+ include InstanceMethods
+
+ adv_attr_accessor :css
+ alias_method_chain :render_message, :inline_styles
+ end
+ end
+
+ end
+end
+
+ActionMailer::Base.send :include, ActionMailer::InlineStyles
Oops, something went wrong.

0 comments on commit ea098c2

Please sign in to comment.