diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index 5e1c7d1deb76eb827b8d56adaf3ac14fca818bbe..514b34a3828b6390e82d7626786a258de389f855 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -51,6 +51,7 @@ class Communication::Website::Page < ApplicationRecord
   include WithMenuItemTarget
   include WithPosition
   include WithTree
+  include WithPath
   include Accessible
 
   has_summernote :text
@@ -71,48 +72,9 @@ class Communication::Website::Page < ApplicationRecord
 
   validates :title, presence: true
 
-  validates :slug,
-            presence: true,
-            unless: :kind_home?
-  validate  :slug_must_be_unique
-  validates :slug,
-            format: {
-              with: /\A[a-z0-9\-]+\z/,
-              message: I18n.t('slug_error')
-            },
-            unless: :kind_home?
-
-  before_validation :check_slug, :make_path
-  after_save :update_children_paths, if: :saved_change_to_path?
-
   scope :recent, -> { order(updated_at: :desc).limit(5) }
   scope :published, -> { where(published: true) }
 
-  def generated_path
-    "#{parent&.path}#{slug}/".gsub(/\/+/, '/')
-  end
-
-  def path_without_language
-    if kind_home?
-      "/"
-    elsif parent_id.present?
-      "#{parent&.path_without_language}#{slug}/".gsub(/\/+/, '/')
-    else
-      "/#{slug}/".gsub(/\/+/, '/')
-    end
-  end
-
-  def git_path(website)
-    return unless published
-    if kind_home?
-      "content/_index.html"
-    elsif is_special_page? && SPECIAL_PAGES_WITH_GIT_SPECIAL_PATH.include?(kind)
-      "content/#{kind.split('_').last}/_index.html"
-    else
-      "content/pages/#{path}/_index.html"
-    end
-  end
-
   def template_static
     "admin/communication/websites/pages/static"
   end
@@ -136,12 +98,6 @@ class Communication::Website::Page < ApplicationRecord
     active_storage_blobs
   end
 
-  def url
-    return unless published
-    return if website.url.blank?
-    "#{website.url}#{path}"
-  end
-
   def language_prefix
     "/#{language.iso_code}" if website.languages.any? && language_id
   end
@@ -178,15 +134,10 @@ class Communication::Website::Page < ApplicationRecord
     parent&.best_bodyclass unless kind_home? || parent&.kind_home?
   end
 
-  def update_children_paths
-    children.each do |child|
-      child.update_column :path, child.generated_path
-      child.update_children_paths
-    end
-  end
-
   def siblings
-    self.class.unscoped.where(parent: parent, university: university, website: website).where.not(id: id)
+    self.class.unscoped
+              .where(parent: parent, university: university, website: website)
+              .where.not(id: id)
   end
 
   protected
@@ -199,31 +150,6 @@ class Communication::Website::Page < ApplicationRecord
     website.pages.where(parent_id: parent_id).ordered.last
   end
 
-  def check_slug
-    self.slug = to_s.parameterize if self.slug.blank? && !kind_home?
-    current_slug = self.slug
-    n = 0
-    while slug_unavailable?(self.slug)
-      n += 1
-      self.slug = [current_slug, n].join('-')
-    end
-  end
-
-  def slug_unavailable?(slug)
-    self.class.unscoped
-              .where(communication_website_id: self.communication_website_id, slug: slug)
-              .where.not(id: self.id)
-              .exists?
-  end
-
-  def make_path
-    self.path = kind_home? ? "#{language_prefix}/" : generated_path
-  end
-
-  def slug_must_be_unique
-    errors.add(:slug, ActiveRecord::Errors.default_error_messages[:taken]) if slug_unavailable?(slug)
-  end
-
   def explicit_blob_ids
     super.concat [featured_image&.blob_id]
   end
diff --git a/app/models/communication/website/page/with_kind.rb b/app/models/communication/website/page/with_kind.rb
index 60983f7557d7d33a2673ee0aa70c0661f1ed1df4..4e5d067bbeb5084547db5dde35fac515d00183d6 100644
--- a/app/models/communication/website/page/with_kind.rb
+++ b/app/models/communication/website/page/with_kind.rb
@@ -46,6 +46,10 @@ module Communication::Website::Page::WithKind
       !is_special_page?
     end
 
+    def has_special_git_path?
+      is_special_page? && SPECIAL_PAGES_WITH_GIT_SPECIAL_PATH.include?(kind)
+    end
+
   end
 
   private
diff --git a/app/models/communication/website/page/with_path.rb b/app/models/communication/website/page/with_path.rb
new file mode 100644
index 0000000000000000000000000000000000000000..707295f3bd810fe0997c48495bd38dc2ca98df86
--- /dev/null
+++ b/app/models/communication/website/page/with_path.rb
@@ -0,0 +1,85 @@
+module Communication::Website::Page::WithPath
+  extend ActiveSupport::Concern
+
+  included do
+    validates :slug,
+              presence: true,
+              unless: :kind_home?
+    validate  :slug_must_be_unique
+    validates :slug,
+              format: {
+                with: /\A[a-z0-9\-]+\z/,
+                message: I18n.t('slug_error')
+              },
+              unless: :kind_home?
+
+    before_validation :check_slug, :make_path
+    after_save :update_children_paths, if: :saved_change_to_path?
+  end
+
+  def generated_path
+    "#{parent&.path}#{slug}/".gsub(/\/+/, '/')
+  end
+
+  def path_without_language
+    if kind_home?
+      "/"
+    elsif parent_id.present?
+      "#{parent&.path_without_language}#{slug}/".gsub(/\/+/, '/')
+    else
+      "/#{slug}/".gsub(/\/+/, '/')
+    end
+  end
+
+  def git_path(website)
+    return unless published
+    if kind_home?
+      "content/_index.html"
+    elsif has_special_git_path?
+      "content/#{kind.split('_').last}/_index.html"
+    else
+      "content/pages/#{path}/_index.html"
+    end
+  end
+
+  def url
+    return unless published
+    return if website.url.blank?
+    "#{website.url}#{path}"
+  end
+
+  protected
+
+  def update_children_paths
+    children.each do |child|
+      child.update_column :path, child.generated_path
+      child.update_children_paths
+    end
+  end
+
+  def check_slug
+    self.slug = to_s.parameterize if self.slug.blank? && !kind_home?
+    current_slug = self.slug
+    n = 0
+    while slug_unavailable?(self.slug)
+      n += 1
+      self.slug = [current_slug, n].join('-')
+    end
+  end
+
+  def slug_unavailable?(slug)
+    self.class.unscoped
+              .where(communication_website_id: self.communication_website_id, slug: slug)
+              .where.not(id: self.id)
+              .exists?
+  end
+
+  def make_path
+    self.path = kind_home? ? "#{language_prefix}/" : generated_path
+  end
+
+  def slug_must_be_unique
+    errors.add(:slug, ActiveRecord::Errors.default_error_messages[:taken]) if slug_unavailable?(slug)
+  end
+
+end