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
@@ -1,17 +1,16 @@
1
1
  # Migration from 0.7.0 to 0.8.0
2
2
 
3
- ## Note about this guide.
3
+ ## Note about this guide
4
4
 
5
5
  This is a work-in-progress guide for all those people that needs to adapt his existing source code from Decidim
6
6
  0.7.0 to Decidim 0.8.0. If you find a mistake or missing parts in this document do not hesitate to make a pull request
7
7
  and add your discoveries.
8
8
 
9
-
10
- ## Upgrading the gem.
9
+ ## Upgrading the gem
11
10
 
12
11
  You need to alter the following files:
13
12
 
14
- ### Gemspec file.
13
+ ### Gemspec file
15
14
 
16
15
  You must set the decidim version to 0.8.0 or higher in your gemspec.
17
16
 
@@ -22,6 +21,7 @@ s.add-dependency "decidim-core", "~> 0.8.0"
22
21
  ```
23
22
 
24
23
  ### Gemfile
24
+
25
25
  You must adjust the decidim version in your gem file as well. You also need to add the new engine 'decidim-verifications':
26
26
 
27
27
  ```ruby
@@ -30,16 +30,17 @@ gem "decidim", "~> 0.8.0"
30
30
  gem "decidim-verifications"
31
31
  ...
32
32
  ```
33
- ### bundle update
33
+
34
34
  Finally run *bundle update* to get the required gems updated.
35
35
 
36
36
  ```bash
37
- $ bundle update --full-index
37
+ bundle update --full-index
38
38
  ```
39
39
 
40
- ## Updating your sources.
40
+ ## Updating your sources
41
41
 
42
42
  ### Factories
43
+
43
44
  Decidim 0.8.0 has migratied from FactoryGirl gem to FactoryBot. Cause this you need to update your factories. Usually the *factories.rb* file looks like this:
44
45
 
45
46
  ```ruby
@@ -68,7 +69,7 @@ end
68
69
 
69
70
  ```
70
71
 
71
- ### Spec tests examples.
72
+ ### Spec tests examples
72
73
 
73
74
  Some examples have changed its name to be more descriptive. In order to have your tests up and running again you must perform the following substitions in the specs folder:
74
75
 
@@ -91,34 +92,36 @@ where the dialog was supposed to be accepted:
91
92
  accept_confirm { click_button "Submit" }
92
93
  ```
93
94
 
94
- ## Steps to do after migrating your source code.
95
+ ## Steps to do after migrating your source code
95
96
 
96
- ### Adapting code for an existing engine:
97
+ ### Adapting code for an existing engine
97
98
 
98
99
  You must remove the external test app and regenerate it:
99
100
 
100
101
  ```bash
101
- $ rm -Rf spec/decidim_dummy_app
102
- $ bundle exec rails decidim:generate_external_test_app
102
+ rm -Rf spec/decidim_dummy_app
103
+ bundle exec rails decidim:generate_external_test_app
103
104
  ```
104
105
 
105
106
  After regenerating the test app you should recreate the test database as well:
106
107
 
107
108
  ```bash
108
- $ cd spec/decidim_dummy_app
109
- $ bundle exec rails db:drop
110
- $ bundle exec rails db:create
111
- $ bundle exec rails db:migrate
112
- $ bundle exec rails db:migrate RAILS_ENV=test
113
- $ bundle exec rails db:seed
109
+ cd spec/decidim_dummy_app
110
+ bundle exec rails db:drop
111
+ bundle exec rails db:create
112
+ bundle exec rails db:migrate
113
+ bundle exec rails db:migrate RAILS_ENV=test
114
+ bundle exec rails db:seed
115
+
114
116
  ```
115
- ### Adapting code for an existing Decidim implementation.
117
+
118
+ ### Adapting code for an existing Decidim implementation
116
119
 
117
120
  After updating the decidim gems you should import the new migrations and execute them:
118
121
 
119
122
  ```bash
120
- $ rails decidim:upgraded
121
- $ rails db:migrate
123
+ rails decidim:upgraded
124
+ rails db:migrate
122
125
  ```
123
126
 
124
127
  Additionally you should change the way uglifier is used in your app:
@@ -132,6 +135,7 @@ Edit the file *config/environments/production.rb* and make the following changes
132
135
  # Enable ES6 support
133
136
  config.assets.js_compressor = Uglifier.new(harmony: true)
134
137
  ```
135
- # To sum it up.
138
+
139
+ ### To sum it up
136
140
 
137
141
  Take a cold beer and enjoy democracy.
@@ -0,0 +1,29 @@
1
+ # How to test Decidim engines
2
+
3
+ ## Requirements
4
+
5
+ You need to create a dummy application to run your tests. Run the following command in the decidim root's folder:
6
+
7
+ ```bash
8
+ bundle exec rake test_app
9
+ ```
10
+
11
+ ## Running tests for a specific component
12
+
13
+ A Decidim engine can be tested running the rake task named after it. For
14
+ example, to test the proposals engine, you can run:
15
+
16
+ ```bash
17
+ bundle exec rake test_proposals
18
+ ```
19
+
20
+ ## Running the whole test suite
21
+
22
+ You can also run the full thing including test application generation and tests
23
+ for all components by running
24
+
25
+ ```bash
26
+ bundle exec rake test_all
27
+ ```
28
+
29
+ But beware, it takes a long time... :)
@@ -0,0 +1,14 @@
1
+ # Technical tradeoffs
2
+
3
+ ## Architecture
4
+
5
+ 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)".
6
+
7
+ ## Turbolinks
8
+
9
+ 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.
10
+
11
+ 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.
12
+
13
+ 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.
14
+
@@ -6,7 +6,7 @@ All engines can define their own view hooks, and register to other engines' ones
6
6
 
7
7
  Take the homepage, for example. It is rendered by the `decidim-core`. We want to show there a list of highlighted participatory spaces (processes and assemblies). We cannot be sure the final app has these engines, so we need to check they exist:
8
8
 
9
- ```
9
+ ```ruby
10
10
  <% if defined? Decidim::Processes %>
11
11
  <% # iterate through the most important ones %>
12
12
  <% end %>
@@ -24,11 +24,11 @@ This raises two important issues:
24
24
 
25
25
  Instead of the previous example, we created the concept of "view hooks". Think of them as a registry of views which can be defined by a given engine and extended by others. To follow the previous example, we would register a view hook in `decidim-core`:
26
26
 
27
- ```
28
- <%= Decidim.view_hooks.render(:highlighted_elements, self) %>
27
+ ```ruby
28
+ <%= Decidim.view_hooks.render(:highlighted_elements, deep_dup) %>
29
29
  ```
30
30
 
31
- We're rendering the view hooks registered as `:highlighted_elements`. The `self` parameter is the view context, we will analyze it later.
31
+ We're rendering the view hooks registered as `:highlighted_elements`. The `deep_dup` parameter is a deep copy of the view context, we will analyze it later.
32
32
 
33
33
  ## Registering view hooks
34
34
 
@@ -43,7 +43,7 @@ initializer "decidim_participatory_processes.view_hooks" do
43
43
  end
44
44
  ```
45
45
 
46
- In order to register a view hook we need the hook name and a block of Ruby code. We're registering a view hook as `:highlighted-elements`, following our example. We're passing the view context to the block so that we can use our views helper methods there, and we're rendering a partial. We could write `ActiveRecord` queries and pass the results to the partial as `locals` if we wanted a more complex view:
46
+ In order to register a view hook we need the hook name and a block of Ruby code. We're registering a view hook as `:highlighted-elements`, following our example. We're passing a deep copy of the view context to the block so that we can use our views helper methods there, and we're rendering a partial. We could write `ActiveRecord` queries and pass the results to the partial as `locals` if we wanted a more complex view:
47
47
 
48
48
  ```ruby
49
49
  # decidim-participatory_processes/lib/decidim/participatory_processes/engine.rb
@@ -57,6 +57,19 @@ initializer "decidim_participatory_processes.view_hooks" do
57
57
  end
58
58
  ```
59
59
 
60
+ We're passing a deep copy of the view context to allow us to extend it without polluting the original view context:
61
+
62
+ ```ruby
63
+ # decidim-proposals/lib/decidim/proposals/engine.rb
64
+ initializer "decidim_participatory_processes.view_hooks" do
65
+ Decidim.view_hooks.register(:participatory_space_highlighted_elements) do |view_context|
66
+ # ...
67
+ view_context.extend Decidim::Proposals::ApplicationHelper
68
+ view_context.render(partial: "decidim/participatory_spaces/highlighted_proposals", locals: { })
69
+ end
70
+ end
71
+ ```
72
+
60
73
  When registering a view hook, we can set a priority for each one. By default, all view hooks are registered with low priority, but we can change it:
61
74
 
62
75
  ```ruby
@@ -14,4 +14,16 @@ One particular thing about this kind of applications is the need to Authorize a
14
14
 
15
15
  * By having a list of valid users emails
16
16
 
17
- Right now Decidim supports only a few of these cases, but we have an internal API where you can program your own kind of verifications. You can go see some example code, read more about how to work with Decidim modules, or even see how it’s done for Decidim Barcelona, the Barcelona City Council.
17
+ Right now Decidim supports only a few of these cases, but we have an internal API where you can program your own kind of authorizations. To create your own `AuthorizationHandler` for an external API (ie a Municipal Census) you should add a `app/services/` file, then activate it on `config/initializers/decidim.rb` and finally enabling it on `/system` for the tenant.
18
+
19
+ You can go see some example code on:
20
+
21
+ * [Erabaki Pamplona](https://github.com/ErabakiPamplona/erabaki/blob/master/app/services/census_authorization_handler.rb)
22
+
23
+ * [Decidim Barcelona](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/blob/master/app/services/census_authorization_handler.rb)
24
+
25
+ * [Decidim Terrassa](https://github.com/AjuntamentDeTerrassa/decidim-terrassa/blob/master/app/services/census_authorization_handler.rb)
26
+
27
+ * [Decidim Sant Cugat](https://github.com/AjuntamentdeSantCugat/decidim-sant_cugat/blob/master/app/services/census_authorization_handler.rb)
28
+
29
+ These are just a few examples but mostly all the Municipal installations have somekind of Authorization.
@@ -0,0 +1,48 @@
1
+ # Data Picker
2
+
3
+ Simple HTML `select`s are not usable enough for the big collections of data Decidim has. We tried using `select2`, but we found problems with its usage and responsiveness, so we moved to a custom data picker. Also, there are many kinds of data that can be selected and many better usable ways to select this data than the simple select provided by html.
4
+
5
+ Current Decidim's selector is inspired on [this](https://medium.com/@mibosc/responsive-design-why-and-how-we-ditched-the-good-old-select-element-bc190d62eff5) article.
6
+
7
+ Data Picker is a selector thought to be reusable in many contexts and kinds of data. The idea behind it is a reusable widget that opens a popup where the user will perform a given selection and, on finish, this selection is returned to the source widget in the main page. The popup is accompained by a semitransparent layer behind it to blur the background and keep the user concentrated in the current action, the selection.
8
+
9
+ ## Artifacts
10
+ Data Picker is composed by 2 visual artifacts, plus the javascript and one controller action for each selection type:
11
+ - **widget**: the first visual artifact is the widget that encapsulates the main Data Picker functionality. This widget manages the rendering of __the button__ that opens the selector and __the popup__. This button is managed via ujs (Unobtrusive JavaScript). The popup is empty and must be filled with a selection partial.
12
+ - **selection functionality** partial: There are many ways to select things (and many kinds of things to select). Thus, the selection functionality can be customized via a selection partial which will be rendered inside the widget's popup. This partial is supplied to the widget via ajax.
13
+ - **controller ajax action**: An ajax action will send the content of the popup in an html partial.
14
+
15
+ ## How to
16
+ ### Placing the Data Picker widget:
17
+ The Data Picker widget structure is as follows:
18
+ ```html
19
+ <div id="some-unique-id" class="data-picker <%= picker_options[:class]%>" data-picker-name="<%=picker_options[:name]%>">
20
+ <div class="picker-values"><% @form.proposals.each do |proposal, params| %>
21
+ <div><a href="<%= prompt_params[:url] %>" data-picker-value="<%=proposal%>"><%=proposal%></a></div>
22
+ <% end %></div>
23
+ <div class="picker-prompt"><a href="<%= prompt_params[:url] %>"><%= prompt_params[:text] %></a></div>
24
+ </div>
25
+ ```
26
+
27
+ Placing the widget in a form requires two steps:
28
+
29
+ It is a good way to implement the widget to think that it is a component that takes parameters.
30
+ 1. Prepare Data Picker parameters
31
+ Data Picker takes two arguments the `picker_params` hash (to fill the main div) and the `prompt_params` hash (for the `picker-prompt` div).
32
+ - `picker_params.id`: the html unique id of the widget instance, required by the JavaScript.
33
+ - `picker_params.name`: the html name of the widget which will be sent by the form.
34
+ - `picker_params.class`: one of `picker-multiple`, when user can select multiple data, or `picker-single`, when only one data is to be selected.
35
+
36
+ 2. Html for the Data Picker widget
37
+
38
+ ### Selector popup content
39
+
40
+ Anchors in the selector can have the following attributes:
41
+ data-close: this anchor will be ignored
42
+ href: the url to be used for choosing
43
+ picker-choose: when 'undefined' will load the given href url. Otherwise a choose action in the component is invoked with params: `url: href, value: picker-value, text: picker-text`.
44
+ picker-value: the selected value
45
+ picker-text (optional): The text to be shown in the picker button.
46
+
47
+ ### Returning the selection to the widget
48
+ To return the selection to the widget in the main page use javascript to set the data-picker-value in the #proposal-picker-choose button.
@@ -10,7 +10,20 @@ If you want to start your own installation of Decidim, you don't need to clone t
10
10
 
11
11
  ## Creating your Decidim app
12
12
 
13
- ### Using Docker [experimental]
13
+ ### A. Using installation script [experimental]
14
+
15
+ > *Please note that this is **experimental***
16
+
17
+ We've made an script for Ubuntu 16.04 LTS and macos sierra 10.2. It's a BETA and as such you should be aware that this could break your environment (if you have any). It'll install rbenv, postgresql, nodejs and install decidim on this directory. It should take 15 minutes depending on your network connection.
18
+
19
+ ```
20
+ wget http://get.decidim.org -O install_decidim.bash
21
+ bash install_decidim.bash
22
+ ```
23
+
24
+ Read more about the [installation script](https://github.com/alabs/decidim-install).
25
+
26
+ ### B. Using Docker [experimental]
14
27
 
15
28
  > *Please note that this is **experimental***
16
29
 
@@ -22,23 +35,25 @@ docker run --rm -v $(pwd):/tmp codegram/decidim bash -c "bundle exec decidim /tm
22
35
 
23
36
  This will create a `decidim_application` Ruby on Rails app using Decidim in the current folder. It will install the latest released version of the gem.
24
37
 
25
- ### Step by step
38
+
39
+ ### C. Step by step
26
40
 
27
41
  First of all, you need to install the `decidim` gem:
28
42
 
29
43
  ```
30
- $ gem install decidim
44
+ gem install decidim
31
45
  ```
32
46
 
33
- Afterwards, you can create an application with the nice `decidim` executable:
47
+ afterwards, you can create an application with the nice `decidim` executable:
34
48
 
35
49
  ```
36
- $ decidim decidim_application
37
- $ cd decidim_application
38
- $ bundle install
50
+ decidim decidim_application
51
+ cd decidim_application
52
+ bundle install
53
+ rails server
39
54
  ```
40
55
 
41
- ### Initializing your app for local development
56
+ ## Initializing your app for local development
42
57
 
43
58
  You should now setup your database:
44
59
 
@@ -52,12 +67,7 @@ This will also create some default data so you can start testing the app:
52
67
  * A `Decidim::Organization` named `Decidim Staging`. You probably want to change its name and hostname to match your needs.
53
68
  * A `Decidim::User` acting as an admin for the organization, with email `admin@example.org` and password `decidim123456`.
54
69
  * A `Decidim::User` that also belongs to the organization but it's a regular user, with email `user@example.org` and password `decidim123456`.
55
-
56
- This data won't be created in production environments, if you still want to do it, run:
57
-
58
- ```
59
- $ SEED=true rails db:setup
60
- ```
70
+ This data won't be created in production environments, if you still want to do it, run: ``` $ SEED=true rails db:setup ```
61
71
 
62
72
  You can now start your server!
63
73
 
@@ -73,9 +83,10 @@ Decidim comes pre-configured with some safe defaults, but can be changed through
73
83
 
74
84
  We also have other guides on how to configure some extra features:
75
85
 
76
- - [Social providers integration](https://github.com/decidim/decidim/blob/master/docs/social_providers.md): Enable sign up from social networks.
77
- - [Analytics](https://github.com/decidim/decidim/blob/master/docs/analytics.md): How to enable analytics
78
- - [Geocoding](https://github.com/decidim/decidim/blob/master/docs/geocoding.md): How to enable geocoding for proposals and meetings
86
+ - [ActiveJob](https://github.com/decidim/decidim/blob/master/docs/services/activejob.md)
87
+ - [Analytics](https://github.com/decidim/decidim/blob/master/docs/services/analytics.md): How to enable analytics
88
+ - [Geocoding](https://github.com/decidim/decidim/blob/master/docs/services/geocoding.md): How to enable geocoding for proposals and meetings
89
+ - [Social providers integration](https://github.com/decidim/decidim/blob/master/docs/services/social_providers.md): Enable sign up from social networks.
79
90
 
80
91
  ## Deploy
81
92
 
@@ -0,0 +1,7 @@
1
+ # ActiveJob
2
+
3
+ For some kind of actions to work on production (for instance, sending emails on user registration) you need to configure an [ActiveJob](http://edgeguides.rubyonrails.org/active_job_basics.html) backend on your application.
4
+
5
+ If you don't want to introduce any other external dependencies for `decidim` (such as `redis`), you can use the `delayed_job` backend. That setup only depends on an underlying database which is already a requirement for `decidim` to work. Add the [delayed_job](https://github.com/collectiveidea/delayed_job/) gem to your `Gemfile` and follow the instructions in its readme to set it up.
6
+
7
+ However, Decidim is agnostic on which kind of backend do you use, so feel free to set up the backend (ie `sidekiq`, `resque`, etc) you like the most.
File without changes
File without changes
@@ -21,17 +21,25 @@ module Decidim
21
21
  end
22
22
 
23
23
  def run(command, out: STDOUT)
24
- command = command.gsub("%version", version).gsub("%name", name)
25
- status = system(command, out: out)
26
- abort unless status || ENV["FAIL_FAST"] == "false"
24
+ Dir.chdir(@dir) do
25
+ command = command.gsub("%version", version).gsub("%name", name)
26
+ status = system(command, out: out)
27
+ abort unless status || ENV["FAIL_FAST"] == "false"
28
+ end
27
29
  end
28
30
 
29
31
  def replace_version
30
- self.class.replace_file(
31
- "lib/#{name.tr("-", "/")}/version.rb",
32
- /def self\.version(\s*)"[^"]*"/,
33
- "def self.version\\1\"#{version}\""
34
- )
32
+ Dir.chdir(@dir) do
33
+ self.class.replace_file(
34
+ "lib/#{name.tr("-", "/")}/version.rb",
35
+ /def self\.version(\s*)"[^"]*"/,
36
+ "def self.version\\1\"#{version}\""
37
+ )
38
+ end
39
+ end
40
+
41
+ def short_name
42
+ name.gsub(/decidim-/, "")
35
43
  end
36
44
 
37
45
  class << self
@@ -42,13 +50,13 @@ module Decidim
42
50
  " \"version\": \"#{version.gsub(/\.pre/, "-pre")}\""
43
51
  )
44
52
 
45
- in_all_dirs do |dir|
53
+ all_dirs do |dir|
46
54
  new(dir).replace_version
47
55
  end
48
56
  end
49
57
 
50
58
  def run_all(command, out: STDOUT, include_root: true)
51
- in_all_dirs(include_root: include_root) do |dir|
59
+ all_dirs(include_root: include_root) do |dir|
52
60
  new(dir).run(command, out: out)
53
61
  end
54
62
  end
@@ -67,28 +75,21 @@ module Decidim
67
75
  File.open(name, "w") { |f| f.write(new_content) }
68
76
  end
69
77
 
70
- private
71
-
72
78
  def all_dirs(include_root: true)
73
79
  Dir.glob(include_root ? "{decidim-*,.}" : "decidim-*")
74
80
  .select { |f| File.directory?(f) }
75
- end
76
-
77
- def in_all_dirs(include_root: true)
78
- all_dirs(include_root: include_root).each do |dir|
79
- Dir.chdir(dir) { yield(dir) }
80
- end
81
+ .each { |dir| yield(dir) }
81
82
  end
82
83
  end
83
84
 
84
85
  private
85
86
 
86
- def name
87
+ def folder_name
87
88
  File.basename(@dir)
88
89
  end
89
90
 
90
- def short_name
91
- name.gsub(/decidim-/, "")
91
+ def name
92
+ folder_name.match?("decidim") ? folder_name : "decidim"
92
93
  end
93
94
 
94
95
  def version