decidim-term_customizer 0.16.3 → 0.16.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e1966c6d76f52620be03f12e047aaae93afeb95fe0514dc4710d89a6f3bfdfd
4
- data.tar.gz: 325607f77cf3ac7760e86ca9a8d29a16dcedfcfcc2b3cb971eb4ab048f49211a
3
+ metadata.gz: b9473c65d949ac1f1c14f152bad4cd0c04ffcff5f2a9ad377dc470f2af4fc256
4
+ data.tar.gz: 64b870998a9239a6242ea2bd1ebe0ac1e00b1bcb9812d7b5bd3efa2618dbbb68
5
5
  SHA512:
6
- metadata.gz: b8020b5e16df220bf10b4daf420a05ae5547eb79eb3a5473b4cb9c1200d6ac5ec6ecd71a85000463459a9abc6057226d9a019c77225956fec165971e546e73a1
7
- data.tar.gz: fb719d2024b32369669f7c62c7aa9b7960d57e79d812299e7498e9b08308767e10f087077dcfdea14eb9b3f4a5b5c5f05df0d28e5b7cd74a71e97767b3d20e0f
6
+ metadata.gz: '08f642fc149b9d8664081607afe9fb167fcc42dc7f6e2f02a8b73c0a0efd746f2c015e0023d46b5e6d4241e342bb13dbf7a2e2087508c850060a44378435933f'
7
+ data.tar.gz: c6648b9f8d3e89a7308d4b320a4bf96b6e09fa5d958a5005b343832534eae8c827d8171fa7a9f0bb669d9f6c350dcdb46bfc5b92986b39e3610ae0491d3ad944
@@ -38,20 +38,19 @@ module Decidim
38
38
  attr_reader :form
39
39
 
40
40
  def create_translations
41
- form.keys.each do |key|
42
- form.current_organization.available_locales.each do |locale|
41
+ items = form.keys.map do |key|
42
+ form.current_organization.available_locales.map do |locale|
43
43
  attrs = {
44
- translation_set: form.translation_set,
45
44
  key: key,
46
45
  locale: locale
47
46
  }
48
47
  next unless TermCustomizer::Translation.find_by(attrs).nil?
49
48
 
50
- TermCustomizer::Translation.create!(
51
- attrs.merge(value: I18n.t(key, locale: locale, default: ""))
52
- )
49
+ attrs.merge(value: I18n.t(key, locale: locale, default: ""))
53
50
  end
54
51
  end.flatten
52
+
53
+ form.translation_set.translations.create!(items)
55
54
  end
56
55
  end
57
56
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ module Admin
6
+ class CachesController < TermCustomizer::Admin::ApplicationController
7
+ def index
8
+ enforce_permission_to :update, :organization
9
+
10
+ redirect_to translation_sets_path
11
+ end
12
+
13
+ def clear
14
+ enforce_permission_to :update, :organization
15
+
16
+ TermCustomizer.loader.clear_cache
17
+ flash[:notice] = I18n.t("caches.clear.success", scope: "decidim.term_customizer.admin")
18
+
19
+ redirect_to translation_sets_path
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -88,7 +88,10 @@ module Decidim
88
88
  end
89
89
 
90
90
  def translations
91
- @translations ||= SetTranslations.new(translation_set, current_locale)
91
+ @translations ||= SetTranslations.new(
92
+ translation_set,
93
+ current_locale
94
+ ).query.page(params[:page]).per(30)
92
95
  end
93
96
 
94
97
  def translation
@@ -1,10 +1,20 @@
1
1
  <div class="card" id="translation_sets">
2
2
  <div class="card-divider">
3
- <h2 class="card-title">
4
- <%= t "decidim.admin.titles.translation_sets" %>
5
- <% if allowed_to? :create, :translation_set %>
6
- <%= link_to t("actions.new_translation_set", scope: "decidim.admin"), new_translation_set_path, class: "button tiny button--title" %>
7
- <% end %>
3
+ <h2 class="card-title flex--sbc">
4
+ <div>
5
+ <%= t "decidim.admin.titles.translation_sets" %>
6
+ </div>
7
+
8
+ <div class="flex--cc flex-gap--1">
9
+ <div id="js-other-actions-wrapper">
10
+ <% if allowed_to? :create, :translation_set %>
11
+ <%= link_to t("actions.new_translation_set", scope: "decidim.admin"), new_translation_set_path, class: "button tiny button--simple" %>
12
+ <% end %>
13
+ <% if allowed_to? :update, :organization %>
14
+ <%= link_to t("actions.clear_cache", scope: "decidim.admin"), clear_caches_path, method: :delete, class: "button tiny button--simple", data: { confirm: t("actions.confirm_destroy", scope: "decidim.admin") } %>
15
+ <% end %>
16
+ </div>
17
+ </div>
8
18
  </h2>
9
19
  </div>
10
20
  <div class="card-section">
@@ -51,6 +51,7 @@
51
51
  <% end %>
52
52
  </tbody>
53
53
  </table>
54
+ <%= paginate @translations, theme: "decidim" %>
54
55
  </div>
55
56
  </div>
56
57
  </div>
@@ -15,6 +15,7 @@ ca:
15
15
  actions:
16
16
  add_multiple_translations: Afegir múltiples
17
17
  back: Enrere
18
+ clear_cache: Clear cache
18
19
  new_translation_set: Nou set/joc de traducció
19
20
  new_translation: Nova traducció
20
21
  models:
@@ -35,6 +36,9 @@ ca:
35
36
  index:
36
37
  add: Afegir
37
38
  search: Buscar
39
+ caches:
40
+ clear:
41
+ success: Cache cleared successfully
38
42
  translation_sets:
39
43
  constraint_fields:
40
44
  constraint: Obligatori
@@ -15,6 +15,7 @@ en:
15
15
  actions:
16
16
  add_multiple_translations: Add multiple
17
17
  back: Back
18
+ clear_cache: Clear cache
18
19
  new_translation_set: New translation set
19
20
  new_translation: New translation
20
21
  models:
@@ -35,6 +36,9 @@ en:
35
36
  index:
36
37
  add: Add
37
38
  search: Search
39
+ caches:
40
+ clear:
41
+ success: Cache cleared successfully
38
42
  translation_sets:
39
43
  constraint_fields:
40
44
  constraint: Constraint
@@ -15,6 +15,7 @@ es:
15
15
  actions:
16
16
  add_multiple_translations: Agregar varios
17
17
  back: Volver
18
+ clear_cache: Clear cache
18
19
  new_translation_set: Nuevo grupo de traducciones
19
20
  new_translation: Nueva traducción
20
21
  models:
@@ -35,6 +36,9 @@ es:
35
36
  index:
36
37
  add: Añadir
37
38
  search: Buscar
39
+ caches:
40
+ clear:
41
+ success: Cache cleared successfully
38
42
  translation_sets:
39
43
  constraint_fields:
40
44
  constraint: Ámbito
@@ -15,6 +15,7 @@ fi:
15
15
  actions:
16
16
  add_multiple_translations: Lisää useita
17
17
  back: Takaisin
18
+ clear_cache: Tyhjennä välimuisti
18
19
  new_translation_set: Uusi käännöspaketti
19
20
  new_translation: Uusi käännös
20
21
  models:
@@ -35,6 +36,9 @@ fi:
35
36
  index:
36
37
  add: Lisää
37
38
  search: Hae
39
+ caches:
40
+ clear:
41
+ success: Välimuistin tyhjennys onnistui
38
42
  translation_sets:
39
43
  constraint_fields:
40
44
  constraint: Rajaussääntö
@@ -15,6 +15,7 @@ sv:
15
15
  actions:
16
16
  add_multiple_translations: Add multiple
17
17
  back: Back
18
+ clear_cache: Clear cache
18
19
  new_translation_set: New translation set
19
20
  new_translation: New translation
20
21
  models:
@@ -35,6 +36,9 @@ sv:
35
36
  index:
36
37
  add: Add
37
38
  search: Search
39
+ caches:
40
+ clear:
41
+ success: Cache cleared successfully
38
42
  translation_sets:
39
43
  constraint_fields:
40
44
  constraint: Constraint
@@ -18,6 +18,12 @@ module Decidim
18
18
  end
19
19
  end
20
20
 
21
+ resources :caches, only: [:index] do
22
+ collection do
23
+ delete :clear
24
+ end
25
+ end
26
+
21
27
  root to: "translation_sets#index"
22
28
  end
23
29
 
@@ -18,17 +18,69 @@ module Decidim
18
18
  # environment variables within Decidim.
19
19
  ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |_name, _started, _finished, _unique_id, data|
20
20
  env = data[:headers].env
21
+ controller = data[:headers].env["action_controller.instance"]
22
+
23
+ # E.g. at the participatory process controller the
24
+ # `decidim.current_participatory_space` environment variable has not
25
+ # been set. Therefore, we need to fetch it directly from the
26
+ # controller using its private method.
27
+ space =
28
+ if controller.respond_to?(:current_participatory_space, true)
29
+ controller.send(:current_participatory_space)
30
+ else
31
+ env["decidim.current_participatory_space"]
32
+ end
21
33
 
22
34
  # Create a new resolver instance within the current request scope
23
- TermCustomizer.resolver = Resolver.new(
35
+ resolver = Resolver.new(
24
36
  env["decidim.current_organization"],
25
- env["decidim.current_participatory_space"],
37
+ space,
26
38
  env["decidim.current_component"]
27
39
  )
28
40
 
41
+ # Create the loader for the backend to fetch the translations from
42
+ TermCustomizer.loader = Loader.new(resolver)
43
+
29
44
  # Force the backend to reload the translations for the current request
30
45
  customizer_backend.reload!
31
46
  end
47
+
48
+ # The jobs are generally run in different context than the controllers
49
+ # which causes the term customizations not to be active. During the
50
+ # jobs, only the organization and global context translations are loaded
51
+ # because otherwise this would have to be job specific.
52
+ #
53
+ # Currently this has been only tested against the event notification
54
+ # jobs but it may work for other jobs as well. Because the jobs
55
+ # themselves don't carry any other context information than their
56
+ # arguments, it is difficult to resolve their correct context. Note also
57
+ # that e.g. the email notifications are always created through a single
58
+ # job that may be fired by another job (i.e. the notification job is
59
+ # always performed last).
60
+ ActiveSupport::Notifications.subscribe "perform_start.active_job" do |_name, _started, _finished, _unique_id, data|
61
+ # Figure out the organization and user through the job arguments if
62
+ # passed for the job.
63
+ organization = nil
64
+ user = nil
65
+ data[:job].arguments.each do |arg|
66
+ organization = arg if arg.is_a?(Decidim::Organization)
67
+ user = arg if arg.is_a?(Decidim::User)
68
+ end
69
+
70
+ # In case an organization was not passed for the job, check it through
71
+ # the user.
72
+ organization = user.organization if organization.nil? && user
73
+
74
+ # Create resolver for the target organization or global context in
75
+ # case organization was not found
76
+ resolver = Resolver.new(organization, nil, nil)
77
+
78
+ # Create the loader for the backend to fetch the translations from
79
+ TermCustomizer.loader = Loader.new(resolver)
80
+
81
+ # Force the backend to reload the translations for the job
82
+ customizer_backend.reload!
83
+ end
32
84
  end
33
85
  end
34
86
  end
@@ -32,24 +32,9 @@ module Decidim
32
32
 
33
33
  def translations
34
34
  return @translations if @translations
35
- return {} unless TermCustomizer.resolver
35
+ return {} unless TermCustomizer.loader
36
36
 
37
- @translations = {}
38
-
39
- TermCustomizer.resolver.translations.each do |tr|
40
- keyparts = [tr.locale] + tr.key.split(".")
41
- lastkey = keyparts.pop.to_sym
42
-
43
- current = @translations
44
- keyparts.each do |key|
45
- current[key.to_sym] ||= {}
46
- current = current[key.to_sym]
47
- end
48
-
49
- current[lastkey] = tr.value
50
- end
51
-
52
- @translations
37
+ @translations = TermCustomizer.loader.translations_hash
53
38
  end
54
39
 
55
40
  protected
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TermCustomizer
5
+ # The loader class is a middleman that converts the Translation model
6
+ # objects to a flat translation hash that can be directly used in the i18n
7
+ # backend. The main purpose of this class is to add caching possibility for
8
+ # the translation hashes.
9
+ class Loader
10
+ def initialize(resolver)
11
+ @resolver = resolver
12
+ end
13
+
14
+ # Converts the translation objects to a flat hash where the keys are
15
+ # the translatable keys used in the i18n backend containing the locales.
16
+ # The values of the hash are the translations for the keys.
17
+ #
18
+ # The final hash looks similar like this:
19
+ # {
20
+ # en: {
21
+ # decidim: {
22
+ # translation: "Term EN"
23
+ # }
24
+ # },
25
+ # fi: {
26
+ # decidim: {
27
+ # translation: "Term FI"
28
+ # }
29
+ # }
30
+ # }
31
+ #
32
+ # This will also cache the results and fetch the result directly from
33
+ # cache on consequent calls until the cache is expired.
34
+ def translations_hash
35
+ @translations_hash ||= Rails.cache.fetch(
36
+ cache_key,
37
+ expires_in: 24.hours
38
+ ) do
39
+ final_hash = {}
40
+ resolver.translations.each do |tr|
41
+ keyparts = [tr.locale] + tr.key.split(".")
42
+ lastkey = keyparts.pop.to_sym
43
+
44
+ current = final_hash
45
+ keyparts.each do |key|
46
+ current[key.to_sym] ||= {}
47
+ current = current[key.to_sym]
48
+ end
49
+
50
+ current[lastkey] = tr.value
51
+ end
52
+ final_hash
53
+ end
54
+ end
55
+
56
+ # Clears the translations cache only for the current context defined by
57
+ # the resolver.
58
+ def clear_cache
59
+ Rails.cache.delete_matched("#{cache_key_base}/*")
60
+ end
61
+
62
+ private
63
+
64
+ attr_reader :resolver
65
+
66
+ def cache_key
67
+ parts = [cache_key_base]
68
+ parts << "space_#{resolver.space.id}" if resolver.space
69
+ parts << "component_#{resolver.component.id}" if resolver.component
70
+
71
+ parts.join("/")
72
+ end
73
+
74
+ def cache_key_base
75
+ main_key =
76
+ if resolver.organization
77
+ "organization_#{resolver.organization.id}"
78
+ else
79
+ "system"
80
+ end
81
+
82
+ "decidim_term_customizer/#{main_key}"
83
+ end
84
+ end
85
+ end
86
+ end
@@ -3,6 +3,8 @@
3
3
  module Decidim
4
4
  module TermCustomizer
5
5
  class Resolver
6
+ attr_reader :organization, :space, :component
7
+
6
8
  def initialize(organization, space, component)
7
9
  @organization = organization
8
10
  @space = space
@@ -19,8 +21,6 @@ module Decidim
19
21
 
20
22
  private
21
23
 
22
- attr_reader :organization, :space, :component
23
-
24
24
  def resolve_translations_query
25
25
  query = translations_base_query
26
26
  translations_add_constraints_query(query)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module TermCustomizer
5
- VERSION = "0.16.3"
5
+ VERSION = "0.16.5"
6
6
  DECIDIM_VERSION = "~> 0.16.0"
7
7
  end
8
8
  end
@@ -8,6 +8,7 @@ require_relative "term_customizer/admin_engine"
8
8
  module Decidim
9
9
  module TermCustomizer
10
10
  autoload :I18nBackend, "decidim/term_customizer/i18n_backend"
11
+ autoload :Loader, "decidim/term_customizer/loader"
11
12
  autoload :Resolver, "decidim/term_customizer/resolver"
12
13
  autoload :TranslationDirectory, "decidim/term_customizer/translation_directory"
13
14
  autoload :TranslationStore, "decidim/term_customizer/translation_store"
@@ -15,7 +16,7 @@ module Decidim
15
16
  EMPTY_HASH = {}.freeze
16
17
 
17
18
  class << self
18
- attr_accessor :resolver
19
+ attr_accessor :loader
19
20
  end
20
21
  end
21
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-term_customizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.3
4
+ version: 0.16.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antti Hukkanen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-07 00:00:00.000000000 Z
11
+ date: 2019-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim-admin
@@ -118,6 +118,7 @@ files:
118
118
  - app/commands/decidim/term_customizer/admin/update_translation_set.rb
119
119
  - app/controllers/decidim/term_customizer/admin/add_translations_controller.rb
120
120
  - app/controllers/decidim/term_customizer/admin/application_controller.rb
121
+ - app/controllers/decidim/term_customizer/admin/caches_controller.rb
121
122
  - app/controllers/decidim/term_customizer/admin/translation_sets_controller.rb
122
123
  - app/controllers/decidim/term_customizer/admin/translations_controller.rb
123
124
  - app/forms/decidim/term_customizer/admin/translation_form.rb
@@ -157,6 +158,7 @@ files:
157
158
  - lib/decidim/term_customizer/admin_engine.rb
158
159
  - lib/decidim/term_customizer/engine.rb
159
160
  - lib/decidim/term_customizer/i18n_backend.rb
161
+ - lib/decidim/term_customizer/loader.rb
160
162
  - lib/decidim/term_customizer/resolver.rb
161
163
  - lib/decidim/term_customizer/test/factories.rb
162
164
  - lib/decidim/term_customizer/translation_directory.rb