decidim 0.23.6 → 0.24.0.rc1

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/docs/README.adoc +74 -0
  4. data/docs/antora.yml +7 -0
  5. data/docs/modules/configure/pages/environment_variables.adoc +69 -0
  6. data/docs/modules/configure/pages/index.adoc +16 -0
  7. data/docs/modules/configure/pages/initializer.adoc +376 -0
  8. data/docs/modules/customize/assets/images/header-snippet.png +0 -0
  9. data/docs/modules/customize/assets/images/menu.png +0 -0
  10. data/docs/modules/customize/assets/images/organization-colors.png +0 -0
  11. data/docs/modules/customize/pages/authorizations.adoc +22 -0
  12. data/docs/{customization/code.md → modules/customize/pages/code.adoc} +12 -9
  13. data/docs/{customization/gemfile.md → modules/customize/pages/gemfile.adoc} +5 -4
  14. data/docs/modules/customize/pages/images.adoc +7 -0
  15. data/docs/modules/customize/pages/javascript.adoc +59 -0
  16. data/docs/modules/customize/pages/menu.adoc +25 -0
  17. data/docs/modules/customize/pages/oauth.adoc +33 -0
  18. data/docs/modules/customize/pages/styles.adoc +64 -0
  19. data/docs/modules/customize/pages/texts.adoc +30 -0
  20. data/docs/modules/customize/pages/users_registration_mode.adoc +17 -0
  21. data/docs/{customization/views.md → modules/customize/pages/views.adoc} +13 -13
  22. data/docs/modules/develop/assets/images/barcelona.png +0 -0
  23. data/docs/modules/develop/assets/images/helsinki.png +0 -0
  24. data/docs/modules/develop/assets/images/indices.png +0 -0
  25. data/docs/{advanced/api.md → modules/develop/pages/api.adoc} +2 -2
  26. data/docs/{advanced/authorship.md → modules/develop/pages/authorable.adoc} +5 -5
  27. data/docs/modules/develop/pages/c4_component.adoc +91 -0
  28. data/docs/modules/develop/pages/c4_container.adoc +42 -0
  29. data/docs/modules/develop/pages/c4_context.adoc +35 -0
  30. data/docs/{advanced/components.md → modules/develop/pages/components.adoc} +47 -10
  31. data/docs/{advanced/content_blocks.md → modules/develop/pages/content_blocks.adoc} +16 -13
  32. data/docs/{advanced/content_processors.md → modules/develop/pages/content_processors.adoc} +25 -19
  33. data/docs/modules/develop/pages/data-picker.adoc +85 -0
  34. data/docs/modules/develop/pages/deploy.adoc +15 -0
  35. data/docs/modules/develop/pages/docker.adoc +12 -0
  36. data/docs/{advanced/embeddable.md → modules/develop/pages/embeddable.adoc} +6 -6
  37. data/docs/{advanced/endorsable.md → modules/develop/pages/endorsable.adoc} +31 -25
  38. data/docs/{advanced/fixing_locales.md → modules/develop/pages/fixing_locales.adoc} +36 -23
  39. data/docs/{advanced/followers.md → modules/develop/pages/followable.adoc} +9 -8
  40. data/docs/modules/develop/pages/guide.adoc +16 -0
  41. data/docs/modules/develop/pages/guide_architecture.adoc +17 -0
  42. data/docs/modules/develop/pages/guide_changelog.adoc +8 -0
  43. data/docs/modules/develop/pages/guide_commands.adoc +86 -0
  44. data/docs/modules/develop/pages/guide_development_app.adoc +44 -0
  45. data/docs/modules/develop/pages/guide_development_with_custom_seed_data.adoc +31 -0
  46. data/docs/modules/develop/pages/guide_development_with_localhost_ssl.adoc +63 -0
  47. data/docs/modules/develop/pages/guide_example_apps.adoc +59 -0
  48. data/docs/modules/develop/pages/guide_git_conventions.adoc +75 -0
  49. data/docs/modules/develop/pages/guide_github_projects.adoc +42 -0
  50. data/docs/modules/develop/pages/guide_semver.adoc +7 -0
  51. data/docs/{advanced/how_to_fix_metrics.md → modules/develop/pages/how_to_fix_metrics.adoc} +76 -59
  52. data/docs/modules/develop/pages/machine_translations.adoc +42 -0
  53. data/docs/modules/develop/pages/managing_translations_i18n.adoc +24 -0
  54. data/docs/modules/develop/pages/maps.adoc +499 -0
  55. data/docs/modules/develop/pages/metrics.adoc +119 -0
  56. data/docs/{advanced/modules.md → modules/develop/pages/modules.adoc} +16 -6
  57. data/docs/{advanced/newsletter_templates.md → modules/develop/pages/newsletter_templates.adoc} +12 -10
  58. data/docs/{advanced/notifications.md → modules/develop/pages/notifications.adoc} +40 -38
  59. data/docs/{advanced/open-data.md → modules/develop/pages/open-data.adoc} +4 -3
  60. data/docs/modules/develop/pages/permissions.adoc +92 -0
  61. data/docs/{advanced/profiling.md → modules/develop/pages/profiling.adoc} +15 -12
  62. data/docs/modules/develop/pages/releases.adoc +148 -0
  63. data/docs/modules/develop/pages/reportable.adoc +31 -0
  64. data/docs/modules/develop/pages/security.adoc +33 -0
  65. data/docs/{advanced/share_tokens.md → modules/develop/pages/share_tokens.adoc} +18 -14
  66. data/docs/{advanced/templates.md → modules/develop/pages/templates.adoc} +14 -12
  67. data/docs/{advanced/testing.md → modules/develop/pages/testing.adoc} +21 -20
  68. data/docs/{advanced/activity_log.md → modules/develop/pages/traceable.adoc} +31 -26
  69. data/docs/modules/develop/pages/turbolinks.adoc +7 -0
  70. data/docs/{advanced/view_hooks.md → modules/develop/pages/view_hooks.adoc} +29 -23
  71. data/docs/modules/develop/pages/view_models_aka_cells.adoc +105 -0
  72. data/docs/modules/install/pages/checklist.adoc +39 -0
  73. data/docs/modules/install/pages/index.adoc +148 -0
  74. data/docs/{manual-installation.md → modules/install/pages/manual.adoc} +54 -42
  75. data/docs/modules/install/pages/update.adoc +95 -0
  76. data/docs/{services/activejob.md → modules/services/pages/activejob.adoc} +3 -3
  77. data/docs/modules/services/pages/elections_bulletin_board.adoc +52 -0
  78. data/docs/{services/etherpad.md → modules/services/pages/etherpad.adoc} +15 -12
  79. data/docs/modules/services/pages/maps.adoc +311 -0
  80. data/docs/modules/services/pages/smtp.adoc +10 -0
  81. data/docs/modules/services/pages/social_providers.adoc +122 -0
  82. data/lib/decidim/gem_manager.rb +5 -5
  83. data/lib/decidim/version.rb +1 -1
  84. metadata +137 -100
  85. data/README.md +0 -157
  86. data/docs/advanced/add_authorizable_action.md +0 -63
  87. data/docs/advanced/adding_fixtures_aka_dummy_content.md +0 -9
  88. data/docs/advanced/data-picker.md +0 -83
  89. data/docs/advanced/deploy.md +0 -9
  90. data/docs/advanced/how_to_create_a_module.md +0 -9
  91. data/docs/advanced/machine_translation_service.md +0 -12
  92. data/docs/advanced/managing_translations_i18n.md +0 -24
  93. data/docs/advanced/metrics.md +0 -114
  94. data/docs/advanced/permissions.md +0 -23
  95. data/docs/advanced/releases.md +0 -114
  96. data/docs/advanced/tradeoffs.md +0 -14
  97. data/docs/advanced/view_models_aka_cells.md +0 -99
  98. data/docs/checklist.md +0 -55
  99. data/docs/customization/authorizations.md +0 -5
  100. data/docs/customization/images.md +0 -7
  101. data/docs/customization/javascript.md +0 -9
  102. data/docs/customization/machine_translations.md +0 -30
  103. data/docs/customization/maps.md +0 -610
  104. data/docs/customization/oauth.md +0 -50
  105. data/docs/customization/styles.md +0 -11
  106. data/docs/customization/texts.md +0 -27
  107. data/docs/customization/users_registration_mode.md +0 -17
  108. data/docs/development_guide.md +0 -166
  109. data/docs/getting_started.md +0 -191
  110. data/docs/possible_flows_for_proposal.png +0 -0
  111. data/docs/services/analytics.md +0 -23
  112. data/docs/services/elections_bulletin_board.md +0 -38
  113. data/docs/services/maps.md +0 -362
  114. data/docs/services/social_providers.md +0 -98
@@ -0,0 +1,42 @@
1
+ [plantuml]
2
+ ....
3
+ @startuml
4
+ !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/v2.0.1/C4_Container.puml
5
+
6
+ ' uncomment the following line to make proposals
7
+ 'LAYOUT_AS_SKETCH()
8
+
9
+ title System Container diagram for Decidim Applications (https://decidim.org)
10
+
11
+
12
+ Person_Ext(visitor_user, "Visitor User", "Anonymous, non registered user.")
13
+ Person(participant_user, "Participant User", "A registered user. Could also be verified.")
14
+ Person(administration_user, "Administration User", "A registered user with special permissions.")
15
+
16
+ System_Boundary(decidim_system, "decidim"){
17
+ Container(web_app, "Web Application", "Ruby on Rails 5.2", "Allows participants to make decisions collaboratively through participatory processes, assemblies, consultations, initiatives, etc.")
18
+ ContainerDb(rel_db, "Relational Database", "PostgreSQL 9.5.x", "Stores users, participatory processes, assemblies, consultations, initiatives, proposals, meetings, etc.")
19
+ Container(filesystem, "File System", "Local or remote", "Stores uploads (images, documents, etc.)")
20
+ Container(worker, "Worker", "Ruby on Rails 5.2", "ActiveJob queues for non syncronuos jobs. Works for open data requests, sending emails, etc.")
21
+ }
22
+
23
+ System_Ext(decidim_bulletin_board_system, "Decidim Bulletin Board", "Allows participants to cast end-to-end verifiable secret votes.")
24
+ System_Ext(mail_system, "SMTP system (e-mail)", "Sends mails to users, like confirmations, reminders, notifications, etc.")
25
+ System_Ext(etherpad_system, "Etherpad-Lite system", "Optional. Allows real-time text edition in Meetings.")
26
+ System_Ext(geocoding_system, "Geocoding system", "Optional. An Open Street Maps provider, allows geographical localization of Proposals and Meetings..")
27
+ System_Ext(oauth_system, "OAUTH2 System", "Optional. Third party sign on systems. Could be Twitter, Facebook, Google or any other OAUTH2 providers.")
28
+
29
+ Rel(visitor_user, web_app, "Uses")
30
+ Rel(participant_user, web_app, "Uses")
31
+ Rel(administration_user, web_app, "Uses")
32
+ Rel_Back(participant_user, mail_system, "Sends e-mails to")
33
+ Rel_Back(administration_user, mail_system, "Sends e-mails to")
34
+ Rel_Back_Neighbor(decidim_bulletin_board_system, web_app, "Uses")
35
+ Rel_Neighbor(worker, mail_system, "Sends e-mails", "SMTP")
36
+ Rel(web_app, rel_db, "Uses")
37
+ Rel(web_app, filesystem, "Uses")
38
+ Rel(web_app, oauth_system, "Uses")
39
+ Rel(web_app, geocoding_system, "Uses")
40
+ Rel(web_app, etherpad_system, "Embeds", "Through an Iframe")
41
+ @enduml
42
+ ....
@@ -0,0 +1,35 @@
1
+ [plantuml]
2
+ ....
3
+ @startuml
4
+ !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/v2.0.1/C4_Context.puml
5
+
6
+ ' uncomment the following line to make proposals
7
+ 'LAYOUT_AS_SKETCH()
8
+
9
+ title System Context diagram for Decidim Applications (https://decidim.org)
10
+
11
+
12
+ Person_Ext(visitor_user, "Visitor User", "Anonymous, non registered user.")
13
+ Person(participant_user, "Participant User", "A registered user. Could also be verified.")
14
+ Person(administration_user, "Administration User", "A registered user with special permissions.")
15
+
16
+ System(decidim_system, "Decidim", "Allows participants to make decisions collaboratively through participatory processes, assemblies, consultations, initiatives, etc.")
17
+
18
+ System_Ext(decidim_bulletin_board_system, "Decidim Bulletin Board", "Allows participants to cast end-to-end verifiable secret votes.")
19
+ System_Ext(mail_system, "SMTP system (e-mail)", "Sends mails to users, like confirmations, reminders, notifications, etc.")
20
+ System_Ext(etherpad_system, "Etherpad-Lite system", "Optional. Allows real-time text edition in Meetings.")
21
+ System_Ext(geocoding_system, "Geocoding system", "Optional. An Open Street Maps provider, allows geographical localization of Proposals and Meetings..")
22
+ System_Ext(oauth_system, "OAUTH2 System", "Optional. Third party sign on systems. Could be Twitter, Facebook, Google or any other OAUTH2 providers.")
23
+
24
+ Rel(visitor_user, decidim_system, "Uses")
25
+ Rel(participant_user, decidim_system, "Uses")
26
+ Rel(administration_user, decidim_system, "Uses")
27
+ Rel_Back(participant_user, mail_system, "Sends e-mails to")
28
+ Rel_Back(administration_user, mail_system, "Sends e-mails to")
29
+ Rel_Back_Neighbor(decidim_bulletin_board_system, decidim_system, "Uses")
30
+ Rel_Neighbor(decidim_system, mail_system, "Sends e-mails", "SMTP")
31
+ Rel(decidim_system, oauth_system, "Uses")
32
+ Rel(decidim_system, geocoding_system, "Uses")
33
+ Rel(decidim_system, etherpad_system, "Embeds", "Through an Iframe")
34
+ @enduml
35
+ ....
@@ -1,20 +1,32 @@
1
- # Components
1
+ = Components
2
2
 
3
- Components are the core contract between external modules and the core. They're used to define pieces of functionality that are pluggable to participatory spaces and can be enabled or disabled by the administrator.
3
+ Components are the core contract between external xref:develop:modules.adoc[modules] and the core. They're used to define pieces of functionality that are pluggable to participatory spaces and can be enabled or disabled by the administrator.
4
4
 
5
- ## How do I create a new component?
5
+ == Creating a new component
6
6
 
7
- Components are just gems with one or more Rails engines included in it. You can use as an example [decidim-pages](https://github.com/decidim/decidim/tree/master/decidim-pages).
7
+ If you want to create a new component, you can use https://github.com/decidim/decidim/tree/develop/decidim-generators[decidim-generators] to
8
+ automatically generate a decidim component skeleton, or copy the basic structure
9
+ of an existing mantained plugin.
10
+
11
+ [source,console]
12
+ ----
13
+ decidim --component engine_name
14
+ ----
15
+
16
+ Components are just gems with one or more Rails engines included in it. You can use as an example https://github.com/decidim/decidim/tree/develop/decidim-pages[decidim-pages].
8
17
 
9
18
  Check out the `lib/decidim/pages` folder: It includes several files, the most important of which is `component.rb`.
10
19
 
11
- ## Defining a component manifest
20
+ Upload the component to GitHub with the naming *decidim-module-engine_name*, so it's easier to find on the https://github.com/decidim/decidim/network/dependents[dependency graph].
21
+
22
+ == Defining a component manifest
12
23
 
13
24
  Components are defined in a manifest, along with its engine and admin engine counterpart.
14
25
 
15
26
  There's a DSL available to describe all this:
16
27
 
17
- ```ruby
28
+ [source,ruby]
29
+ ----
18
30
  # :my_component is the unique name of the component that will be globally registered.
19
31
  Decidim.register_component(:my_component) do |component|
20
32
  # The user will be redirected to the component's engine when accessing it through
@@ -54,12 +66,21 @@ Decidim.register_component(:my_component) do |component|
54
66
 
55
67
  exports.serializer MyComponent::ResourceSerializer
56
68
  end
69
+
70
+ # Import definitions allow data to be imported into a component.
71
+ #
72
+ # For now supported formats for imports are CSV, JSON and Excel (.xls).
73
+ # Every resource type needs it's own creator, which creates resource
74
+ # from parsed data.
75
+ component.imports :component_resources do |imports|
76
+ imports.creator MyComponent::ResourceCreator
77
+ end
57
78
  end
58
- ```
79
+ ----
59
80
 
60
81
  Every model in a component doesn't have to (and should not) know about its parent participatory space, but instead should be scoped to the components.
61
82
 
62
- ## Settings
83
+ == Settings
63
84
 
64
85
  Components can define settings that modify its behavior. This settings can be defined to be set for the whole life of the component (global settings), or to be set for each different step of the participatory space (step settings).
65
86
 
@@ -73,7 +94,8 @@ Each attribute defined can be described through properties:
73
94
  * `enum` attributes should have a `choices` attributes that list all the possible values. This could be a lambda function.
74
95
  * they can be `readonly` in some cases, throught a lambda function that received the current component within the `context`.
75
96
 
76
- ```ruby
97
+ [source,ruby]
98
+ ----
77
99
  # :my_component is the unique name of the component that will be globally registered.
78
100
  Decidim.register_component(:my_component) do |component|
79
101
  ...
@@ -91,10 +113,25 @@ Decidim.register_component(:my_component) do |component|
91
113
 
92
114
  ...
93
115
  end
94
- ```
116
+ ----
95
117
 
96
118
  Each setting should have one or more translation texts related for the admin zone:
97
119
 
98
120
  * `decidim.components.[component_name].settings.[global|step].[attribute_name]`: Admin label for the setting.
99
121
  * `decidim.components.[component_name].settings.[global|step].[attribute_name]_help`: Additional text with help for the setting use.
100
122
  * `decidim.components.[component_name].settings.[global|step].[attribute_name]_readonly`: Additional text for the setting when it is readonly.
123
+
124
+ == Fixtures
125
+
126
+ This sections explains how to add dummy content to a development application.
127
+
128
+ === Proposals example
129
+
130
+ . In decidim-proposals open `lib/decidim/proposals/component.rb`.
131
+ . Find the `+component.seeds do...+` block.
132
+ . Create your dummy content as if you were in a `db/seed.rb` script.
133
+
134
+ === Tips and Tricks
135
+
136
+ * Take advantage of the Faker gem, already in decidim.
137
+ * If you need content for i18n fields, you can use https://github.com/decidim/decidim/blob/develop/decidim-core/lib/decidim/faker/localized.rb[Localizaed], which uses `Faker` internally.
@@ -1,11 +1,11 @@
1
- # Content blocks
1
+ = Content blocks
2
2
 
3
3
  Content blocks come from the need of making sortable and configurable layout chunks. The abstraction is similar to view hooks, but content blocks allow the user to manually configure and sort each block. The order and configuration is backed in the database.
4
4
 
5
5
  As of today, content blocks can be:
6
6
 
7
- - Sorted
8
- - Published
7
+ * Sorted
8
+ * Published
9
9
 
10
10
  Configuration will come in the near future.
11
11
 
@@ -13,22 +13,24 @@ Content blocks are defined per scope, and must be unique in that scope. Examples
13
13
 
14
14
  Content blocks are used in the organization homepage.
15
15
 
16
- ## Registering a content block
16
+ == Registering a content block
17
17
 
18
18
  Content blocks use the same manifests-registry pattern used in other places around Decidim. Here's how to register them:
19
19
 
20
- ```ruby
20
+ [source,ruby]
21
+ ----
21
22
  Decidim.content_blocks.register(:homepage, :stats) do |content_block|
22
23
  content_block.cell "decidim/content_blocks/stats_block"
23
24
  content_block.public_name_key "decidim.content_blocks.stats_block.name"
24
25
  end
25
- ```
26
+ ----
26
27
 
27
28
  Let's analyze the example. In the first line, we register a content block named `:stats` for the `:homepage` scope. Then we define the name of the `cell` that will be used to render the content block, and we define the i18n key that holds the name for the content block. These are the only required fields to register a content block.
28
29
 
29
30
  Note that content blocks need to be registered from an initializer. If you are adding a content block from a module, use this in the `engine.rb` file of your module:
30
31
 
31
- ```ruby
32
+ [source,ruby]
33
+ ----
32
34
  module Decidim::MyModule::Engine < ::Rails::Engine
33
35
  # ...
34
36
 
@@ -40,23 +42,24 @@ module Decidim::MyModule::Engine < ::Rails::Engine
40
42
 
41
43
  # ...
42
44
  end
43
- ```
45
+ ----
44
46
 
45
- ## Managing content blocks
47
+ == Managing content blocks
46
48
 
47
- Content blocks registered under the `:homepage` scope can be seen in the admin area, under Settings -> Homepage. You need to be an organization admin in order to enter this section.
49
+ Content blocks registered under the `:homepage` scope can be seen in the admin area, under Settings \-> Homepage. You need to be an organization admin in order to enter this section.
48
50
 
49
51
  You'll see all the registered content blocks for the `:homepage` scope, those active and those inactive. You can reorder blocks and (un)publish them.
50
52
 
51
53
  Another use for content blocks, for example, can be seen at the newsletter templates system.
52
54
 
53
- ## Rendering content blocks
55
+ == Rendering content blocks
54
56
 
55
57
  You can check the code we use in the homepage to render them, or use something like this:
56
58
 
57
- ```ruby
59
+ [source,ruby]
60
+ ----
58
61
  <% Decidim::ContentBlock.published.for_scope(:homepage, organization: current_organization).each do |content_block| %>
59
62
  <% next unless content_block.manifest %>
60
63
  <%= cell content_block.manifest.cell %>
61
64
  <% end %>
62
- ```
65
+ ----
@@ -1,25 +1,27 @@
1
- # Content processors
1
+ = Content processors
2
2
 
3
3
  A content processor is a concept to refer to a set of two classes: a content parser class and a content renderer class.
4
4
 
5
5
  The content parser class is used to process the text before it is saved to the database, and the associated renderer class is used to render the saved content.
6
6
 
7
- ## How do I add a content processor?
7
+ == How do I add a content processor?
8
8
 
9
9
  Register the content processor in an `initializer`:
10
10
 
11
- ```ruby
11
+ [source,ruby]
12
+ ----
12
13
  Decidim.content_processors += [:special_words]
13
- ```
14
+ ----
14
15
 
15
16
  This symbol will be used to instantiate parsers and processors using the following convention:
16
17
 
17
- - "Decidim::ContentParsers::#{type.to_s.camelize}Parser"
18
- - "Decidim::ContentRenderers::#{type.to_s.camelize}Renderer"
18
+ * "Decidim::ContentParsers::#{type.to_s.camelize}Parser"
19
+ * "Decidim::ContentRenderers::#{type.to_s.camelize}Renderer"
19
20
 
20
21
  Autoload parser and renderer if in the lib/ dir. For example if in proposals module edit `lib/decidim/proposals.rb`:
21
22
 
22
- ```rb
23
+ [source,rb]
24
+ ----
23
25
  module Decidim
24
26
  ...
25
27
  module ContentParsers
@@ -30,11 +32,12 @@ module Decidim
30
32
  end
31
33
  ...
32
34
  end
33
- ```
35
+ ----
34
36
 
35
37
  Declare the parser class:
36
38
 
37
- ```rb
39
+ [source,rb]
40
+ ----
38
41
  class Decidim::ContentParsers::SpecialWordsParser < BaseParser
39
42
  Metadata = Struct.new(:count)
40
43
 
@@ -46,33 +49,36 @@ class Decidim::ContentParsers::SpecialWordsParser < BaseParser
46
49
  Metadata.new(content.scan('foo').size)
47
50
  end
48
51
  end
49
- ```
52
+ ----
50
53
 
51
54
  And the renderer class:
52
55
 
53
- ```rb
56
+ [source,rb]
57
+ ----
54
58
  class Decidim::ContentRenderers::SpecialWordsRenderer < BaseRenderer
55
59
  def render
56
60
  content.gsub(/\~\~(.*?)\~\~/, '<del>\1</del>')
57
61
  end
58
62
  end
59
- ```
63
+ ----
60
64
 
61
- ## How to use the content parser class
65
+ == How to use the content parser class
62
66
 
63
- ```rb
67
+ [source,rb]
68
+ ----
64
69
  parser = Decidim::ContentParsers::SpecialWordsParser.new(content, {})
65
70
  parser.rewrite # returns the content rewritten
66
71
  parser.metadata # returns a Metadata object
67
- ```
72
+ ----
68
73
 
69
- ## How to use the content renderer class
74
+ == How to use the content renderer class
70
75
 
71
- ```rb
76
+ [source,rb]
77
+ ----
72
78
  renderer = Decidim::ContentRenderers::SpecialWordsRenderer.new(content)
73
79
  parser.render # returns the content formatted
74
- ```
80
+ ----
75
81
 
76
- ## Additional documentation
82
+ == Additional documentation
77
83
 
78
84
  You can check the docs in the base classes and the user processor.
@@ -0,0 +1,85 @@
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 https://medium.com/@mibosc/responsive-design-why-and-how-we-ditched-the-good-old-select-element-bc190d62eff5[this] 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 then return to 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
+
11
+ Data Picker is composed by 2 visual artifacts, plus the javascript and one controller action for each selection type:
12
+
13
+ * *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.
14
+ * *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.
15
+ * *controller ajax action*: An ajax action will send the content of the popup in an html partial.
16
+
17
+ == How to
18
+
19
+ === Placing the Data Picker widget
20
+
21
+ The Data Picker widget structure is as follows:
22
+
23
+ [source,html]
24
+ ----
25
+ <div id="some-unique-id" class="data-picker <%= picker_options[:class]%>" data-picker-name="<%=picker_options[:name]%>">
26
+ <div class="picker-values"><% @form.proposals.each do |proposal, params| %>
27
+ <div><a href="<%= prompt_params[:url] %>" data-picker-value="<%=proposal%>"><%=proposal%></a></div>
28
+ <% end %></div>
29
+ <div class="picker-prompt"><a href="<%= prompt_params[:url] %>"><%= prompt_params[:text] %></a></div>
30
+ </div>
31
+ ----
32
+
33
+ Placing the widget in a form requires two steps:
34
+
35
+ It is a good way to implement the widget to think that it is a component that takes parameters.
36
+
37
+ . Prepare Data Picker parameters
38
+ Data Picker takes two arguments the `picker_params` hash (to fill the main div) and the `prompt_params` hash (for the `picker-prompt` div).
39
+ ** `picker_params.id`: the html unique id of the widget instance, required by the JavaScript.
40
+ ** `picker_params.name`: the html name of the widget which will be sent by the form.
41
+ ** `picker_params.class`: one of `picker-multiple`, when user can select multiple data, or `picker-single`, when only one data is to be selected.
42
+ . Html for the Data Picker widget
43
+
44
+ === Selector popup content
45
+
46
+ *Anchors* in the selector can have the following attributes:
47
+
48
+ * data-close: this anchor will be ignored and will close the picker
49
+ * href: the url to be used for choosing
50
+ * picker-choose: when not present the picker will navigate as a regular anchor. Otherwise a choose action in the component is invoked with params: `url: href, value: picker-value, text: picker-text`.
51
+ * picker-value: the selected value
52
+ * picker-text (optional): The text to be shown in the picker button.
53
+
54
+ This is an example of a link used to choose an element:
55
+
56
+ [source,html]
57
+ ----
58
+ <a class="button" href="[picker path browsing this element]" data-picker-text="[text]" data-picker-value="[value]" data-picker-choose>[text]</a>
59
+ ----
60
+
61
+ *Checkboxes* also can be used in the selector, to allow to select several values at once. In this case, the `href` attribute is replaced with `data-picker-url` and the `data-picker-value` attribute is replaced with the `value` built-in attribute.
62
+
63
+ This is an example of a checkbox that allow to choose an element without closing the picker:
64
+
65
+ [source,html]
66
+ ----
67
+ <label><input type="checkbox" data-picker-url="[picker path browsing this element]" data-picker-text="[text]" value="[value]" data-picker-choose>[text]</label>
68
+ ----
69
+
70
+ == Examples of use of the DataPicker
71
+
72
+ * Scopes picker: Allows to browse the tree of scopes and select one or several scopes.
73
+ ** link:../../decidim-core/lib/decidim/form_builder.rb[FormBuilder scopes picker field]: Basic method to render a scope picker for a form.
74
+ ** link:../../decidim-core/lib/decidim/filter_form_builder.rb[FilterFormBuilder scopes picker field]: Basic method to render a scope picker for a filter form.
75
+ ** link:../../decidim-core/app/helpers/decidim/scopes_helper.rb[Scopes pickers helpers]: Helpers to simplify the call to basic methods.
76
+ ** link:../../decidim-core/app/controllers/decidim/scopes_controller.rb[Global scopes picker controller]: Controller used to browse the scopes on a picker in any part of the application.
77
+ ** link:../../decidim-proposals/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb[Proposals' frontend form using a scopes picker]: Use of a scope picker helper on a frontend page.
78
+ ** link:../../decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb[Proposals' admin form using a scopes picker]: Use of a scope picker helper on an admin page.
79
+ ** link:../../decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb[Meetings' multiple scopes picker for filtering]: Use of a multiple scopes picker on a filter form.
80
+ * Proposals picker: Allows to search and select multiple proposals to be referenced from other components.
81
+ ** link:../../decidim-proposals/app/helpers/decidim/proposals/admin/proposals_picker_helper.rb[Proposals pickers helper]: Helper to render a DataPicker for proposals selection.
82
+ ** link:../../decidim-proposals/app/controllers/concerns/decidim/proposals/admin/picker.rb[Proposals picker concern for admin pages]: You will need to add this concern to your controller, add a route for `proposals_picker` endpoint and create a view for it to show the proposals picker in your component context.
83
+ ** link:../../decidim-proposals/app/cells/decidim/proposals/proposals_picker_cell.rb[Proposals picker cell]: You can use this cell to reuse the logic in your picker view.
84
+ ** link:../../decidim-accountability/app/controllers/decidim/accountability/admin/results_controller.rb[Accountability's admin controller with a proposals picker]: It only needs to add the concern (and the endpoint to the routes).
85
+ ** link:../../decidim-accountability/app/views/decidim/accountability/admin/results/proposals_picker.html.erb[Accountability's admin view with a proposals picker]: It only needs to render the cell.
@@ -0,0 +1,15 @@
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 https://github.com/codegram/decidim-deploy-heroku[deployed to Heroku].
10
+
11
+ == Docker
12
+
13
+ You can also deploy a Decidim app using Docker on hosting services that support it like Dokku, Heroku and all the cloud providers.
14
+
15
+ See the xref:develop:docker.adoc[Decidim on Docker doc] for more details.