newsly 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +0 -0
- data/README.rdoc +7 -0
- data/Rakefile +39 -0
- data/app/controllers/newsly/application_controller.rb +5 -0
- data/app/controllers/newsly/newsletters_controller.rb +57 -0
- data/app/controllers/newsly/snippets_controller.rb +10 -0
- data/app/controllers/newsly/templates_controller.rb +47 -0
- data/app/helpers/newsly/application_helper.rb +4 -0
- data/app/mailers/newsly/mailer.rb +51 -0
- data/app/models/newsly/newsletter.rb +13 -0
- data/app/models/newsly/template.rb +16 -0
- data/app/views/layouts/newsly/application.html.erb +20 -0
- data/app/views/layouts/newsly/mailer.html.erb +5 -0
- data/app/views/newsly/_navigation.html.erb +5 -0
- data/app/views/newsly/newsletters/_newsletter.html.liquid +26 -0
- data/app/views/newsly/newsletters/_sidebar.html.erb +28 -0
- data/app/views/newsly/newsletters/index.html.erb +20 -0
- data/app/views/newsly/newsletters/show.html.erb +9 -0
- data/app/views/newsly/snippets/index.html.erb +12 -0
- data/app/views/newsly/templates/index.html.erb +15 -0
- data/app/views/newsly/templates/show.html.erb +19 -0
- data/app/workers/newsly/newsletter_sender.rb +14 -0
- data/config/routes.rb +20 -0
- data/db/migrate/20110907161522_create_newsly_newsletters.rb +11 -0
- data/db/migrate/20110912110413_create_newsly_templates.rb +12 -0
- data/db/migrate/20110926113235_add_draft_column_to_templates.rb +6 -0
- data/db/migrate/20110927120903_add_text_body_fields.rb +6 -0
- data/db/migrate/20110929142039_remove_text_body_fields.rb +6 -0
- data/lib/newsly.rb +27 -0
- data/lib/newsly/engine.rb +19 -0
- data/lib/newsly/version.rb +3 -0
- data/lib/tasks/newsly_tasks.rake +7 -0
- data/public/javascripts/jquery.js +49 -0
- data/public/javascripts/newsletters.js +68 -0
- data/public/javascripts/rails.js +363 -0
- data/public/javascripts/templates.js +41 -0
- data/public/mercury/javascripts/mercury.min.js +16937 -0
- data/public/mercury/javascripts/mercury_dialogs.js +18 -0
- data/public/mercury/javascripts/mercury_loader.js +191 -0
- data/public/mercury/stylesheets/mercury.bundle.css +241 -0
- data/public/stylesheets/application.css +253 -0
- metadata +176 -0
data/MIT-LICENSE
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
##Newsly lets you manage your rails mailer templates via liquid.
|
2
|
+
Included is the mercury editor (https://github.com/jejacks0n/mercury) for wysiwyg and are ready for
|
3
|
+
sending mails via resque.
|
4
|
+
|
5
|
+
Better description is coming... soon!
|
6
|
+
|
7
|
+
This project rocks and uses MIT-LICENSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
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
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Newsly'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
Bundler::GemHelper.install_tasks
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
|
31
|
+
Rake::TestTask.new(:test) do |t|
|
32
|
+
t.libs << 'lib'
|
33
|
+
t.libs << 'test'
|
34
|
+
t.pattern = 'test/**/*_test.rb'
|
35
|
+
t.verbose = false
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
task :default => :test
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Newsly
|
2
|
+
class NewslettersController < ApplicationController
|
3
|
+
|
4
|
+
respond_to :html, :json
|
5
|
+
respond_to :text, :only => :preview
|
6
|
+
|
7
|
+
|
8
|
+
before_filter :get_newsletter, :except => [:index]
|
9
|
+
|
10
|
+
def index
|
11
|
+
@newsletters = Newsletter.all
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
end
|
16
|
+
|
17
|
+
def new
|
18
|
+
render :show
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
if @newsletter.update_attributes(params[:newsletter])
|
23
|
+
render :text => "Last saved #{distance_of_time_in_words_to_now(Time.now, true)} ago"
|
24
|
+
else
|
25
|
+
render :text => "Kunde inte sparas"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def send_test
|
30
|
+
if Newsly::Mailer.send_newsletter(@newsletter.id, params[:to], Newsly.test_data).deliver
|
31
|
+
render :text => "Okidoki"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deliver
|
36
|
+
if params[:answer] == "DELIVER"
|
37
|
+
#Newsly::NewsletterSender.perform(@newsletter.id, params[:recipient_groups])
|
38
|
+
Resque.enqueue(Newsly::NewsletterSender, @newsletter.id, params[:recipient_groups])
|
39
|
+
@newsletter.sent = true
|
40
|
+
@newsletter.save
|
41
|
+
render :text => "NEWSLETTER DELIVERED"
|
42
|
+
else
|
43
|
+
render :text => "WARNING! Not sent, did you answer correctly?"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
@newsletter.destroy
|
49
|
+
redirect_to newsletters_url
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
def get_newsletter
|
54
|
+
@newsletter = params[:id] ? Newsly::Newsletter.find(params[:id]) : Newsly::Newsletter.create(:title => "Nyhetsbrevs rubrik", :body => "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod.", :sent => false)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Newsly
|
3
|
+
class TemplatesController < ApplicationController
|
4
|
+
|
5
|
+
def index
|
6
|
+
@templates = Newsly::Template.where(:draft => false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
@template = Newsly::Template.where(:parent_id => params[:id], :draft => true).first
|
11
|
+
if @template.nil?
|
12
|
+
@template = Newsly::Template.find(params[:id]).dup
|
13
|
+
@template.draft = true
|
14
|
+
@template.parent_id = params[:id]
|
15
|
+
@template.save
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
@template = Newsly::Template.find(params[:id])
|
21
|
+
if @template.update_attributes(params[:template])
|
22
|
+
render :text => "Last saved #{distance_of_time_in_words_to_now(Time.now, true)} ago"
|
23
|
+
else
|
24
|
+
render :text => "Kunde inte sparas"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def send_test
|
29
|
+
@template = Newsly::Template.find(params[:id])
|
30
|
+
if Newsly::Mailer.send_mail(@template.id, params[:to], Newsly.test_data).deliver
|
31
|
+
render :text => "Okidoki"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def publish
|
38
|
+
@draft = Newsly::Template.find(params[:id])
|
39
|
+
@original = Newsly::Template.find(@draft.parent_id)
|
40
|
+
@original.subject = @draft.subject
|
41
|
+
@original.body = @draft.body
|
42
|
+
@original.save
|
43
|
+
render :text => "Published"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Newsly
|
3
|
+
class Mailer < ActionMailer::Base
|
4
|
+
|
5
|
+
default :from => "Newsly <noreply@newsly.com>"
|
6
|
+
|
7
|
+
def mail(headers = {}, &block)
|
8
|
+
caller = caller[0][/`.*'/][1..-2] if caller
|
9
|
+
|
10
|
+
template_data = headers.delete(:template_data)
|
11
|
+
template_id = headers.delete(:template_id)
|
12
|
+
template_name = headers.delete(:template_name)
|
13
|
+
|
14
|
+
tmpl = if template_id
|
15
|
+
Newsly::Template.find(template_id)
|
16
|
+
elsif template_name
|
17
|
+
Newsly::Template.where(:name => template_name, :draft => false).first
|
18
|
+
else
|
19
|
+
Newsly::Template.find_by_caller(self.class.to_s, caller).where(:draft => false).first
|
20
|
+
end
|
21
|
+
|
22
|
+
if tmpl
|
23
|
+
headers[:subject] ||= tmpl.subject
|
24
|
+
mail_body = tmpl.render(template_data).html_safe
|
25
|
+
super(headers) do |format|
|
26
|
+
#format.text { Premailer.new(mail_body, :with_html_string => true).to_plain_text }
|
27
|
+
format.html { render :inline => mail_body, :layout => true }
|
28
|
+
end
|
29
|
+
else
|
30
|
+
super(headers, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_newsletter(newsletter_id, to, template_data = {})
|
35
|
+
@newsletter = Newsly::Newsletter.find(newsletter_id)
|
36
|
+
@template = Newsly::Template.where(:name => "newsletter", :draft => false).first
|
37
|
+
@template_data = template_data.merge({"newsletter" => {"body" => @newsletter.render(template_data)}})
|
38
|
+
mail(:to => to, :subject => "#{@newsletter.title}", :template_id => @template.id, :template_data => @template_data)
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_mail(template_id, to, template_data = {})
|
42
|
+
mail(:to => to, :template_id => template_id, :template_data => template_data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.render_body(template_name, template_type, template_data = {})
|
46
|
+
tpl = Newsly::Template.where(:name => template_name.to_s, :template_type => template_type, :draft => false).first
|
47
|
+
tpl.render(template_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Newsly
|
3
|
+
class Newsletter < ActiveRecord::Base
|
4
|
+
liquid_methods :title, :body
|
5
|
+
|
6
|
+
|
7
|
+
#these 2 methods are duplicated in template.rb.. DRY up!
|
8
|
+
def render(options={})
|
9
|
+
Liquid::Template.parse(self.body).render options
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Newsly
|
3
|
+
class Template < ActiveRecord::Base
|
4
|
+
liquid_methods :body
|
5
|
+
|
6
|
+
scope :find_by_caller, lambda { |mailer, method|
|
7
|
+
where(:mailer => mailer, :method => method)
|
8
|
+
}
|
9
|
+
|
10
|
+
#these 2 methods are duplicated in newsletter.rb.. DRY up!
|
11
|
+
def render(options={})
|
12
|
+
Liquid::Template.parse(self.body).render options
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Newsly</title>
|
5
|
+
<%= javascript_include_tag "jquery", "rails" %>
|
6
|
+
<%= stylesheet_link_tag "application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<% if flash[:notice] %>
|
11
|
+
<div class="flash"> <%= flash[:notice] %> </div>
|
12
|
+
<div class="clearfix"></div>
|
13
|
+
<% end %>
|
14
|
+
<div id="flash" class="flash"></div>
|
15
|
+
<div id="page">
|
16
|
+
<%= yield %>
|
17
|
+
<div class="clearfix"></div>
|
18
|
+
</div>
|
19
|
+
</body>
|
20
|
+
</html>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<ul id="nav">
|
2
|
+
<li class="<%= "active" if params[:controller] == "newsly/newsletters" %>"><%= link_to t('Newsletters'), newsletters_path %></li>
|
3
|
+
<li class="<%= "active" if params[:controller] == "newsly/templates" %>"><%= link_to t('Templates'), templates_path %></li>
|
4
|
+
</ul>
|
5
|
+
<div class="clearfix"></div>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#THIS GOES IN DATABASE MOFO!
|
2
|
+
<style type="text/css">
|
3
|
+
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
|
4
|
+
.clearfix:after { clear: both; }
|
5
|
+
.clearfix { zoom: 1; }
|
6
|
+
#newsletter{font-family: "Lucida Grande", sans-serif;}
|
7
|
+
h2, h3{ margin: 0; padding: 0;}
|
8
|
+
</style>
|
9
|
+
<div style="width: 650px; margin: 20px auto; background-color: #eee;">
|
10
|
+
|
11
|
+
<img src="http://minasidor.baraspara.se/images/web/my_pages/temp_logo2.png" style="float: left; margin: 20px 0 0 20px" class="editable"/>
|
12
|
+
<div class="editable"style="float: right; margin: 20px 20px 0 0; font-size: 11px; color: #777;">Ser brevet konstigt ut? <a href="#">Läs det på webben</a> istället.</div>
|
13
|
+
<div class="clearfix"></div>
|
14
|
+
<div style="float: left; background-image: url('http://minasidor.baraspara.se/images/web/my_pages/mail_header_640.png'); width: 630px; padding: 10px 10px 0 0; background-repeat: no-repeat; margin: 20px 0 0 10px; height: 30px;">
|
15
|
+
<h4 class="title editable_block" id="title" style="font-weight: normal; font-size: 12px; text-align: right; margin: 0; padding: 0; color: #555;">{{newsletter.title}}</h4>
|
16
|
+
</div>
|
17
|
+
<div style="float: left; text-align: left;width: 618px; margin: 0 10px; font-size: 12px; line-height: 24px; color: #444; background: #fff; padding: 1px 10px; border: 1px solid #cecece; border-top: 0;" id="body">
|
18
|
+
{{newsletter.body}}
|
19
|
+
</div>
|
20
|
+
<div class="editable" style="width: 620px; margin: 0 10px; font-size: 11px; line-height: 18px; padding: 20px 5px; text-align: left; float: left;">
|
21
|
+
<b>Varför får jag detta mail?</b>
|
22
|
+
<br />
|
23
|
+
Du får detta nyhetsbrev eftersom du är medlem på Baraspara. Vill du inte ha fler nyhetsbrev kan du givetvis <a href="#">avsluta din prenumeration.</a>
|
24
|
+
</div>
|
25
|
+
<div class="clearfix"></div>
|
26
|
+
</div>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div id="sidebar">
|
2
|
+
<ul class="links">
|
3
|
+
<% if !@newsletter.sent? and @newsletter.persisted?%>
|
4
|
+
<li class="button">
|
5
|
+
<%= link_to "<em>❖</em>Send test".html_safe, send_test_newsletter_path(@newsletter), :id => "send_test"%>
|
6
|
+
</li>
|
7
|
+
<% if Newsly.recipient_groups.count > 0 %>
|
8
|
+
<li class="groups">
|
9
|
+
<form id="groupform" class="groupform">
|
10
|
+
<ul>
|
11
|
+
<% for group in Newsly.recipient_groups %>
|
12
|
+
<li>
|
13
|
+
<input type="checkbox" name="<%=group[0].to_s%>" value="<%=group[0].to_s%>" id="group_<%=group[0].to_s%>" />
|
14
|
+
<label for="group_<%=group[0].to_s%>"><%= group[0].to_s.humanize %> (<%= group[1].call.count %>)</label>
|
15
|
+
</li>
|
16
|
+
<% end %>
|
17
|
+
</ul>
|
18
|
+
</form>
|
19
|
+
</li>
|
20
|
+
<li class="button">
|
21
|
+
<%= link_to "<em>✈</em>Deliver!".html_safe, deliver_newsletter_path(@newsletter), :id => "deliver"%>
|
22
|
+
</li>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
<li><%= link_to '<em>☜</em> Back'.html_safe, newsletters_path %></li>
|
26
|
+
</ul>
|
27
|
+
<div id="saved"></div>
|
28
|
+
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%= render :partial => "/newsly/navigation" %>
|
2
|
+
<div id="content">
|
3
|
+
<h2><%= t("Newsletters")%></h2>
|
4
|
+
<table cellspacing="0" cellpadding="0">
|
5
|
+
<tbody>
|
6
|
+
<% @newsletters.each do |newsletter| %>
|
7
|
+
<tr>
|
8
|
+
<td class="<%= newsletter.sent? ? "sent": "draft" %>"><%= newsletter.sent? ? t("sent"): t("draft") %></td>
|
9
|
+
<td class="title"><%= link_to newsletter.title, newsletter %></td>
|
10
|
+
<td class="action"><%= link_to 'Destroy', newsletter, confirm: 'Are you sure?', method: :delete if !newsletter.sent?%></td>
|
11
|
+
</tr>
|
12
|
+
<% end %>
|
13
|
+
</tbody>
|
14
|
+
</table>
|
15
|
+
</div>
|
16
|
+
<div id="sidebar">
|
17
|
+
<ul class="links">
|
18
|
+
<li><%= link_to "<em>+</em>#{t('New Newsletter')}".html_safe, new_newsletter_path %></li>
|
19
|
+
</ul>
|
20
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div id="content">
|
2
|
+
<div id="newsletter" data-id="<%=@newsletter.id%>" data-url="<%=newsletter_path(@newsletter)%>">
|
3
|
+
<h2 id="title" class="mercury-region" data-type="markupable"><%= @newsletter.title.html_safe %></h2>
|
4
|
+
<div id="body" class="mercury-region" data-type="editable"><%= @newsletter.body.html_safe %></div>
|
5
|
+
</div>
|
6
|
+
</div>
|
7
|
+
<%= render 'sidebar' %>
|
8
|
+
|
9
|
+
<%= javascript_include_tag "/mercury/javascripts/mercury_loader.js", "newsletters" %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="mercury-snippet-panel">
|
2
|
+
<div class="filter">
|
3
|
+
<input class="filter" type="text">
|
4
|
+
</div>
|
5
|
+
<ul>
|
6
|
+
<li data-filter="name-snippet">
|
7
|
+
<img alt="Mottagarens namn" data-snippet="person_name" src="/assets/mercury/default-snippet.png"/>
|
8
|
+
<h4>Mottagarens namn</h4>
|
9
|
+
<div class="description">Mottagarens namn visas i mailet. t.ex "Kim F"</div>
|
10
|
+
</li>
|
11
|
+
</ul>
|
12
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<%= render :partial => "/newsly/navigation" %>
|
2
|
+
<div id="content">
|
3
|
+
<h2><%= t("Templates")%></h2>
|
4
|
+
<table cellspacing="0" cellpadding="0">
|
5
|
+
<tbody>
|
6
|
+
<% @templates.each do |template| %>
|
7
|
+
<tr>
|
8
|
+
<td class="title"><%= link_to template.name, template %> (<%=t(template.template_type)%>)</td>
|
9
|
+
</tr>
|
10
|
+
<% end %>
|
11
|
+
</tbody>
|
12
|
+
</table>
|
13
|
+
</div>
|
14
|
+
<div id="sidebar">
|
15
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div id="content">
|
2
|
+
<div id="template" data-id="<%=@template.id%>" data-url="<%=template_path(@template)%>">
|
3
|
+
<h2 id="subject" class="mercury-region" data-type="markupable"><%= @template.subject.html_safe %></h2>
|
4
|
+
<div id="body" class="mercury-region" data-type="editable"><%= @template.body.html_safe %></div>
|
5
|
+
</div>
|
6
|
+
</div>
|
7
|
+
<div id="sidebar">
|
8
|
+
<ul class="links">
|
9
|
+
<li class="buttons">
|
10
|
+
<%= link_to "<em>❖</em>Test".html_safe, send_test_template_path(@template), :class => "remote" %>
|
11
|
+
<%= link_to "<em>✈</em>Publish".html_safe, publish_template_path(@template), :class => "remote", :id => "publish" %>
|
12
|
+
</li>
|
13
|
+
|
14
|
+
<li><%= link_to '<em>☜</em> Back'.html_safe, templates_path %></li>
|
15
|
+
</ul>
|
16
|
+
<div id="saved"></div>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<%= javascript_include_tag "/mercury/javascripts/mercury_loader.js", "templates" %>
|