diff --git a/app/helpers/cms_helper.rb b/app/helpers/cms_helper.rb index e7695bf0c..5de2606a2 100644 --- a/app/helpers/cms_helper.rb +++ b/app/helpers/cms_helper.rb @@ -88,6 +88,41 @@ def get_filtered_pages pages pages end + def load_categories + return [] unless @cms_page + layouts_categories = Comfy::Cms::LayoutsCategory.where(layout_id: @cms_page.layout_id) + + # TODO This is a workaround to load the custom categories also based on child pages + # in case the categories for the given page are empty. + # This seems to be necessary now because the layout used for the main page + # can be different from the layout used in the child pages + if layouts_categories.blank? + children_layouts = @cms_page.children.map(&:layout_id) + layouts_categories = Comfy::Cms::LayoutsCategory.where(layout_id: children_layouts) + end + + categories_yml = I18n.t('search')[:custom_categories] + layouts_categories.map do |lc| + name = categories_yml[lc.layout_category.label.to_sym][:name] + page_categories = lc.layout_category.page_categories + localised_pcs = categories_yml[name.to_sym][:items] + + items = page_categories.map do |pc| + { + id: pc.id, + name: localised_pcs[pc.label.to_sym] + } + end + + # frontend should return the list of selected categories as follows: + # 'group_name' => [category_ids] ; e.g. 'topics' => [1,2,3] + { + name: name, + items: items + } + end + end + def cta_api @cta_api ||= CallToAction.find_by_css_class('api') end diff --git a/app/models/comfy/cms/layout_category.rb b/app/models/comfy/cms/layout_category.rb new file mode 100644 index 000000000..5f8bdd2b5 --- /dev/null +++ b/app/models/comfy/cms/layout_category.rb @@ -0,0 +1,7 @@ +class Comfy::Cms::LayoutCategory < ApplicationRecord + self.table_name = 'comfy_cms_layout_categories' + + has_many :page_categories + has_many :layouts_categories + has_many :layouts, through: :layouts_categories +end \ No newline at end of file diff --git a/app/models/comfy/cms/layouts_category.rb b/app/models/comfy/cms/layouts_category.rb new file mode 100644 index 000000000..77dc7dfe1 --- /dev/null +++ b/app/models/comfy/cms/layouts_category.rb @@ -0,0 +1,6 @@ +class Comfy::Cms::LayoutsCategory < ApplicationRecord + self.table_name = 'comfy_cms_layouts_categories' + + belongs_to :layout + belongs_to :layout_category +end \ No newline at end of file diff --git a/app/models/comfy/cms/page_category.rb b/app/models/comfy/cms/page_category.rb new file mode 100644 index 000000000..6313f88ac --- /dev/null +++ b/app/models/comfy/cms/page_category.rb @@ -0,0 +1,7 @@ +class Comfy::Cms::PageCategory < ApplicationRecord + self.table_name = 'comfy_cms_page_categories' + + belongs_to :layout_category + has_many :pages_categories + has_many :pages, through: :pages_categories +end \ No newline at end of file diff --git a/app/models/comfy/cms/pages_category.rb b/app/models/comfy/cms/pages_category.rb new file mode 100644 index 000000000..310446755 --- /dev/null +++ b/app/models/comfy/cms/pages_category.rb @@ -0,0 +1,6 @@ +class Comfy::Cms::PagesCategory < ApplicationRecord + self.table_name = 'comfy_cms_pages_categories' + + belongs_to :page + belongs_to :page_category +end \ No newline at end of file diff --git a/app/models/comfy/cms/searchable_page.rb b/app/models/comfy/cms/searchable_page.rb index 23a8efa09..6e506893d 100644 --- a/app/models/comfy/cms/searchable_page.rb +++ b/app/models/comfy/cms/searchable_page.rb @@ -17,6 +17,8 @@ def as_indexed_json include: { fragments_for_index: { only: [:id, :content] } } }, categories: { only: [:id, :label] }, + topics: { only: [:id, :label] }, + page_types: { only: [:id, :label] }, ancestors: { only: [:id, :label] } } ) diff --git a/app/views/resources/index.html.erb b/app/views/resources/index.html.erb index 02b4a47d3..45027e7f1 100644 --- a/app/views/resources/index.html.erb +++ b/app/views/resources/index.html.erb @@ -3,6 +3,8 @@

filters

+ + <%= load_categories %>
diff --git a/config/initializers/comfortable_mexican_sofa.rb b/config/initializers/comfortable_mexican_sofa.rb index e4739abeb..7c33b3bb7 100644 --- a/config/initializers/comfortable_mexican_sofa.rb +++ b/config/initializers/comfortable_mexican_sofa.rb @@ -2,6 +2,7 @@ require 'cms_tags/date_not_null' require 'cms_tags/text_custom' +require 'cms_tags/categories' # encoding: utf-8 ComfortableMexicanSofa.configure do |config| diff --git a/config/initializers/comfy_patching.rb b/config/initializers/comfy_patching.rb new file mode 100644 index 000000000..94c21f394 --- /dev/null +++ b/config/initializers/comfy_patching.rb @@ -0,0 +1,60 @@ +Rails.configuration.to_prepare do + Comfy::Cms::Page.class_eval do + has_many :pages_categories, foreign_key: 'page_id' + has_many :page_categories, through: :pages_categories, foreign_key: 'page_id' + + has_many :topics, -> { joins(:layout_category).where("comfy_cms_layout_categories.label = 'topics'") }, + through: :pages_categories, class_name: 'Comfy::Cms::PageCategory', source: :page_category + + has_many :page_types, -> { joins(:layout_category).where("comfy_cms_layout_categories.label = 'types'") }, + through: :pages_categories, class_name: 'Comfy::Cms::PageCategory', source: :page_category + + accepts_nested_attributes_for :pages_categories + end + + Comfy::Cms::Layout.class_eval do + has_many :layouts_categories, foreign_key: 'layout_id' + has_many :layout_categories, through: :layouts_categories, foreign_key: 'layout_id' + + accepts_nested_attributes_for :layouts_categories + + after_save :assign_layout_categories + + def assign_layout_categories + _categories = self.content_tokens.select do |t| + unless t.is_a?(Hash) + false + else + t[:tag_class] == 'categories' + end + end + + delete_orphan_categories && return if _categories.blank? + + _categories.each do |cat| + tag_name = cat[:tag_params].split(',').first + _layout_category = Comfy::Cms::LayoutCategory.find_by(label: tag_name) + Comfy::Cms::LayoutsCategory.find_or_create_by( + layout_id: self.id, + layout_category_id: _layout_category.id + ) + end + end + + def delete_orphan_categories + layouts_categories = Comfy::Cms::LayoutsCategory.where(layout_id: self.id) + + self.pages.each do |page| + layouts_categories.each do |lc| + pcs_ids = page.page_categories.where(layout_category_id: lc.id).map(&:id) + Comfy::Cms::PagesCategory.where( + page_id: page.id, + page_category_id: pcs_ids + ).destroy_all + end + end + + layout_categories.destroy_all + end + end +end \ No newline at end of file diff --git a/config/locales/search/en.yml b/config/locales/search/en.yml index 608d8c1ee..52d5b44be 100644 --- a/config/locales/search/en.yml +++ b/config/locales/search/en.yml @@ -40,4 +40,18 @@ en: - all - news-and-stories - resources - - areas \ No newline at end of file + - areas + custom_categories: + topics: + name: 'topics' + items: + wdpa: WDPA + oecm: OECM + pame: PAME + types: + name: 'types' + items: + publications: 'Publications' + statistics: 'Statistics' + technical: 'Technical' + training: 'Training' \ No newline at end of file diff --git a/config/search.yml b/config/search.yml index 711dae922..ce0dfea44 100644 --- a/config/search.yml +++ b/config/search.yml @@ -116,6 +116,16 @@ filters: path: 'categories' field: 'categories.id' required: true + topic: + type: 'nested' + path: 'topics' + field: 'topics.id' + required: true + page_type: + type: 'nested' + path: 'page_types' + field: 'page_types.id' + required: true ancestor: type: 'nested' path: 'ancestors' diff --git a/db b/db index 5c67afab7..7f970b02d 160000 --- a/db +++ b/db @@ -1 +1 @@ -Subproject commit 5c67afab71ecbc42bec757a208c41efeaa364261 +Subproject commit 7f970b02d2eb785833ad9f9be2f31b7925f851ad diff --git a/lib/cms_tags/categories.rb b/lib/cms_tags/categories.rb new file mode 100644 index 000000000..9af437eaf --- /dev/null +++ b/lib/cms_tags/categories.rb @@ -0,0 +1,23 @@ +class Categories < ComfortableMexicanSofa::Content::Tag::Fragment + def initialize(context:, params: [], source: nil) + super + @group_name = params.first + @categories = Comfy::Cms::LayoutCategory.find_by(label: @group_name).page_categories + end + + def form_field(object_name, view, index) + input = view.collection_check_boxes(:page, :page_category_ids, @categories, :id, :label) do |b| + view.content_tag(:div, class: "form-check form-check-inline") do + view.concat b.check_box(class: "form-check-input") + view.concat b.label(class: "form-check-label") + end + end + + yield input + end +end + +ComfortableMexicanSofa::Content::Renderer.register_tag( + :categories, Categories +) + \ No newline at end of file diff --git a/lib/modules/search/matcher.rb b/lib/modules/search/matcher.rb index c25d07442..8d93ac56a 100644 --- a/lib/modules/search/matcher.rb +++ b/lib/modules/search/matcher.rb @@ -47,6 +47,7 @@ class Search::Matcher ) }, { type: 'nested', path: 'categories', fields: ['categories.label'] }, + { type: 'nested', path: 'topics', fields: ['topics.label'] }, { type: 'nested', path: 'ancestors', fields: ['ancestors.label'] } ] } diff --git a/lib/modules/search/templates/mappings.json b/lib/modules/search/templates/mappings.json index 582c11344..7606fad9b 100644 --- a/lib/modules/search/templates/mappings.json +++ b/lib/modules/search/templates/mappings.json @@ -232,6 +232,28 @@ } } }, + "topics": { + "type": "nested", + "properties": { + "id": { + "type": "integer" + }, + "label": { + "type": "keyword" + } + } + }, + "page_types": { + "type": "nested", + "properties": { + "id": { + "type": "integer" + }, + "label": { + "type": "keyword" + } + } + }, "fragments_for_index": { "type": "nested", "properties": { diff --git a/lib/tasks/cms_categories.rake b/lib/tasks/cms_categories.rake new file mode 100644 index 000000000..5b0e7f469 --- /dev/null +++ b/lib/tasks/cms_categories.rake @@ -0,0 +1,15 @@ +namespace :cms_categories do + desc 'Seed database tables with custom categories for the CMS' + task import: :environment do + groups = I18n.t('search')[:custom_categories] + + groups.each do |group_name, categories| + layout_category = Comfy::Cms::LayoutCategory.find_or_create_by(label: group_name.to_s) + categories_names = categories[:items].keys + + categories_names.each do |cat_name| + Comfy::Cms::PageCategory.find_or_create_by(layout_category_id: layout_category.id, label: cat_name) + end + end + end +end \ No newline at end of file