newsletter 3.0.2 → 3.2.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 +5 -13
- data/.gitignore +6 -0
- data/.ruby-version +1 -1
- data/Gemfile +17 -5
- data/README.md +40 -0
- data/app/assets/images/newsletter/BottomRight.gif +0 -0
- data/app/assets/images/newsletter/MidRight.gif +0 -0
- data/app/assets/images/newsletter/TopCenter.gif +0 -0
- data/app/assets/images/newsletter/TopRight.gif +0 -0
- data/app/assets/images/newsletter/calendar_date_select/calendar.gif +0 -0
- data/app/assets/images/newsletter/iReach_logo.gif +0 -0
- data/app/assets/images/newsletter/spacer.gif +0 -0
- data/app/assets/images/newsletter/topMid.gif +0 -0
- data/app/assets/javascripts/newsletter/application.js +6 -0
- data/app/assets/stylesheets/newsletter/admin.css +261 -0
- data/app/assets/stylesheets/newsletter/application.css +3 -1
- data/app/assets/stylesheets/newsletter/nav.css +68 -0
- data/app/assets/stylesheets/newsletter/timepicker.css +54 -0
- data/app/controllers/newsletter/application_controller.rb +5 -26
- data/app/controllers/newsletter/areas_controller.rb +0 -38
- data/app/controllers/newsletter/designs_controller.rb +5 -2
- data/app/controllers/newsletter/elements_controller.rb +7 -7
- data/app/controllers/newsletter/fields_controller.rb +1 -46
- data/app/controllers/newsletter/newsletters_controller.rb +6 -24
- data/app/controllers/newsletter/pieces_controller.rb +8 -21
- data/app/helpers/newsletter/designs_helper.rb +1 -8
- data/app/helpers/newsletter/layout_helper.rb +43 -0
- data/app/helpers/newsletter/newsletters_helper.rb +9 -5
- data/app/models/newsletter/area.rb +1 -4
- data/app/models/newsletter/asset.rb +7 -1
- data/app/models/newsletter/design.rb +48 -34
- data/app/models/newsletter/element.rb +0 -42
- data/app/models/newsletter/field.rb +7 -10
- data/app/models/newsletter/field/inline_asset.rb +15 -2
- data/app/models/newsletter/newsletter.rb +18 -11
- data/app/models/newsletter/piece.rb +20 -24
- data/app/views/layouts/newsletter/application.html.erb +20 -116
- data/app/views/layouts/newsletter/layout.html.erb +15 -0
- data/app/views/newsletter/areas/_area.html.erb +1 -1
- data/app/views/newsletter/designs/_area_fields.html.erb +1 -1
- data/app/views/newsletter/designs/_form.html.erb +11 -29
- data/app/views/newsletter/designs/_newsletter_area.html.erb +2 -2
- data/app/views/newsletter/designs/edit.html.erb +3 -6
- data/app/views/newsletter/designs/index.html.erb +7 -6
- data/app/views/newsletter/designs/new.html.erb +2 -2
- data/app/views/newsletter/designs/show.html.erb +5 -5
- data/app/views/newsletter/elements/_field_fields.html.erb +12 -25
- data/app/views/newsletter/elements/_form.html.erb +38 -34
- data/app/views/newsletter/elements/edit.html.erb +2 -5
- data/app/views/newsletter/elements/index.html.erb +7 -7
- data/app/views/newsletter/elements/new.html.erb +2 -2
- data/app/views/newsletter/elements/show.html.erb +5 -5
- data/app/views/newsletter/fields/_inline_asset.html.erb +12 -32
- data/app/views/newsletter/fields/_text.html.erb +2 -4
- data/app/views/newsletter/fields/_text_area.html.erb +2 -7
- data/app/views/newsletter/newsletters/_form.html.erb +6 -16
- data/app/views/newsletter/newsletters/_head.html.erb +2 -3
- data/app/views/newsletter/newsletters/_newsletter.html.erb +11 -6
- data/app/views/newsletter/newsletters/archive.html.erb +1 -1
- data/app/views/newsletter/newsletters/edit.html.erb +8 -16
- data/app/views/newsletter/newsletters/index.html.erb +7 -7
- data/app/views/newsletter/newsletters/new.html.erb +2 -2
- data/app/views/newsletter/newsletters/show.html.erb +11 -6
- data/app/views/newsletter/pieces/_form.html.erb +1 -8
- data/app/views/newsletter/pieces/edit.html.erb +2 -4
- data/app/views/newsletter/pieces/new.html.erb +3 -5
- data/config/locales/newsletters.en.yml +27 -0
- data/config/routes.rb +4 -4
- data/designs/exports/Example.yml +202 -0
- data/designs/exports/example-export.yaml +481 -87
- data/lib/deleteable.rb +12 -14
- data/lib/newsletter/engine.rb +112 -6
- data/lib/newsletter/version.rb +1 -1
- data/lib/tasks/newsletter.rake +54 -41
- data/newsletter.gemspec +3 -1
- data/spec/test_app/.rspec +2 -0
- data/spec/test_app/app/controllers/application_controller.rb +5 -0
- data/spec/test_app/app/models/ability.rb +8 -0
- data/spec/test_app/app/models/user.rb +10 -0
- data/spec/test_app/app/views/layouts/application.html.erb +3 -1
- data/spec/test_app/config/database.postgres.yml +21 -0
- data/spec/test_app/config/initializers/carrierwave.rb +23 -0
- data/spec/test_app/config/newsletter.yml +6 -3
- data/spec/test_app/config/routes.rb +1 -2
- data/spec/test_app/db/migrate/20131222171230_create_users.rb +13 -0
- data/spec/test_app/db/schema.rb +13 -2
- data/spec/test_app/features/newsletter_management.feature +39 -0
- data/spec/test_app/features/piece_management.feature +20 -0
- data/spec/test_app/features/step_definitions/debugging_steps.rb +3 -0
- data/spec/test_app/features/step_definitions/design_steps.rb +3 -0
- data/spec/test_app/features/step_definitions/login_steps.rb +4 -0
- data/spec/test_app/features/step_definitions/newsletter_steps.rb +24 -0
- data/spec/test_app/features/step_definitions/piece_steps.rb +26 -0
- data/{features → spec/test_app/features}/step_definitions/webrat_steps.rb +10 -6
- data/spec/test_app/features/support/env.rb +36 -0
- data/spec/test_app/features/support/functions.rb +3 -0
- data/{features → spec/test_app/features}/support/paths.rb +10 -1
- data/spec/test_app/lib/debugging.rb +61 -0
- data/spec/test_app/script/full_suite +44 -0
- data/spec/test_app/script/rspec_multi_db +26 -0
- data/spec/test_app/spec/controllers/newsletter/pieces_controller_spec.rb +175 -0
- data/spec/test_app/spec/factories/_functions.rb +19 -0
- data/spec/test_app/spec/factories/assets.rb +8 -0
- data/spec/test_app/spec/factories/designs.rb +1 -1
- data/spec/test_app/spec/factories/newsletters.rb +68 -6
- data/spec/test_app/spec/factories/pieces.rb +8 -0
- data/spec/test_app/spec/factories/users.rb +13 -0
- data/spec/test_app/spec/features/newsletter/design_spec.rb +175 -0
- data/spec/test_app/spec/features/newsletter/element_spec.rb +53 -0
- data/spec/test_app/spec/features/newsletter/newsletter_spec.rb +99 -3
- data/spec/test_app/spec/helpers/newsletter/newsletters_helper_spec.rb +65 -0
- data/spec/test_app/spec/models/newsletter/asset_spec.rb +23 -0
- data/spec/test_app/spec/models/newsletter/design_spec.rb +23 -2
- data/spec/test_app/spec/models/newsletter/element_spec.rb +4 -0
- data/spec/test_app/spec/models/newsletter/inline_asset_spec.rb +43 -0
- data/spec/test_app/spec/models/newsletter/newsletter_spec.rb +102 -2
- data/spec/test_app/spec/models/newsletter/piece_spec.rb +33 -0
- data/spec/test_app/spec/rails_helper.rb +82 -0
- data/spec/test_app/spec/routing/newsletter/pieces_routing_spec.rb +28 -0
- data/spec/test_app/spec/spec_helper.rb +73 -64
- data/spec/test_app/spec/support/carrierwave.rb +7 -0
- data/spec/test_app/spec/support/continuances.rb +18 -0
- data/spec/test_app/spec/support/files/iReach_logo.gif +0 -0
- data/spec/test_app/spec/support/files/test.pdf +0 -0
- data/spec/test_app/spec/support/functions.rb +3 -0
- metadata +145 -726
- data/README +0 -243
- data/README.rdoc +0 -3
- data/app/views/newsletter/elements/_newsletter_field.html.erb +0 -37
- data/features/support/env.rb +0 -17
- data/lib/tasks/newsletter_tasks.rake +0 -4
- data/lib/tasks/rspec.rake +0 -158
- data/spec/spec_helper.rb +0 -55
- data/spec/test_app/db/structure.sql +0 -12
- data/spec/test_app/newsletters/designs/My_Design/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/My_Design/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/My_Design/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/My_Design/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/My_Design/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/My_Design/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/My_Design/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/Testo_Changeo/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/Testo_Changeo/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/empower_innovative_e-business/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/enable_extensible_systems/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/enable_extensible_systems/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/enable_extensible_systems/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/enable_extensible_systems/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/enable_extensible_systems/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/enable_extensible_systems/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/enable_extensible_systems/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/engage_innovative_schemas/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/envisioneer_seamless_ROI/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/harness_integrated_partnerships/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/innovate_24_365_functionalities/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/integrate_mission-critical_systems/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/integrate_mission-critical_systems/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/iterate_real-time_web-readiness/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/iterate_strategic_architectures/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/orchestrate_sticky_communities/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/repurpose_impactful_partnerships/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/revolutionize_robust_partnerships/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/revolutionize_turn-key_bandwidth/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/scale_ubiquitous_synergies/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/syndicate_visionary_metrics/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/target_enterprise_functionalities/layout.html.erb +0 -67
- data/spec/test_app/newsletters/designs/transition_enterprise_systems/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/transition_enterprise_systems/layout.html.erb +0 -66
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/elements/_left_column_article.html.erb +0 -10
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/elements/_left_column_image.html.erb +0 -2
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/elements/_right_column_article.html.erb +0 -5
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/elements/_right_column_headline.html.erb +0 -1
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/elements/_right_column_image.html.erb +0 -1
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/elements/_right_column_paragraph.html.erb +0 -3
- data/spec/test_app/newsletters/designs/utilize_one-to-one_schemas/layout.html.erb +0 -66
@@ -21,7 +21,7 @@ module ::Newsletter
|
|
21
21
|
|
22
22
|
scope :active, :conditions => {:deleted_at => nil}
|
23
23
|
|
24
|
-
|
24
|
+
validates :name, presence: true, uniqueness: true
|
25
25
|
|
26
26
|
# attr_protected :id
|
27
27
|
#FIXME: make this work with deletable or convert to auditable, and extend it to access destroyed records
|
@@ -37,7 +37,8 @@ module ::Newsletter
|
|
37
37
|
:html_text => html_text,
|
38
38
|
:description => description,
|
39
39
|
:areas => areas.collect{|area| area.export_fields},
|
40
|
-
:elements => elements.collect{|element| element.export_fields}
|
40
|
+
:elements => elements.collect{|element| element.export_fields},
|
41
|
+
:images => base64_encoded_images
|
41
42
|
},file)
|
42
43
|
end
|
43
44
|
end
|
@@ -52,7 +53,7 @@ module ::Newsletter
|
|
52
53
|
design = nil
|
53
54
|
transaction do
|
54
55
|
data[:name] = design_name if design_name
|
55
|
-
design = Design.create
|
56
|
+
design = Design.create(:name => data[:name],
|
56
57
|
:html_text => data[:html_text],
|
57
58
|
:description => data[:description])
|
58
59
|
data[:areas].each do |area_data|
|
@@ -61,21 +62,59 @@ module ::Newsletter
|
|
61
62
|
data[:elements].each do |element_data|
|
62
63
|
Element.import(design,element_data)
|
63
64
|
end
|
65
|
+
design.import_images(data[:images])
|
64
66
|
end
|
67
|
+
raise "Error importing design: #{design.errors.full_messages.join("\n ")}" unless design.valid?
|
65
68
|
design
|
66
69
|
end
|
67
70
|
|
68
71
|
# returns path to newsletter design for use in views and is the same for actual file
|
69
72
|
def view_path(this_name=nil)
|
70
|
-
|
73
|
+
File.join(base_design_path(this_name),'layout.html.erb')
|
71
74
|
end
|
72
75
|
|
73
|
-
#
|
76
|
+
# returns the path to the base of the design's files
|
74
77
|
def base_design_path(this_name=nil)
|
75
|
-
|
78
|
+
File.join(::Newsletter.designs_path,'designs',name_as_path(this_name))
|
76
79
|
end
|
77
|
-
|
78
80
|
|
81
|
+
# returns the image filenames inside a design
|
82
|
+
def images
|
83
|
+
Dir.glob(File.join(images_path,'*.*')).map{|f| File.basename(f)} || []
|
84
|
+
rescue => e
|
85
|
+
[]
|
86
|
+
end
|
87
|
+
|
88
|
+
# returns the images as an array of base64 encoded strings
|
89
|
+
def base64_encoded_images
|
90
|
+
images.map {|image| {
|
91
|
+
name: image,
|
92
|
+
data: Base64.encode64(File.binread(File.join(images_path,image)))
|
93
|
+
}}
|
94
|
+
end
|
95
|
+
|
96
|
+
# returns where a design's images should go, can override for 'old_name'
|
97
|
+
def images_path(the_name=nil)
|
98
|
+
the_name ||= name
|
99
|
+
File.join('public','images',name_as_path(the_name))
|
100
|
+
end
|
101
|
+
|
102
|
+
# move a design's images on name change
|
103
|
+
def move_images
|
104
|
+
return unless @old_name && @old_name != name
|
105
|
+
FileUtils.mv(images_path(@old_name),images_path)
|
106
|
+
end
|
107
|
+
|
108
|
+
# imports images from array of base64 encoded images
|
109
|
+
def import_images(image_imports)
|
110
|
+
image_imports ||= []
|
111
|
+
FileUtils.mkdir_p(images_path)
|
112
|
+
image_imports.each do |image|
|
113
|
+
File.binwrite(File.join(images_path,image[:name]),
|
114
|
+
Base64.decode64(image[:data])
|
115
|
+
)
|
116
|
+
end
|
117
|
+
end
|
79
118
|
|
80
119
|
def html_text
|
81
120
|
return @html_text if @html_text
|
@@ -86,20 +125,6 @@ module ::Newsletter
|
|
86
125
|
@html_text = text
|
87
126
|
end
|
88
127
|
|
89
|
-
# def area_attributes=(area_attributes)
|
90
|
-
# area_attributes.each do |attributes|
|
91
|
-
# if attributes[:id].blank?
|
92
|
-
# Rails.logger.debug "Building Area : #{attributes.inspect}"
|
93
|
-
# areas.build(attributes)
|
94
|
-
# else
|
95
|
-
# Rails.logger.debug "Setting Area data: #{attributes.inspect}"
|
96
|
-
# area = areas.detect{|area| area.id == attributes[:id].to_i}
|
97
|
-
# area.attributes = attributes
|
98
|
-
# end
|
99
|
-
# end
|
100
|
-
# end
|
101
|
-
|
102
|
-
|
103
128
|
def name=(new_name)
|
104
129
|
return if self[:name].eql?(new_name)
|
105
130
|
@old_name = self[:name] unless @old_name
|
@@ -121,6 +146,7 @@ module ::Newsletter
|
|
121
146
|
end
|
122
147
|
|
123
148
|
include Deleteable
|
149
|
+
|
124
150
|
protected
|
125
151
|
def read_design
|
126
152
|
File.readlines(view_path).join
|
@@ -137,6 +163,7 @@ module ::Newsletter
|
|
137
163
|
def move_design_on_name_change
|
138
164
|
return unless @old_name and File.exists?(view_path(@old_name))
|
139
165
|
FileUtils.mv(base_design_path(@old_name),base_design_path)
|
166
|
+
move_images(@old_name, name)
|
140
167
|
end
|
141
168
|
|
142
169
|
def write_design
|
@@ -145,18 +172,5 @@ module ::Newsletter
|
|
145
172
|
file.write html_text
|
146
173
|
end
|
147
174
|
end
|
148
|
-
|
149
|
-
|
150
|
-
# def save_areas
|
151
|
-
# areas.each do |area|
|
152
|
-
# if area.should_destroy?
|
153
|
-
# Rails.logger.debug "Destroying newsletter area: #{area.inspect}"
|
154
|
-
# area.destroy
|
155
|
-
# else
|
156
|
-
# Rails.logger.debug "Saving newsletter area: #{area.inspect}"
|
157
|
-
# area.save
|
158
|
-
# end
|
159
|
-
# end
|
160
|
-
# end
|
161
175
|
end
|
162
176
|
end
|
@@ -61,35 +61,6 @@ module Newsletter
|
|
61
61
|
@html_text = text
|
62
62
|
end
|
63
63
|
|
64
|
-
def update_attributes(params={})
|
65
|
-
transaction do
|
66
|
-
super
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def save_fields
|
71
|
-
return true unless @fields_attributes.present?
|
72
|
-
@fields_attributes.each_pair do |index,attributes|
|
73
|
-
should_destroy = ['true','1'].include?attributes.delete(:_destroy)
|
74
|
-
if attributes[:id].blank?
|
75
|
-
next if should_destroy
|
76
|
-
attributes.delete(:id)
|
77
|
-
klass = attributes.delete(:type)
|
78
|
-
fields << klass.constantize.new(attributes)
|
79
|
-
else
|
80
|
-
id = attributes.delete(:id).to_i
|
81
|
-
if should_destroy
|
82
|
-
fields.where(id: id).limit(1).each(&:destroy)
|
83
|
-
else
|
84
|
-
type = attributes.delete(:type)
|
85
|
-
field = fields.detect{|field| field.id == id}
|
86
|
-
field.update_attributes(attributes)
|
87
|
-
field = Field.morph(field,type) unless field.class.name.eql?(type)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
64
|
# returns field data so that Newsletter::Design.export(instance) can export itself to a YAML file
|
94
65
|
def export_fields
|
95
66
|
{ :name => name,
|
@@ -121,7 +92,6 @@ module Newsletter
|
|
121
92
|
move_design_on_name_change
|
122
93
|
write_design
|
123
94
|
super
|
124
|
-
save_fields
|
125
95
|
end
|
126
96
|
end
|
127
97
|
|
@@ -146,17 +116,5 @@ module Newsletter
|
|
146
116
|
FileUtils.mv(file_path(@old_name),file_path)
|
147
117
|
end
|
148
118
|
|
149
|
-
# def save_fields
|
150
|
-
# Rails.logger.warn "Fields: #{fields.inspect}"
|
151
|
-
# fields.each do |field|
|
152
|
-
# if field.should_destroy?
|
153
|
-
# Rails.logger.warn "Destroy Field: #{field.inspect}"
|
154
|
-
# field.delete
|
155
|
-
# else
|
156
|
-
# Rails.logger.warn "Save Field: #{field.inspect}"
|
157
|
-
# field.save!
|
158
|
-
# end
|
159
|
-
# end
|
160
|
-
# end
|
161
119
|
end
|
162
120
|
end
|
@@ -15,6 +15,8 @@ module Newsletter
|
|
15
15
|
has_many :field_values, :class_name => 'Newsletter::FieldValue'
|
16
16
|
belongs_to :updated_by, :class_name => 'User'
|
17
17
|
|
18
|
+
acts_as_list :scope => :element, :column => :sequence
|
19
|
+
|
18
20
|
validates_presence_of :name
|
19
21
|
=begin
|
20
22
|
FIXME: make this work with deletable or convert to auditable, and extend it to access destroyed records
|
@@ -25,9 +27,8 @@ module Newsletter
|
|
25
27
|
["name=? and element_id=? and id!=? and deleted_at is null", field.element_id,
|
26
28
|
field.id]).nil? }
|
27
29
|
=end
|
28
|
-
|
29
|
-
|
30
|
-
attr_protected :id
|
30
|
+
attr_accessible :name, :type, :element_id, :label, :sequence, :is_required,
|
31
|
+
:description, :updated_by
|
31
32
|
|
32
33
|
include Deleteable
|
33
34
|
|
@@ -58,8 +59,9 @@ module Newsletter
|
|
58
59
|
end
|
59
60
|
|
60
61
|
# returns a pieces value for a given Newsletter::Field
|
61
|
-
def value_for_piece(piece)
|
62
|
-
get_value(piece).to_s.html_safe
|
62
|
+
def value_for_piece(piece,safe=true)
|
63
|
+
return get_value(piece).to_s.html_safe if safe
|
64
|
+
get_value(piece).to_s
|
63
65
|
end
|
64
66
|
|
65
67
|
# sets a pieces value for a Newsletter::Field
|
@@ -92,11 +94,6 @@ module Newsletter
|
|
92
94
|
Field.find(field.id)
|
93
95
|
end
|
94
96
|
|
95
|
-
# used in figuring out whether to destroy a field as we are editing fields inside an element form
|
96
|
-
def should_destroy?
|
97
|
-
should_destroy.to_i == 1
|
98
|
-
end
|
99
|
-
|
100
97
|
# find the partial to display a form for creating a Newsletter::Piece
|
101
98
|
def form_partial_path
|
102
99
|
"newsletter/fields/#{type.to_s.gsub(/.*Newsletter::Field::/,'').gsub(/([^A-Z])([A-Z])/,'\\1_\\2').downcase}"
|
@@ -11,8 +11,6 @@ module Newsletter
|
|
11
11
|
has_many :assets, :foreign_key => :field_id,
|
12
12
|
:class_name => 'Newsletter::Asset'
|
13
13
|
|
14
|
-
attr_protected :id
|
15
|
-
|
16
14
|
# overridden from main class to choose between a Newsletter::Asset or a given URL
|
17
15
|
def value_for_piece(piece)
|
18
16
|
Value.new(:url => url_for_piece(piece), :text => get_value(piece,:text), :asset => asset(piece))
|
@@ -55,6 +53,21 @@ module Newsletter
|
|
55
53
|
# fields
|
56
54
|
class Value
|
57
55
|
attr_accessor :url, :text, :asset, :asset_id
|
56
|
+
def is_image?
|
57
|
+
if asset.present?
|
58
|
+
asset.is_image?
|
59
|
+
else
|
60
|
+
is_image_by_extension?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def is_image_by_extension?
|
65
|
+
extension = File.extname(url).gsub(/^\./,'')
|
66
|
+
[ 'bmp', 'cod', 'gif', 'ief', 'jpe', 'jpeg', 'jpg', 'png',
|
67
|
+
'jfif', 'svg', 'tif', 'tiff'
|
68
|
+
].include?(extension.downcase)
|
69
|
+
end
|
70
|
+
|
58
71
|
def initialize(params)
|
59
72
|
@url = params[:url]
|
60
73
|
@text = params[:text]
|
@@ -27,6 +27,7 @@ module Newsletter
|
|
27
27
|
|
28
28
|
attr_protected :id
|
29
29
|
|
30
|
+
# returns any piece that is a headline
|
30
31
|
def headlines
|
31
32
|
pieces.select{|piece| piece.respond_to?(:headline)}
|
32
33
|
end
|
@@ -52,6 +53,7 @@ module Newsletter
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
# whether or not the newsletter will show on the archives page
|
55
57
|
def published?
|
56
58
|
!published_at.nil?
|
57
59
|
end
|
@@ -70,6 +72,10 @@ module Newsletter
|
|
70
72
|
def public_url(mode='')
|
71
73
|
"#{::Newsletter.site_url}/newsletters/#{self[:id]}#{mode.blank? ? '' : "/#{mode}"}"
|
72
74
|
end
|
75
|
+
|
76
|
+
def image_uri(filename)
|
77
|
+
File.join(design.images_path.gsub(/.*public\//,'/'), filename)
|
78
|
+
end
|
73
79
|
|
74
80
|
# used to generate the newsletter from a model or someplace other than the web stack
|
75
81
|
# FIXME: There has to be a better way, where railsy stuff works ... erb doesn't seem
|
@@ -82,7 +88,7 @@ module Newsletter
|
|
82
88
|
fetch(public_url(mode))
|
83
89
|
end
|
84
90
|
|
85
|
-
# retrieve a newsletter area by name
|
91
|
+
# retrieve a newsletter area by name - for use in render/views
|
86
92
|
def area(name)
|
87
93
|
design.areas.by_name(name).first
|
88
94
|
end
|
@@ -94,30 +100,31 @@ module Newsletter
|
|
94
100
|
design.areas.each do |area|
|
95
101
|
variables[area.name.to_sym] = area
|
96
102
|
end
|
103
|
+
variables[:title] = self.name
|
97
104
|
variables
|
98
105
|
end
|
99
106
|
|
107
|
+
# :nodoc sets a pieces attributes coming from the form
|
108
|
+
# FIXME: this is probably covered by rails 3 accepts_attributes_for, but we
|
109
|
+
# will change when we go to 4 anyways
|
100
110
|
def piece_attributes=(piece_attributes)
|
101
111
|
piece_attributes.each do |attributes|
|
102
112
|
pieces.build(attributes)
|
103
113
|
end
|
104
114
|
end
|
105
115
|
|
116
|
+
# helper to get areas for newsletter
|
106
117
|
def areas
|
107
118
|
design.try(:areas).to_a
|
108
119
|
end
|
109
|
-
|
120
|
+
|
121
|
+
# fetch a url and return the body
|
110
122
|
def fetch(uri_str, limit = 10)
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
response = Net::HTTP.get_response(URI.parse(uri_str))
|
116
|
-
case response
|
117
|
-
when Net::HTTPSuccess then response.body
|
118
|
-
when Net::HTTPRedirection then fetch(response['location'], limit - 1)
|
123
|
+
uri = URI.parse(uri_str)
|
124
|
+
if uri.scheme.eql?('file')
|
125
|
+
File.binread(uri_str.gsub(%r#^file://#,''))
|
119
126
|
else
|
120
|
-
|
127
|
+
uri.read
|
121
128
|
end
|
122
129
|
end
|
123
130
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin rdoc
|
2
|
-
|
2
|
+
Aduthor:: Chris Hauboldt (mailto:biz@lnstar.com)
|
3
3
|
Copyright:: 2009 Lone Star Internet Inc.
|
4
4
|
|
5
5
|
NewsletterPieces are the glue that tie data together to form a piece in an area of a design.
|
@@ -24,7 +24,10 @@ module Newsletter
|
|
24
24
|
|
25
25
|
attr_accessor :field_values_attributes
|
26
26
|
|
27
|
+
#attr_accessible :field_values_attributes, :newsletter_id, :element_id, :area_id
|
27
28
|
attr_protected :id
|
29
|
+
|
30
|
+
#validates_presence_of :newsletter, :element, :area, :field_values
|
28
31
|
|
29
32
|
# returns locals to be used in its Newsletter::Element design
|
30
33
|
def locals
|
@@ -32,51 +35,41 @@ module Newsletter
|
|
32
35
|
@locals = Hash.new
|
33
36
|
fields.each do |field|
|
34
37
|
@locals[field.name.to_sym] = field.value_for_piece(self)
|
35
|
-
define_getter_for_locals(field.name.to_sym) unless respond_to?(field.name.to_sym)
|
36
38
|
end
|
37
39
|
@locals
|
38
40
|
end
|
39
41
|
|
42
|
+
# returns a pieces fields
|
40
43
|
def fields
|
41
44
|
element.try(:fields).try(:uniq) || []
|
42
45
|
end
|
43
46
|
|
44
|
-
def newsletter
|
45
|
-
return nil unless newsletter_id.present?
|
46
|
-
@newsletter ||= ::Newsletter::Newsletter.find(newsletter_id)
|
47
|
-
end
|
48
|
-
|
49
47
|
# used to save out a piece's fields, since they are inline in a piece's form
|
50
48
|
def field_values_attributes=(values)
|
51
49
|
@field_values_attributes = values
|
52
50
|
end
|
53
51
|
|
54
|
-
|
55
|
-
return unless defined?(@field_values_attributes) && @field_values_attributes.present?
|
56
|
-
@field_values_attributes.each_pair do |field_id,key_value_pairs|
|
57
|
-
field = Field.find(field_id)
|
58
|
-
field.set_value_for_piece(self,key_value_pairs)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
52
|
+
# whether it can respond to a 'method' in its locals hash
|
62
53
|
def respond_to?(my_method,use_private=false)
|
63
54
|
return true if super
|
64
55
|
if locals.keys.include?(my_method.to_sym)
|
65
|
-
define_getter_for_locals(my_method)
|
66
56
|
true
|
67
57
|
else
|
68
58
|
false
|
69
59
|
end
|
70
60
|
end
|
71
61
|
|
62
|
+
# respond for its named methods for its element's template
|
63
|
+
# these values will be in its locals hash
|
72
64
|
def method_missing(*args)
|
73
65
|
if args.length == 1 and locals.has_key?(args[0].to_sym)
|
74
|
-
|
66
|
+
locals[args[0].to_sym]
|
75
67
|
else
|
76
68
|
super
|
77
69
|
end
|
78
70
|
end
|
79
71
|
|
72
|
+
# :nodoc override save for transaction to set its field values
|
80
73
|
def save(*args)
|
81
74
|
transaction do
|
82
75
|
set_field_values
|
@@ -84,13 +77,16 @@ module Newsletter
|
|
84
77
|
end
|
85
78
|
end
|
86
79
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
80
|
+
protected
|
81
|
+
|
82
|
+
# sets the piece's field values after a save
|
83
|
+
def set_field_values
|
84
|
+
return unless defined?(@field_values_attributes) && @field_values_attributes.present?
|
85
|
+
@field_values_attributes.each_pair do |field_id,key_value_pairs|
|
86
|
+
field = Field.find(field_id)
|
87
|
+
field.set_value_for_piece(self,key_value_pairs)
|
88
|
+
end
|
94
89
|
end
|
90
|
+
|
95
91
|
end
|
96
92
|
end
|