mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
FIX: Code and Emoticon formatting in HTML emails.
This commit is contained in:
parent
4ec0543362
commit
8c8645f158
11 changed files with 100 additions and 43 deletions
2
Gemfile
2
Gemfile
|
@ -59,6 +59,8 @@ gem 'redis', :require => ["redis", "redis/connection/hiredis"]
|
||||||
|
|
||||||
gem 'active_model_serializers'
|
gem 'active_model_serializers'
|
||||||
|
|
||||||
|
gem 'truncate_html'
|
||||||
|
|
||||||
# we had issues with latest, stick to the rev till we figure this out
|
# we had issues with latest, stick to the rev till we figure this out
|
||||||
# PR that makes it all hang together welcome
|
# PR that makes it all hang together welcome
|
||||||
gem 'ember-rails'
|
gem 'ember-rails'
|
||||||
|
|
|
@ -442,6 +442,7 @@ GEM
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
trollop (2.0)
|
trollop (2.0)
|
||||||
|
truncate_html (0.9.2)
|
||||||
tzinfo (0.3.38)
|
tzinfo (0.3.38)
|
||||||
uglifier (2.3.1)
|
uglifier (2.3.1)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
|
@ -543,6 +544,7 @@ DEPENDENCIES
|
||||||
therubyracer
|
therubyracer
|
||||||
thin
|
thin
|
||||||
timecop
|
timecop
|
||||||
|
truncate_html
|
||||||
uglifier
|
uglifier
|
||||||
unf
|
unf
|
||||||
unicorn
|
unicorn
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Admin::EmailController < Admin::AdminController
|
||||||
|
|
||||||
def preview_digest
|
def preview_digest
|
||||||
params.require(:last_seen_at)
|
params.require(:last_seen_at)
|
||||||
renderer = Email::Renderer.new(UserNotifications.digest(current_user, since: params[:last_seen_at]), html_template: true)
|
renderer = Email::Renderer.new(UserNotifications.digest(current_user, since: params[:last_seen_at]))
|
||||||
render json: MultiJson.dump(html_content: renderer.html, text_content: renderer.text)
|
render json: MultiJson.dump(html_content: renderer.html, text_content: renderer.text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,20 @@ module UserNotificationsHelper
|
||||||
fragment.to_html.html_safe
|
fragment.to_html.html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def logo_url
|
||||||
|
logo_url = SiteSetting.logo_url
|
||||||
|
if logo_url !~ /http(s)?\:\/\//
|
||||||
|
logo_url = "#{Discourse.base_url}#{logo_url}"
|
||||||
|
end
|
||||||
|
logo_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def html_site_link
|
||||||
|
"<a href='#{Discourse.base_url}'>#{@site_name}</a>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def email_excerpt(html)
|
||||||
|
html_string = TruncateHtml::HtmlString.new(html)
|
||||||
|
raw Sanitize.clean(TruncateHtml::HtmlTruncator.new(html_string, length: 1000).truncate, Sanitize::Config::RELAXED)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
47
app/views/user_notifications/digest.html.erb
Normal file
47
app/views/user_notifications/digest.html.erb
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<table style="border: 1px solid #ddd;" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 10px 10px; background-color: #eee; border: 1px solid #ddd;">
|
||||||
|
<a href="<%= Discourse.base_url %>">
|
||||||
|
<img src="<%= logo_url %>" style="max-height: 35px; min-height: 35px; height: 35px;" class='site-logo'></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #fff; padding: 10px 10px; font-family: Arial, Helvetica, sans-serif; font-size: 14px;">
|
||||||
|
<%= raw(t 'user_notifications.digest.why', site_link: html_site_link, last_seen_at: @last_seen_at) %>
|
||||||
|
|
||||||
|
<%- if @featured_topics.present? %>
|
||||||
|
<h3><%=t 'user_notifications.digest.top_topics' %></h3>
|
||||||
|
|
||||||
|
<%- @featured_topics.each_with_index do |t, i| %>
|
||||||
|
<%= link_to t.title, t.relative_url %>
|
||||||
|
|
||||||
|
<%- if t.best_post.present? %>
|
||||||
|
<div class='digest-post'>
|
||||||
|
<%= email_excerpt(t.best_post.cooked) %>
|
||||||
|
</div>
|
||||||
|
<%- end %>
|
||||||
|
|
||||||
|
<%- if i < @featured_topics.size - 1 %><hr><% end %>
|
||||||
|
|
||||||
|
<%- end %>
|
||||||
|
<%- end %>
|
||||||
|
|
||||||
|
<%- if @new_topics.present? %>
|
||||||
|
<h3><%=t 'user_notifications.digest.other_new_topics' %></h3>
|
||||||
|
|
||||||
|
<%- @new_topics.each do |t| %>
|
||||||
|
<ul>
|
||||||
|
<li><%= link_to t.title, t.relative_url %> <%- if t.category %>[<%= t.category.name %>]<%- end %></li>
|
||||||
|
</ul>
|
||||||
|
<%- end -%>
|
||||||
|
|
||||||
|
<%- end -%>
|
||||||
|
|
||||||
|
<span class='footer-notice'>
|
||||||
|
<%=raw(t :'user_notifications.digest.unsubscribe',
|
||||||
|
site_link: html_site_link,
|
||||||
|
unsubscribe_link: link_to(t('user_notifications.digest.click_here'), email_unsubscribe_path(key: @user.temporary_key))) %>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
|
@ -10,11 +10,10 @@
|
||||||
<%= raw(@markdown_linker.create(t.title, t.relative_url)) %>
|
<%= raw(@markdown_linker.create(t.title, t.relative_url)) %>
|
||||||
|
|
||||||
<%- if t.best_post.present? %>
|
<%- if t.best_post.present? %>
|
||||||
<div class='digest-post'><%= raw(t.best_post.excerpt(1000,
|
<%= raw(t.best_post.excerpt(1000,
|
||||||
strip_links: true,
|
strip_links: true,
|
||||||
text_entities: true,
|
text_entities: true,
|
||||||
markdown_images: true)) %></div>
|
markdown_images: true)) %>
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
<%- end %>
|
<%- end %>
|
||||||
|
@ -35,9 +34,9 @@
|
||||||
|
|
||||||
<%= raw(@markdown_linker.references) %>
|
<%= raw(@markdown_linker.references) %>
|
||||||
|
|
||||||
<span class='footer-notice'><%=raw(t :'user_notifications.digest.unsubscribe',
|
<%=raw(t :'user_notifications.digest.unsubscribe',
|
||||||
site_link: site_link,
|
site_link: site_link,
|
||||||
unsubscribe_link: raw(@markdown_linker.create(t('user_notifications.digest.click_here'), email_unsubscribe_path(key: @user.temporary_key)))) %></span>
|
unsubscribe_link: raw(@markdown_linker.create(t('user_notifications.digest.click_here'), email_unsubscribe_path(key: @user.temporary_key)))) %>
|
||||||
|
|
||||||
<%= raw(@markdown_linker.references) %>
|
<%= raw(@markdown_linker.references) %>
|
||||||
|
|
||||||
|
|
|
@ -9,32 +9,22 @@ module Email
|
||||||
end
|
end
|
||||||
|
|
||||||
def text
|
def text
|
||||||
@text ||= @message.body.to_s.force_encoding('UTF-8')
|
return @text if @text
|
||||||
end
|
@text = (@message.text_part ? @message.text_part : @message).body.to_s.force_encoding('UTF-8')
|
||||||
|
|
||||||
def logo_url
|
|
||||||
logo_url = SiteSetting.logo_url
|
|
||||||
if logo_url !~ /http(s)?\:\/\//
|
|
||||||
logo_url = "#{Discourse.base_url}#{logo_url}"
|
|
||||||
end
|
|
||||||
logo_url
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def html
|
def html
|
||||||
style = Email::Styles.new(PrettyText.cook(text))
|
|
||||||
style.format_basic
|
|
||||||
|
|
||||||
if @opts[:html_template]
|
if @message.html_part
|
||||||
|
style = Email::Styles.new(@message.html_part.body.to_s)
|
||||||
|
style.format_basic
|
||||||
style.format_html
|
style.format_html
|
||||||
|
|
||||||
ActionView::Base.new(Rails.configuration.paths["app/views"]).render(
|
|
||||||
template: 'email/template',
|
|
||||||
format: :html,
|
|
||||||
locals: { html_body: style.to_html, logo_url: logo_url }
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
style.to_html
|
style = Email::Styles.new(PrettyText.cook(text))
|
||||||
|
style.format_basic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
style.to_html
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,15 +21,17 @@ module Email
|
||||||
def send
|
def send
|
||||||
return if @message.blank?
|
return if @message.blank?
|
||||||
return if @message.to.blank?
|
return if @message.to.blank?
|
||||||
return if @message.body.blank?
|
|
||||||
|
if @message.text_part
|
||||||
|
return if @message.text_part.body.to_s.blank?
|
||||||
|
else
|
||||||
|
return if @message.body.to_s.blank?
|
||||||
|
end
|
||||||
|
|
||||||
@message.charset = 'UTF-8'
|
@message.charset = 'UTF-8'
|
||||||
|
|
||||||
opts = {}
|
opts = {}
|
||||||
|
|
||||||
# Only use the html template on digest emails
|
|
||||||
opts[:html_template] = true if (@email_type == 'digest')
|
|
||||||
|
|
||||||
renderer = Email::Renderer.new(@message, opts)
|
renderer = Email::Renderer.new(@message, opts)
|
||||||
|
|
||||||
unless @message.html_part
|
unless @message.html_part
|
||||||
|
|
|
@ -13,7 +13,9 @@ module Email
|
||||||
def format_basic
|
def format_basic
|
||||||
@fragment.css('img').each do |img|
|
@fragment.css('img').each do |img|
|
||||||
|
|
||||||
if img['src'] =~ /\/assets\/emoji\//
|
next if img['class'] == 'site-logo'
|
||||||
|
|
||||||
|
if img['class'] == "emoji" || img['src'] =~ /plugins\/emoji/
|
||||||
img['width'] = 20
|
img['width'] = 20
|
||||||
img['height'] = 20
|
img['height'] = 20
|
||||||
else
|
else
|
||||||
|
@ -57,11 +59,6 @@ module Email
|
||||||
style('div.digest-post', 'margin-left: 15px; margin-top: 20px; max-width: 694px;')
|
style('div.digest-post', 'margin-left: 15px; margin-top: 20px; max-width: 694px;')
|
||||||
style('div.digest-post h1', 'font-size: 20px;')
|
style('div.digest-post h1', 'font-size: 20px;')
|
||||||
style('span.footer-notice', 'color:#666; font-size:80%')
|
style('span.footer-notice', 'color:#666; font-size:80%')
|
||||||
|
|
||||||
@fragment.css('pre').each do |pre|
|
|
||||||
pre.replace(pre.text)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_html
|
def to_html
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe Email::Styles do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "adds a width and height to images with an emoji path" do
|
it "adds a width and height to images with an emoji path" do
|
||||||
frag = basic_fragment("<img src='/assets/emoji/fish.png'>")
|
frag = basic_fragment("<img src='/plugins/emoji/fish.png' class='emoji'>")
|
||||||
expect(frag.at("img")["width"]).to eq("20")
|
expect(frag.at("img")["width"]).to eq("20")
|
||||||
expect(frag.at("img")["height"]).to eq("20")
|
expect(frag.at("img")["height"]).to eq("20")
|
||||||
end
|
end
|
||||||
|
@ -85,12 +85,6 @@ describe Email::Styles do
|
||||||
expect(frag.at('li')['style']).to be_present
|
expect(frag.at('li')['style']).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes pre tags but keeps their contents" do
|
|
||||||
style = Email::Styles.new("<pre>hello</pre>")
|
|
||||||
style.format_basic
|
|
||||||
style.format_html
|
|
||||||
expect(style.to_html).to eq("hello")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,15 @@ describe UserNotifications do
|
||||||
its(:to) { should == [user.email] }
|
its(:to) { should == [user.email] }
|
||||||
its(:subject) { should be_present }
|
its(:subject) { should be_present }
|
||||||
its(:from) { should == [SiteSetting.notification_email] }
|
its(:from) { should == [SiteSetting.notification_email] }
|
||||||
its(:body) { should be_present }
|
|
||||||
|
it 'should have a html body' do
|
||||||
|
subject.html_part.body.to_s.should be_present
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have a text body' do
|
||||||
|
subject.html_part.body.to_s.should be_present
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue