decidim-blogs 0.11.0.pre1

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 (53) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +30 -0
  3. data/Rakefile +3 -0
  4. data/app/assets/images/decidim/blogs/icon.svg +3 -0
  5. data/app/commands/decidim/blogs/admin/create_post.rb +50 -0
  6. data/app/commands/decidim/blogs/admin/update_post.rb +44 -0
  7. data/app/controllers/decidim/blogs/admin/application_controller.rb +22 -0
  8. data/app/controllers/decidim/blogs/admin/posts_controller.rb +64 -0
  9. data/app/controllers/decidim/blogs/application_controller.rb +14 -0
  10. data/app/controllers/decidim/blogs/posts_controller.rb +35 -0
  11. data/app/events/decidim/blogs/create_post_event.rb +8 -0
  12. data/app/forms/decidim/blogs/admin/post_form.rb +18 -0
  13. data/app/helpers/decidim/blogs/admin/posts_helper.rb +25 -0
  14. data/app/helpers/decidim/blogs/application_helper.rb +13 -0
  15. data/app/helpers/decidim/blogs/posts_helper.rb +25 -0
  16. data/app/models/decidim/blogs/application_record.rb +10 -0
  17. data/app/models/decidim/blogs/post.rb +44 -0
  18. data/app/presenters/decidim/module/blogs/post_presenter.rb +14 -0
  19. data/app/views/decidim/blogs/admin/posts/_form.html.erb +13 -0
  20. data/app/views/decidim/blogs/admin/posts/edit.html.erb +7 -0
  21. data/app/views/decidim/blogs/admin/posts/index.html.erb +53 -0
  22. data/app/views/decidim/blogs/admin/posts/new.html.erb +7 -0
  23. data/app/views/decidim/blogs/posts/_author_data.html.erb +7 -0
  24. data/app/views/decidim/blogs/posts/_datetime.html.erb +1 -0
  25. data/app/views/decidim/blogs/posts/_posts.html.erb +20 -0
  26. data/app/views/decidim/blogs/posts/_sidebar_blog.html.erb +21 -0
  27. data/app/views/decidim/blogs/posts/index.html.erb +10 -0
  28. data/app/views/decidim/blogs/posts/show.html.erb +23 -0
  29. data/config/locales/ca.yml +69 -0
  30. data/config/locales/en.yml +70 -0
  31. data/config/locales/es.yml +69 -0
  32. data/config/locales/eu.yml +69 -0
  33. data/config/locales/fi.yml +69 -0
  34. data/config/locales/fr.yml +69 -0
  35. data/config/locales/gl.yml +69 -0
  36. data/config/locales/it.yml +69 -0
  37. data/config/locales/nl.yml +69 -0
  38. data/config/locales/pl.yml +69 -0
  39. data/config/locales/pt-BR.yml +69 -0
  40. data/config/locales/pt.yml +69 -0
  41. data/config/locales/ru.yml +5 -0
  42. data/config/locales/sv.yml +69 -0
  43. data/config/locales/uk.yml +6 -0
  44. data/db/migrate/20171129131353_create_decidim_blogs_posts.rb +12 -0
  45. data/db/migrate/20171211084630_add_author_to_decidim_blogs_posts.rb +7 -0
  46. data/lib/decidim/blogs.rb +13 -0
  47. data/lib/decidim/blogs/admin.rb +10 -0
  48. data/lib/decidim/blogs/admin_engine.rb +22 -0
  49. data/lib/decidim/blogs/component.rb +65 -0
  50. data/lib/decidim/blogs/engine.rb +24 -0
  51. data/lib/decidim/blogs/test/factories.rb +20 -0
  52. data/lib/decidim/blogs/version.rb +10 -0
  53. metadata +235 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 77d681860119dee520f12322bc3f82962b485e3710348cf0f95d3c2a3ac8fa2e
4
+ data.tar.gz: b48ac462f570f74867ff27af60100619bac5a9324654ac916696e8266fd90f43
5
+ SHA512:
6
+ metadata.gz: 46b48ee482df01acd8c07a2e24dd98efd75a5550eee2a33d96bf4d3ffae82718f269c5fdcb3f1bf01b5d7e7bc0b46fbdf3e4f502904bf2d7fd0407962b21fce8
7
+ data.tar.gz: 401e1475f4107a3b265ea7f3bbf1e72ec2dc6188ce213da3f229f8bea989eec290708ce3008fa5d6aaf1c1022381634b09edef1c16e1e81c78d44958f7ccd6cb
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # decidim-blogs
2
+
3
+ The BLOG module adds posts to any participatory process. It adds a CRUD engine
4
+ to the admin and public view scoped inside the participatory process.
5
+
6
+ ## Usage
7
+
8
+ BLOG will be available as a Component for a Participatory Process.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'decidim-blogs'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ ```bash
21
+ bundle
22
+ ```
23
+
24
+ ## Contributing
25
+
26
+ See [Decidim](https://github.com/decidim/decidim).
27
+
28
+ ## License
29
+
30
+ See [Decidim](https://github.com/decidim/decidim).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
2
+ <path d="M18 0C8.07 0 0 8.07 0 18s8.07 18 18 18 18-8.071 18-18S27.93 0 18 0zm0 2c8.85 0 16 7.152 16 16 0 8.848-7.15 16-16 16-8.848 0-16-7.152-16-16C2 9.152 9.152 2 18 2zm-7 9a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2H11zm0 4a1 1 0 1 0 0 2h10a1 1 0 1 0 0-2H11zm0 4a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2H11zm0 4a1 1 0 1 0 0 2h10a1 1 0 1 0 0-2H11z"/>
3
+ </svg>
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ module Admin
6
+ # This command is executed when the user creates a Post from the admin
7
+ # panel.
8
+ class CreatePost < Rectify::Command
9
+ def initialize(form, current_user)
10
+ @form = form
11
+ @current_user = current_user
12
+ end
13
+
14
+ # Creates the post if valid.
15
+ #
16
+ # Broadcasts :ok if successful, :invalid otherwise.
17
+ def call
18
+ return broadcast(:invalid) if @form.invalid?
19
+
20
+ transaction do
21
+ create_post!
22
+ send_notification
23
+ end
24
+
25
+ broadcast(:ok, @post)
26
+ end
27
+
28
+ private
29
+
30
+ def create_post!
31
+ @post = Post.create!(
32
+ title: @form.title,
33
+ body: @form.body,
34
+ component: @form.current_component,
35
+ decidim_author_id: @current_user.id
36
+ )
37
+ end
38
+
39
+ def send_notification
40
+ Decidim::EventsManager.publish(
41
+ event: "decidim.events.blogs.post_created",
42
+ event_class: Decidim::Blogs::CreatePostEvent,
43
+ resource: @post,
44
+ recipient_ids: @post.participatory_space.followers.pluck(:id)
45
+ )
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ module Admin
6
+ # This command is executed when the user changes a Blog from the admin
7
+ # panel.
8
+ class UpdatePost < Rectify::Command
9
+ # Initializes a UpdateBlog Command.
10
+ #
11
+ # form - The form from which to get the data.
12
+ # blog - The current instance of the page to be updated.
13
+ def initialize(form, post)
14
+ @form = form
15
+ @post = post
16
+ end
17
+
18
+ # Updates the blog if valid.
19
+ #
20
+ # Broadcasts :ok if successful, :invalid otherwise.
21
+ def call
22
+ return broadcast(:invalid) if form.invalid?
23
+
24
+ transaction do
25
+ update_post!
26
+ end
27
+
28
+ broadcast(:ok, post)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :form, :post
34
+
35
+ def update_post!
36
+ post.update!(
37
+ title: form.title,
38
+ body: form.body
39
+ )
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ module Admin
6
+ # Base controller for the administration of this module. It inherits from
7
+ # Decidim's admin base controller in order to inherit the layout and other
8
+ # convenience methods relevant to a this component.
9
+ class ApplicationController < Decidim::Admin::Components::BaseController
10
+ helper_method :posts, :post
11
+
12
+ def posts
13
+ @posts ||= Post.where(component: current_component).page(params[:page]).per(15)
14
+ end
15
+
16
+ def post
17
+ @post ||= posts.find(params[:id])
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ module Admin
6
+ # This controller allows the create or update a blog.
7
+ class PostsController < Admin::ApplicationController
8
+ def new
9
+ @form = form(PostForm).instance
10
+ end
11
+
12
+ def create
13
+ @form = form(PostForm).from_params(params, current_component: current_component)
14
+
15
+ CreatePost.call(@form, current_user) do
16
+ on(:ok) do
17
+ flash[:notice] = I18n.t("posts.create.success", scope: "decidim.blogs.admin")
18
+ redirect_to posts_path
19
+ end
20
+
21
+ on(:invalid) do
22
+ flash.now[:alert] = I18n.t("posts.create.invalid", scope: "decidim.blogs.admin")
23
+ render action: "new"
24
+ end
25
+ end
26
+ end
27
+
28
+ def edit
29
+ @form = form(PostForm).from_model(post)
30
+ end
31
+
32
+ def update
33
+ @form = form(PostForm).from_params(params, current_component: current_component)
34
+
35
+ UpdatePost.call(@form, post) do
36
+ on(:ok) do
37
+ flash[:notice] = I18n.t("posts.update.success", scope: "decidim.blogs.admin")
38
+ redirect_to posts_path
39
+ end
40
+
41
+ on(:invalid) do
42
+ flash.now[:alert] = I18n.t("posts.update.invalid", scope: "decidim.blogs.admin")
43
+ render action: "edit"
44
+ end
45
+ end
46
+ end
47
+
48
+ def destroy
49
+ post.destroy!
50
+
51
+ flash[:notice] = I18n.t("posts.destroy.success", scope: "decidim.blogs.admin")
52
+
53
+ redirect_to posts_path
54
+ end
55
+
56
+ private
57
+
58
+ def post
59
+ @post ||= Blogs::Post.find_by(component: current_component)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ # Note that it inherits from `Decidim::Components::Basecontroller`, which
9
+ # override its layout and provide all kinds of useful methods.
10
+ class ApplicationController < Decidim::Components::BaseController
11
+ helper Decidim::Blogs::ApplicationHelper
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # Exposes the blog resource so users can view them
6
+ class PostsController < Decidim::Blogs::ApplicationController
7
+ helper_method :posts, :post, :paginate_posts, :posts_most_commented
8
+
9
+ def index; end
10
+
11
+ def show; end
12
+
13
+ private
14
+
15
+ def paginate_posts
16
+ @paginate_posts ||= posts.created_at_desc.page(params[:page]).per(4)
17
+ end
18
+
19
+ def post
20
+ @post ||= posts.find(params[:id])
21
+ end
22
+
23
+ def posts
24
+ @posts ||= Post.where(component: current_component)
25
+ end
26
+
27
+ # PROVISIONAL if we implement counter cache
28
+ def posts_most_commented
29
+ @posts_most_commented ||= posts.joins(:comments).group(:id)
30
+ .select("count(decidim_comments_comments.id) as counter")
31
+ .select("decidim_blogs_posts.*").order("counter DESC").created_at_desc.limit(7)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ class CreatePostEvent < Decidim::Events::SimpleEvent
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ module Admin
6
+ # This class holds a Form to update pages from Decidim's admin panel.
7
+ class PostForm < Decidim::Form
8
+ include TranslatableAttributes
9
+
10
+ translatable_attribute :title, String
11
+ translatable_attribute :body, String
12
+
13
+ validates :title, translatable_presence: true
14
+ validates :body, translatable_presence: true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ module Admin
6
+ # Custom helpers used in posts views
7
+ module PostsHelper
8
+ include Decidim::ApplicationHelper
9
+ # include Decidim::TranslationsHelper
10
+ # include Decidim::ResourceHelper
11
+
12
+ # Public: truncates the post body
13
+ #
14
+ # post - a Decidim::Blog instance
15
+ # max_length - a number to limit the length of the body
16
+ #
17
+ # Returns the post's body truncated.
18
+ def post_description_admin(post, max_length = 100)
19
+ body = translated_attribute(post.body)
20
+ CGI.unescapeHTML html_truncate(body, max_length: max_length)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # Custom helpers, scoped to the blogs engine.
6
+ #
7
+ module ApplicationHelper
8
+ include PaginateHelper
9
+ include Decidim::Blogs::PostsHelper
10
+ include Decidim::Comments::CommentsHelper
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # Custom helpers used in posts views
6
+ module PostsHelper
7
+ include Decidim::ApplicationHelper
8
+ include Decidim::TranslationsHelper
9
+ include Decidim::ResourceHelper
10
+
11
+ # Public: truncates the post body
12
+ #
13
+ # post - a Decidim::Blog instance
14
+ # max_length - a number to limit the length of the body
15
+ #
16
+ # Returns the post's body truncated.
17
+ def post_description(post, max_length = 600)
18
+ link = post_path(post)
19
+ body = translated_attribute(post.body)
20
+ tail = "... <br/> #{link_to(t("read_more", scope: "decidim.blogs"), link)}".html_safe
21
+ CGI.unescapeHTML html_truncate(body, max_length: max_length, tail: tail)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # Abstract class from which all models in this engine inherit.
6
+ class ApplicationRecord < ActiveRecord::Base
7
+ self.abstract_class = true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Blogs
5
+ # The data store for a Blog in the Decidim::Blogs component. It stores a
6
+ # title, description and any other useful information to render a blog.
7
+ class Post < Blogs::ApplicationRecord
8
+ include Decidim::Resourceable
9
+ include Decidim::HasComponent
10
+ include Decidim::Authorable
11
+ include Decidim::Comments::Commentable
12
+
13
+ component_manifest_name "blogs"
14
+
15
+ validates :title, presence: true
16
+
17
+ scope :created_at_desc, -> { order(arel_table[:created_at].desc) }
18
+
19
+ # Public: Overrides the `commentable?` Commentable concern method.
20
+ def commentable?
21
+ component.settings.comments_enabled?
22
+ end
23
+
24
+ # Public: Overrides the `accepts_new_comments?` Commentable concern method.
25
+ def accepts_new_comments?
26
+ commentable? && !component.current_settings.comments_blocked
27
+ end
28
+
29
+ # Public: Overrides the `comments_have_alignment?` Commentable concern method.
30
+ def comments_have_alignment?
31
+ true
32
+ end
33
+
34
+ # Public: Overrides the `comments_have_votes?` Commentable concern method.
35
+ def comments_have_votes?
36
+ true
37
+ end
38
+
39
+ def official?
40
+ author.nil?
41
+ end
42
+ end
43
+ end
44
+ end