proclaim 0.3.1 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG +9 -0
- data/README.md +91 -10
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/proclaim/comments_handler.js.coffee +3 -0
- data/app/assets/stylesheets/proclaim/subscriptions.css.scss +33 -0
- data/app/controllers/proclaim/comments_controller.rb +3 -1
- data/app/controllers/proclaim/posts_controller.rb +10 -6
- data/app/controllers/proclaim/subscriptions_controller.rb +31 -14
- data/app/helpers/proclaim/application_helper.rb +3 -8
- data/app/models/proclaim/comment.rb +1 -0
- data/app/models/proclaim/post.rb +2 -0
- data/app/models/proclaim/subscription.rb +7 -6
- data/app/policies/proclaim/image_policy.rb +1 -1
- data/app/policies/proclaim/subscription_policy.rb +10 -6
- data/app/views/layouts/proclaim/subscription_mailer.html.erb +34 -4
- data/app/views/proclaim/posts/edit.html.erb +3 -1
- data/app/views/proclaim/posts/index.html.erb +2 -0
- data/app/views/proclaim/posts/new.html.erb +3 -1
- data/app/views/proclaim/posts/show.html.erb +3 -1
- data/app/views/proclaim/subscription_mailer/welcome_email.html.erb +9 -7
- data/app/views/proclaim/subscriptions/_form.html.erb +7 -2
- data/app/views/proclaim/subscriptions/index.html.erb +89 -0
- data/app/views/proclaim/subscriptions/new.html.erb +3 -1
- data/app/views/proclaim/subscriptions/show.html.erb +26 -0
- data/config/routes.rb +2 -6
- data/db/migrate/20150123115226_add_name_to_subscriptions.rb +7 -0
- data/lib/generators/proclaim/templates/initialize_proclaim.rb +19 -0
- data/lib/proclaim.rb +93 -0
- data/lib/proclaim/engine.rb +18 -0
- data/lib/proclaim/version.rb +1 -1
- data/test/controllers/proclaim/subscriptions_controller_test.rb +76 -21
- data/test/dummy/db/schema.rb +4 -3
- data/test/factories/proclaim/subscription.rb +1 -0
- data/test/integration/with_javascript/post_subscription_test.rb +29 -0
- data/test/integration/without_javascript/blog_subscription_test.rb +29 -2
- data/test/integration/without_javascript/manage_subscriptions_test.rb +37 -0
- data/test/integration/without_javascript/unsubscribe_test.rb +6 -6
- data/test/mailers/proclaim/subscription_mailer_test.rb +10 -6
- data/test/models/proclaim/subscription_test.rb +5 -0
- data/test/policies/proclaim/image_policy_test.rb +83 -0
- data/test/policies/proclaim/post_policy_test.rb +11 -0
- data/test/policies/proclaim/subscription_policy_test.rb +27 -15
- data/test/unit/proclaim/new_comment_callback_test.rb +62 -0
- data/test/unit/proclaim/new_subscription_callback_test.rb +62 -0
- data/test/unit/proclaim/post_published_callback_test.rb +74 -0
- metadata +15 -5
- data/app/views/proclaim/subscriptions/subscribed.html.erb +0 -7
- data/app/views/proclaim/subscriptions/unsubscribe.html.erb +0 -7
- data/app/views/proclaim/subscriptions/unsubscribed.html.erb +0 -3
@@ -1,5 +1,13 @@
|
|
1
1
|
module Proclaim
|
2
2
|
class SubscriptionPolicy < ApplicationPolicy
|
3
|
+
def index?
|
4
|
+
not @user.nil? # A user can view the list of subscriptions
|
5
|
+
end
|
6
|
+
|
7
|
+
def show?
|
8
|
+
true # Anyone can show the subscription since it requires a token
|
9
|
+
end
|
10
|
+
|
3
11
|
def create?
|
4
12
|
# A user can subscribe to anything. Guests can only subscribe to
|
5
13
|
# published posts or the blog in general.
|
@@ -10,12 +18,8 @@ module Proclaim
|
|
10
18
|
end
|
11
19
|
end
|
12
20
|
|
13
|
-
def unsubscribe?
|
14
|
-
destroy?
|
15
|
-
end
|
16
|
-
|
17
21
|
def destroy?
|
18
|
-
|
22
|
+
show?
|
19
23
|
end
|
20
24
|
|
21
25
|
class Scope < Scope
|
@@ -24,7 +28,7 @@ module Proclaim
|
|
24
28
|
scope.all # Users can access all subscriptions
|
25
29
|
else
|
26
30
|
# Guests can see none
|
27
|
-
|
31
|
+
scope.none
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -2,9 +2,11 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
5
6
|
|
6
7
|
<style>
|
7
|
-
*
|
8
|
+
*
|
9
|
+
{
|
8
10
|
box-sizing: border-box;
|
9
11
|
}
|
10
12
|
|
@@ -16,6 +18,7 @@
|
|
16
18
|
table.post
|
17
19
|
{
|
18
20
|
width: 600px;
|
21
|
+
table-layout: fixed;
|
19
22
|
margin: 0 auto;
|
20
23
|
}
|
21
24
|
|
@@ -36,6 +39,7 @@
|
|
36
39
|
td.post_title h1
|
37
40
|
{
|
38
41
|
margin: 0 0 10px 0;
|
42
|
+
font-size: 30px;
|
39
43
|
padding: 0;
|
40
44
|
}
|
41
45
|
|
@@ -48,7 +52,6 @@
|
|
48
52
|
{
|
49
53
|
float: left;
|
50
54
|
max-width: 35%;
|
51
|
-
max-width: calc(33.33% + 40px);
|
52
55
|
min-height: 18px;
|
53
56
|
}
|
54
57
|
|
@@ -56,7 +59,7 @@
|
|
56
59
|
{
|
57
60
|
margin: 0px;
|
58
61
|
vertical-align: top;
|
59
|
-
max-width:
|
62
|
+
max-width: 100%;
|
60
63
|
border: 0px none;
|
61
64
|
}
|
62
65
|
|
@@ -94,6 +97,7 @@
|
|
94
97
|
td.post_body
|
95
98
|
{
|
96
99
|
padding-bottom: 10px;
|
100
|
+
font-size: 18px;
|
97
101
|
}
|
98
102
|
|
99
103
|
td.post_body blockquote
|
@@ -117,6 +121,32 @@
|
|
117
121
|
color: #888;
|
118
122
|
}
|
119
123
|
</style>
|
124
|
+
|
125
|
+
<style data-premailer="ignore">
|
126
|
+
@media only screen and (min-width: 521px) and (max-width: 620px)
|
127
|
+
{
|
128
|
+
table[class="post"]
|
129
|
+
{
|
130
|
+
width: 500px !important;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
@media only screen and (min-width: 421px) and (max-width: 520px)
|
135
|
+
{
|
136
|
+
table[class="post"]
|
137
|
+
{
|
138
|
+
width: 400px !important;
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
@media only screen and (max-width: 420px)
|
143
|
+
{
|
144
|
+
table[class="post"]
|
145
|
+
{
|
146
|
+
width: 320px !important;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
</style>
|
120
150
|
</head>
|
121
151
|
<body>
|
122
152
|
<table class = "main">
|
@@ -134,7 +164,7 @@
|
|
134
164
|
<% else %>
|
135
165
|
You're receiving this email because you requested to be notified if a new post was made at <%= link_to url, posts_url %>.
|
136
166
|
<% end %>
|
137
|
-
If you no longer wish to receive these emails, simply <%= link_to "unsubscribe",
|
167
|
+
If you no longer wish to receive these emails, simply <%= link_to "unsubscribe", subscription_url(@subscription.token) %>.
|
138
168
|
</td>
|
139
169
|
</tr>
|
140
170
|
</table>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
<% proclaim_title @post.title %>
|
2
|
+
|
1
3
|
<script type="text/javascript">
|
2
4
|
$(document).ready(function()
|
3
5
|
{
|
@@ -28,7 +30,7 @@
|
|
28
30
|
</div>
|
29
31
|
|
30
32
|
<div class = "post">
|
31
|
-
<h1 class = "post_title"><%=
|
33
|
+
<h1 class = "post_title"><%= content_for :proclaim_title %></h1>
|
32
34
|
|
33
35
|
<div class = "post_body show">
|
34
36
|
<%= @post.body.html_safe %>
|
@@ -1,11 +1,7 @@
|
|
1
1
|
<table class = "post">
|
2
2
|
<tr>
|
3
3
|
<td class = "post_title"><h1>
|
4
|
-
|
5
|
-
You'll be notified!
|
6
|
-
<% else %>
|
7
|
-
Thanks for subscribing!
|
8
|
-
<% end %>
|
4
|
+
Hello, <%= @subscription.name %>!
|
9
5
|
</h1></td>
|
10
6
|
</tr>
|
11
7
|
|
@@ -13,12 +9,18 @@
|
|
13
9
|
<td class = "post_body">
|
14
10
|
<% if @subscription.post %>
|
15
11
|
<p>
|
16
|
-
You signed up to be notified of any new comments on
|
12
|
+
You signed up to be notified of any new comments on
|
13
|
+
<%= link_to "this post", @subscription.post %>.
|
17
14
|
</p>
|
18
15
|
<% else %>
|
19
16
|
<p>
|
20
|
-
You
|
17
|
+
You signed up to receive a notification each time a new post is
|
18
|
+
made at
|
19
|
+
<%= link_to root_url.gsub(/\A.*:\/\//, '').gsub(/\A(.*?)\/*\z/, '\1'),
|
20
|
+
posts_url %>.
|
21
21
|
</p>
|
22
|
+
|
23
|
+
<p>Thanks for subscribing!</p>
|
22
24
|
<% end %>
|
23
25
|
</td>
|
24
26
|
</tr>
|
@@ -11,9 +11,14 @@
|
|
11
11
|
</div>
|
12
12
|
<% end %>
|
13
13
|
|
14
|
+
<div class="field">
|
15
|
+
<%= f.label :name %><br>
|
16
|
+
<%= f.text_field :name %>
|
17
|
+
</div>
|
18
|
+
|
14
19
|
<div class="field">
|
15
20
|
<%= f.label :email %><br>
|
16
|
-
<%= f.
|
21
|
+
<%= f.email_field :email %>
|
17
22
|
</div>
|
18
23
|
|
19
24
|
<%
|
@@ -27,6 +32,6 @@
|
|
27
32
|
</div>
|
28
33
|
|
29
34
|
<div class="actions">
|
30
|
-
<%= f.submit
|
35
|
+
<%= f.submit %>
|
31
36
|
</div>
|
32
37
|
<% end %>
|
@@ -0,0 +1,89 @@
|
|
1
|
+
<% proclaim_title "Manage Subscriptions" %>
|
2
|
+
|
3
|
+
<h1><%= content_for :proclaim_title %></h1>
|
4
|
+
|
5
|
+
<%= link_to "New Blog Subscription", new_subscription_path %>
|
6
|
+
|
7
|
+
<%
|
8
|
+
blog_subscriptions = @subscriptions.select {|subscription| subscription.post.nil?}
|
9
|
+
post_subscriptions = @subscriptions - blog_subscriptions
|
10
|
+
|
11
|
+
posts = Hash.new
|
12
|
+
|
13
|
+
post_subscriptions.each do | subscription |
|
14
|
+
post_title = subscription.post.title
|
15
|
+
unless posts.has_key? post_title
|
16
|
+
posts[post_title] = Array.new
|
17
|
+
end
|
18
|
+
|
19
|
+
posts[post_title] << subscription
|
20
|
+
end
|
21
|
+
%>
|
22
|
+
|
23
|
+
<% unless posts.empty? %>
|
24
|
+
<div class = "post_subscriptions">
|
25
|
+
<h2>Post Subscriptions</h2>
|
26
|
+
<% posts.each do | post_title, subscriptions | %>
|
27
|
+
<h4><%= post_title %></h4>
|
28
|
+
<table class = "subscriptions">
|
29
|
+
<thead>
|
30
|
+
<tr>
|
31
|
+
<th>Name</th>
|
32
|
+
<th>Email</th>
|
33
|
+
<th></th>
|
34
|
+
</tr>
|
35
|
+
</thead>
|
36
|
+
<tbody>
|
37
|
+
<% subscriptions.each do | subscription | %>
|
38
|
+
<tr class = "subscription">
|
39
|
+
<td><%= subscription.name %></td>
|
40
|
+
<td><%= subscription.email %></td>
|
41
|
+
<td style = "text-align: right;">
|
42
|
+
<% if policy(subscription).destroy? %>
|
43
|
+
<%= link_to 'Delete',
|
44
|
+
subscription_path(subscription.token),
|
45
|
+
method: :delete,
|
46
|
+
data: { confirm: 'Are you sure?' } %>
|
47
|
+
<% end %>
|
48
|
+
</td>
|
49
|
+
</tr>
|
50
|
+
<% end %>
|
51
|
+
</tbody>
|
52
|
+
</table>
|
53
|
+
<% end %>
|
54
|
+
</div>
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
<% unless blog_subscriptions.empty? %>
|
58
|
+
<div class = "blog_subscriptions">
|
59
|
+
<h2>Blog Subscriptions</h2>
|
60
|
+
<table class = "subscriptions">
|
61
|
+
<thead>
|
62
|
+
<tr>
|
63
|
+
<th>Name</th>
|
64
|
+
<th>Email</th>
|
65
|
+
<th></th>
|
66
|
+
</tr>
|
67
|
+
</thead>
|
68
|
+
<tbody>
|
69
|
+
<% blog_subscriptions.each do | subscription | %>
|
70
|
+
<tr class = "subscription">
|
71
|
+
<td><%= subscription.name %></td>
|
72
|
+
<td><%= subscription.email %></td>
|
73
|
+
<td style = "text-align: right;">
|
74
|
+
<% if policy(subscription).destroy? %>
|
75
|
+
<%= link_to 'Delete', subscription_path(subscription.token), method: :delete, data: { confirm: 'Are you sure?' } %>
|
76
|
+
<% end %>
|
77
|
+
</td>
|
78
|
+
</tr>
|
79
|
+
<% end %>
|
80
|
+
</tbody>
|
81
|
+
</table>
|
82
|
+
</div>
|
83
|
+
<% end %>
|
84
|
+
|
85
|
+
<% if posts.empty? and blog_subscriptions.empty? %>
|
86
|
+
<p style = "margin-top: 10px;">
|
87
|
+
This blog has no current subscribers.
|
88
|
+
</p>
|
89
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<% proclaim_title "Subscription for #{@subscription.name}" %>
|
2
|
+
|
3
|
+
<h1><%= content_for :proclaim_title %></h1>
|
4
|
+
|
5
|
+
<p>
|
6
|
+
<% if @subscription.post %>
|
7
|
+
Will be notified of new comments on
|
8
|
+
<%= link_to @subscription.post.title, @subscription.post %>
|
9
|
+
<% else %>
|
10
|
+
Will be notified of new blog posts.
|
11
|
+
<% end %>
|
12
|
+
</p>
|
13
|
+
<p>
|
14
|
+
<% if policy(@subscription).destroy? %>
|
15
|
+
<%= button_to 'Unsubscribe',
|
16
|
+
subscription_path(@subscription.token),
|
17
|
+
method: :delete,
|
18
|
+
data: {
|
19
|
+
confirm: "Are you sure you'd like to unsubscribe from "\
|
20
|
+
"this notification item? Note that if you've "\
|
21
|
+
"subscribed elsewhere (e.g. other posts), "\
|
22
|
+
"you'll still receive notifications for them "\
|
23
|
+
"unless you unsubscribe from them as well."
|
24
|
+
} %>
|
25
|
+
<% end %>
|
26
|
+
</p>
|
data/config/routes.rb
CHANGED
@@ -7,12 +7,8 @@ Proclaim::Engine.routes.draw do
|
|
7
7
|
|
8
8
|
resources :comments, only: [:create, :update, :destroy]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
get 'subscriptions/subscribed' => 'subscriptions#subscribed', as: :subscribed
|
13
|
-
get 'subscriptions/unsubscribe' => 'subscriptions#unsubscribed', as: :unsubscribed
|
14
|
-
get 'subscriptions/unsubscribe/:token' => 'subscriptions#unsubscribe', as: :unsubscribe
|
15
|
-
delete 'subscriptions/unsubscribe/:token' => 'subscriptions#destroy'
|
10
|
+
# Subscription administration is authenticated via tokens
|
11
|
+
resources :subscriptions, param: :token, except: [:edit, :update]
|
16
12
|
|
17
13
|
root 'posts#index'
|
18
14
|
end
|
@@ -38,4 +38,23 @@ Proclaim.setup do |config|
|
|
38
38
|
|
39
39
|
# Email address to use in the "from" field of all emails
|
40
40
|
#config.mailer_sender = '"My Blog" <blog@example.com>'
|
41
|
+
|
42
|
+
# Secret key to use for subscription tokens. Changing this will invalidate
|
43
|
+
# any tokens already generated.
|
44
|
+
#config.secret_key = nil
|
45
|
+
|
46
|
+
# Register a callback to be called when a post is published
|
47
|
+
#config.after_post_published do |post|
|
48
|
+
# puts "A post was just published!"
|
49
|
+
#end
|
50
|
+
|
51
|
+
# Register a callback to be called when a new comment is created
|
52
|
+
#config.after_new_comment do |comment|
|
53
|
+
# puts "A new comment was just made!"
|
54
|
+
#end
|
55
|
+
|
56
|
+
# Register a callback to be called when a new subscription is created
|
57
|
+
#config.after_new_subscription do |subscription|
|
58
|
+
# puts "A new subscription was just created!"
|
59
|
+
#end
|
41
60
|
end
|
data/lib/proclaim.rb
CHANGED
@@ -35,7 +35,100 @@ module Proclaim
|
|
35
35
|
mattr_accessor :mailer_sender
|
36
36
|
@@mailer_sender = nil
|
37
37
|
|
38
|
+
mattr_accessor :secret_key
|
39
|
+
@@secret_key = nil
|
40
|
+
|
41
|
+
# Callbacks (must be Procs)
|
42
|
+
mattr_accessor :post_published_callbacks
|
43
|
+
@@post_published_callbacks = Array.new
|
44
|
+
private_class_method :post_published_callbacks, :post_published_callbacks=
|
45
|
+
|
46
|
+
mattr_accessor :new_comment_callbacks
|
47
|
+
@@new_comment_callbacks = Array.new
|
48
|
+
private_class_method :new_comment_callbacks, :new_comment_callbacks=
|
49
|
+
|
50
|
+
mattr_accessor :new_subscription_callbacks
|
51
|
+
@@new_subscription_callbacks = Array.new
|
52
|
+
private_class_method :new_subscription_callbacks,
|
53
|
+
:new_subscription_callbacks=
|
54
|
+
|
55
|
+
# Default way to setup Proclaim from initializer
|
38
56
|
def self.setup
|
39
57
|
yield self
|
40
58
|
end
|
59
|
+
|
60
|
+
def self.after_post_published(*callbacks, &block)
|
61
|
+
callbacks.each do |callback|
|
62
|
+
if callback.respond_to? :call
|
63
|
+
@@post_published_callbacks.unshift(callback)
|
64
|
+
else
|
65
|
+
raise "Proclaim does not support callbacks that aren't blocks or "\
|
66
|
+
"Procs"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if block_given?
|
71
|
+
@@post_published_callbacks.unshift(block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.reset_post_published_callbacks
|
76
|
+
@@post_published_callbacks = Array.new
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.after_new_comment(*callbacks, &block)
|
80
|
+
callbacks.each do |callback|
|
81
|
+
if callback.respond_to? :call
|
82
|
+
@@new_comment_callbacks.unshift(callback)
|
83
|
+
else
|
84
|
+
raise "Proclaim does not support callbacks that aren't blocks or "\
|
85
|
+
"Procs"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
if block_given?
|
90
|
+
@@new_comment_callbacks.unshift(block)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.reset_new_comment_callbacks
|
95
|
+
@@new_comment_callbacks = Array.new
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.after_new_subscription(*callbacks, &block)
|
99
|
+
callbacks.each do |callback|
|
100
|
+
if callback.respond_to? :call
|
101
|
+
@@new_subscription_callbacks.unshift(callback)
|
102
|
+
else
|
103
|
+
raise "Proclaim does not support callbacks that aren't blocks or "\
|
104
|
+
"Procs"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
if block_given?
|
109
|
+
@@new_subscription_callbacks.unshift(block)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.reset_new_subscription_callbacks
|
114
|
+
@@new_subscription_callbacks = Array.new
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.notify_post_published(post)
|
118
|
+
@@post_published_callbacks.each do |callback|
|
119
|
+
callback.call(post)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.notify_new_comment(comment)
|
124
|
+
@@new_comment_callbacks.each do |callback|
|
125
|
+
callback.call(comment)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.notify_new_subscription(subscription)
|
130
|
+
@@new_subscription_callbacks.each do |callback|
|
131
|
+
callback.call(subscription)
|
132
|
+
end
|
133
|
+
end
|
41
134
|
end
|