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,53 @@
1
+ module Workarea
2
+ class BlogSeeds
3
+ def perform
4
+ puts 'Adding blogs...'
5
+
6
+ Sidekiq::Callbacks.disable do
7
+ Content::Blog.create!(name: 'Hi, Fashion')
8
+ Content::Blog.create!(name: 'HowTo Couture')
9
+ end
10
+
11
+ create_landing_page_content
12
+ add_blog_navigation
13
+ end
14
+
15
+ def create_landing_page_content
16
+ landing_page_content = Workarea::Content.for('Blog Landing Page')
17
+
18
+ landing_page_content.blocks.create!(
19
+ area: 'header_content',
20
+ type: 'text',
21
+ data: {
22
+ text: Faker::Hipster.paragraph(4)
23
+ }
24
+ )
25
+
26
+ landing_page_content.save!
27
+ end
28
+
29
+ def add_blog_navigation
30
+ blog_root = add_blogs_index
31
+ blogs = Workarea::Content::Blog.all
32
+
33
+ blogs.each do |blog|
34
+ blog_root.children.create!(navigable: blog)
35
+ end
36
+
37
+ add_taxonomy_content_block(blog_root)
38
+ end
39
+
40
+ def add_blogs_index
41
+ Navigation::Taxon.root.children.create!(name: 'Blog', url: '/blogs')
42
+ end
43
+
44
+ def add_taxonomy_content_block(blog_root)
45
+ menu = Navigation::Menu.create!(taxon: blog_root)
46
+ content = Content.for(menu)
47
+ content.blocks.create!(
48
+ type: 'taxonomy',
49
+ data: { start: blog_root.id.to_s }
50
+ )
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ module Workarea
2
+ module Search
3
+ module Queries
4
+ class BlogAdmin
5
+ include Query
6
+
7
+ # repository Repositories::Admin
8
+ # refinements(
9
+ # Refinements::AdminSearch,
10
+ # Refinements::AdminFilters,
11
+ # Refinements::AdminSorting
12
+ # )
13
+
14
+ def initialize(params = {})
15
+ super(params.merge(type: 'blog'))
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ module Search
3
+ module Queries
4
+ class BlogEntryAdmin
5
+ include Query
6
+
7
+ def initialize(params = {})
8
+ super(params.merge(type: 'blog_entry', term_filters: %w[blog_id]))
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module Workarea
2
+ decorate SetNavigable, with: :blog do
3
+ decorated do
4
+ self.slug_map = slug_map.merge({
5
+ 'blog' => Content::Blog,
6
+ 'blog_entry' => Content::BlogEntry
7
+ })
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ module Workarea
2
+ module Admin
3
+ class BlogCommentsViewModel < ApplicationViewModel
4
+ cattr_accessor :per_page
5
+ self.per_page = 15
6
+
7
+ delegate :sorts, to: Content::BlogComment
8
+
9
+ def comments
10
+ return @comments if defined?(@comments)
11
+
12
+ comments = if options[:content_blog_entry_id].present?
13
+ blog_entry
14
+ .comments
15
+ .page(options[:page])
16
+ .per(per_page)
17
+ .order_by(options[:built_sort])
18
+ else
19
+ Content::BlogComment
20
+ .page(options[:page])
21
+ .per(per_page)
22
+ .order_by(options[:built_sort])
23
+ end
24
+
25
+ @comments = PagedArray.from(
26
+ comments,
27
+ comments.current_page,
28
+ per_page,
29
+ comments.total_count
30
+ )
31
+ end
32
+
33
+ def blog_entry
34
+ return nil unless options[:content_blog_entry_id].present?
35
+ @blog_entry ||= Content::BlogEntry.find_by(slug:
36
+ options[:content_blog_entry_id])
37
+ end
38
+
39
+ def blog
40
+ return nil unless blog_entry.present?
41
+ blog_entry.blog
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ module Workarea
2
+ module Admin
3
+ class BlogEntriesViewModel < ApplicationViewModel
4
+ cattr_accessor :per_page
5
+ self.per_page = 15
6
+
7
+ delegate :sorts, to: Content::BlogEntry
8
+
9
+ def entries
10
+ @entries ||=
11
+ begin
12
+ blog_entries = blog.entries
13
+ .page(options[:page])
14
+ .per(per_page)
15
+ .order_by(options[:built_sort])
16
+
17
+ PagedArray.from(
18
+ Admin::BlogEntryViewModel.wrap(blog_entries),
19
+ blog_entries.current_page,
20
+ per_page,
21
+ blog_entries.total_count
22
+ )
23
+ end
24
+ end
25
+
26
+ def blog
27
+ @blog ||= Content::Blog.find_by(slug: options[:content_blog_id])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Workarea
2
+ module Admin
3
+ class BlogEntryViewModel < ApplicationViewModel
4
+ include ContentableViewModel
5
+ include FeaturedProductsViewModel
6
+
7
+ def timeline
8
+ @timeline ||= TimelineViewModel.new(model)
9
+ end
10
+
11
+ def thumbnail_image_url
12
+ find_asset(model.thumbnail_image).url
13
+ end
14
+
15
+ def find_asset(id)
16
+ id = id.to_s
17
+ @assets ||= Hash.new do |hash, key|
18
+ hash[key] = begin
19
+ Content::Asset.find(id)
20
+ rescue StandardError
21
+ Content::Asset.placeholder
22
+ end
23
+ end
24
+
25
+ @assets[id]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ module Workarea
2
+ module Admin
3
+ class BlogSearchViewModel < SearchViewModel
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ module Admin
3
+ class BlogViewModel < ApplicationViewModel
4
+ include CommentableViewModel
5
+ include ContentableViewModel
6
+ # include RecommendableViewModel
7
+
8
+ def timeline
9
+ @timeline ||= TimelineViewModel.new(model)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ module Workarea
2
+ module Storefront
3
+ class BlogEntryViewModel < ApplicationViewModel
4
+ include DisplayContent
5
+
6
+ def blog
7
+ @blog ||= Storefront::BlogViewModel.new(model.blog)
8
+ end
9
+
10
+ def comments
11
+ @comments ||= model.comments.approved.limit(100)
12
+ end
13
+
14
+ def products
15
+ @products ||= Workarea::Storefront::ProductViewModel.wrap(
16
+ Catalog::Product.find_ordered(product_ids)
17
+ )
18
+ end
19
+
20
+ def thumbnail_image_url
21
+ find_asset(model.thumbnail_image).url(host: thumbnail_image_url_host)
22
+ end
23
+
24
+ # This ensures memoization happens
25
+ def find_asset(id)
26
+ @assets ||= {}
27
+ return @assets[id.to_s] if @assets[id.to_s].present?
28
+
29
+ @assets[id.to_s] = begin
30
+ Content::Asset.find(id)
31
+ rescue StandardError
32
+ Content::Asset.placeholder
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def thumbnail_image_url_host
39
+ Rails.configuration.action_controller.asset_host
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ module Workarea
2
+ module Storefront
3
+ class BlogIndexViewModel < ApplicationViewModel
4
+ include DisplayContent
5
+
6
+ def breadcrumbs
7
+ @breadcrumbs ||= Navigation::Breadcrumbs.new(model)
8
+ end
9
+
10
+ private
11
+
12
+ def content_lookup
13
+ 'blog_landing_page'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,83 @@
1
+ module Workarea
2
+ module Storefront
3
+ class BlogViewModel < ApplicationViewModel
4
+ include DisplayContent
5
+ include Pagination
6
+
7
+ cattr_accessor :per_page
8
+ self.per_page = 10
9
+
10
+ def breadcrumbs
11
+ @breadcrumbs ||= Navigation::Breadcrumbs.new(model)
12
+ end
13
+
14
+ def entries
15
+ @entries ||=
16
+ begin
17
+ arr = scoped_entries
18
+ .page(page)
19
+ .per(self.class.per_page)
20
+ .map { |e| BlogEntryViewModel.new(e) }
21
+
22
+ PagedArray.from(arr, page, self.class.per_page, total)
23
+ end
24
+ end
25
+
26
+ def entries_on_index
27
+ @entries ||=
28
+ begin
29
+ scoped_entries[0...Workarea.config.blog_entries_on_index]
30
+ .map { |entry| Storefront::BlogEntryViewModel.wrap(entry) }
31
+ end
32
+ end
33
+
34
+ def tags
35
+ @tags ||= if model.entries.any?
36
+ model.entries.where(active: true).all_tags
37
+ else
38
+ []
39
+ end
40
+ end
41
+
42
+ def total
43
+ @total ||= scoped_entries.count
44
+ end
45
+
46
+ def page
47
+ options[:page].present? ? options[:page].to_f : 1
48
+ end
49
+
50
+ def updated_at
51
+ @updated_at ||= model.entries.active.newest.first.try(:updated_at)
52
+ end
53
+
54
+ private
55
+
56
+ def current_release
57
+ Release.current || Release.new
58
+ end
59
+
60
+ def scoped_entries
61
+ return scoped_entries_from_database if current_release.published?
62
+
63
+ Kaminari.paginate_array(scoped_entries_filtered_by_current_release)
64
+ end
65
+
66
+ def ordered_entries
67
+ model.entries.order_by([:featured.desc, :written_at.desc])
68
+ end
69
+
70
+ def scoped_entries_from_database
71
+ scope = ordered_entries.active
72
+ scope = scope.tagged_with(options[:tag]) if options[:tag].present?
73
+ scope
74
+ end
75
+
76
+ def scoped_entries_filtered_by_current_release
77
+ scope = ordered_entries.select(&:active?)
78
+ scope.select! { |entry| entry.tags.include?(options[:tag]) } if options[:tag].present?
79
+ scope
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,63 @@
1
+ module Workarea
2
+ module Storefront
3
+ module ContentBlocks
4
+ class BlogEntryContentBlockViewModel < ContentBlockViewModel
5
+ def locals
6
+ return super if manual_entries_missing?
7
+
8
+ super.merge(entries: entries)
9
+ end
10
+
11
+ def multiple_entries?
12
+ if use_manual_entries?
13
+ model.data[:blog_entry].count > 1
14
+ else
15
+ model.data[:number_of_entries] > 1
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def entries
22
+ @entries ||= if use_manual_entries?
23
+ manual_entries
24
+ else
25
+ recent_entries
26
+ end
27
+ end
28
+
29
+ def recent_entries
30
+ entries = if model.data[:blog].present?
31
+ blog = Workarea::Content::Blog.find(model.data[:blog])
32
+ blog.entries.desc('written_at').limit(model.data[:number_of_entries])
33
+ else
34
+ Workarea::Content::BlogEntry.all.desc('written_at').limit(model.data[:number_of_entries])
35
+ end
36
+
37
+ Storefront::BlogEntryViewModel.wrap(entries)
38
+ end
39
+
40
+ def manual_entries
41
+ entries = Workarea::Content::BlogEntry.find(model.data[:blog_entry].reject(&:empty?))
42
+ Array.wrap(Storefront::BlogEntryViewModel.wrap(entries))
43
+ end
44
+
45
+ def use_manual_entries?
46
+ model.data[:use_manual_entries]
47
+ end
48
+
49
+ def manual_entries_missing?
50
+ use_manual_entries? && model.data[:blog_entry].empty?
51
+ end
52
+
53
+ def entry
54
+ @entry ||=
55
+ begin
56
+ blog_entry = Workarea::Content::BlogEntry.find(model.data[:id])
57
+ Storefront::BlogEntryViewModel.wrap(blog_entry)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,12 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ - if entry.audited.present?
10
+ = t('workarea.admin.activities.blog_comment_create_html', name: link_to(entry.audited.entry.name, edit_content_blog_user_comment_path(entry.audited, blog_entry_id: entry.audited.entry)))
11
+ - else
12
+ = t('workarea.admin.activities.blog_comment_create')
@@ -0,0 +1,9 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ = t('workarea.admin.activities.blog_comment_destroy')
@@ -0,0 +1,10 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ - name = entry.audited.blank? ? t('workarea.admin.activities.blog_comment') : link_to(t('workarea.admin.activities.blog_comment'), edit_content_blog_user_comment_path(entry.audited))
10
+ = t('workarea.admin.activities.blog_comment_update_html', fields: fields_clause_for(entry.tracked_changes), name: name)
@@ -0,0 +1,12 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ - if entry.audited.present?
10
+ = t('workarea.admin.activities.blog_create_html', name: link_to(entry.audited.name, edit_content_blog_path(entry.audited, blog_entry_id: entry.audited.id)))
11
+ - else
12
+ = t('workarea.admin.activities.blog_create_html', name: link_to(entry.model_name))
@@ -0,0 +1,10 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ = t('workarea.admin.activities.blog_destroy_html', name: entry.model_name)
10
+ = link_to_restore_for(entry)
@@ -0,0 +1,12 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ - if entry.audited.present?
10
+ = t('workarea.admin.activities.blog_entry_create_html', name: link_to(entry.audited.name, edit_content_blog_entry_path(entry.audited)))
11
+ - else
12
+ = t('workarea.admin.activities.blog_entry_create_html', name: link_to(entry.model_name))
@@ -0,0 +1,10 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ = t('workarea.admin.activities.blog_entry_destroy_html', name: entry.model_name)
10
+ = link_to_restore_for(entry)
@@ -0,0 +1,10 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ - name = entry.audited.blank? ? entry.model_name : link_to(entry.audited.name, edit_content_blog_entry_path(entry.audited))
10
+ = t('workarea.admin.activities.blog_entry_update_html', fields: fields_clause_for(entry.tracked_changes), name: name)
@@ -0,0 +1,10 @@
1
+ .activity
2
+ .activity__header
3
+ .activity__avatar
4
+ = link_to_modifier(entry) do
5
+ = avatar_for entry.modifier
6
+ %h3.activity__name= link_to_modifier(entry)
7
+ %p.activity__time= activity_time(entry.created_at)
8
+ .activity__message
9
+ - name = entry.audited.blank? ? entry.model_name : link_to(entry.audited.name, edit_content_blog_path(entry.audited))
10
+ = t('workarea.admin.activities.blog_update_html', fields: fields_clause_for(entry.tracked_changes), name: name)
@@ -0,0 +1 @@
1
+ %li= link_to t('workarea.admin.blog'), content_blogs_path, class: 'dashboard__navigation-link'
@@ -0,0 +1,13 @@
1
+ .primary-nav__section
2
+ .primary-nav__heading= link_to t('workarea.admin.shared.primary_nav.blogs'), content_blogs_path, tabindex: 0, class: 'primary-nav__heading-link'
3
+ %ul.primary-nav__children
4
+ - content = current_system_page_content_for(:blog_landing_page)
5
+ - if content.present?
6
+ %li{ class: "primary-nav__item" }= link_to content.name, current_system_page_content_for(:blog_landing_page), class: navigation_link_classes(url_for(current_system_page_content_for(:blog_landing_page)))
7
+
8
+ - pending_comment_count = Workarea::Content::BlogComment.pending.count
9
+ %li{ class: "primary-nav__item" }= link_to t('workarea.admin.shared.primary_nav.manage_comments', count: pending_comment_count), content_blog_user_comments_path, class: navigation_link_classes(content_blog_user_comments_path)
10
+
11
+ - Workarea::Content::Blog.each do |blog|
12
+ %li{ class: "primary-nav__item" }
13
+ = link_to blog.name, content_blog_path(blog), class: navigation_link_classes(content_blog_path(blog))
@@ -0,0 +1,4 @@
1
+ .property{ class: ('property--required' if field.required?) }
2
+ = label_tag dom_id(block, field.slug), field.name, class: 'property__name'
3
+ = select_tag "block[data][#{field.slug}]", options_for_blog_entries(block.data[field.slug]), id: dom_id(block, 'blog_entry_search'), title: t('workarea.admin.content_blocks.blog_entry_id.search_field_placeholder'), tabindex: '1', class: 'text-box', include_blank: true, multiple: true, data: { remote_select: { source: content_blog_entries_path, options: { placeholder: t('workarea.admin.content_blocks.blog_entry_id.search_field_placeholder') } } }
4
+ = hidden_field_tag "block[data][id]", block.data[:id], id: dom_id(block, 'blog_entry_id')
@@ -0,0 +1,3 @@
1
+ .property{ class: ('property--required' if field.required?) }
2
+ = label_tag dom_id(block, field.slug), field.name, class: 'property__name'
3
+ = select_tag "block[data][#{field.slug}]", options_for_blogs(block.data[field.slug]), id: dom_id(block, 'blog_search'), title: t('workarea.admin.content_blocks.blog_id.search_field_placeholder'), tabindex: '1', class: 'text-box', data: { remote_select: { source: content_blogs_path, options: { allowClear: true, placeholder: t('workarea.admin.content_blocks.blog_id.search_field_placeholder') } } }
@@ -0,0 +1,24 @@
1
+ %li.comments__comment
2
+ .comments__comment-header
3
+ .comments__comment-avatar
4
+ = link_to user_path(model.author) do
5
+ = avatar_for model.author, additional_css_class: 'avatar'
6
+ %h3.comments__comment-author= link_to model.author.name, user_path(model.author)
7
+ %p.comments__comment-time
8
+ #{time_ago_in_words(model.created_at)} ago
9
+ - if model.pending
10
+ %span= t('workarea.admin.content_blogs_comments.summary.pending')
11
+ .comments__comment-actions
12
+ .grid.grid--auto
13
+ %p.grid__cell
14
+ = link_to edit_content_blog_user_comment_path(model), class: 'text-button' do
15
+ Edit
16
+ = inline_svg('workarea/admin/icons/edit.svg', class: 'text-button__icon')
17
+
18
+ = form_tag content_blog_user_comment_path(model), method: 'delete', class: 'grid__cell' do
19
+ %p
20
+ = button_tag t('workarea.admin.actions.delete'), value: 'delete_comment', class: 'text-button text-button--destroy' do
21
+ = t('workarea.admin.actions.delete')
22
+ = inline_svg('workarea/admin/icons/delete.svg', class: 'text-button__icon')
23
+ .comments__comment-body
24
+ %p= model.body
@@ -0,0 +1,60 @@
1
+ - @page_title = t('workarea.admin.content_blogs_comments.edit.page_title', name: @blog_comment.entry.name)
2
+
3
+ .view
4
+ .view__header
5
+ .grid.grid--middle
6
+ .grid__cell.grid__cell--100
7
+ .view__heading
8
+ = link_to t('workarea.admin.content_blogs_comments.edit.comments_for_name', name: @blog_comment.entry.name), content_blog_user_comments_path(blog_entry_id: @blog_comment.entry.slug)
9
+ %h1= t('workarea.admin.content_blogs_comments.edit.edit_comment_by_user', user_name: @blog_comment.author.name)
10
+
11
+ .view__container
12
+ = render_cards_for(@blog_comment, :attributes)
13
+
14
+ - if @blog_comment.errors.present?
15
+ = render 'workarea/admin/shared/errors', errors: @blog_comment.errors
16
+
17
+ .view__container.view__container--narrow
18
+ = form_tag content_blog_user_comment_path(@blog_comment), method: 'put', id: 'blog_comment_form' do
19
+ = hidden_field_tag 'blog_entry_id', params[:blog_entry_id] if params[:blog_entry_id].present?
20
+
21
+ .grid.grid--middle
22
+ .grid__cell.grid__cell--75-at-medium
23
+ .comments
24
+ .comments__comment-header
25
+ .comments__comment-avatar
26
+ = link_to user_path(@blog_comment.author) do
27
+ = avatar_for @blog_comment.author, additional_css_class: 'avatar'
28
+ - if @user.present?
29
+ %h3.comments__comment-author= link_to @blog_comment.author.name, user_path(@blog_comment.author)
30
+ - else
31
+ %h3.comments__comment-author= t('workarea.admin.content_blogs_comments.edit.unregistered_user')
32
+
33
+ .grid__cell.grid__cell--25-at-medium
34
+ .grid.grid--auto.grid--right.grid--middle
35
+ .grid__cell
36
+ .compound-property
37
+ %span.compound-property__name= t('workarea.admin.content_blogs_comments.edit.approved')
38
+ = toggle_button_for 'blog_comment[approved]', @blog_comment.approved
39
+
40
+ .property.property--stacked
41
+ = label_tag 'blog_comment_body', t('workarea.admin.content_blogs_comments.edit.comment'), class: 'property__name'
42
+ = text_area_tag 'blog_comment[body]', @blog_comment.body, class: 'text-box text-box--multi-line'
43
+
44
+ .grid.grid--huge
45
+ .grid__cell.grid__cell--50.grid__cell--25-at-medium
46
+ .property
47
+ = label_tag 'comment_updated_at', t('workarea.admin.fields.updated_at'), class: 'property__name'
48
+ = local_time(@blog_comment.updated_at)
49
+ .grid__cell.grid__cell--50.grid__cell--25-at-medium
50
+ .property
51
+ = label_tag 'comment_created_at', t('workarea.admin.fields.created_at'), class: 'property__name'
52
+ = local_time(@blog_comment.created_at)
53
+
54
+ .workflow-bar
55
+ .grid.grid--middle
56
+ .grid__cell.grid__cell--50-at-medium
57
+ = link_to t('workarea.admin.form.cancel'), :back, class: 'workflow-bar__button workflow-bar__button--delete'
58
+ .grid__cell.grid__cell--50-at-medium
59
+ .grid.grid--auto.grid--right.grid--middle
60
+ .grid__cell= button_tag t('workarea.admin.form.save_changes'), value: 'save_blog_comment', class: 'workflow-bar__button workflow-bar__button--update'