workarea-blog 3.4.7

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 (213) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +20 -0
  3. data/.eslintignore +2 -0
  4. data/.eslintrc +24 -0
  5. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  6. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  7. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  8. data/.gitignore +16 -0
  9. data/.rspec +2 -0
  10. data/.scss-lint.yml +188 -0
  11. data/.tailor +180 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +1123 -0
  14. data/CODE_OF_CONDUCT.md +3 -0
  15. data/CONTRIBUTING.md +3 -0
  16. data/Gemfile +7 -0
  17. data/LICENSE +52 -0
  18. data/README.md +140 -0
  19. data/Rakefile +42 -0
  20. data/app/assets/images/workarea/admin/blog/content_block_types/blog_entry.svg +1 -0
  21. data/app/assets/images/workarea/admin/blog/icons/blog.svg +1 -0
  22. data/app/assets/images/workarea/admin/blog/icons/blog_entry.svg +1 -0
  23. data/app/assets/images/workarea/admin/blog/icons/blog_post_comment.svg +1 -0
  24. data/app/assets/javascripts/workarea/storefront/blog/modules/blog_comment_placeholder.js +33 -0
  25. data/app/assets/stylesheets/workarea/admin/blog/components/_blog_entry_card.scss +14 -0
  26. data/app/assets/stylesheets/workarea/storefront/blog/components/_blog_entry.scss +91 -0
  27. data/app/assets/stylesheets/workarea/storefront/blog/components/_blog_entry_summary.scss +74 -0
  28. data/app/assets/stylesheets/workarea/storefront/blog/components/_featured_entry_content_block.scss +22 -0
  29. data/app/controllers/workarea/admin/application_controller.decorator +5 -0
  30. data/app/controllers/workarea/admin/content_blog_comments_controller.rb +54 -0
  31. data/app/controllers/workarea/admin/content_blog_entries_controller.rb +70 -0
  32. data/app/controllers/workarea/admin/content_blogs_controller.rb +56 -0
  33. data/app/controllers/workarea/admin/create_content_blog_entries_controller.rb +69 -0
  34. data/app/controllers/workarea/storefront/blog_comments_controller.rb +14 -0
  35. data/app/controllers/workarea/storefront/blog_entries_controller.rb +48 -0
  36. data/app/controllers/workarea/storefront/blogs_controller.rb +19 -0
  37. data/app/helpers/workarea/admin/blogs_helper.rb +61 -0
  38. data/app/models/workarea/content/blog.rb +26 -0
  39. data/app/models/workarea/content/blog_comment.rb +67 -0
  40. data/app/models/workarea/content/blog_entry.rb +35 -0
  41. data/app/models/workarea/content/fields/blog_entry_id.rb +11 -0
  42. data/app/models/workarea/content/fields/blog_id.rb +8 -0
  43. data/app/models/workarea/search/admin/content_blog.rb +27 -0
  44. data/app/models/workarea/search/admin/content_blog_entry.rb +37 -0
  45. data/app/queries/workarea/metadata/content_blog.rb +6 -0
  46. data/app/queries/workarea/metadata/content_blog_entry.rb +6 -0
  47. data/app/queries/workarea/search/admin_blog_entries.rb +24 -0
  48. data/app/queries/workarea/search/admin_blogs.rb +20 -0
  49. data/app/seeds/workarea/blog_comments_seeds.rb +26 -0
  50. data/app/seeds/workarea/blog_entry_seeds.rb +73 -0
  51. data/app/seeds/workarea/blog_seeds.rb +53 -0
  52. data/app/services/workarea/search/queries/blog_admin.rb +20 -0
  53. data/app/services/workarea/search/queries/blog_entry_admin.rb +13 -0
  54. data/app/services/workarea/set_navigable.decorator +10 -0
  55. data/app/view_models/workarea/admin/blog_comments_view_model.rb +45 -0
  56. data/app/view_models/workarea/admin/blog_entries_view_model.rb +31 -0
  57. data/app/view_models/workarea/admin/blog_entry_view_model.rb +29 -0
  58. data/app/view_models/workarea/admin/blog_search_view_model.rb +6 -0
  59. data/app/view_models/workarea/admin/blog_view_model.rb +13 -0
  60. data/app/view_models/workarea/storefront/blog_entry_view_model.rb +43 -0
  61. data/app/view_models/workarea/storefront/blog_index_view_model.rb +17 -0
  62. data/app/view_models/workarea/storefront/blog_view_model.rb +83 -0
  63. data/app/view_models/workarea/storefront/content_blocks/blog_entry_content_block_view_model.rb +63 -0
  64. data/app/views/workarea/admin/activities/_content_blog_comment_create.html.haml +12 -0
  65. data/app/views/workarea/admin/activities/_content_blog_comment_destroy.html.haml +9 -0
  66. data/app/views/workarea/admin/activities/_content_blog_comment_update.html.haml +10 -0
  67. data/app/views/workarea/admin/activities/_content_blog_create.html.haml +12 -0
  68. data/app/views/workarea/admin/activities/_content_blog_destroy.html.haml +10 -0
  69. data/app/views/workarea/admin/activities/_content_blog_entry_create.html.haml +12 -0
  70. data/app/views/workarea/admin/activities/_content_blog_entry_destroy.html.haml +10 -0
  71. data/app/views/workarea/admin/activities/_content_blog_entry_update.html.haml +10 -0
  72. data/app/views/workarea/admin/activities/_content_blog_update.html.haml +10 -0
  73. data/app/views/workarea/admin/blog/_dashboard_navigation.html.haml +1 -0
  74. data/app/views/workarea/admin/blog/_menu.html.haml +13 -0
  75. data/app/views/workarea/admin/content_blocks/_blog_entry_id.html.haml +4 -0
  76. data/app/views/workarea/admin/content_blocks/_blog_id.html.haml +3 -0
  77. data/app/views/workarea/admin/content_blog_comments/_summary.html.haml +24 -0
  78. data/app/views/workarea/admin/content_blog_comments/edit.html.haml +60 -0
  79. data/app/views/workarea/admin/content_blog_comments/index.html.haml +49 -0
  80. data/app/views/workarea/admin/content_blog_entries/_aux_navigation.html.haml +4 -0
  81. data/app/views/workarea/admin/content_blog_entries/_cards.html.haml +113 -0
  82. data/app/views/workarea/admin/content_blog_entries/_summary.html.haml +10 -0
  83. data/app/views/workarea/admin/content_blog_entries/edit.html.haml +75 -0
  84. data/app/views/workarea/admin/content_blog_entries/index.html.haml +80 -0
  85. data/app/views/workarea/admin/content_blog_entries/index.json.jbuilder +5 -0
  86. data/app/views/workarea/admin/content_blog_entries/show.html.haml +20 -0
  87. data/app/views/workarea/admin/content_blog_entries/thumbnail_image.html.haml +55 -0
  88. data/app/views/workarea/admin/content_blogs/_aux_navigation.html.haml +2 -0
  89. data/app/views/workarea/admin/content_blogs/_cards.html.haml +58 -0
  90. data/app/views/workarea/admin/content_blogs/_summary.html.haml +6 -0
  91. data/app/views/workarea/admin/content_blogs/edit.html.haml +51 -0
  92. data/app/views/workarea/admin/content_blogs/index.html.haml +76 -0
  93. data/app/views/workarea/admin/content_blogs/index.json.jbuilder +4 -0
  94. data/app/views/workarea/admin/content_blogs/new.html.haml +33 -0
  95. data/app/views/workarea/admin/content_blogs/show.html.haml +19 -0
  96. data/app/views/workarea/admin/create_content_blog_entries/content.html.haml +28 -0
  97. data/app/views/workarea/admin/create_content_blog_entries/featured_products.html.haml +71 -0
  98. data/app/views/workarea/admin/create_content_blog_entries/publish.html.haml +51 -0
  99. data/app/views/workarea/admin/create_content_blog_entries/setup.html.haml +61 -0
  100. data/app/views/workarea/admin/create_content_blog_entries/thumbnail_image.html.haml +48 -0
  101. data/app/views/workarea/storefront/blog_comments/index.html.haml +31 -0
  102. data/app/views/workarea/storefront/blog_entries/_summary.html.haml +25 -0
  103. data/app/views/workarea/storefront/blog_entries/show.html.haml +85 -0
  104. data/app/views/workarea/storefront/blog_metadata/_publisher.html.haml +7 -0
  105. data/app/views/workarea/storefront/blogs/_blog_navigation.html.haml +7 -0
  106. data/app/views/workarea/storefront/blogs/index.html.haml +25 -0
  107. data/app/views/workarea/storefront/blogs/show.atom.builder +26 -0
  108. data/app/views/workarea/storefront/blogs/show.html.haml +31 -0
  109. data/app/views/workarea/storefront/content_blocks/_blog_entry.html.haml +20 -0
  110. data/app/workers/workarea/generate_content_metadata.decorator +15 -0
  111. data/bin/rails +18 -0
  112. data/config/initializers/appends.rb +26 -0
  113. data/config/initializers/content_block_types.rb +13 -0
  114. data/config/initializers/jump_to_navigation.rb +3 -0
  115. data/config/initializers/seeds.rb +5 -0
  116. data/config/initializers/workarea.rb +15 -0
  117. data/config/locales/en.yml +244 -0
  118. data/config/routes.rb +49 -0
  119. data/data/blog_thumbnails/thumbnail_1.png +0 -0
  120. data/data/blog_thumbnails/thumbnail_2.png +0 -0
  121. data/data/blog_thumbnails/thumbnail_3.png +0 -0
  122. data/lib/tasks/import_wordpress.rake +13 -0
  123. data/lib/tasks/import_wordpress_attachments.rake +18 -0
  124. data/lib/tasks/import_wordpress_pages.rake +21 -0
  125. data/lib/tasks/import_wordpress_posts.rake +25 -0
  126. data/lib/workarea/blog/engine.rb +8 -0
  127. data/lib/workarea/blog/import/wordpress/attachment.rb +40 -0
  128. data/lib/workarea/blog/import/wordpress/content_cleaner.rb +64 -0
  129. data/lib/workarea/blog/import/wordpress/entry.rb +76 -0
  130. data/lib/workarea/blog/import/wordpress/entry_parser.rb +64 -0
  131. data/lib/workarea/blog/import/wordpress/page.rb +69 -0
  132. data/lib/workarea/blog/import/wordpress/page_parser.rb +50 -0
  133. data/lib/workarea/blog/version.rb +5 -0
  134. data/lib/workarea/blog.rb +11 -0
  135. data/test/dummy/Rakefile +6 -0
  136. data/test/dummy/app/assets/config/manifest.js +4 -0
  137. data/test/dummy/app/assets/images/.keep +0 -0
  138. data/test/dummy/app/assets/javascripts/application.js +13 -0
  139. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  140. data/test/dummy/app/controllers/application_controller.rb +3 -0
  141. data/test/dummy/app/controllers/concerns/.keep +0 -0
  142. data/test/dummy/app/helpers/application_helper.rb +2 -0
  143. data/test/dummy/app/jobs/application_job.rb +2 -0
  144. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  145. data/test/dummy/app/models/concerns/.keep +0 -0
  146. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  147. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  148. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  149. data/test/dummy/bin/bundle +3 -0
  150. data/test/dummy/bin/rails +4 -0
  151. data/test/dummy/bin/rake +4 -0
  152. data/test/dummy/bin/setup +34 -0
  153. data/test/dummy/bin/update +29 -0
  154. data/test/dummy/config/application.rb +26 -0
  155. data/test/dummy/config/boot.rb +5 -0
  156. data/test/dummy/config/cable.yml +9 -0
  157. data/test/dummy/config/environment.rb +5 -0
  158. data/test/dummy/config/environments/development.rb +59 -0
  159. data/test/dummy/config/environments/production.rb +86 -0
  160. data/test/dummy/config/environments/test.rb +43 -0
  161. data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
  162. data/test/dummy/config/initializers/assets.rb +11 -0
  163. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  164. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  165. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  166. data/test/dummy/config/initializers/inflections.rb +16 -0
  167. data/test/dummy/config/initializers/mime_types.rb +4 -0
  168. data/test/dummy/config/initializers/new_framework_defaults.rb +18 -0
  169. data/test/dummy/config/initializers/session_store.rb +3 -0
  170. data/test/dummy/config/initializers/workarea.rb +3 -0
  171. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  172. data/test/dummy/config/locales/en.yml +23 -0
  173. data/test/dummy/config/puma.rb +47 -0
  174. data/test/dummy/config/routes.rb +5 -0
  175. data/test/dummy/config/secrets.yml +22 -0
  176. data/test/dummy/config/spring.rb +6 -0
  177. data/test/dummy/config.ru +5 -0
  178. data/test/dummy/db/seeds.rb +2 -0
  179. data/test/dummy/lib/assets/.keep +0 -0
  180. data/test/dummy/log/.keep +0 -0
  181. data/test/factories/blog.rb +33 -0
  182. data/test/factories/wordpress_import.rb +17 -0
  183. data/test/fixtures/test_wordpress.xml +493 -0
  184. data/test/integration/workarea/blog/admin_integration_test.rb +55 -0
  185. data/test/integration/workarea/blog/create_blog_entries_integration_test.rb +106 -0
  186. data/test/integration/workarea/blog/storefront_integration_test.rb +112 -0
  187. data/test/integration/workarea/blog/wordpress_import_integration_test.rb +26 -0
  188. data/test/lib/workarea/blog/import/wordpress/attachment_test.rb +20 -0
  189. data/test/lib/workarea/blog/import/wordpress/content_cleaner_test.rb +65 -0
  190. data/test/lib/workarea/blog/import/wordpress/entry_parser_test.rb +42 -0
  191. data/test/lib/workarea/blog/import/wordpress/entry_test.rb +61 -0
  192. data/test/lib/workarea/blog/import/wordpress/page_parser_test.rb +35 -0
  193. data/test/lib/workarea/blog/import/wordpress/page_test.rb +52 -0
  194. data/test/models/workarea/content/blog_comment_test.rb +57 -0
  195. data/test/models/workarea/content/blog_entry_test.rb +17 -0
  196. data/test/queries/workarea/metadata/content_blog_entry_test.rb +36 -0
  197. data/test/queries/workarea/metadata/content_blog_test.rb +36 -0
  198. data/test/support/workarea/blog/stub_wordpress_assets.rb +19 -0
  199. data/test/system/workarea/admin/blog_entries_system_test.rb +103 -0
  200. data/test/system/workarea/admin/blog_system_test.rb +93 -0
  201. data/test/system/workarea/admin/blog_taxonomy_system_test.rb +21 -0
  202. data/test/system/workarea/admin/blog_user_comments_system_test.rb +138 -0
  203. data/test/system/workarea/storefront/blog_content_block_system_test.rb +36 -0
  204. data/test/system/workarea/storefront/blog_system_test.rb +256 -0
  205. data/test/test_helper.rb +9 -0
  206. data/test/view_models/workarea/admin/blog_comments_view_model_test.rb +77 -0
  207. data/test/view_models/workarea/admin/blog_entries_view_model_test.rb +36 -0
  208. data/test/view_models/workarea/storefront/blog_entry_content_block_view_model_test.rb +100 -0
  209. data/test/view_models/workarea/storefront/blog_entry_view_model_test.rb +47 -0
  210. data/test/view_models/workarea/storefront/blog_view_model_test.rb +149 -0
  211. data/test/workers/workarea/generate_content_blog_metadata_test.rb +18 -0
  212. data/workarea-blog.gemspec +19 -0
  213. metadata +274 -0
@@ -0,0 +1,26 @@
1
+ Workarea.append_javascripts(
2
+ 'storefront.modules',
3
+ 'workarea/storefront/blog/modules/blog_comment_placeholder'
4
+ )
5
+
6
+ Workarea.append_stylesheets(
7
+ 'storefront.components',
8
+ 'workarea/storefront/blog/components/blog_entry',
9
+ 'workarea/storefront/blog/components/blog_entry_summary',
10
+ 'workarea/storefront/blog/components/featured_entry_content_block'
11
+ )
12
+
13
+ Workarea.append_partials(
14
+ 'admin.primary_nav',
15
+ 'workarea/admin/blog/menu'
16
+ )
17
+
18
+ Workarea.append_partials(
19
+ 'admin.dashboard.index.navigation',
20
+ 'workarea/admin/blog/dashboard_navigation'
21
+ )
22
+
23
+ Workarea.append_partials(
24
+ 'admin.releasable_models',
25
+ 'workarea/admin/content_blog_entries/releasable_model'
26
+ )
@@ -0,0 +1,13 @@
1
+ Workarea::Content.define_block_types do
2
+ block_type 'Blog Entry' do
3
+ description 'Feature a blog entry as a content block'
4
+ view_model 'Workarea::Storefront::ContentBlocks::BlogEntryContentBlockViewModel'
5
+ icon 'workarea/admin/blog/content_block_types/blog_entry.svg'
6
+
7
+ field 'Blog', :blog_id, default: ''
8
+ field 'Number of entries', :options, values: %w[1 2 3 4], default: '1'
9
+ field 'Use manual entries', :boolean, default: false
10
+
11
+ field 'Blog Entry', :blog_entry_id, default: ''
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ Workarea.configure do |config|
2
+ config.jump_to_navigation.merge!('Blog' => :content_blogs_path)
3
+ end
@@ -0,0 +1,5 @@
1
+ Workarea.configure do |config|
2
+ config.seeds.insert_after('Workarea::CustomersSeeds', 'Workarea::BlogSeeds')
3
+ config.seeds.insert_after('Workarea::BlogSeeds', 'Workarea::BlogEntrySeeds')
4
+ config.seeds.insert_after('Workarea::BlogEntrySeeds', 'Workarea::BlogCommentSeeds')
5
+ end
@@ -0,0 +1,15 @@
1
+ Workarea.configure do |config|
2
+ # Number of articles to be displayed per blog on blog index page
3
+ config.blog_entries_on_index ||= 4
4
+
5
+ config.content_areas.merge!(
6
+ 'blog_entry' => %w[blog_content blog_header],
7
+ 'blog' => %w[header_content],
8
+ 'blog_landing_page' => %w[header_content]
9
+ )
10
+
11
+ config.wordpress_import = {
12
+ blog_name: 'Wordpress Import',
13
+ author_name: 'Wordpress User'
14
+ }
15
+ end
@@ -0,0 +1,244 @@
1
+ en:
2
+ workarea:
3
+ admin:
4
+ activities:
5
+ blog_comment_create: Created a blog comment
6
+ blog_comment_create_html: Create a blog comment on %{name}
7
+ blog_comment_destroy: Removed a blog comment
8
+ blog_comment_update_html: Updated %{fields} on a %{name}
9
+ blog_comment: blog comment
10
+ blog_create_html: Created %{name} blog
11
+ blog_destroy_html: Removed the %{name} blog
12
+ blog_update_html: Updated %{fields} on the %{name} blog
13
+ blog_entry_create_html: Created %{name} blog entry
14
+ blog_entry_destroy_html: Removed the %{name} blog entry
15
+ blog_entry_update_html: Updated %{fields} on the %{name} blog entry
16
+ landing_page: Blog Landing Page
17
+ content_blocks:
18
+ blog_id:
19
+ search_field_placeholder: Search blogs by name
20
+ blog_entry_id:
21
+ search_field_placeholder: Search entries by name
22
+ content_blogs_comments:
23
+ flash_messages:
24
+ destroyed: This blog entry comment has been removed
25
+ summary:
26
+ pending: (Pending)
27
+ edit:
28
+ page_title: Edit comment for %{name}
29
+ comments_for_name: Comments for %{name}
30
+ edit_comment_by_user: Edit Comment by %{user_name}
31
+ unregistered_user: Unregistered User
32
+ approved: Approved
33
+ comment: Comment
34
+ index:
35
+ dashboard_link: ↑ All Entries for %{blog_name}
36
+ all_blogs: All Blogs
37
+ comments_for_entry: Blog entry comments for %{entry_name}
38
+ blog_entry_comments: Blog Entry Comments
39
+ no_comments_found: No comments found.
40
+ page_title: Comments for blog
41
+ comments:
42
+ one: "%{count} Comment"
43
+ other: "%{count} Comments"
44
+ new_comment: New Comment
45
+ comment_body: Comment Body
46
+ create_comment: Create Comment
47
+ content_blog_entries:
48
+ fields:
49
+ author: Author
50
+ featured: Featured
51
+ comments: Comments
52
+ aux_navigation:
53
+ view_blog: View Blog
54
+ cards:
55
+ attributes:
56
+ button: Edit Attributes
57
+ author: 'Author:'
58
+ summary: 'Summary:'
59
+ tags: 'Tags:'
60
+ comments: 'Comments:'
61
+ featured: 'Featured:'
62
+ written_at: 'Written at:'
63
+ modified: 'Modified:'
64
+ created: 'Created:'
65
+ title: Attributes
66
+ none: (none)
67
+ comments:
68
+ button_add: Create a Comment
69
+ button_edit: View Comment
70
+ title: Comments
71
+ no_comments: This entry has no comments
72
+ featured_products:
73
+ button: Manage Products
74
+ description: Featured products are shown on blog entry and allow you to merchandise your blog.
75
+ empty: No featured products.
76
+ empty_button: Add Products
77
+ title: Featured Products
78
+ thumbnail_image:
79
+ button_add: Add Thumbnail
80
+ button_edit: Edit Thumbnail
81
+ description: Thumbnail images appear next to your blog entry when displayed on the index page for your blog.
82
+ no_thumbnail_image: No thumbnail image
83
+ title: Thumbnail Image
84
+ summary:
85
+ blog_entry: Blog Entry
86
+ written_at: 'Written at:'
87
+ updated_at: 'Updated at:'
88
+ comments:
89
+ one: "%{count} Comment"
90
+ other: "%{count} Comments"
91
+ edit:
92
+ author: Author
93
+ date_written: Date Written
94
+ featured: Featured
95
+ not_featured: Not featured
96
+ inactive: Inactive
97
+ index_link: Entries for %{name}
98
+ name: Name
99
+ page_title: Edit %{name}
100
+ slug_label: Entry URL
101
+ summary: Summary
102
+ tags: Tags
103
+ tags_note: 'Comma separated: just, like, this'
104
+ featured_products:
105
+ featured_products: Featured Products
106
+ page_title: Featured Products for %{name}
107
+ product_ids_note: Select products to feature on your blog entry.
108
+ index_link: All Entries for %{name}
109
+ flash_messages:
110
+ deleted: This blog entry has been removed
111
+ updated: Blog entry has been updated
112
+ index:
113
+ blog: Blog
114
+ entries_for: Entries for %{name}
115
+ new_blog_entry: New blog entry
116
+ show:
117
+ index_link: All Entries for %{name}
118
+ thumbnail_image:
119
+ choose_image_file: Choose Image File
120
+ current_image: Current Image
121
+ asset_input_note: After selecting an asset refresh to see an updated preview
122
+ index_link: All Entries for %{name}
123
+ page_title: Thumbnail for %{name}
124
+ thumbnail_image: Thumbnail Image
125
+ view_thumbnail_image: View thumbnail image
126
+ content_blogs:
127
+ fields:
128
+ entries: Entries
129
+ navigation: Navigation
130
+ actions:
131
+ delete_confirmation: Are you sure you want to delete this blog?
132
+ cards:
133
+ attributes:
134
+ button: Edit Attributes
135
+ created: 'Created:'
136
+ entries: 'Entries:'
137
+ modified: 'Modified:'
138
+ navigation: 'Navigation:'
139
+ no_navigation: 'N/A'
140
+ tags: 'Tags:'
141
+ title: Attributes
142
+ blog_entries:
143
+ by: "By: %{author}"
144
+ button: View Entries
145
+ button_create: Create Entry
146
+ empty: No blog entries.
147
+ title: Blog Entries
148
+ edit:
149
+ index_link: All Blogs
150
+ name: Name
151
+ page_title: Edit %{name}
152
+ page_url: Page Url
153
+ page_url_note: The URL is auto-generated using the page's name
154
+ index:
155
+ button: Add new Blog
156
+ dashboard_link: Main Dashboard
157
+ title: Blogs
158
+ new:
159
+ name: Name
160
+ page_title: New Blog
161
+ page_url: Page Url
162
+ page_url_note: The URL is auto-generated using the page's name
163
+ title: New Blog
164
+ blogs: Blogs
165
+ create_blog: Create Blog
166
+ summary:
167
+ type: Blog
168
+ entries:
169
+ one: 1 Entry
170
+ other: "%{count} Entries"
171
+ create_content_blog_entries:
172
+ content:
173
+ button: Continue and add products
174
+ page_title: Blog entry content for %{name}
175
+ title: Blog entry content for %{name}
176
+ featured_products:
177
+ button: Save and Continue
178
+ instruction: Click on products to add them to the blog entry.
179
+ no_matching_products: No matching products found
180
+ page_title: Featured products for %{name}
181
+ start_over: Start over
182
+ title: Featured products for %{name}
183
+ flash_messages:
184
+ blog_entry_created: Your blog entry has been created
185
+ publish:
186
+ button: Save and Finish
187
+ page_title: Publish %{name}
188
+ title: Publish %{name}
189
+ setup:
190
+ author_label: Author
191
+ button: Save and add thumbnail
192
+ blog_label: Blog
193
+ name_label: Entry Name
194
+ page_title: Create a blog entry
195
+ slug_label: Slug
196
+ slug_placeholder: your-slug-here
197
+ tags_label: Tags
198
+ tags_note: 'Comma separated: just, like this'
199
+ title: Create a blog entry
200
+ summary:
201
+ button: Save and add thumbnail image
202
+ page_title: Blog Entry Summary for %{name}
203
+ summary_label: Blog Entry Summary
204
+ title: Blog Entry Summary for %{name}
205
+ thumbnail_image:
206
+ button: Save and add content
207
+ thumbnail_label: Choose image file
208
+ page_title: Thumbnail image for %{name}
209
+ title: Thumbnail image for %{name}
210
+ workflow:
211
+ cancel_message: Are you sure? All work on this blog entry will be lost.
212
+ skip_this: Skip this
213
+ steps:
214
+ setup: Setup
215
+ summary: Summary
216
+ thumbnail_image: Thumbnail Image
217
+ content: Content
218
+ featured_products: Featured Products
219
+ publish: Publish
220
+
221
+ navigation_taxons:
222
+ types:
223
+ blog: Blog
224
+ blog_entry: Blog Entry
225
+ shared:
226
+ primary_nav:
227
+ blogs: Blogs
228
+ manage_comments: Manage Comments (%{count})
229
+ storefront:
230
+ blogs:
231
+ comment: Comment
232
+ comments:
233
+ one: 1 Comment
234
+ other: '%{count} Comments'
235
+ message: Check out %{name} from %{site}
236
+ tags: Tags
237
+ tag_link: "%{name} (%{count})"
238
+ byline: "By: %{author}"
239
+ related_products: Related Products
240
+ write_comment: Write Comment
241
+ must_be_logged_in: You must be logged in to write a comment.
242
+ submit_comment: Submit Comment
243
+ read_more: Read More »
244
+ name: Blog
data/config/routes.rb ADDED
@@ -0,0 +1,49 @@
1
+ Workarea::Admin::Engine.routes.draw do
2
+ scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
3
+ resources :content_blogs do
4
+ resources :comments, except: :new
5
+ get :unsubscribe, to: 'comments#unsubscribe'
6
+
7
+ get :create_entry, to: 'create_content_blog_entries#new'
8
+ resources :blog_entries, controller: 'content_blog_entries', only: :index
9
+ end
10
+
11
+ # named to prevent conflict with nested (commentable) comments resource above
12
+ resources :content_blog_comments, as: :content_blog_user_comments, only: %i[index edit update destroy]
13
+
14
+ resources :content_blog_entries, only: %i[index show edit update destroy] do
15
+ resources :comments, controller: 'content_blog_comments', only: :index
16
+
17
+ member do
18
+ get :thumbnail_image
19
+ put :update_thumbnail_image
20
+ end
21
+ end
22
+
23
+ resources :create_content_blog_entries, except: %i[index show] do
24
+ member do
25
+ get :thumbnail_image
26
+ post :save_thumbnail_image
27
+
28
+ get :content
29
+ post :save_content
30
+
31
+ get :featured_products
32
+
33
+ get :publish
34
+ post :save_publish
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ Workarea::Storefront::Engine.routes.draw do
41
+ get 'blogs/:id/tagged/:tag', to: 'blogs#show', as: :blog_tagged
42
+
43
+ resources :blogs, only: %i[index show]
44
+
45
+ resources :blog_entries, only: :show do
46
+ get 'comments', to: 'blog_comments#index', as: :comments
47
+ post 'comment', to: 'blog_entries#add_comment'
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ namespace :workarea do
2
+ namespace :blog do
3
+ desc 'Import Wordpress XML'
4
+ task :import_wordpress, [:path] => :environment do |t, args|
5
+ args.with_defaults(path: 'data/blog/wordpress.xml')
6
+ puts 'Importing wordpress content...'
7
+ Rake::Task['workarea:blog:import_wordpress_attachments'].invoke(args[:path])
8
+ Rake::Task['workarea:blog:import_wordpress_posts'].invoke(args[:path])
9
+ Rake::Task['workarea:blog:import_wordpress_pages'].invoke(args[:path])
10
+ puts 'Wordpress import complete!'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ require 'workarea/blog/import/wordpress/attachment'
2
+
3
+ namespace :workarea do
4
+ namespace :blog do
5
+ desc 'Import attachments from Wordpress'
6
+ task :import_wordpress_attachments, [:path] => :environment do |t, args|
7
+ args.with_defaults(path: "#{Rails.root}/data/blog/wordpress.xml")
8
+ puts 'Importing all assets...'
9
+
10
+ doc = Nokogiri::XML(File.open(args[:path]))
11
+ attachment_urls = doc.xpath("//item[wp:post_type='attachment']/wp:attachment_url").children.map(&:text)
12
+
13
+ attachment_urls.each do |url|
14
+ Workarea::Blog::Import::Wordpress::Attachment.new(url).save
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require 'workarea/blog/import/wordpress/page'
2
+ require 'workarea/blog/import/wordpress/page_parser'
3
+
4
+ namespace :workarea do
5
+ namespace :blog do
6
+ desc 'Import posts from Wordpress'
7
+ task :import_wordpress_pages, [:path] => :environment do |t, args|
8
+ args.with_defaults(path: "#{Rails.root}/data/blog/wordpress.xml")
9
+ puts 'Importing all Wordpress pages...'
10
+
11
+ doc = Nokogiri::XML(File.open(args[:path]))
12
+
13
+ all_pages = Workarea::Blog::Import::Wordpress::PageParser.new(doc).parse
14
+
15
+ all_pages.each do |page|
16
+ Workarea::Blog::Import::Wordpress::Page.new(page).save
17
+ end
18
+ puts 'Wordpress pages imported!'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require 'workarea/blog/import/wordpress/entry'
2
+ require 'workarea/blog/import/wordpress/entry_parser'
3
+
4
+ namespace :workarea do
5
+ namespace :blog do
6
+ desc 'Import posts from Wordpress'
7
+ task :import_wordpress_posts, [:path] => :environment do |t, args|
8
+ args.with_defaults(path: "#{Rails.root}/data/blog/wordpress.xml")
9
+ puts 'Importing all Wordpress posts...'
10
+
11
+ blog_name = Workarea.config.wordpress_import[:blog_name]
12
+ blog =
13
+ Workarea::Content::Blog.where(name: blog_name).first ||
14
+ Workarea::Content::Blog.create(name: blog_name)
15
+
16
+ doc = Nokogiri::XML(File.open(args[:path]))
17
+ all_posts = Workarea::Blog::Import::Wordpress::EntryParser.new(doc).parse
18
+
19
+ all_posts.each do |post|
20
+ Workarea::Blog::Import::Wordpress::Entry.new(post, blog).save
21
+ end
22
+ puts 'Wordpress posts imported!'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ module Workarea
2
+ module Blog
3
+ class Engine < ::Rails::Engine
4
+ include Workarea::Plugin
5
+ isolate_namespace Workarea::Blog
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,40 @@
1
+ module Workarea
2
+ module Blog
3
+ module Import
4
+ module Wordpress
5
+ class Attachment
6
+ def initialize(url)
7
+ @attachment_path = url
8
+ end
9
+
10
+ def save
11
+ attributes = {
12
+ name: file_name,
13
+ tag_list: 'Wordpress',
14
+ file: image_file
15
+ }
16
+
17
+ asset = Workarea::Content::Asset.create!(attributes)
18
+ puts "Created Asset: #{asset.name}"
19
+ asset
20
+ end
21
+
22
+ private
23
+
24
+ def image_file
25
+ Net::HTTP.get(uri)
26
+ end
27
+
28
+ def uri
29
+ URI.parse(@attachment_path)
30
+ end
31
+
32
+ def file_name
33
+ path = uri.path
34
+ path.rpartition('.').first.split('/').join('-')
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,64 @@
1
+ module Workarea
2
+ module Blog
3
+ module Import
4
+ module Wordpress
5
+ class ContentCleaner
6
+ def initialize(content, wordpress_hostname)
7
+ @content = content
8
+ @wordpress_hostname = wordpress_hostname
9
+ end
10
+
11
+ def clean
12
+ @content = update_asset_paths
13
+ @content = make_internal_links_relative
14
+ @content
15
+ end
16
+
17
+ private
18
+
19
+ def update_asset_paths
20
+ doc = Nokogiri::HTML.fragment(@content)
21
+ doc.search("img").each do |image|
22
+ src = ensure_schema(image.attributes['src'].value)
23
+ uri = URI.parse(src)
24
+ next unless internal_link?(uri)
25
+ new_asset = find_asset(uri)
26
+ image.set_attribute("src", new_asset.url)
27
+ image
28
+ end
29
+ doc.to_html
30
+ end
31
+
32
+ def find_asset(uri)
33
+ name = uri.path.rpartition('.').first.split('/').join('-')
34
+ Content::Asset.find_by(name: name) rescue Content::Asset.placeholder
35
+ end
36
+
37
+ def make_internal_links_relative
38
+ doc = Nokogiri::HTML.fragment(@content)
39
+ doc.search("a").each do |link|
40
+ href = ensure_schema(link.attributes['href'].value)
41
+ uri = URI.parse(href)
42
+ next unless internal_link?(uri)
43
+ link.set_attribute("href", uri.path)
44
+ link
45
+ end
46
+ doc.to_html
47
+ end
48
+
49
+ def internal_link?(uri)
50
+ uri.hostname == @wordpress_hostname
51
+ end
52
+
53
+ def ensure_schema(url)
54
+ if url[/\Ahttp:\/\//] || url[/\Ahttps:\/\//]
55
+ url
56
+ else
57
+ "https://#{url}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,76 @@
1
+ require 'workarea/blog/import/wordpress/content_cleaner'
2
+
3
+ module Workarea
4
+ module Blog
5
+ module Import
6
+ module Wordpress
7
+ class Entry
8
+ def initialize(post_hash, blog)
9
+ @post_hash = post_hash
10
+ @blog = blog
11
+ end
12
+
13
+ def save
14
+ if Workarea::Content::BlogEntry.where(slug: @post_hash[:new_slug]).present?
15
+ puts "An entry already exists with the slug #{@post_hash[:new_slug]}"
16
+ return
17
+ end
18
+ create_entry
19
+ create_redirects
20
+ create_entry_content
21
+ puts "Imported #{@entry.name}"
22
+ @entry
23
+ end
24
+
25
+ private
26
+
27
+ def create_entry
28
+ @entry ||= @blog.entries.create!(
29
+ tags: @post_hash[:tags],
30
+ active: @post_hash[:published?],
31
+ name: @post_hash[:title],
32
+ slug: @post_hash[:new_slug],
33
+ author: @post_hash[:author],
34
+ written_at: @post_hash[:published_date]
35
+ )
36
+ end
37
+
38
+ def create_entry_content
39
+ content = Content.for(@entry)
40
+ content.blocks.build(
41
+ area: 'blog_content',
42
+ type_id: :html,
43
+ data: {
44
+ html: cleaned_content
45
+ }
46
+ )
47
+ content.save!
48
+ end
49
+
50
+ def cleaned_content
51
+ Workarea::Blog::Import::Wordpress::ContentCleaner.new(
52
+ @post_hash[:content],
53
+ @post_hash[:wordpress_hosname]
54
+ ).clean
55
+ end
56
+
57
+ def create_redirects
58
+ old_path = URI.parse(@post_hash[:url]).path
59
+ new_path = "/blog_entries/#{@post_hash[:new_slug]}"
60
+
61
+ new_redirect(old_path, new_path)
62
+ new_redirect("/?#{@post_hash[:guid_path]}", new_path)
63
+ end
64
+
65
+ def new_redirect(old_path, new_path)
66
+ return if Workarea::Navigation::Redirect.find_by_path(old_path).present?
67
+ Workarea::Navigation::Redirect.create!(
68
+ path: old_path,
69
+ destination: new_path
70
+ )
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end