From 79c9f08aa25bcad9b566ce34cd8abf2adf46918c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Fri, 2 Dec 2022 15:38:04 +0100
Subject: [PATCH] concern WithWebsitePermalink

---
 app/models/communication/website/category.rb  |  9 ++++++
 .../website/configs/permalinks.rb             | 18 +++++++++++
 app/models/communication/website/page.rb      |  9 ++++--
 app/models/communication/website/post.rb      | 12 +++++++
 app/models/concerns/with_website_permalink.rb | 26 +++++++++++++++
 app/models/university/person.rb               |  5 +++
 .../configs/permalinks/static.html.erb        | 32 ++-----------------
 7 files changed, 80 insertions(+), 31 deletions(-)
 create mode 100644 app/models/concerns/with_website_permalink.rb

diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb
index 15d4c5c5e..b64503042 100644
--- a/app/models/communication/website/category.rb
+++ b/app/models/communication/website/category.rb
@@ -45,6 +45,7 @@ class Communication::Website::Category < ApplicationRecord
   include WithSlug # We override slug_unavailable? method
   include WithTree
   include WithPosition
+  include WithWebsitePermalink
 
   has_one                 :imported_category,
                           class_name: 'Communication::Website::Imported::Category',
@@ -106,6 +107,10 @@ class Communication::Website::Category < ApplicationRecord
     self.class.unscoped.where(parent: parent, university: university, website: website).where.not(id: id)
   end
 
+  def computed_permalink_for_website(website)
+    raw_permalink_for_website(website).gsub(':slug', self.path)
+  end
+
   protected
 
   def last_ordered_element
@@ -123,4 +128,8 @@ class Communication::Website::Category < ApplicationRecord
   def inherited_blob_ids
     [best_featured_image&.blob_id]
   end
+
+  def permalink_config_key
+    :categories
+  end
 end
diff --git a/app/models/communication/website/configs/permalinks.rb b/app/models/communication/website/configs/permalinks.rb
index cf836fd47..4c5176baf 100644
--- a/app/models/communication/website/configs/permalinks.rb
+++ b/app/models/communication/website/configs/permalinks.rb
@@ -43,4 +43,22 @@ class Communication::Website::Configs::Permalinks < Communication::Website
     "admin/communication/websites/configs/permalinks/static"
   end
 
+  def permalinks_data
+    @permalinks_data ||= begin
+      data = {}
+      data[:posts] = "#{self.special_page(:communication_posts).path_without_language}:year/:month/:day/:slug/" if has_communication_posts?
+      data[:categories] = "#{self.special_page(:communication_posts).path_without_language}:slug/" if has_communication_posts? && has_communication_categories?
+      data[:persons] = "#{self.special_page(:persons).path_without_language}:slug/" if has_persons?
+      data[:organizations] = "#{self.special_page(:organizations).path_without_language}:slug/" if has_organizations?
+      # website might have authors but no communication_posts (if a post unpublished exists)
+      data[:authors] = "#{self.special_page(:persons).path_without_language}:slug/#{self.special_page(:communication_posts).slug}/" if has_authors? && has_communication_posts?
+      data[:diplomas] = "#{self.special_page(:education_diplomas).path_without_language}:slug/" if has_education_diplomas?
+      # ces paths complémentaires sont nécessaires à Hugo mais on ne les utilise pas
+      data[:administrators] = "#{self.special_page(:persons).path_without_language}:slug/roles/" if has_administrators?
+      data[:teachers] = "#{self.special_page(:persons).path_without_language}:slug/programs/" if has_teachers?
+      data[:researchers] = "#{self.special_page(:persons).path_without_language}:slug/papers/" if has_researchers?
+      data
+    end
+  end
+
 end
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index 514b34a38..29e2add7d 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -41,6 +41,7 @@
 #
 
 class Communication::Website::Page < ApplicationRecord
+  include Accessible
   include Sanitizable
   include WithUniversity
   include WithBlobs
@@ -52,7 +53,7 @@ class Communication::Website::Page < ApplicationRecord
   include WithPosition
   include WithTree
   include WithPath
-  include Accessible
+  include WithWebsitePermalink
 
   has_summernote :text
 
@@ -115,7 +116,7 @@ class Communication::Website::Page < ApplicationRecord
   end
 
   def full_width
-    kind_home?  ? true 
+    kind_home?  ? true
                 : attributes['full_width']
   end
 
@@ -140,6 +141,10 @@ class Communication::Website::Page < ApplicationRecord
               .where.not(id: id)
   end
 
+  def computed_permalink_for_website(website)
+    path
+  end
+
   protected
 
   def check_accessibility
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index 83ffa5860..50488f275 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -43,6 +43,7 @@ class Communication::Website::Post < ApplicationRecord
   include WithBlocks
   include WithMenuItemTarget
   include WithSlug # We override slug_unavailable? method
+  include WithWebsitePermalink
 
   has_summernote :text
 
@@ -142,6 +143,13 @@ class Communication::Website::Post < ApplicationRecord
     "#{website.url}#{website.special_page(:communication_posts).path}#{path}"
   end
 
+  def computed_permalink_for_website(website)
+    return unless website.id == communication_website_id && published && published_at
+    raw_permalink_for_website(website)
+      .gsub(':slug', self.slug)
+      .gsub(':year/:month/:day', published_at.strftime("%Y/%m/%d"))
+  end
+
   def to_s
     "#{title}"
   end
@@ -174,4 +182,8 @@ class Communication::Website::Post < ApplicationRecord
     end
     author.update_and_sync(is_author: true) if author_id
   end
+
+  def permalink_config_key
+    :posts
+  end
 end
diff --git a/app/models/concerns/with_website_permalink.rb b/app/models/concerns/with_website_permalink.rb
new file mode 100644
index 000000000..f3691e458
--- /dev/null
+++ b/app/models/concerns/with_website_permalink.rb
@@ -0,0 +1,26 @@
+module WithWebsitePermalink
+  extend ActiveSupport::Concern
+
+  included do
+
+    def permalink_for_website(website)
+      computed_permalink = computed_permalink_for_website(website)
+      computed_permalink.present? ? Static.clean_path(computed_permalink) : nil
+    end
+
+    def computed_permalink_for_website(website)
+      raw_permalink_for_website(website).gsub(':slug', self.slug)
+    end
+
+    protected
+
+    def raw_permalink_for_website(website)
+      website.config_permalinks.permalinks_data[permalink_config_key]
+    end
+
+    def permalink_config_key
+      raise NotImplementedError
+    end
+
+  end
+end
diff --git a/app/models/university/person.rb b/app/models/university/person.rb
index ca6f03bb5..622c91a59 100644
--- a/app/models/university/person.rb
+++ b/app/models/university/person.rb
@@ -56,6 +56,7 @@ class University::Person < ApplicationRecord
   include WithPicture
   include WithRoles
   include WithBlocks
+  include WithWebsitePermalink
 
   LIST_OF_ROLES = [
     :administration,
@@ -235,4 +236,8 @@ class University::Person < ApplicationRecord
   def prepare_name
     self.name = to_s
   end
+
+  def permalink_config_key
+    :persons
+  end
 end
diff --git a/app/views/admin/communication/websites/configs/permalinks/static.html.erb b/app/views/admin/communication/websites/configs/permalinks/static.html.erb
index 71371e535..3574b6256 100644
--- a/app/views/admin/communication/websites/configs/permalinks/static.html.erb
+++ b/app/views/admin/communication/websites/configs/permalinks/static.html.erb
@@ -1,29 +1,3 @@
-<% if @website.has_communication_posts? %>
-posts:          <%= @website.special_page(:communication_posts).path_without_language %>:year/:month/:day/:slug/
-<% end %>
-<% if @website.has_communication_posts? && @website.has_communication_categories? %>
-categories:     <%= @website.special_page(:communication_posts).path_without_language %>:slug/
-<% end %>
-<% if @website.has_persons? %>
-persons:        <%= @website.special_page(:persons).path_without_language %>:slug/
-<% end %>
-<% if @website.has_organizations? %>
-organizations:  <%= @website.special_page(:organizations).path_without_language %>:slug/
-<% end %>
-<%# website might have authors but no communication_posts (if a post unpublished exists) %>
-<% if @website.has_authors? && @website.has_communication_posts? %>
-authors:        <%= @website.special_page(:persons).path_without_language %>:slug/<%= @website.special_page(:communication_posts).slug %>/
-<% end %>
-<% if @website.has_education_diplomas? %>
-diplomas:       <%= @website.special_page(:education_diplomas).path_without_language %>:slug/
-<% end %>
-<%# ces paths complémentaires sont nécessaires à Hugo mais on ne les utilise pas %>
-<% if @website.has_administrators? %>
-administrators: <%= @website.special_page(:persons).path_without_language %>:slug/roles/
-<% end %>
-<% if @website.has_teachers? %>
-teachers:       <%= @website.special_page(:persons).path_without_language %>:slug/programs/
-<% end %>
-<% if @website.has_researchers? %>
-researchers:    <%= @website.special_page(:persons).path_without_language %>:slug/papers/
-<% end %>
+<% @website.config_permalinks.permalinks_data.each do |key, value| %>
+<%= key %>: <%= value %>
+<% end %>
\ No newline at end of file
-- 
GitLab