newsletter 0.0.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 (144) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +20 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +26 -0
  6. data/Gemfile.lock +199 -0
  7. data/Guardfile +24 -0
  8. data/LICENSE +22 -0
  9. data/MIT-LICENSE +20 -0
  10. data/Manifest.txt +220 -0
  11. data/Procfile +2 -0
  12. data/README +243 -0
  13. data/README.rdoc +3 -0
  14. data/Rakefile +29 -0
  15. data/app/assets/images/newsletter/.gitkeep +0 -0
  16. data/app/assets/javascripts/newsletter/application.js +15 -0
  17. data/app/assets/stylesheets/newsletter/application.css +13 -0
  18. data/app/controllers/newsletter/application_controller.rb +27 -0
  19. data/app/controllers/newsletter/areas_controller.rb +63 -0
  20. data/app/controllers/newsletter/designs_controller.rb +51 -0
  21. data/app/controllers/newsletter/elements_controller.rb +75 -0
  22. data/app/controllers/newsletter/fields_controller.rb +49 -0
  23. data/app/controllers/newsletter/newsletters_controller.rb +104 -0
  24. data/app/controllers/newsletter/pieces_controller.rb +72 -0
  25. data/app/helpers/newsletter/application_helper.rb +4 -0
  26. data/app/helpers/newsletter/areas_helper.rb +4 -0
  27. data/app/helpers/newsletter/assets_helper.rb +4 -0
  28. data/app/helpers/newsletter/designs_helper.rb +11 -0
  29. data/app/helpers/newsletter/elements_helper.rb +4 -0
  30. data/app/helpers/newsletter/field_values_helper.rb +4 -0
  31. data/app/helpers/newsletter/fields_helper.rb +4 -0
  32. data/app/helpers/newsletter/newsletters_helper.rb +43 -0
  33. data/app/helpers/newsletter/pieces_helper.rb +4 -0
  34. data/app/models/newsletter/area.rb +50 -0
  35. data/app/models/newsletter/asset.rb +31 -0
  36. data/app/models/newsletter/design.rb +160 -0
  37. data/app/models/newsletter/element.rb +169 -0
  38. data/app/models/newsletter/field/inline_asset.rb +67 -0
  39. data/app/models/newsletter/field/text.rb +15 -0
  40. data/app/models/newsletter/field/text_area.rb +15 -0
  41. data/app/models/newsletter/field.rb +115 -0
  42. data/app/models/newsletter/field_value.rb +20 -0
  43. data/app/models/newsletter/newsletter.rb +125 -0
  44. data/app/models/newsletter/piece.rb +96 -0
  45. data/app/models/newsletter.rb +11 -0
  46. data/app/uploaders/newsletter/asset_uploader.rb +51 -0
  47. data/app/views/layouts/newsletter/application.html.erb +135 -0
  48. data/app/views/newsletter/areas/_area.html.erb +49 -0
  49. data/app/views/newsletter/designs/_area_fields.html.erb +4 -0
  50. data/app/views/newsletter/designs/_form.html.erb +41 -0
  51. data/app/views/newsletter/designs/_newsletter_area.html.erb +17 -0
  52. data/app/views/newsletter/designs/edit.html.erb +14 -0
  53. data/app/views/newsletter/designs/index.html.erb +31 -0
  54. data/app/views/newsletter/designs/new.html.erb +9 -0
  55. data/app/views/newsletter/designs/show.html.erb +22 -0
  56. data/app/views/newsletter/elements/_field_fields.html.erb +27 -0
  57. data/app/views/newsletter/elements/_form.html.erb +51 -0
  58. data/app/views/newsletter/elements/_newsletter_field.html.erb +37 -0
  59. data/app/views/newsletter/elements/edit.html.erb +12 -0
  60. data/app/views/newsletter/elements/index.html.erb +32 -0
  61. data/app/views/newsletter/elements/new.html.erb +9 -0
  62. data/app/views/newsletter/elements/show.html.erb +22 -0
  63. data/app/views/newsletter/fields/_form.html.erb +15 -0
  64. data/app/views/newsletter/fields/_inline_asset.html.erb +36 -0
  65. data/app/views/newsletter/fields/_text.html.erb +4 -0
  66. data/app/views/newsletter/fields/_text_area.html.erb +7 -0
  67. data/app/views/newsletter/newsletters/_form.html.erb +21 -0
  68. data/app/views/newsletter/newsletters/_head.html.erb +48 -0
  69. data/app/views/newsletter/newsletters/_newsletter.html.erb +6 -0
  70. data/app/views/newsletter/newsletters/_newsletter_area.html.erb +30 -0
  71. data/app/views/newsletter/newsletters/archive.html.erb +9 -0
  72. data/app/views/newsletter/newsletters/edit.html.erb +37 -0
  73. data/app/views/newsletter/newsletters/index.html.erb +29 -0
  74. data/app/views/newsletter/newsletters/new.html.erb +9 -0
  75. data/app/views/newsletter/newsletters/show.html.erb +6 -0
  76. data/app/views/newsletter/pieces/_form.html.erb +19 -0
  77. data/app/views/newsletter/pieces/edit.html.erb +11 -0
  78. data/app/views/newsletter/pieces/new.html.erb +10 -0
  79. data/app/views/newsletter/pieces/show.html.erb +2 -0
  80. data/assets/docs/index.html +45 -0
  81. data/assets/docs/newsletter_templates/index.html +45 -0
  82. data/config/routes.rb +33 -0
  83. data/db/migrate/001_newsletter_initial.rb +104 -0
  84. data/db/migrate/002_carrier_wave_for_assets.rb +9 -0
  85. data/db/pre-scoped/002_newsletter_scoped.rb +61 -0
  86. data/doc/README_FOR_APP +2 -0
  87. data/doc/newsletter.wiki.txt +130 -0
  88. data/doc/start_rails_engine_with_rspec.txt +43 -0
  89. data/engine_plan.rb +13 -0
  90. data/features/step_definitions/webrat_steps.rb +115 -0
  91. data/features/support/env.rb +17 -0
  92. data/features/support/paths.rb +27 -0
  93. data/lib/deleteable.rb +50 -0
  94. data/lib/newsletter/config.rb +50 -0
  95. data/lib/newsletter/engine.rb +62 -0
  96. data/lib/newsletter/settings.rb +50 -0
  97. data/lib/newsletter/version.rb +3 -0
  98. data/lib/newsletter.rb +7 -0
  99. data/lib/tasks/newsletter.rake +84 -0
  100. data/lib/tasks/newsletter_tasks.rake +4 -0
  101. data/lib/tasks/rspec.rake +158 -0
  102. data/newsletter.gemspec +30 -0
  103. data/newsletters/exports/example-export.yaml +213 -0
  104. data/script/rails +8 -0
  105. data/spec/rcov.opts +2 -0
  106. data/spec/spec.opts +4 -0
  107. data/spec/spec_helper.rb +41 -0
  108. data/spec/test_app/README.rdoc +261 -0
  109. data/spec/test_app/Rakefile +7 -0
  110. data/spec/test_app/app/assets/javascripts/application.js +15 -0
  111. data/spec/test_app/app/assets/stylesheets/application.css +13 -0
  112. data/spec/test_app/app/controllers/application_controller.rb +3 -0
  113. data/spec/test_app/app/helpers/application_helper.rb +2 -0
  114. data/spec/test_app/app/mailers/.gitkeep +0 -0
  115. data/spec/test_app/app/models/.gitkeep +0 -0
  116. data/spec/test_app/app/views/layouts/application.html.erb +14 -0
  117. data/spec/test_app/config/application.rb +65 -0
  118. data/spec/test_app/config/boot.rb +10 -0
  119. data/spec/test_app/config/database.yml +25 -0
  120. data/spec/test_app/config/environment.rb +5 -0
  121. data/spec/test_app/config/environments/development.rb +37 -0
  122. data/spec/test_app/config/environments/production.rb +67 -0
  123. data/spec/test_app/config/environments/test.rb +37 -0
  124. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  125. data/spec/test_app/config/initializers/inflections.rb +15 -0
  126. data/spec/test_app/config/initializers/mime_types.rb +5 -0
  127. data/spec/test_app/config/initializers/secret_token.rb +7 -0
  128. data/spec/test_app/config/initializers/session_store.rb +8 -0
  129. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  130. data/spec/test_app/config/locales/en.yml +5 -0
  131. data/spec/test_app/config/newsletter.yml +9 -0
  132. data/spec/test_app/config/routes.rb +4 -0
  133. data/spec/test_app/config.ru +4 -0
  134. data/spec/test_app/db/migrate/20131222171229_newsletter_initial.rb +104 -0
  135. data/spec/test_app/db/schema.rb +116 -0
  136. data/spec/test_app/lib/assets/.gitkeep +0 -0
  137. data/spec/test_app/log/.gitkeep +0 -0
  138. data/spec/test_app/public/404.html +26 -0
  139. data/spec/test_app/public/422.html +26 -0
  140. data/spec/test_app/public/500.html +25 -0
  141. data/spec/test_app/public/favicon.ico +0 -0
  142. data/spec/test_app/script/rails +6 -0
  143. data/zeus.json +22 -0
  144. metadata +352 -0
@@ -0,0 +1,45 @@
1
+ <html>
2
+ <head><title>Newsletter Documentation</title></head>
3
+ <body>
4
+ <h1>Table of Contents</h1>
5
+ <p>
6
+ <ul>
7
+ <li><a href="#Newsletter+Listing">Newsletter Listing</a> - You can manage newsletters here.</li>
8
+ <li><a href="#Newsletter+Archive">Newsletter Archive</a> - The public listing of newsletters you've published.</li>
9
+ <li><a href="#Newsletter+Designs">Newsletter Designs</a> - Used to create newsletters of different styles.
10
+ <ul>
11
+ <li>"<a href="#Newsletter+Areas">Newsletter Areas</a>" are sections of your newsletter which can contain different "<a href="#Newsletter+Elements">Newsletter Elements</a>". Examples of these can be headers, footers or columns in your article.</li>
12
+ <li>"<a href="#Newsletter+Elements">Newsletter Elements</a>" are things which the designer of your design has provided for you to add content to your newsletter, such as images and articles, and provide a layout and style for the content.</li>
13
+ </ul></li>
14
+ </ul>
15
+ </p>
16
+
17
+
18
+ <h1><a name="Newsletter+Listing"/>Newsletter Listing</h1>
19
+ <p>This screen is used to manage newsletters. You can Create, Edit, Publish, Unpublish and reorder newsletters from this screen. A link to the newsletter archive is also provided.<br/>
20
+ <ul>
21
+ <li>Click "<a href="#New+Newsletter">New Newsletter</a>" in the navigation to create a newsletter</li>
22
+ <li>Click "<a href="#Newsletter+Edit">Edit</a>" next to the newsletter you would like to manage/modify.<li>
23
+ <li>Click "Publish" on a newsletter for it to show up in the archive</li>
24
+ <li>Click "Unpublish" to remove a newsletter from the archive</li>
25
+ <li>Click on the name of a newsletter and drag it up or down to reorder them in the archive</li>
26
+ <li>Click "View Newsletter Archive" to open up your archive in a new window</li>
27
+ <li>Click "Delete" to delete the newsletter.</li>
28
+ </ul>
29
+ </p>
30
+ <h1><a name="New+Newsletter"/>New Newsletter</h1>
31
+ <p>This screen is used to add a new newsletter. Give the newsletter a name that is descriptive as it will show up in your archive listing with this value. Choose a design for your newsletter at this time. You cannot change this after you have created a newsletter; if you want to use a different design, you can delete the unwanted newsletter and start a new one. If no newsletter designs exist, or you would like a new one added, contact your site administrator.
32
+ </p>
33
+ <h1><a name="Edit">
34
+ <h1><a name="Newsletter+Archive"/>Newsletter Archive</h1>
35
+ <p>The archive is simply a list of newsletters that you have published. Their order and whether they are published is controlled on the <a href="#Newsletter+Listing">Newsletter Listing</a> screen.
36
+ </p>
37
+ <h1><a name="Newsletter+Designs"/>Newsletter Designs</h1>
38
+ <p>These are provided by your site administrator, who can install and modify them to achieve different looks for your newsletter. Newsletter designs are made up of the following items.
39
+ <ul>
40
+ <li><a name="Newsletter+Areas"/>Newsletter Areas are sections of your newsletter which can contain different "<a href="#Newsletter+Elements">Newsletter Elements</a>". Examples of these can be headers, footers or columns in your article.</li>
41
+ <li>"<a href="#Newsletter+Elements">Newsletter Elements</a>" are things which the designer of your design has provided for you to add content to your newsletter, such as images and articles, and provide a layout and style for the content.</li>
42
+ <li>
43
+ </ul>
44
+ </p>
45
+ </body>
@@ -0,0 +1,45 @@
1
+ <html>
2
+ <head><title>Newsletter Design Documentation</title></head>
3
+ <body>
4
+ <h1>Table of Contents</h1>
5
+ <p>
6
+ <ul>
7
+ <li><a href="#Newsletter+Listing">Newsletter Listing</a> - You can manage newsletters here.</li>
8
+ <li><a href="#Newsletter+Archive">Newsletter Archive</a> - The public listing of newsletters you've published.</li>
9
+ <li><a href="#Newsletter+Designs">Newsletter Designs</a> - Used to create newsletters of different styles.
10
+ <ul>
11
+ <li>"<a href="#Newsletter+Areas">Newsletter Areas</a>" are sections of your newsletter which can contain different "<a href="#Newsletter+Elements">Newsletter Elements</a>". Examples of these can be headers, footers or columns in your article.</li>
12
+ <li>"<a href="#Newsletter+Elements">Newsletter Elements</a>" are things which the designer of your design has provided for you to add content to your newsletter, such as images and articles, and provide a layout and style for the content.</li>
13
+ </ul></li>
14
+ </ul>
15
+ </p>
16
+
17
+
18
+ <h1><a name="Newsletter+Listing"/>Newsletter Listing</h1>
19
+ <p>This screen is used to manage newsletters. You can Create, Edit, Publish, Unpublish and reorder newsletters from this screen. A link to the newsletter archive is also provided.<br/>
20
+ <ul>
21
+ <li>Click "<a href="#New+Newsletter">New Newsletter</a>" in the navigation to create a newsletter</li>
22
+ <li>Click "<a href="#Newsletter+Edit">Edit</a>" next to the newsletter you would like to manage/modify.<li>
23
+ <li>Click "Publish" on a newsletter for it to show up in the archive</li>
24
+ <li>Click "Unpublish" to remove a newsletter from the archive</li>
25
+ <li>Click on the name of a newsletter and drag it up or down to reorder them in the archive</li>
26
+ <li>Click "View Newsletter Archive" to open up your archive in a new window</li>
27
+ <li>Click "Delete" to delete the newsletter.</li>
28
+ </ul>
29
+ </p>
30
+ <h1><a name="New+Newsletter"/>New Newsletter</h1>
31
+ <p>This screen is used to add a new newsletter. Give the newsletter a name that is descriptive as it will show up in your archive listing with this value. Choose a design for your newsletter at this time. You cannot change this after you have created a newsletter; if you want to use a different design, you can delete the unwanted newsletter and start a new one. If no newsletter designs exist, or you would like a new one added, contact your site administrator.
32
+ </p>
33
+ <h1><a name="Edit">
34
+ <h1><a name="Newsletter+Archive"/>Newsletter Archive</h1>
35
+ <p>The archive is simply a list of newsletters that you have published. Their order and whether they are published is controlled on the <a href="#Newsletter+Listing">Newsletter Listing</a> screen.
36
+ </p>
37
+ <h1><a name="Newsletter+Designs"/>Newsletter Designs</h1>
38
+ <p>These are provided by your site administrator, who can install and modify them to achieve different looks for your newsletter. Newsletter designs are made up of the following items.
39
+ <ul>
40
+ <li><a name="Newsletter+Areas"/>Newsletter Areas are sections of your newsletter which can contain different "<a href="#Newsletter+Elements">Newsletter Elements</a>". Examples of these can be headers, footers or columns in your article.</li>
41
+ <li>"<a href="#Newsletter+Elements">Newsletter Elements</a>" are things which the designer of your design has provided for you to add content to your newsletter, such as images and articles, and provide a layout and style for the content.</li>
42
+ <li>
43
+ </ul>
44
+ </p>
45
+ </body>
data/config/routes.rb ADDED
@@ -0,0 +1,33 @@
1
+ Newsletter::Engine.routes.draw do
2
+
3
+ resources :newsletters, except: [:show,:index] do
4
+ member do
5
+ get :unpublish
6
+ get :publish
7
+ get :editor
8
+ end
9
+ collection do
10
+ get :short
11
+ end
12
+ resources :pieces, :only => [:index,:new,:create]
13
+ end
14
+ resources :pieces, :only => [:edit,:create,:update,:destroy]
15
+ resources :designs do
16
+ resources :elements, :only => [:index,:new,:create]
17
+ end
18
+ resources :elements, :only => [:edit,:create,:update,:destroy]
19
+
20
+ match "/:newsletter_id/areas/:id/sort" => "newsletter/areas#sort", :method => :get, as: 'sort_area'
21
+ match '/newsletters/:id/:mode' => 'newsletters#show', :method => :get, :as => :public_newsletter_mode
22
+ match '/newsletters/:id/public' => 'newsletters#show', :method => :get, :as => :public_newsletter
23
+ match '/newsletters/:id' => 'newsletters#show', :method => :get, :as => :newsletter
24
+ match '/newsletters' => 'newsletters#index', :method => :get, :as => :newsletter
25
+ root :to => 'newsletters#index'
26
+ end
27
+
28
+ #public top-level routes
29
+ Rails.application.routes.draw do
30
+ match '/newsletters/archive' => 'newsletter/newsletters#archive', :method => :get, :as => :newsletter_archive
31
+ match '/newsletters/:id/:mode' => 'newsletter/newsletters#show', :method => :get, :as => :public_newsletter_mode
32
+ match '/newsletters/:id/public' => 'newsletter/newsletters#show', :method => :get, :as => :public_newsletter
33
+ end
@@ -0,0 +1,104 @@
1
+ class NewsletterInitial < ActiveRecord::Migration
2
+ def self.up
3
+ table_prefix = 'newsletter_'
4
+ begin
5
+ table_prefix = ::Newsletter.table_prefix
6
+ rescue
7
+ end
8
+ create_table :"#{table_prefix}designs" do |t|
9
+ t.string :name, :null => false
10
+ t.string :description
11
+ t.text :html_design
12
+ t.integer :updated_by
13
+ t.datetime :deleted_at
14
+ t.timestamps
15
+ end
16
+ create_table :"#{table_prefix}areas" do |t|
17
+ t.string :name, :null => false
18
+ t.string :description
19
+ t.integer :design_id
20
+ t.integer :updated_by
21
+ t.datetime :deleted_at
22
+ t.timestamps
23
+ end
24
+ create_table :"#{table_prefix}elements" do |t|
25
+ t.string :name, :null => false
26
+ t.string :description
27
+ t.text :html_design
28
+ t.integer :design_id
29
+ t.integer :updated_by
30
+ t.datetime :deleted_at
31
+ t.timestamps
32
+ end
33
+ create_table :"#{table_prefix}areas_#{table_prefix}elements", :id => false do |t|
34
+ t.integer :area_id, :null => false
35
+ t.integer :element_id, :null => false
36
+ end
37
+ create_table :"#{table_prefix}fields" do |t|
38
+ t.string :name, :null => false
39
+ t.integer :element_id, :null => false
40
+ t.string :label
41
+ t.integer :sequence
42
+ t.boolean :is_required
43
+ t.string :description
44
+ t.string :type
45
+ t.integer :updated_by
46
+ t.datetime :deleted_at
47
+ t.timestamps
48
+ end
49
+ create_table :"#{table_prefix}newsletters" do |t|
50
+ t.string :name, :null => false
51
+ t.string :description
52
+ t.integer :design_id
53
+ t.integer :sequence
54
+ t.datetime :published_at
55
+ t.integer :updated_by
56
+ t.datetime :deleted_at
57
+ t.timestamps
58
+ end
59
+ create_table :"#{table_prefix}pieces" do |t|
60
+ t.integer :newsletter_id, :null => false
61
+ t.integer :area_id, :null => false
62
+ t.integer :element_id, :null => false
63
+ t.integer :sequence, :null => false
64
+ t.integer :updated_by
65
+ t.datetime :deleted_at
66
+ t.timestamps
67
+ end
68
+ create_table :"#{table_prefix}field_values" do |t|
69
+ t.integer :piece_id, :null => false
70
+ t.integer :field_id, :null => false
71
+ t.string :key, :null => false
72
+ t.text :value, :null => false
73
+ t.integer :updated_by
74
+ t.datetime :deleted_at
75
+ t.timestamps
76
+ end
77
+ create_table :"#{table_prefix}assets" do |t|
78
+ t.integer :field_id
79
+ t.integer :piece_id
80
+ t.string :filename
81
+ t.string :content_type
82
+ t.integer :size
83
+ t.integer :width
84
+ t.integer :height
85
+ t.integer :parent_id
86
+ t.string :thumbnail
87
+ t.integer :updated_by
88
+ t.datetime :deleted_at
89
+ t.timestamps
90
+ end
91
+ end
92
+
93
+ def self.down
94
+ drop_table :"#{table_prefix}assets"
95
+ drop_table :"#{table_prefix}field_values"
96
+ drop_table :"#{table_prefix}pieces"
97
+ drop_table :"#{table_prefix}newsletters"
98
+ drop_table :"#{table_prefix}fields"
99
+ drop_table :"#{table_prefix}areas_#{table_prefix}elements"
100
+ drop_table :"#{table_prefix}elements"
101
+ drop_table :"#{table_prefix}areas"
102
+ drop_table :"#{table_prefix}designs"
103
+ end
104
+ end
@@ -0,0 +1,9 @@
1
+ class CarrierWaveForAssets < ActiveRecord::Migration
2
+ def up
3
+ rename_column :newsletter_assets, :filename, :image
4
+ end
5
+
6
+ def down
7
+ rename_column :newsletter_assets, :image, :filename
8
+ end
9
+ end
@@ -0,0 +1,61 @@
1
+ class NewsletterScoped < ActiveRecord::Migration
2
+ def self.up
3
+ rename_column :newsletter_areas, :newsletter_template_id, :design_id
4
+ rename_column :newsletter_elements, :newsletter_template_id, :design_id
5
+ rename_column :newsletter_areas_newsletter_elements, :newsletter_area_id, :area_id
6
+ rename_column :newsletter_areas_newsletter_elements, :newsletter_element_id, :element_id
7
+ rename_column :newsletter_fields, :newsletter_element_id, :element_id
8
+ rename_column :newsletters, :newsletter_template_id, :design_id
9
+ rename_column :newsletter_pieces, :newsletter_area_id, :area_id
10
+ rename_column :newsletter_pieces, :newsletter_element_id, :element_id
11
+ rename_column :newsletter_field_values, :newsletter_piece_id, :piece_id
12
+ rename_column :newsletter_field_values, :newsletter_field_id, :field_id
13
+ rename_column :newsletter_assets, :newsletter_field_id, :field_id
14
+ rename_column :newsletter_assets, :newsletter_piece_id, :piece_id
15
+ rename_table :newsletters, :newsletter_newsletters
16
+ rename_table :newsletter_templates, :newsletter_designs
17
+ conn = ActiveRecord::Base.connection
18
+ conn.execute("UPDATE `mlm_mailings`
19
+ SET mailable_type='Newsletter::Newsletter'
20
+ WHERE mailable_type='Newsletter'")
21
+ ["InlineAsset","Text","TextArea"].each do |type|
22
+ conn.execute("UPDATE newsletter_fields
23
+ SET type='Newsletter::Field::#{type}'
24
+ WHERE type='NewsletterField::#{type}'")
25
+ end
26
+ end
27
+
28
+ def self.down
29
+ rename_column :newsletter_areas, :design_id, :newsletter_template_id
30
+ rename_column :newsletter_elements, :design_id, :newsletter_template_id
31
+ rename_column :newsletter_areas_newsletter_elements, :area_id, :newsletter_area_id
32
+ rename_column :newsletter_areas_newsletter_elements, :element_id, :newsletter_element_id
33
+ rename_column :newsletter_fields, :element_id, :newsletter_element_id
34
+ rename_column :newsletters, :design_id, :newsletter_template_id
35
+ rename_column :newsletter_pieces, :area_id, :newsletter_area_id
36
+ rename_column :newsletter_pieces, :element_id, :newsletter_element_id
37
+ rename_column :newsletter_field_values, :piece_id, :newsletter_piece_id
38
+ rename_column :newsletter_field_values, :field_id, :newsletter_field_id
39
+ rename_column :newsletter_assets, :field_id, :newsletter_field_id
40
+ rename_column :newsletter_assets, :piece_id, :newsletter_piece_id
41
+ rename_table :newsletter_newsletters, :newsletters
42
+ rename_table :newsletter_designs, :newsletter_templates
43
+ conn = ActiveRecord::Base.connection
44
+ conn.execute("UPDATE `mlm_mailings`
45
+ SET mailable_type='Newsletter'
46
+ WHERE mailable_type='Newsletter::Newsletter'")
47
+ ["InlineAsset","Text","TextArea"].each do |type|
48
+ conn.execute("UPDATE newsletter_fields
49
+ SET type='NewsletterField::#{type}'
50
+ WHERE type='Newsletter::Field::#{type}'")
51
+ end
52
+ menu = AdminMenu.find_by_description('Create/Manage')
53
+ menu.update_attributes(:path => 'admin/newsletters',
54
+ :description => 'Newsletters') unless menu.nil?
55
+ menu = AdminMenu.find_by_description('Newsletter')
56
+ menu.update_attributes(:path => 'admin/newsletters') unless menu.nil?
57
+ menu = AdminMenu.find_by_description('Designs')
58
+ menu.update_attributes(:path => 'admin/newsletter_templates',
59
+ :description => 'Newsletter Templates') unless menu.nil?
60
+ end
61
+ end
@@ -0,0 +1,2 @@
1
+ Use this README file to introduce your application and point to useful places in the API for learning more.
2
+ Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
@@ -0,0 +1,130 @@
1
+ =General Requirements=
2
+ Newsletters will be created from newsletter designs, which will allow users to add data to predefined elements such as articles and images where they have no need to know html or use a wysiwyg editor. The design defines what elements exist and where they can be placed in a layout.
3
+ Elements will be sortable/draggable within an area. There will be an archive page and newsletters can be published or hidden from this view as well as sorted. If the Mailing List Manager is also installed, published newsletters will be available as mailable objects when creating a mailing. Currently only an html design can be defined, and a plain text version is available by converting the html of the newsletter.
4
+
5
+ ==Additional RVArt Gallery Needs==
6
+ * Include products from the shopping cart, and possibly an 'override' description of the product.
7
+ * Multiple mailing lists and subcsription options.
8
+
9
+ =Overview=
10
+ ==Newsletter Designs==
11
+ Newsletter designs currently are based on erb designs which are tied together with data elements and an overall layout. Most likely the end user will not be modifying these, but will be handled by a designer/site administrator.
12
+
13
+ ===Basic Configuration===
14
+ Configuration currently is defined with a plugin [[AppConfig]], which pulls application configuration in from the file: "'''config/config.yml'''" in the root of your rails application. Paths and urls in general do NOT have a trailing slash. Here are the applicable settings for newsletter designs:
15
+ * Newsletter Specific
16
+ ** '''newsletters_path''' - path to the root of your newsletter design files
17
+ ** '''asset_path''' - path to where newsletter users where upload assets for their newsletters
18
+ ** '''newsletter_path_prefix''' - relative path for newsletter administrative routes, '''site_path/site_url''' are prepended when calculating urls and paths for routes
19
+ * Site wide
20
+ ** '''site_path''' - path relative to your domain name if your project is in a sub url
21
+ ** '''site_url''' - full url to your site... will include your '''site_path'''
22
+
23
+ ===Installation or Injection into App===
24
+
25
+ <pre>
26
+ </pre>
27
+
28
+
29
+ ===NewsletterDesign===
30
+ This defines the overall structure of the newsletter with an name, erb design, which is stored on the filesystem as '''newsletters_path/designs/[design name with underscores for non-alphanumeric characters]/layout.html.erb'''. And newsletter areas, which are referenced with a render tag, which references the areas name, and the newsletter's name is also available. You may also add an unsubscribe block with the unsubscribe url = #UNSUBSCRIBE_URL# if you are tying into the mailing list manager. Since you won't want to show this block in the main site, you may enclose your unsubscribe block with a conditional based on "'''is_email?'''".
31
+ * Screens
32
+ ** (Listing) Newsletter Designs - Add/Edit/Delete newsletter designs
33
+ * Console Snippets for import/export of designs
34
+ <pre>
35
+ #export a design with the 'export' method
36
+ #this creates a file '''newsletters_path/exports/[design name with underscores for non-alphanumeric characters]-export.yaml'''
37
+ NewsletterDesign.first.export
38
+ #import a design from an exported design's YAML file
39
+ NewsletterDesign.import(filename[,design_name])
40
+ </pre>
41
+ * Data
42
+ ** name
43
+ ** description
44
+ ** html_design (file-based - not in db)
45
+ ** has_many: NewsletterAreas - list of areas, so that we know which areas exist in this design other than trying to inspect the design itself
46
+ ** has_many: NewsletterElements - building blocks of the design, such as articles, images and paragraphs
47
+
48
+ Here is an example layout.html.erb, with newsletter areas 'left column' and 'right column'.
49
+ <pre>
50
+ <html>
51
+ <head><title><%= @newsletter_design.name %></title></head>
52
+ <body>
53
+ <table border="0">
54
+ <tr>
55
+ <td><%= render left_column %></td>
56
+ <td><%= render right_column %></td>
57
+ </tr>
58
+ </table>
59
+ <% if is_email? %>
60
+ You may unsubscribe from this list by clicking <%= link_to "here", "#UNSUBSCRIBE_URL#" %>.
61
+ <% end %>
62
+ </body>
63
+ </html>
64
+ </pre>
65
+
66
+ ===NewsletterArea===
67
+ This will represent an area of a design, which can hold multiple sortable elements - currently just a dumb container.
68
+ * Data
69
+ ** name
70
+ ** description
71
+ ** has_and_belongs_to_many NewsletterElements
72
+ ** belongs_to NewsletterDesign
73
+ ** has_many NewsletterPieces
74
+
75
+ ===NewsletterElement===
76
+ This is a terminal element for display, it has an erb design on the filesystem at '''newsletters_path/designs/[newsletter design name with underscores for non-alphanumeric characters]/newsletter_elements/_[element name with underscores for non-alphanumeric characters].html.erb''' and Fields to hold and modify its data.
77
+ * Data
78
+ ** name
79
+ ** description
80
+ ** html_design (on the filesystem... not db)
81
+ ** has_many NewsletterFields
82
+ ** has_and_belongs_to_many NewsletterAreas
83
+ ** belongs_to NewsletterDesign
84
+
85
+ ===NewsletterField===
86
+ These are data members that can be used in an element. They are polymorphic, and have a model associated with their type that may contain validation logic and defines how their data is stored and views for representation in a form.
87
+ * name
88
+ * description
89
+ * type - polymorphic
90
+ ** :text - string, text field,
91
+ ** :text_area - string, text area,
92
+ ** :inline_asset - url (asset or external) for an inline asset
93
+ ** :product - id(int) and type of an object to show, ajaxified search form (autocomplete/form)
94
+ *** this is in response to needing a way to tie in a product (*future for RVArt)
95
+ * belongs_to NewsletterElement
96
+ * belongs_to NewsletterPiece
97
+
98
+ ===NewsletterAsset===
99
+ Assets that can be linked from pieces, given that they have a field which supports this. This is using the '''attachment_fu''' plugin
100
+
101
+ ===Newsletter===
102
+ These are the actual newsletters which tie actual newsletter data to a newsletter design and its elements.
103
+ * Screens
104
+ ** List Newsletters - lists all newsletters, allows publishing, unpublishing, reordering with drag/drop and links to New & Edit functionality
105
+ ** New Newsletter - allows them to enter a name for the newsletter and select a design.
106
+ ** Edit (Newsletter) - brings up an editor where they may add "Pieces" to newsletter areas and reorder/edit/remove them in a preview pane.
107
+ ** Newsletter Archive - lists published newsletters for public view
108
+ * Data
109
+ ** name
110
+ ** description
111
+ ** subject
112
+ ** newsletter_design_id
113
+ ** belongs_to :newsletter_design
114
+ ** has_and_belongs_to_many :pieces
115
+
116
+ ==Piece==
117
+ An instance of element that is tied to a newsletter in an area, and ties in field values to an elements fields.
118
+ * belongs_to :newsletter_area
119
+ * belongs_to :newsletter_element
120
+ * belongs_to :newsletter
121
+ * has_many :newsletter_field_values
122
+
123
+ ==FieldValue==
124
+ This may be used to save data for a field and a given piece, depending on the field.
125
+ * newsletter_piece_id
126
+ * newsletter_field_id
127
+ * key - varchar - may be used if a field has multiple values to store.
128
+ * value - text
129
+
130
+ =Creating a Design=
@@ -0,0 +1,43 @@
1
+ # build plugin skeleton (and copy into your current old plugin if necessary)
2
+ rails plugin new gem_name -T --mountable --full --dummy-path=spec/test_app
3
+
4
+ # zeus example:
5
+ # Gemfile: (bundle install)
6
+ gem 'zeus'
7
+ # zeus.json example:
8
+ {
9
+ "command": "ruby -rubygems -r./engine_plan -eZeus.go",
10
+
11
+ "plan": {
12
+ "boot": {
13
+ "default_bundle": {
14
+ "development_environment": {
15
+ "prerake": {"rake": []},
16
+ "runner": ["r"],
17
+ "console": ["c"],
18
+ "server": ["s"],
19
+ "generate": ["g"],
20
+ "destroy": ["d"],
21
+ "dbconsole": []
22
+ },
23
+ "test_environment": {
24
+ "test_helper": {"test": ["rspec", "testrb"]}
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
30
+ # engine_plan.rb(fix test_app if different && ENGINE_PATH)
31
+ require 'zeus/rails'
32
+
33
+ ROOT_PATH = File.expand_path(Dir.pwd)
34
+ ENV_PATH = File.expand_path('spec/test_app/config/environment', ROOT_PATH)
35
+ BOOT_PATH = File.expand_path('spec/test_app/config/boot', ROOT_PATH)
36
+ APP_PATH = File.expand_path('spec/test_app/config/application', ROOT_PATH)
37
+ ENGINE_ROOT = File.expand_path(Dir.pwd)
38
+ ENGINE_PATH = File.expand_path('lib/mail_manager/engine', ENGINE_ROOT)
39
+
40
+ class EnginePlan < Zeus::Rails
41
+ end
42
+
43
+ Zeus.plan = EnginePlan.new
data/engine_plan.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'zeus/rails'
2
+
3
+ ROOT_PATH = File.expand_path(Dir.pwd)
4
+ ENV_PATH = File.expand_path('spec/test_app/config/environment', ROOT_PATH)
5
+ BOOT_PATH = File.expand_path('spec/test_app/config/boot', ROOT_PATH)
6
+ APP_PATH = File.expand_path('spec/test_app/config/application', ROOT_PATH)
7
+ ENGINE_ROOT = File.expand_path(Dir.pwd)
8
+ ENGINE_PATH = File.expand_path('lib/newsletter/engine', ENGINE_ROOT)
9
+
10
+ class EnginePlan < Zeus::Rails
11
+ end
12
+
13
+ Zeus.plan = EnginePlan.new
@@ -0,0 +1,115 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
2
+
3
+ # Commonly used webrat steps
4
+ # http://github.com/brynary/webrat
5
+
6
+ Given /^I am on (.+)$/ do |page_name|
7
+ visit path_to(page_name)
8
+ end
9
+
10
+ When /^I go to (.+)$/ do |page_name|
11
+ visit path_to(page_name)
12
+ end
13
+
14
+ When /^I press "([^\"]*)"$/ do |button|
15
+ click_button(button)
16
+ end
17
+
18
+ When /^I follow "([^\"]*)"$/ do |link|
19
+ click_link(link)
20
+ end
21
+
22
+ When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
23
+ fill_in(field, :with => value)
24
+ end
25
+
26
+ When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
27
+ select(value, :from => field)
28
+ end
29
+
30
+ # Use this step in conjunction with Rail's datetime_select helper. For example:
31
+ # When I select "December 25, 2008 10:00" as the date and time
32
+ When /^I select "([^\"]*)" as the date and time$/ do |time|
33
+ select_datetime(time)
34
+ end
35
+
36
+ # Use this step when using multiple datetime_select helpers on a page or
37
+ # you want to specify which datetime to select. Given the following view:
38
+ # <%= f.label :preferred %><br />
39
+ # <%= f.datetime_select :preferred %>
40
+ # <%= f.label :alternative %><br />
41
+ # <%= f.datetime_select :alternative %>
42
+ # The following steps would fill out the form:
43
+ # When I select "November 23, 2004 11:20" as the "Preferred" date and time
44
+ # And I select "November 25, 2004 10:30" as the "Alternative" date and time
45
+ When /^I select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
46
+ select_datetime(datetime, :from => datetime_label)
47
+ end
48
+
49
+ # Use this step in conjunction with Rail's time_select helper. For example:
50
+ # When I select "2:20PM" as the time
51
+ # Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
52
+ # will convert the 2:20PM to 14:20 and then select it.
53
+ When /^I select "([^\"]*)" as the time$/ do |time|
54
+ select_time(time)
55
+ end
56
+
57
+ # Use this step when using multiple time_select helpers on a page or you want to
58
+ # specify the name of the time on the form. For example:
59
+ # When I select "7:30AM" as the "Gym" time
60
+ When /^I select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
61
+ select_time(time, :from => time_label)
62
+ end
63
+
64
+ # Use this step in conjunction with Rail's date_select helper. For example:
65
+ # When I select "February 20, 1981" as the date
66
+ When /^I select "([^\"]*)" as the date$/ do |date|
67
+ select_date(date)
68
+ end
69
+
70
+ # Use this step when using multiple date_select helpers on one page or
71
+ # you want to specify the name of the date on the form. For example:
72
+ # When I select "April 26, 1982" as the "Date of Birth" date
73
+ When /^I select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
74
+ select_date(date, :from => date_label)
75
+ end
76
+
77
+ When /^I check "([^\"]*)"$/ do |field|
78
+ check(field)
79
+ end
80
+
81
+ When /^I uncheck "([^\"]*)"$/ do |field|
82
+ uncheck(field)
83
+ end
84
+
85
+ When /^I choose "([^\"]*)"$/ do |field|
86
+ choose(field)
87
+ end
88
+
89
+ When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
90
+ attach_file(field, path)
91
+ end
92
+
93
+ Then /^I should see "([^\"]*)"$/ do |text|
94
+ response.should contain(text)
95
+ end
96
+
97
+ Then /^I should not see "([^\"]*)"$/ do |text|
98
+ response.should_not contain(text)
99
+ end
100
+
101
+ Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
102
+ field_labeled(field).value.should =~ /#{value}/
103
+ end
104
+
105
+ Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
106
+ field_labeled(field).value.should_not =~ /#{value}/
107
+ end
108
+
109
+ Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
110
+ field_labeled(label).should be_checked
111
+ end
112
+
113
+ Then /^I should be on (.+)$/ do |page_name|
114
+ URI.parse(current_url).path.should == path_to(page_name)
115
+ end
@@ -0,0 +1,17 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] ||= "test"
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
4
+ require 'cucumber/rails/world'
5
+ require 'cucumber/formatter/unicode' # Comment out this line if you don't want Cucumber Unicode support
6
+ Cucumber::Rails.use_transactional_fixtures
7
+ Cucumber::Rails.bypass_rescue # Comment out this line if you want Rails own error handling
8
+ # (e.g. rescue_action_in_public / rescue_responses / rescue_from)
9
+
10
+ require 'webrat'
11
+
12
+ Webrat.configure do |config|
13
+ config.mode = :rails
14
+ end
15
+
16
+ require 'cucumber/rails/rspec'
17
+ require 'webrat/core/matchers'
@@ -0,0 +1,27 @@
1
+ module NavigationHelpers
2
+ # Maps a name to a path. Used by the
3
+ #
4
+ # When /^I go to (.+)$/ do |page_name|
5
+ #
6
+ # step definition in webrat_steps.rb
7
+ #
8
+ def path_to(page_name)
9
+ case page_name
10
+
11
+ when /the homepage/
12
+ '/'
13
+
14
+ # Add more mappings here.
15
+ # Here is a more fancy example:
16
+ #
17
+ # when /^(.*)'s profile page$/i
18
+ # user_profile_path(User.find_by_login($1))
19
+
20
+ else
21
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
22
+ "Now, go and add a mapping in #{__FILE__}"
23
+ end
24
+ end
25
+ end
26
+
27
+ World(NavigationHelpers)