decidim 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim might be problematic. Click here for more details.

Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -8
  3. data/Gemfile.lock +143 -145
  4. data/README.md +42 -62
  5. data/Rakefile +26 -25
  6. data/docs/add_authenticable_action.md +20 -0
  7. data/docs/adding_fixtures_aka_dummy_content.md +7 -0
  8. data/docs/advanced/activity_log.md +138 -0
  9. data/docs/{content_processors.md → advanced/content_processors.md} +1 -1
  10. data/docs/advanced/deploy.md +9 -0
  11. data/docs/{features_and_components.md → advanced/features.md} +0 -0
  12. data/docs/{create_followers_from_resource_authors.md → advanced/followers.md} +17 -1
  13. data/docs/advanced/how_to_create_a_module.md +9 -0
  14. data/docs/{managing_translations_i18n.md → advanced/managing_translations_i18n.md} +0 -0
  15. data/docs/{migrate_to_0.8.0.md → advanced/migrate_to_0.8.0.md} +26 -22
  16. data/docs/advanced/testing.md +29 -0
  17. data/docs/advanced/tradeoffs.md +14 -0
  18. data/docs/{view_hooks.md → advanced/view_hooks.md} +18 -5
  19. data/docs/customization/authorizations.md +13 -1
  20. data/docs/data-picker.md +48 -0
  21. data/docs/getting_started.md +28 -17
  22. data/docs/services/activejob.md +7 -0
  23. data/docs/{analytics.md → services/analytics.md} +0 -0
  24. data/docs/{geocoding.md → services/geocoding.md} +0 -0
  25. data/docs/{social_providers.md → services/social_providers.md} +0 -0
  26. data/lib/decidim/component_manager.rb +22 -21
  27. data/lib/decidim/version.rb +1 -1
  28. data/lib/generators/decidim/app_generator.rb +33 -16
  29. data/lib/generators/decidim/install_generator.rb +9 -3
  30. data/lib/generators/decidim/templates/database.yml.erb +2 -2
  31. data/lib/generators/decidim/templates/initializer.rb +1 -1
  32. metadata +51 -45
  33. data/docs/create_followers_from_comment_authors.md +0 -12
  34. data/docs/how_to_create_a_module.md +0 -170
  35. data/docs/testing.md +0 -17
data/README.md CHANGED
@@ -41,77 +41,49 @@ Project management [[See on Waffle.io]](https://waffle.io/decidim/decidim)
41
41
 
42
42
  * [Get started with Decidim](#getting-started-with-decidim)
43
43
  * [Contribute to the project](#how-to-contribute)
44
- * [Officially supported modules](#officially-supported-modules)
45
- * [How to test Decidim engines](docs/testing.md)
44
+ * [Modules](#modules)
46
45
  * [Create & browse development app](#browse-decidim)
47
- * [Technical tradeoffs](#technical-tradeoffs)
48
46
 
49
47
  ---
50
48
 
51
49
  ## Getting started with Decidim
52
50
 
53
- We've set up a guide on how to install, set up and upgrade Decidim. See the [Getting started guide](https://github.com/decidim/decidim/blob/master/docs/getting_started.md).
54
-
55
- ## How to contribute
56
-
57
- ### As a Translator
58
-
59
- Decidim is already translated on multiple languages (English, Spanish, Catalan, Basque, Galician, Italian, Finnish, Dutch, French, Portuguese (and Brazilian Portuguese), Swedish, Russian and Ukrainian). You can help us at [Crowdin, the translation service](https://crowdin.com/project/decidim), reviewing these translations or proposing a new language to add to the platform.
60
-
61
- ### As a Developer
51
+ TLDR: install gem, generate a Ruby on Rails app, enjoy.
62
52
 
63
- In order to develop on decidim, you'll need:
64
-
65
- * **Git** 2.15+
66
- * **PostgreSQL** 9.4+
67
- * **Ruby** 2.5.0 (2.3+ should work just fine, but that's the version we test against)
68
- * **NodeJS** 9.x.x (with `yarn` as a package manager)
69
- * **ImageMagick**
70
- * **Chrome** browser and [chromedriver](https://sites.google.com/a/chromium.org/chromedriver/).
71
-
72
- The easiest way to work on decidim is to clone decidim's repository and install its dependencies
73
-
74
- ```bash
75
- git clone git@github.com:decidim/decidim.git
76
- cd decidim
77
- bundle install
78
- yarn install
53
+ ```console
54
+ gem install decidim
55
+ decidim decidim_application
79
56
  ```
80
57
 
81
- You have several rake tasks available:
82
-
83
- * `bundle exec rake development_app`: Creates a development app which you can use to run an application with the gems in your path.
84
- * `bundle exec rake test_app`: Generates a dummy application to be used for testing.
85
- * `bundle exec rake test_all`: Runs the tests of every engine using the dummy
86
- application
58
+ We've set up a guide on how to install, set up and upgrade Decidim. See the [Getting started guide](https://github.com/decidim/decidim/blob/master/docs/getting_started.md).
87
59
 
88
- #### Browse Decidim
60
+ ## How to contribute
89
61
 
90
- After you create a development app (`bundle exec rake development_app`):
62
+ See [Contributing](CONTRIBUTING.md).
91
63
 
92
- * `cd development_app`
93
- * `bundle exec rails s`
94
- * Go to 'http://localhost:3000'
64
+ ### Browse Decidim
95
65
 
96
- Optionally, you can log in as: user@example.org | decidim123456
66
+ After you create a development app (`bundle exec rake development_app`), you
67
+ have to switch to it and boot the rails server with `cd development_app &&
68
+ bundle exec rails s`.
97
69
 
98
- Also, if you want to verify yourself against the default authorization handler use a document number ended with "X".
70
+ After that, you can:
99
71
 
100
- #### Browse Admin Interface
72
+ * Browse the main interface at `http://localhost:3000`, and log in as: user@example.org | decidim123456
73
+ * Browse the admin interface at `http://localhost:3000/admin`, and log in as: admin@example.org | decidim123456
74
+ * Browse the system interface at `http://localhost:3000/system`, and log in as: system@example.org | decidim123456
101
75
 
102
- After you create a development app (`bundle exec rake development_app`):
76
+ Also, if you want to verify yourself against the default authorization handler use a document number ended with "X".
103
77
 
104
- * `cd development_app`
105
- * `bundle exec rails s`
106
- * Go to 'http://localhost:3000/admin'
107
- * Login data: admin@example.org | decidim123456
78
+ ## Modules
108
79
 
109
- ## Officially supported modules
80
+ ### Official (stable)
110
81
 
111
- | Library | Description |
82
+ | Module | Description |
112
83
  | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
84
+ | [Accountability](https://github.com/decidim/decidim/tree/master/decidim-accountability) | Adds an accountability section to any participatory space so users can follow along the state of the accepted proposals. |
113
85
  | [Admin](https://github.com/decidim/decidim/tree/master/decidim-admin) | Adds an administration dashboard so users can manage their organization and all other entities. |
114
- | [API](https://github.com/decidim/decidim/tree/master/decidim-api) | Exposes a GraphQL API to programatically interact with the Decidim platform via HTTP |
86
+ | [API](https://github.com/decidim/decidim/tree/master/decidim-api) | Exposes a GraphQL API to programatically interact with the Decidim platform via HTTP. |
115
87
  | [Assemblies](https://github.com/decidim/decidim/tree/master/decidim-assemblies) | Permanent participatory spaces. |
116
88
  | [Budgets](https://github.com/decidim/decidim/tree/master/decidim-budgets) | Adds a participatory budgets system to any participatory space. |
117
89
  | [Comments](https://github.com/decidim/decidim/tree/master/decidim-comments) | The Comments module adds the ability to include comments to any resource which can be commentable by users. |
@@ -121,23 +93,31 @@ After you create a development app (`bundle exec rake development_app`):
121
93
  | [Meeting](https://github.com/decidim/decidim/tree/master/decidim-meetings) | The Meeting module adds meeting to any participatory space. It adds a CRUD engine to the admin and public view scoped inside the participatory space. |
122
94
  | [Pages](https://github.com/decidim/decidim/tree/master/decidim-pages) | The Pages module adds static page capabilities to any participatory space. It basically provides an interface to include arbitrary HTML content to any step. |
123
95
  | [Proposals](https://github.com/decidim/decidim/tree/master/decidim-proposals) | The Proposals module adds one of the main features of Decidim: allows users to contribute to a participatory space by creating proposals. |
124
- | [Accountability](https://github.com/decidim/decidim/tree/master/decidim-accountability) | Adds an accountability section to any participatory space so users can follow along the state of the accepted proposals. |
125
96
  | [Surveys](https://github.com/decidim/decidim/tree/master/decidim-surveys) | Adds the ability for admins to create arbitrary surveys. |
126
- | [System](https://github.com/decidim/decidim/tree/master/decidim-system) | Multitenant Admin to manage multiple organizations in a single installation |
97
+ | [System](https://github.com/decidim/decidim/tree/master/decidim-system) | Multitenant Admin to manage multiple organizations in a single installation. |
127
98
 
128
- ## Technical tradeoffs
99
+ ### Official (on development)
129
100
 
130
- ### Architecture
131
-
132
- This is not your typical Ruby on Rails Vanilla App. We've tried using [Consul](http://decide.es) but we found some problems on reutilization, adaptation, modularization and configuration. You can read more about that on "[Propuesta de Cambios de Arquitectura de Consul](https://www.gitbook.com/book/alabs/propuesta-de-cambios-en-la-arquitectura-de-consul/details)".
133
-
134
- ### Turbolinks
135
-
136
- Decidim doesn't support `turbolinks` so it isn't included on our generated apps and it's removed for existing Rails applications which install the Decidim engine.
101
+ | Module | Description |
102
+ | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
103
+ | [Blogs](https://github.com/decidim/decidim-module-blogs) | This component makes possible to add posts ordered by publication time to spaces. |
104
+ | [Consultations](https://github.com/decidim/decidim-module-consultations) | This module creates a new space for decidim to host consultations: debates around critical questions and a proxy for eVoting |
105
+ | [Initiatives](https://github.com/decidim/decidim-initiatives) | Initiatives is the place on Decidim's where citizens can promote a civic initiative. Unlike participatory processes that must be created by an administrator, Civic initiatives can be created by any user of the platform. |
106
+ | [Sortitions](https://github.com/decidim/decidim-module-sortitions) | This component makes possible to select randomly a number of proposals among a set of proposals (or a category of proposals within a set) maximizing guarantees of randomness and avoiding manipulation of results by the administrator. |
137
107
 
138
- The main reason is we are injecting some scripts into the body for some individual pages and Turbolinks loads the scripts in parallel. For some libraries like [leaflet](http://leafletjs.com/) it's very inconvenient because its plugins extend an existing global object.
108
+ ### Community
139
109
 
140
- The support of Turbolinks was dropped in [d8c7d9f](https://github.com/decidim/decidim/commit/d8c7d9f63e4d75307e8f7a0360bef977fab209b6). If you're interested in bringing turbolinks back, further discussion is welcome.
110
+ | Module | Description |
111
+ | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
112
+ | [Census](https://github.com/diputacioBCN/decidim-diba/tree/master/decidim-census) | Allows to upload a census CSV file to perform authorizations against real users parameterised by their age. |
113
+ | [Crowdfunding](https://github.com/podemos-info/decidim-module-crowdfundings) | This rails engine implements a Decidim feature that allows to the administrators to configure crowfunding campaigns for a participatory space. |
114
+ | [DataViz](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/tree/master/decidim-dataviz) | The Dataviz module adds the PAM data visualizations to any participatory process but it is intended to be used just for the PAM participatory process. |
115
+ | [Members](https://github.com/ElectricThings/decidim-members) | Members list and search plugin for Decidim |
116
+ | [Pol.is](https://github.com/OpenSourcePolitics/decidim-polis) | Pol.is integration on Decidim |
117
+ | [User Export](https://github.com/OpenSourcePolitics/decidim-user-export) | Allow user export |
118
+ | [Verification DIBA Census API](https://github.com/diputacioBCN/decidim-diba/tree/master/decidim-diba_census_api) | A decidim package to provice user authorizations agains the Diputació of Barcelona census API |
119
+ | [Verification Podemos Census API](https://github.com/podemos-info/decidim-module-census_connector) | A decidim package to provice user authorizations against the Podemos census API |
120
+ | [Votings](https://github.com/podemos-info/decidim-module-votings) | An administrator can add one or more votings to a participatory process or assambly |
141
121
 
142
122
  ## Following our license
143
123
 
data/Rakefile CHANGED
@@ -30,19 +30,36 @@ end
30
30
  desc "Installs all gems locally."
31
31
  task :install_all do
32
32
  Decidim::ComponentManager.run_all(
33
- "rake install:local",
34
- out: File::NULL
33
+ "gem build %name && mv %name-%version.gem ..",
34
+ include_root: false
35
+ )
36
+
37
+ Decidim::ComponentManager.new(__dir__).run(
38
+ "gem build %name && gem install *.gem"
35
39
  )
36
40
  end
37
41
 
38
42
  desc "Uninstalls all gems locally."
39
43
  task :uninstall_all do
40
44
  Decidim::ComponentManager.run_all(
41
- "gem uninstall %name -v %version --executables --force",
42
- out: File::NULL
45
+ "gem uninstall %name -v %version --executables --force"
46
+ )
47
+
48
+ Decidim::ComponentManager.new(__dir__).run(
49
+ "rm decidim-*.gem"
43
50
  )
44
51
  end
45
52
 
53
+ Decidim::ComponentManager.all_dirs(include_root: false) do |dir|
54
+ manager = Decidim::ComponentManager.new(dir)
55
+ name = manager.short_name
56
+
57
+ desc "Runs tests on #{name}"
58
+ task "test_#{name}" do
59
+ manager.run("rake")
60
+ end
61
+ end
62
+
46
63
  desc "Pushes a new build for each gem."
47
64
  task release_all: [:update_versions, :check_locale_completeness, :webpack] do
48
65
  Decidim::ComponentManager.run_all("rake release")
@@ -53,31 +70,15 @@ task :check_locale_completeness do
53
70
  system({ "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }, "rspec spec/i18n_spec.rb")
54
71
  end
55
72
 
56
- desc "Generates a dummy app for testing"
57
- task :test_app do
58
- dummy_app_path = File.expand_path(File.join(Dir.pwd, "spec", "decidim_dummy_app"))
73
+ load "decidim-dev/lib/tasks/generators.rake"
59
74
 
60
- Dir.chdir(__dir__) do
61
- sh "rm -fR #{dummy_app_path}", verbose: false
62
-
63
- Decidim::Generators::AppGenerator.start(
64
- [dummy_app_path, "--path", "../..", "--recreate_db", "--demo"]
65
- )
66
- end
67
- end
75
+ desc "Generates a dummy app for testing"
76
+ task test_app: "decidim:generate_external_test_app"
68
77
 
69
78
  desc "Generates a development app."
70
- task :development_app do
71
- Dir.chdir(__dir__) do
72
- sh "rm -fR development_app", verbose: false
73
- end
74
-
75
- Decidim::Generators::AppGenerator.start(
76
- ["development_app", "--path", "..", "--recreate_db", "--seed_db", "--demo"]
77
- )
78
- end
79
+ task development_app: "decidim:generate_external_development_app"
79
80
 
80
81
  desc "Build webpack bundle files"
81
82
  task :webpack do
82
- sh "yarn install && yarn build:prod"
83
+ sh "npm install && npm run build:prod"
83
84
  end
@@ -0,0 +1,20 @@
1
+ # How to add a new authenticable action?
2
+ ## Proposals example
3
+ We're going to reproduce the steps to add an action (adhere) for a proposal step by step.
4
+ ### Configuring a new 'adhere' action
5
+ 1. Edit decidim-proposals/lib/decidim/proposals/feature.rb
6
+ 1. Add the new 'adhere' action into the `feature.actions` array and save the file:
7
+ ```
8
+ feature.actions = %w(adhere vote create)
9
+ ```
10
+
11
+ 3. Translate the action for the corresponding key: `en.decidim.features.proposals.actions.adhere = Adhere`
12
+ 1. Edit `app/models/decidim/proposals/abilities/current_user_ability.rb` and add the corresponding cancancan ability like `can :adhere, Proposal do |_proposal| ...`.
13
+ 1. Restart the server to pick up the changes.
14
+ 1. Now the admin should be able to go to the Control Panel and edit `PROCESSES/Proposals/Permissions/Adhere` panel. There an `Authorization Handler` can be set.
15
+
16
+ ### Using the new 'adhere' action
17
+ With a user which has the selected permission verified:
18
+ 1. Go to a Proposal detail in the front-end
19
+ 1. Adhere to the current proposal (see ProposalAdhesionsController): the user should be able to perform an adhesion.
20
+ - If the user had the required permission unverified, the 'adhere' button should block the action. You can check it with an unverified user.
@@ -0,0 +1,7 @@
1
+ # How to add dummy content to a development application?
2
+ ## Proposals example
3
+ 1. In decidim-proposals open `lib/decidim/proposals/feature.rb`.
4
+ 1. Find the `feature.seeds do...` block.
5
+ 1. Create your dummy content as if you were in a `db/seed.rb` script.
6
+ - Take advantage of the Faker gem, already in decidim.
7
+ - You can use https://github.com/decidim/decidim/blob/master/decidim-core/lib/decidim/faker/localized.rb, which uses `Faker` internally, if you need content for i18n fields.
@@ -0,0 +1,138 @@
1
+ # Activity log
2
+
3
+ In order to make your component compatible with the activity log, you need to follow these steps:
4
+
5
+ 1. Make your model include the `Decidim::Traceable` module. This will let Decidim create versions every time your model records are changed. It uses [`paper_trail`](https://github.com/airblade/paper_trail) to generate the versions.
6
+ 1. Make your commands use `Decidim.traceability` to create and update records. Documentation can be found in `Decidim::Traceability`. This should set the author of the change in your record properly.
7
+
8
+ That's all you need to do to get it working, really. We have a default way to present logs that Just Works™. Keep reading if you want to customize how the logs for your resources look!
9
+
10
+ ## The default renderer
11
+
12
+ The default renderer doesn't know many things. It knows the author, what action was done, the resource affected and the space where the resource resides. When the resource is updated it shows the diff of all the fields that have been changed, with the old and new values for each field. values are not formatted in any specific way, so you might see some weirdly formatted values on the log diff: that's how it's rendered from the database.
13
+
14
+ ## Customizing the logs for your resources
15
+
16
+ The default presenter doesn't fulfill your needs? You might want to create your own presenter if you find yourself in one of these cases:
17
+
18
+ - You want to show what type of resource is affected by the action log
19
+ - The default renderer cannot find the correct field to render the resource name
20
+ - You want to show more info
21
+ - You want to change the order of the factors in the log sentence
22
+ - You want to change the format of the values in the diff
23
+
24
+ Let's go ahead and see how to create your own resource presenter.
25
+
26
+ Custom presenters should be named as `Decidim::<your module name>::<log name>::<your model name>Presenter`. There's currently only one log, `AdminLog`. This means that if your model is `Decidim::Accountability::Result`, then your admin log presenter is must be `Decidim::Accountability::AdminLog::ResultPresenter`. You can inherit from `Decidim::Log::BasePresenter` for simplicity:
27
+
28
+ ```ruby
29
+ module Decidim
30
+ module Accountability
31
+ module AdminLog
32
+ class ResultPresenter < Decidim::Log::BasePresenter
33
+ end
34
+ end
35
+ end
36
+ end
37
+ ```
38
+
39
+ Some examples with basic customization follow, although you can read the source code docs and overwrite any method you need.
40
+
41
+ ### Changing the action log sentence
42
+
43
+ In order to change the default sentence to something that fits better to your resource, you can overwrite the `action_string` method in your presenter:
44
+
45
+ ```ruby
46
+ module Decidim
47
+ module Accountability
48
+ module AdminLog
49
+ class ResultPresenter < Decidim::Log::BasePresenter
50
+ private
51
+
52
+ def action_string
53
+ case action
54
+ when "create"
55
+ "decidim.accountability.admin_log.result.create"
56
+ when "update"
57
+ "decidim.accountability.admin_log.result.update"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ ```
65
+
66
+ This is useful to show the resource type in the sentence.
67
+
68
+ ### Limiting what fields get presented in the diff
69
+
70
+ By default, all changed fields are presented in the diff. In order to limit them, overwrite the `diff_fields_mapping` method in your custom presenter. It has to return a `Hash`, where keys are the name of the attributes and values are the presenters that render the attributes. **Limitations**: we can only show diffs for column fields, not dynamic methods, so the `diff_fields_mapping` only accepts column names.
71
+
72
+ In this example, we're telling our presenter to only present the `start_date` as a date, the `title` as an i18n field, the `decidim_scope_id` with no particular presenter, and `progress` as a percentage:
73
+
74
+ ```ruby
75
+ module Decidim
76
+ module Accountability
77
+ module AdminLog
78
+ class ResultPresenter < Decidim::Log::BasePresenter
79
+ private
80
+
81
+ def diff_fields_mapping
82
+ {
83
+ start_date: :date,
84
+ title: :i18n,
85
+ decidim_scope_id: :default,
86
+ progress: :percentage
87
+ }
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ ```
94
+
95
+ #### Value types presenters
96
+
97
+ Decidim comes with some default value types presenters to be used in the diffs. They all live in `Decidim::Log::ValueTypes`, check the source code for the full list. These presenters are used with a symbol, but you can use your own value type presenter if you use a string:
98
+
99
+ ```ruby
100
+ module Decidim
101
+ module Accountability
102
+ module AdminLog
103
+ class ResultPresenter < Decidim::Log::BasePresenter
104
+ private
105
+
106
+ def diff_fields_mapping
107
+ {
108
+ decidim_scope_id: "Decidim::Accountability::AdminLog::ValueTypes::MyCustomPresenter",
109
+ }
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ ```
116
+
117
+ Then you can write your own value presenter as:
118
+
119
+ ```ruby
120
+ module Decidim
121
+ module Accountability
122
+ module AdminLog
123
+ module ValueTypes
124
+ class MyCustomPresenter < Decidim::Log::Valuetypes::DefaultPresenter
125
+ def present
126
+ return unless value
127
+ "My super duper value: #{value}"
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ ```
135
+
136
+ ## Multiple logs
137
+
138
+ Although Decidim currently only has a log for the admin section, in the future we might need an activity log for the public part. It's easy to assume we might need to render the same data in different formats, so we need to differentiate the presenters for each log. The current system handles the case for multiple logs, although we only have one.
@@ -8,7 +8,7 @@ The content parser class is used to process the text before it is saved to the d
8
8
 
9
9
  Register the content processor in an `initializer`:
10
10
 
11
- ```
11
+ ```ruby
12
12
  Decidim.content_processors += [:special_words]
13
13
  ```
14
14
 
@@ -0,0 +1,9 @@
1
+ # Deploy
2
+
3
+ ## Self-hosted
4
+
5
+ You can install Decidim like a regular Ruby on Rails application, with nginx, Passenger, rbenv and PostgreSQL. You should also configure a valid SMTP account to send emails and add the delayed_job gem and execute it so you can receive emails (ie on user registration).
6
+
7
+ ## Heroku
8
+
9
+ You can follow an opinionated Rails generator to configure your decidim app so that it can be [deployed to Heroku](https://github.com/codegram/decidim-deploy-heroku).
@@ -1,4 +1,19 @@
1
- # Create followers from resource authors
1
+ # Followers
2
+
3
+ ## Create followers from comment authors
4
+
5
+ Run the following script to make all comment authors follow the commented resource:
6
+
7
+ ```ruby
8
+ Decidim::Comments::Comment.includes(:author, :root_commentable).find_each do |comment|
9
+ begin
10
+ Decidim::Follow.create!(followable: comment.root_commentable, user: comment.author)
11
+ rescue
12
+ end
13
+ end; p 1
14
+ ```
15
+
16
+ ## Create followers from resource authors
2
17
 
3
18
  Run the following script to make all resource authors follow the resource:
4
19
 
@@ -17,3 +32,4 @@ Decidim.feature_manifests.each do |feature_manifest|
17
32
  end
18
33
  end; p 1
19
34
  ```
35
+
@@ -0,0 +1,9 @@
1
+ # How to create a Decidim component
2
+
3
+ Use [decidim-generators](https://github.com/decidim/decidim-generators) to
4
+ automatically generate a decidim component skeleton, or copy the basic structure
5
+ of an existing mantained plugin.
6
+
7
+ Upload the component to GitHub with the naming *decidim-module-<engine_name>*,
8
+ so it's easier to find on the
9
+ [dependency graph](https://github.com/decidim/decidim/network/dependents).