storytime 1.0.7 → 1.1.1

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/storytime/subscriptions.js +0 -2
  3. data/app/assets/javascripts/storytime/subscriptions.js.coffee +2 -0
  4. data/app/assets/stylesheets/storytime/posts.css.scss +5 -4
  5. data/app/assets/stylesheets/storytime/sites.css.scss +0 -4
  6. data/app/assets/stylesheets/storytime/subscriptions.css.scss +0 -0
  7. data/app/controllers/storytime/dashboard/posts_controller.rb +19 -2
  8. data/app/controllers/storytime/dashboard/subscriptions_controller.rb +83 -0
  9. data/app/controllers/storytime/posts_controller.rb +25 -0
  10. data/app/controllers/storytime/subscriptions_controller.rb +21 -5
  11. data/app/helpers/storytime/dashboard/media_helper.rb +1 -5
  12. data/app/helpers/storytime/subscriptions_helper.rb +16 -0
  13. data/app/mailers/storytime/subscription_mailer.rb +13 -0
  14. data/app/models/storytime/action.rb +1 -0
  15. data/app/models/storytime/permission.rb +12 -9
  16. data/app/models/storytime/post.rb +3 -3
  17. data/app/models/storytime/site.rb +15 -0
  18. data/app/models/storytime/subscription.rb +24 -0
  19. data/app/policies/storytime/post_policy.rb +1 -1
  20. data/app/policies/storytime/subscription_policy.rb +43 -0
  21. data/app/views/storytime/application/storytime/_header.html.erb +5 -1
  22. data/app/views/storytime/dashboard/_navigation.html.erb +2 -0
  23. data/app/views/storytime/dashboard/posts/_form.html.erb +6 -0
  24. data/app/views/storytime/dashboard/subscriptions/_subscription.html.erb +10 -0
  25. data/app/views/storytime/dashboard/subscriptions/edit.html.erb +10 -0
  26. data/app/views/storytime/dashboard/subscriptions/index.html.erb +19 -0
  27. data/app/views/storytime/dashboard/subscriptions/new.html.erb +9 -0
  28. data/app/views/storytime/subscription_mailer/new_post_email.html.erb +3 -2
  29. data/app/views/storytime/subscription_mailer/new_post_email.text.erb +7 -0
  30. data/app/views/storytime/subscriptions/_form.html.erb +5 -0
  31. data/app/views/storytime/subscriptions/_modal.html.erb +16 -0
  32. data/config/locales/en.yml +13 -1
  33. data/config/routes.rb +6 -15
  34. data/db/migrate/20141111164439_create_storytime_subscriptions.rb +14 -0
  35. data/db/migrate/20150122200805_add_title_and_content_index_to_storytime_post.rb +56 -0
  36. data/db/migrate/20150129215308_add_site_id_to_storytime_subscription.rb +5 -0
  37. data/lib/generators/templates/storytime.rb +9 -0
  38. data/lib/storytime/concerns/has_versions.rb +0 -1
  39. data/lib/storytime/engine.rb +2 -0
  40. data/lib/storytime/mysql_fulltext_search_adapter.rb +7 -0
  41. data/lib/storytime/mysql_search_adapter.rb +7 -0
  42. data/lib/storytime/postgres_search_adapter.rb +9 -0
  43. data/lib/storytime/sqlite3_search_adapter.rb +7 -0
  44. data/lib/storytime/version.rb +1 -1
  45. data/lib/storytime.rb +43 -0
  46. data/spec/controllers/subscriptions_controller_spec.rb +0 -0
  47. data/spec/dummy/config/environments/development.rb +8 -0
  48. data/spec/dummy/config/initializers/storytime.rb +37 -2
  49. data/spec/dummy/db/development.sqlite3 +0 -0
  50. data/spec/dummy/db/migrate/20150130213631_create_storytime_posts.storytime.rb +18 -0
  51. data/spec/dummy/db/migrate/20150130213632_create_friendly_id_slugs.storytime.rb +16 -0
  52. data/spec/dummy/db/migrate/20150130213633_create_storytime_media.storytime.rb +11 -0
  53. data/spec/dummy/db/migrate/20150130213634_create_storytime_sites.storytime.rb +14 -0
  54. data/spec/dummy/db/migrate/20150130213635_create_storytime_tags.storytime.rb +10 -0
  55. data/spec/dummy/db/migrate/20150130213636_create_storytime_taggings.storytime.rb +11 -0
  56. data/spec/dummy/db/migrate/20150130213637_create_storytime_versions.storytime.rb +13 -0
  57. data/spec/dummy/db/migrate/20150130213638_create_storytime_roles.storytime.rb +10 -0
  58. data/spec/dummy/db/migrate/20150130213639_add_storytime_role_id_to_users.storytime.rb +7 -0
  59. data/spec/dummy/db/migrate/20150130213640_create_storytime_permissions.storytime.rb +11 -0
  60. data/spec/dummy/db/migrate/20150130213641_create_storytime_actions.storytime.rb +11 -0
  61. data/spec/dummy/db/migrate/20150130213642_create_storytime_comments.storytime.rb +12 -0
  62. data/spec/dummy/db/migrate/20150130213643_add_storytime_name_to_users.storytime.rb +6 -0
  63. data/spec/dummy/db/migrate/20150130213644_create_storytime_autosaves.storytime.rb +13 -0
  64. data/spec/dummy/db/migrate/20150130213645_add_secondary_media_id_to_storytime_post.storytime.rb +6 -0
  65. data/spec/dummy/db/migrate/20150130213646_create_storytime_snippets.storytime.rb +22 -0
  66. data/spec/dummy/db/migrate/20150130213647_create_storytime_subscriptions.storytime.rb +15 -0
  67. data/spec/dummy/db/migrate/20150130213648_add_title_and_content_index_to_storytime_post.storytime.rb +57 -0
  68. data/spec/dummy/db/migrate/20150130213649_add_site_id_to_storytime_subscription.storytime.rb +6 -0
  69. data/spec/dummy/db/schema.rb +10 -2
  70. data/spec/dummy/db/test.sqlite3 +0 -0
  71. data/spec/factories/subscription_factories.rb +5 -5
  72. data/spec/features/dashboard/posts_spec.rb +0 -1
  73. data/spec/features/dashboard/subscription_spec.rb +37 -48
  74. data/spec/features/posts_spec.rb +2 -2
  75. data/spec/features/subscription_spec.rb +45 -15
  76. data/spec/lib/mysql_fulltext_search_adapter_spec.rb +31 -0
  77. data/spec/lib/mysql_search_adapter_spec.rb +31 -0
  78. data/spec/lib/postgres_search_adapter_spec.rb +31 -0
  79. data/spec/lib/sqlite3_search_adapter_spec.rb +31 -0
  80. data/spec/models/subscription_spec.rb +27 -27
  81. data/spec/requests/routings_spec.rb +2 -0
  82. metadata +71 -4
  83. data/app/views/storytime/subscription_mailer/new_post_email.txt.erb +0 -1
  84. data/lib/storytime/subscription_emails.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91d49457b192f13b7c8bcd673c56032d66391651
4
- data.tar.gz: 0d86828ad2e793852463fa1ac999cb1aa0000d65
3
+ metadata.gz: 06f4a653cab5a07931cdc7c80d0892bd5a7daa12
4
+ data.tar.gz: 3fb261085ce26f70bf249ce1724a3005afa3c6f7
5
5
  SHA512:
6
- metadata.gz: 2126e2e0e4b39b13e779683e21974382c9d8084791f8a4c6f0771739ab034405bada3235ab3856bd63ec96b141ad0e0e70767fc22b08ca07a0683e1267bde95a
7
- data.tar.gz: 75a7c2fb54395a4e660d0a862b9dd29209bd862765108b5101c7502d4906a72e2a6faa3c0cf31884846354a265300775dab7c54a46e2c1696e70208ac3198b2a
6
+ metadata.gz: 3d35eeeb18f0d289a16f3a7b312d2e76f17220dfd57b0c6077cea8de1012dc9a0227cdac33c8a05a444e5d819cd5b03e70b8e79138d8e14490ca959314cfe4e0
7
+ data.tar.gz: 5b5621d9c72c07e3ede66912eefc1c06a629ffca917075915e153bdf0e4a7f7aee85d14c262f8670654c520aea03fec3c435544f79384e06c724c540d3eb47a7
@@ -1,2 +0,0 @@
1
- // Place all the behaviors and hooks related to the matching controller here.
2
- // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ class Storytime.Dashboard.Subscriptions
2
+
@@ -1,7 +1,3 @@
1
- /*
2
- Place all the styles related to the matching controller here.
3
- They will automatically be included in application.css.
4
- */
5
1
  .row.page-admin {
6
2
  padding: 10px;
7
3
  &:hover {
@@ -26,4 +22,9 @@
26
22
 
27
23
  .post_field {
28
24
  margin: 15px 0px;
25
+ }
26
+
27
+ .notify_subscribers_checkbox {
28
+ margin-right: 30px;
29
+ margin-top: -3px;
29
30
  }
@@ -1,4 +0,0 @@
1
- /*
2
- Place all the styles related to the matching controller here.
3
- They will automatically be included in application.css.
4
- */
@@ -38,7 +38,9 @@ module Storytime
38
38
 
39
39
  if @post.save
40
40
  @post.create_autosave(post_params.slice(:draft_content)) if params[:preview] == "true"
41
-
41
+
42
+ publish if post_params['published'] == "1"
43
+
42
44
  opts = params[:preview] == "true" ? { preview: true } : {}
43
45
 
44
46
  redirect_to edit_dashboard_post_path(@post, opts), notice: I18n.t('flash.posts.create.success')
@@ -51,9 +53,12 @@ module Storytime
51
53
  def update
52
54
  authorize @post
53
55
  @post.draft_user_id = current_user.id
54
-
56
+
55
57
  if @post.update(post_params)
56
58
  @post.autosave.destroy unless @post.autosave.nil?
59
+
60
+ publish if post_params['published'] == "1"
61
+
57
62
  redirect_to [:edit, :dashboard, @post], notice: I18n.t('flash.posts.update.success')
58
63
  else
59
64
  load_media
@@ -96,6 +101,18 @@ module Storytime
96
101
  params.require(:post).permit(*permitted_attrs)
97
102
  end
98
103
 
104
+ def publish
105
+ unless @post.published?
106
+ @post.publish!
107
+
108
+ if post_params[:send_subscriber_email] == "1"
109
+ @site.active_email_subscriptions.each do |subscription|
110
+ Storytime::SubscriptionMailer.new_post_email(@post, subscription).deliver
111
+ end
112
+ end
113
+ end
114
+ end
115
+
99
116
  def current_post_type
100
117
  @current_post_type ||= begin
101
118
  type_param = params[:type] || (params[:post] && params[:post].delete(:type))
@@ -0,0 +1,83 @@
1
+ require_dependency "storytime/application_controller"
2
+
3
+ module Storytime
4
+ module Dashboard
5
+ class SubscriptionsController < DashboardController
6
+ skip_before_action :authenticate_user!, only: [:unsubscribe]
7
+ skip_before_action :verify_storytime_user, only: [:unsubscribe]
8
+
9
+ before_action :load_subscriptions, only: [:index]
10
+ before_action :set_subscription, only: [:edit, :update, :destroy]
11
+
12
+ skip_after_action :verify_authorized, only: [:unsubscribe]
13
+
14
+ respond_to :json, only: :destroy
15
+
16
+ def index
17
+ authorize @subscriptions
18
+ end
19
+
20
+ def new
21
+ @subscription = Storytime::Subscription.new
22
+ authorize @subscription
23
+ end
24
+
25
+ def create
26
+ @subscription = Storytime::Subscription.new(subscription_params)
27
+ authorize @subscription
28
+
29
+ if @subscription.save
30
+ redirect_to dashboard_subscriptions_path, notice: I18n.t('flash.subscriptions.create.success')
31
+ else
32
+ render :new
33
+ end
34
+ end
35
+
36
+ def edit
37
+ authorize @subscription
38
+ end
39
+
40
+ def update
41
+ authorize @subscription
42
+
43
+ if @subscription.update(subscription_params)
44
+ redirect_to dashboard_subscriptions_path, notice: I18n.t('flash.subscriptions.update.success')
45
+ else
46
+ render :edit
47
+ end
48
+ end
49
+
50
+ def destroy
51
+ authorize @subscription
52
+ @subscription.destroy
53
+ respond_with @subscription
54
+ end
55
+
56
+ def unsubscribe
57
+ @subscription = Storytime::Subscription.find_by(token: params[:t])
58
+
59
+ if @subscription.nil?
60
+ redirect_to main_app.storytime_path, alert: I18n.t('flash.subscriptions.unsubscribe.not_found')
61
+ else
62
+ @subscription.update_attributes(subscribed: false)
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def subscription_params
69
+ subscription = @subscription || Storytime::Subscription.new
70
+ permitted_attrs = policy(subscription).permitted_attributes
71
+ params.require(:subscription).permit(*permitted_attrs)
72
+ end
73
+
74
+ def set_subscription
75
+ @subscription = Storytime::Subscription.find(params[:id])
76
+ end
77
+
78
+ def load_subscriptions
79
+ @subscriptions = Storytime::Subscription.order(created_at: :desc).page(params[:page_number]).per(10)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -12,6 +12,8 @@ module Storytime
12
12
  Post.primary_feed
13
13
  end
14
14
 
15
+ @posts = Storytime.search_adapter.search(params[:search], get_search_type) if (params[:search] && params[:search].length > 0)
16
+
15
17
  @posts = @posts.tagged_with(params[:tag]) if params[:tag]
16
18
  @posts = @posts.published.order(published_at: :desc).page(params[:page])
17
19
 
@@ -48,5 +50,28 @@ module Storytime
48
50
  end
49
51
  end
50
52
 
53
+ private
54
+
55
+ def get_search_type
56
+ if params[:type]
57
+ legal_search_types(params[:type])
58
+ else
59
+ Storytime::Post
60
+ end
61
+ end
62
+
63
+ def legal_search_types(type)
64
+ begin
65
+ if Object.const_defined?("Storytime::#{type.camelize}")
66
+ "Storytime::#{type.camelize}".constantize
67
+ elsif Object.const_defined?("#{type.camelize}")
68
+ type.camelize.constantize
69
+ else
70
+ Storytime::Post
71
+ end
72
+ rescue NameError
73
+ Storytime::Post
74
+ end
75
+ end
51
76
  end
52
77
  end
@@ -4,19 +4,35 @@ module Storytime
4
4
  class SubscriptionsController < ApplicationController
5
5
  before_action :set_subscription, only: [:destroy]
6
6
 
7
- def index
8
- @subscriptions = Storytime::Subscription.all
9
- render json: {subscriptions: @subscriptions}
7
+ def create
8
+ @subscription = Storytime::Subscription.new(permitted_attributes)
9
+
10
+ if @subscription.save
11
+ flash[:notice] = I18n.t('flash.subscriptions.create.success')
12
+ else
13
+ flash[:error] = I18n.t('flash.subscriptions.create.fail')
14
+ end
15
+
16
+ redirect_to :back
10
17
  end
11
18
 
12
19
  def destroy
13
-
20
+ if params[:t] == @subscription.token
21
+ flash[:notice] = I18n.t('flash.subscriptions.destroy.success') if @subscription.unsubscribe!
22
+ else
23
+ flash[:error] = I18n.t('flash.subscriptions.destroy.fail')
24
+ end
25
+
26
+ redirect_to Storytime.home_page_path
14
27
  end
15
28
 
16
29
  private
17
30
 
31
+ def permitted_attributes
32
+ params.require(:subscription).permit(:email, :t, :site_id)
33
+ end
34
+
18
35
  def set_subscription
19
- binding.pry
20
36
  @subscription = Storytime::Subscription.find_by(email: params[:email])
21
37
  end
22
38
  end
@@ -24,11 +24,7 @@ module Storytime
24
24
  end
25
25
 
26
26
  def full_media_file_url(media, size = nil)
27
- if media.file_url.starts_with?("http")
28
- media.file_url(size)
29
- else
30
- storytime_root_post_url[0..-2]+media.file_url(size)
31
- end
27
+ media.file_url(size)
32
28
  end
33
29
  end
34
30
  end
@@ -0,0 +1,16 @@
1
+ module Storytime
2
+ module SubscriptionsHelper
3
+ def subscription_label(subscription)
4
+ status_label = subscription.subscribed ? "label-info" : "label-warning"
5
+ status = subscription.subscribed ? "Subscribed" : "Unsubscribed"
6
+
7
+ "<label class='label #{status_label}'>#{status}</label>".html_safe
8
+ end
9
+
10
+ def storytime_email_subscription_form(site=Storytime::Site.last)
11
+ @storytime_site = site
12
+
13
+ render "storytime/subscriptions/form"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Storytime
2
+ class SubscriptionMailer < ActionMailer::Base
3
+ default from: Storytime.subscription_email_from
4
+
5
+ def new_post_email(post, subscription)
6
+ @post = post
7
+ @subscription = subscription
8
+ @site = subscription.site
9
+
10
+ mail(to: @subscription.email, subject: "New Post from #{@site.title}")
11
+ end
12
+ end
13
+ end
@@ -12,6 +12,7 @@ module Storytime
12
12
  find_by(guid: "47342a") || create(guid: "47342a", name: "Manage Site Settings")
13
13
  find_by(guid: "1f7d47") || create(guid: "1f7d47", name: "Manage Users")
14
14
  find_by(guid: "5qg25i") || create(guid: "5qg25i", name: "Manage Text Snippets")
15
+ find_by(guid: "d29d76") || create(guid: "d29d76", name: "Manage Email Subscriptions")
15
16
  end
16
17
  end
17
18
  end
@@ -13,19 +13,22 @@ module Storytime
13
13
  manage_site = Action.find_by(guid: "47342a")
14
14
  manage_users = Action.find_by(guid: "1f7d47")
15
15
  manage_snippets = Action.find_by(guid: "5qg25i")
16
+ manage_subscriptions = Action.find_by(guid: "d29d76")
16
17
 
17
- create(role: writer, action: publish_own)
18
- create(role: editor, action: publish_own)
19
- create(role: admin, action: publish_own)
18
+ find_or_create_by(role: writer, action: publish_own)
19
+ find_or_create_by(role: editor, action: publish_own)
20
+ find_or_create_by(role: admin, action: publish_own)
20
21
 
21
- create(role: editor, action: manage_others)
22
- create(role: admin, action: manage_others)
22
+ find_or_create_by(role: editor, action: manage_others)
23
+ find_or_create_by(role: admin, action: manage_others)
23
24
 
24
- create(role: admin, action: manage_site)
25
- create(role: admin, action: manage_users)
25
+ find_or_create_by(role: admin, action: manage_site)
26
+ find_or_create_by(role: admin, action: manage_users)
26
27
 
27
- create(role: editor, action: manage_snippets)
28
- create(role: admin, action: manage_snippets)
28
+ find_or_create_by(role: editor, action: manage_snippets)
29
+ find_or_create_by(role: admin, action: manage_snippets)
30
+
31
+ find_or_create_by(role: admin, action: manage_subscriptions)
29
32
  end
30
33
  end
31
34
  end
@@ -16,7 +16,7 @@ module Storytime
16
16
 
17
17
  has_one :autosave, as: :autosavable, dependent: :destroy, class_name: "Autosave"
18
18
 
19
- attr_accessor :preview, :published_at_date, :published_at_time
19
+ attr_accessor :preview, :published_at_date, :published_at_time, :send_subscriber_email
20
20
 
21
21
  validates_presence_of :title, :draft_content
22
22
  validates :title, length: { in: 1..Storytime.post_title_character_limit }
@@ -118,11 +118,11 @@ module Storytime
118
118
  end
119
119
 
120
120
  def slug_candidates
121
- if slug.nil? then [:title] elsif slug_changed? then [:slug] end
121
+ if slug.blank? then [:title] elsif slug_changed? then [:slug] end
122
122
  end
123
123
 
124
124
  def should_generate_new_friendly_id?
125
- self.slug = nil if slug == ""
125
+ slug = nil if slug == ""
126
126
  slug_changed? || (slug.nil? && published_at_changed? && published_at_change.first.nil?)
127
127
  end
128
128
 
@@ -5,9 +5,20 @@ module Storytime
5
5
  enum post_slug_style: [:default, :day_and_name, :month_and_name, :post_id]
6
6
  enum root_page_content: [:posts, :page]
7
7
 
8
+ has_many :subscriptions, dependent: :destroy
9
+
8
10
  validates :root_post_id, presence: true, if: ->(site){ site.root_page_content == "page" }
9
11
  validates :title, length: { in: 1..200 }
10
12
 
13
+ after_create :ensure_routes_updated
14
+ after_update :ensure_routes_updated
15
+
16
+ def ensure_routes_updated
17
+ if id_changed? || root_post_id_changed? || post_slug_style_changed? || root_page_content_changed?
18
+ Rails.application.reload_routes!
19
+ end
20
+ end
21
+
11
22
  def save_with_seeds(user)
12
23
  self.class.setup_seeds
13
24
  user.update_attributes(storytime_role: Storytime::Role.find_by(name: "admin"))
@@ -23,5 +34,9 @@ module Storytime
23
34
  def root_post_options
24
35
  Storytime::Page.published
25
36
  end
37
+
38
+ def active_email_subscriptions
39
+ subscriptions.active
40
+ end
26
41
  end
27
42
  end
@@ -0,0 +1,24 @@
1
+ module Storytime
2
+ class Subscription < ActiveRecord::Base
3
+ belongs_to :site
4
+
5
+ scope :active, -> { where(subscribed: true) }
6
+
7
+ validates_presence_of :email
8
+ validates_format_of :email, with: Storytime.email_regexp
9
+ validates :email, uniqueness: true
10
+
11
+ before_create :generate_token
12
+
13
+ def generate_token
14
+ key = Rails.application.secrets.secret_key_base
15
+ digest = OpenSSL::Digest.new('sha1')
16
+
17
+ self.token = OpenSSL::HMAC.hexdigest(digest, key, self.email)
18
+ end
19
+
20
+ def unsubscribe!
21
+ update_attributes(subscribed: false)
22
+ end
23
+ end
24
+ end
@@ -79,7 +79,7 @@ module Storytime
79
79
  end
80
80
 
81
81
  def permitted_attributes
82
- attrs = [:title, :draft_content, :draft_version_id, :excerpt, :featured_media_id, :secondary_media_id, :slug, :published_at_date, :published_at_time, {:tag_list => []}]
82
+ attrs = [:title, :draft_content, :draft_version_id, :excerpt, :featured_media_id, :secondary_media_id, :slug, :published_at_date, :send_subscriber_email, :published_at_time, {:tag_list => []}]
83
83
  attrs << :published if publish?
84
84
  attrs
85
85
  end
@@ -0,0 +1,43 @@
1
+ module Storytime
2
+ class SubscriptionPolicy
3
+ attr_reader :user, :record
4
+
5
+ def initialize(user, record)
6
+ @user = user
7
+ @post = record
8
+ end
9
+
10
+ def index?
11
+ manage?
12
+ end
13
+
14
+ def new?
15
+ manage?
16
+ end
17
+
18
+ def create?
19
+ manage?
20
+ end
21
+
22
+ def edit?
23
+ manage?
24
+ end
25
+
26
+ def update?
27
+ manage?
28
+ end
29
+
30
+ def destroy?
31
+ manage?
32
+ end
33
+
34
+ def manage?
35
+ action = Storytime::Action.find_by(guid: "d29d76")
36
+ user.storytime_role.allowed_actions.include?(action)
37
+ end
38
+
39
+ def permitted_attributes
40
+ [:email, :subscribed, :site_id]
41
+ end
42
+ end
43
+ end
@@ -18,6 +18,9 @@
18
18
  <li><%= link_to "Blog", storytime.url_for(Storytime::BlogPost.type_name.pluralize) %></li>
19
19
  </ul>
20
20
  <ul class="nav navbar-nav navbar-right">
21
+ <li>
22
+ <%= link_to "#{t 'layout.subscribe_to', site_name: @site.title}", "#", data: {target: "#addSubscriptionModal", toggle: "modal"} %>
23
+ </li>
21
24
  <% unless user_signed_in? %>
22
25
  <li><%= link_to "Sign In", main_app.new_user_session_path %></li>
23
26
  <% end %>
@@ -25,4 +28,5 @@
25
28
  </div>
26
29
  </div>
27
30
  </div>
28
- </header>
31
+ </header>
32
+ <%= render partial: "storytime/subscriptions/modal" %>
@@ -26,6 +26,8 @@
26
26
  <li <%= active_nav_item_class("media") %>><%= link_to "Media", storytime.url_for([:dashboard, Storytime::Media]) %></li>
27
27
  <% end %>
28
28
 
29
+ <li <%= active_nav_item_class("Subscriptions") %>><%= link_to "Subscriptions", dashboard_subscriptions_path %></li>
30
+
29
31
  <% if Pundit.policy(current_user, Storytime.user_class).index? %>
30
32
  <li <%= active_nav_item_class("users") %>><%= link_to "Users", storytime.url_for([:dashboard, :users]) %></li>
31
33
  <% end %>
@@ -143,6 +143,12 @@
143
143
  <%= f.submit "Publish", class: "btn btn-primary publish", publish: true unless @post.published? %>
144
144
  <%= f.submit "Update", class: "btn btn-default save" if @post.published? %>
145
145
  </div>
146
+
147
+
148
+ <div class="notify_subscribers_checkbox pull-right">
149
+ <%= f.input :send_subscriber_email, as: :boolean, label: "Notify subscribers of new post" unless @post.published? %>
150
+ </div>
151
+
146
152
  </div>
147
153
  <% end %>
148
154
 
@@ -0,0 +1,10 @@
1
+ <tr id="subscription_<%= subscription.id %>">
2
+ <td><%= subscription.email %></td>
3
+ <td><%= subscription_label(subscription) %></td>
4
+ <td class="right">
5
+ <div class="btn-group">
6
+ <%= link_to "Edit", edit_polymorphic_url([:dashboard, subscription]), class: "btn btn-xs btn-default" %>
7
+ <%= delete_resource_link subscription, polymorphic_url([:dashboard, subscription]) %>
8
+ </div>
9
+ </td>
10
+ </tr>
@@ -0,0 +1,10 @@
1
+ <div class="container">
2
+ <h2>Edit Subscription</h2>
3
+
4
+ <%= simple_form_for [:dashboard, @subscription] do |f| %>
5
+ <%= f.input :site_id, as: :hidden, input_html: { value: @site.id } %>
6
+ <%= f.input :email %>
7
+ <%= f.input :subscribed, as: :boolean %>
8
+ <%= f.submit class: "btn btn-info" %>
9
+ <% end %>
10
+ </div>
@@ -0,0 +1,19 @@
1
+ <div class="container">
2
+ <h2>
3
+ Subscriptions
4
+ <%= link_to "New Subscription", new_dashboard_subscription_path, class: "btn btn-default pull-right" %>
5
+ </h2>
6
+
7
+ <table class="table">
8
+ <thead>
9
+ <tr>
10
+ <th>Email</th>
11
+ <th>Subscription Status</th>
12
+ <th class="right">Actions</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <%= render partial: 'subscription', collection: @subscriptions %>
17
+ </tbody>
18
+ </table>
19
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="container">
2
+ <h2>New Subscription</h2>
3
+
4
+ <%= simple_form_for [:dashboard, @subscription] do |f| %>
5
+ <%= f.input :site_id, as: :hidden, input_html: { value: @site.id } %>
6
+ <%= f.input :email %>
7
+ <%= f.submit class: "btn btn-info" %>
8
+ <% end %>
9
+ </div>
@@ -4,9 +4,10 @@
4
4
  <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
5
  </head>
6
6
  <body>
7
- <h1>There is some new post...</h1>
7
+ <h4>A new post was published on <%= @site.title %></h4>
8
8
  <p>
9
- Yay, that's so awesome... Check it out here?
9
+ We published a new post, "<%= link_to @post.title, post_url(@post) %>", on our blog.
10
10
  </p>
11
11
  </body>
12
+ <footer>If you no longer want to receive these emails, <%= link_to "click here", unsubscribe_mailing_list_url(email: @subscription.email, t: @subscription.token) %>.</footer>
12
13
  </html>
@@ -0,0 +1,7 @@
1
+ A new post was published on <%= @site.title %>
2
+
3
+ We published a new post, "<%= link_to @post.title, post_url(@post) %>", on our blog.
4
+
5
+ ----------
6
+
7
+ If you no longer want to receive these emails, go to <%= unsubscribe_mailing_list_url(email: @subscription.email, t: @subscription.token) %>.
@@ -0,0 +1,5 @@
1
+ <%= simple_form_for Storytime::Subscription.new do |f| %>
2
+ <%= f.input :site_id, as: :hidden, input_html: { value: @storytime_site.id } %>
3
+ <div class="storytime-subscription-input"><%= f.input :email %></div>
4
+ <div class="storytime-subscription-submit"><%= f.submit %></div>
5
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <div id="addSubscriptionModal" class='modal fade'>
2
+ <div class='modal-dialog'>
3
+ <div class='modal-content'>
4
+ <div class='modal-header'>
5
+ <a class='close' data-dismiss='modal'>&times;</a>
6
+ <h4><%= t 'layout.subscribe_to', site_name: @site.title %></h4>
7
+ </div>
8
+ <div class='modal-body'>
9
+ <p><%= t 'layout.subscribe_modal_msg', site_name: @site.title %></p>
10
+
11
+ <br>
12
+ <%= storytime_email_subscription_form %>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </div>
@@ -27,6 +27,17 @@ en:
27
27
  success: "Text snippet successfully updated."
28
28
  destroy:
29
29
  success: "Text snippet successfully deleted."
30
+ subscriptions:
31
+ create:
32
+ success: "Subscription successfully created."
33
+ fail: "Could not create a subscription."
34
+ update:
35
+ success: "Subscription successfully updated."
36
+ destroy:
37
+ success: >
38
+ You have been successfully removed form this subscriber list.
39
+ You will no longer hear from us.
40
+ fail: "Could not unsubscribe email."
30
41
  users:
31
42
  create:
32
43
  success: "User successfully created."
@@ -87,6 +98,7 @@ en:
87
98
  new:
88
99
  header: "New %{resource}"
89
100
 
90
-
91
101
  layout:
92
102
  title: "Storytime"
103
+ subscribe_to: "Subscribe to %{site_name}"
104
+ subscribe_modal_msg: "Stay up-to-date with %{site_name} by signing up for our mailing list!"