diff --git a/app/assets/javascripts/admin/commons/slug_input.js b/app/assets/javascripts/admin/commons/slug_input.js
index 11284f933..b2c438f61 100644
--- a/app/assets/javascripts/admin/commons/slug_input.js
+++ b/app/assets/javascripts/admin/commons/slug_input.js
@@ -34,9 +34,12 @@ window.osuny.slugInput = {
onSourceChange: function (sourceInputs, slugInput) {
'use strict';
- var values = [],
+ var maxLength = slugInput.maxLength,
+ generatedSlug,
+ values = [],
value,
i;
+
for (i = 0; i < sourceInputs.length; i += 1) {
value = sourceInputs[i].value.trim();
if (value !== '') {
@@ -44,7 +47,14 @@ window.osuny.slugInput = {
}
}
- slugInput.value = window.slug(values.join(' '));
+ generatedSlug = window.slug(values.join(' '));
+ if (generatedSlug.length > maxLength) {
+ generatedSlug = generatedSlug.slice(0, maxLength);
+ }
+ if (generatedSlug[generatedSlug.length - 1] === '-') {
+ generatedSlug = generatedSlug.slice(0, -1);
+ }
+ slugInput.value = generatedSlug;
},
invoke: function () {
diff --git a/app/controllers/admin/education/diplomas_controller.rb b/app/controllers/admin/education/diplomas_controller.rb
index 2be48e2e1..258b5b8ae 100644
--- a/app/controllers/admin/education/diplomas_controller.rb
+++ b/app/controllers/admin/education/diplomas_controller.rb
@@ -64,6 +64,6 @@ def breadcrumb
def diploma_params
params.require(:education_diploma)
- .permit(:name, :short_name, :summary, :level, :ects, :duration)
+ .permit(:name, :slug, :short_name, :summary, :level, :ects, :duration)
end
end
diff --git a/app/controllers/admin/research/publications_controller.rb b/app/controllers/admin/research/publications_controller.rb
index 0c229a7db..179b43319 100644
--- a/app/controllers/admin/research/publications_controller.rb
+++ b/app/controllers/admin/research/publications_controller.rb
@@ -61,6 +61,6 @@ def breadcrumb
def publication_params
params.require(:research_publication)
- .permit(:title, :publication_date, :abstract, :authors_list, :doi, :ref, :journal_title, :url, :open_access, :citation_full, researcher_ids: [])
+ .permit(:title, :slug, :publication_date, :abstract, :authors_list, :doi, :ref, :journal_title, :url, :open_access, :citation_full, researcher_ids: [])
end
end
diff --git a/app/models/communication/website/agenda/category.rb b/app/models/communication/website/agenda/category.rb
index 049f0b88f..338c3e207 100644
--- a/app/models/communication/website/agenda/category.rb
+++ b/app/models/communication/website/agenda/category.rb
@@ -39,7 +39,8 @@ class Communication::Website::Agenda::Category < ApplicationRecord
include AsDirectObject
include Contentful
include Sanitizable
- include Sluggable
+ include Sluggable # We override slug_unavailable? method
+ include Pathable # Included after Sluggable to make sure slug is correct before anything
include WithBlobs
include WithFeaturedImage
include WithMenuItemTarget
@@ -47,7 +48,7 @@ class Communication::Website::Agenda::Category < ApplicationRecord
include WithPosition
include WithTranslations
include WithUniversity
-
+
belongs_to :parent,
class_name: 'Communication::Website::Agenda::Category',
optional: true
diff --git a/app/models/communication/website/menu.rb b/app/models/communication/website/menu.rb
index fc424526f..fbdc06293 100644
--- a/app/models/communication/website/menu.rb
+++ b/app/models/communication/website/menu.rb
@@ -28,6 +28,8 @@
# fk_rails_dcc7198fc5 (communication_website_id => communication_websites.id)
#
class Communication::Website::Menu < ApplicationRecord
+ IDENTIFIER_MAX_LENGTH = 100
+
include AsDirectObject
include Sanitizable
include WithAutomatism
@@ -37,7 +39,8 @@ class Communication::Website::Menu < ApplicationRecord
has_many :items, class_name: 'Communication::Website::Menu::Item', dependent: :destroy
validates :title, :identifier, presence: true
- validates :identifier, uniqueness: { scope: [:communication_website_id, :language_id] }
+ validates :identifier, length: { maximum: IDENTIFIER_MAX_LENGTH },
+ uniqueness: { scope: [:communication_website_id, :language_id] }
scope :ordered, -> { order(created_at: :asc) }
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index db4ec9e50..a478d5e15 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -49,11 +49,13 @@
#
class Communication::Website::Page < ApplicationRecord
+ # FIXME: Remove legacy column from db
self.ignored_columns = %w(path)
include AsDirectObject
include Contentful
include Sanitizable
+ include Sluggable # We override slug_unavailable? method (and set_slug and skip_slug_validation? in Page::Home)
include WithAccessibility
include WithAutomaticMenus
include WithBlobs
@@ -66,7 +68,7 @@ class Communication::Website::Page < ApplicationRecord
include WithPermalink
include WithTranslations
include WithTree
- include WithPath # WithPath overwrites the git_path method defined in WithWebsites
+ include WithPath # Must be included after Sluggable. WithPath overwrites the git_path method defined in WithWebsites
include WithUniversity
has_summernote :text # TODO: Remove text attribute
@@ -155,6 +157,13 @@ def self.direct_connection_permitted_about_type
protected
+ def slug_unavailable?(slug)
+ self.class.unscoped
+ .where(communication_website_id: self.communication_website_id, language_id: language_id, slug: slug)
+ .where.not(id: self.id)
+ .exists?
+ end
+
def check_accessibility
accessibility_merge_array blocks
end
diff --git a/app/models/communication/website/page/home.rb b/app/models/communication/website/page/home.rb
index 7c2d5c671..cee59da02 100644
--- a/app/models/communication/website/page/home.rb
+++ b/app/models/communication/website/page/home.rb
@@ -22,7 +22,7 @@ def set_slug
self.slug = ''
end
- def validate_slug
+ def skip_slug_validation?
true
end
diff --git a/app/models/communication/website/page/with_path.rb b/app/models/communication/website/page/with_path.rb
index 4d65126df..fb63c3841 100644
--- a/app/models/communication/website/page/with_path.rb
+++ b/app/models/communication/website/page/with_path.rb
@@ -1,11 +1,6 @@
module Communication::Website::Page::WithPath
extend ActiveSupport::Concern
- included do
- before_validation :set_slug
- validate :validate_slug
- end
-
def path
path = ''
if website.languages.many?
@@ -15,6 +10,7 @@ def path
path.gsub(/\/+/, '/')
end
+ # FIXME @arnaud : Should it be moved to Sluggable? To discuss
def slug_with_ancestors
(ancestors.map(&:slug) << slug).reject(&:blank?).join('/')
end
@@ -48,39 +44,4 @@ def git_path_prefix
@git_path_prefix ||= git_path_content_prefix(website)
end
- def set_slug
- self.slug = to_s.parameterize if self.slug.blank?
- 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, language_id: language_id, slug: slug)
- .where.not(id: self.id)
- .exists?
- end
-
- def validate_slug
- slug_must_be_present
- slug_must_be_unique
- slug_must_have_proper_format
- end
-
- def slug_must_be_present
- errors.add(:slug, :absent) if slug.blank?
- end
-
- def slug_must_be_unique
- errors.add(:slug, :taken) if slug_unavailable?(slug)
- end
-
- def slug_must_have_proper_format
- errors.add(:slug, I18n.t('slug_error')) unless /\A[a-z0-9\-]+\z/.match?(slug)
- end
-
end
diff --git a/app/models/communication/website/post/category.rb b/app/models/communication/website/post/category.rb
index eb21c8709..9e94111d8 100644
--- a/app/models/communication/website/post/category.rb
+++ b/app/models/communication/website/post/category.rb
@@ -45,6 +45,7 @@ class Communication::Website::Post::Category < ApplicationRecord
include Contentful
include Sanitizable
include Sluggable # We override slug_unavailable? method
+ include Pathable # Included after Sluggable to make sure slug is correct before anything
include WithBlobs
include WithFeaturedImage
include WithMenuItemTarget
@@ -72,8 +73,6 @@ class Communication::Website::Post::Category < ApplicationRecord
validates :name, presence: true
- after_save :update_children_paths, if: :saved_change_to_path?
-
def to_s
"#{name}"
end
@@ -101,13 +100,6 @@ def references
abouts_with_post_block
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)
end
diff --git a/app/models/concerns/pathable.rb b/app/models/concerns/pathable.rb
new file mode 100644
index 000000000..5bc216e67
--- /dev/null
+++ b/app/models/concerns/pathable.rb
@@ -0,0 +1,27 @@
+module Pathable
+ extend ActiveSupport::Concern
+
+ included do
+ before_validation :make_path
+ after_save :update_children_paths, if: :saved_change_to_path?
+
+ def generated_path
+ "#{parent.nil? ? '/' : parent.path}#{slug}/".gsub(/\/+/, '/')
+ end
+
+ def update_children_paths
+ children.each do |child|
+ child.update_column :path, child.generated_path
+ child.update_children_paths
+ end
+ end
+
+ protected
+
+ def make_path
+ return unless respond_to?(:path) && respond_to?(:parent)
+ self.path = generated_path
+ end
+
+ end
+end
diff --git a/app/models/concerns/sluggable.rb b/app/models/concerns/sluggable.rb
index 14f9cb4ef..cad943faa 100644
--- a/app/models/concerns/sluggable.rb
+++ b/app/models/concerns/sluggable.rb
@@ -1,47 +1,54 @@
module Sluggable
extend ActiveSupport::Concern
+ # Filenames uses 255 bytes so should have 255 characters max. To be safe, we limit to 100.
+ # Source: https://askubuntu.com/questions/166764/how-long-can-file-names-be/166767#166767
+ SLUG_MAX_LENGTH = 100
+
included do
- validates :slug, presence: true
- validate :slug_must_be_unique
- validates :slug, format: { with: /\A[a-z0-9\-]+\z/, message: I18n.t('slug_error') }
-
- before_validation :check_slug, :make_path
-
- def check_slug
- self.slug = to_s.parameterize if self.slug.blank?
- current_slug = self.slug
- n = 0
- while slug_unavailable?(self.slug)
- n += 1
- self.slug = [current_slug, n].join('-')
- end
- end
+ validates :slug, presence: true, unless: :skip_slug_validation?
+ validate :slug_must_be_unique, unless: :skip_slug_validation?
+ validates :slug, format: { with: /\A[a-z0-9\-]+\z/, message: I18n.t('slug_error') }, unless: :skip_slug_validation?
+
+ before_validation :set_slug
+ end
- def generated_path
- "#{parent.nil? ? '/' : parent.path}#{slug}/".gsub(/\/+/, '/')
+ def set_slug
+ self.slug = to_s.parameterize if self.slug.blank?
+ adjust_slug_length
+ current_slug = self.slug
+ n = 0
+ while slug_unavailable?(self.slug)
+ n += 1
+ self.slug = [current_slug, n].join('-')
end
+ end
+
+ protected
- protected
+ def adjust_slug_length
+ return unless self.slug.length > SLUG_MAX_LENGTH
+ # "my-very-long-and-detailed-first-blog-post" => "my-very-long-and-detailed-first-"
+ self.slug = self.slug[0, SLUG_MAX_LENGTH]
+ # "my-very-long-and-detailed-first-" => "my-very-long-and-detailed-first"
+ self.slug.chop! if self.slug.ends_with?('-')
+ end
- def slug_unavailable?(slug)
- existence_params = { university_id: self.university_id, slug: slug }
- existence_params[:language_id] = self.language_id if respond_to?(:language_id)
+ def slug_unavailable?(slug)
+ existence_params = { university_id: self.university_id, slug: slug }
+ existence_params[:language_id] = self.language_id if respond_to?(:language_id)
- self.class.unscoped
- .where(**existence_params)
- .where.not(id: self.id)
- .exists?
- end
+ self.class.unscoped
+ .where(**existence_params)
+ .where.not(id: self.id)
+ .exists?
+ end
- # FIXME `respond_to?(:parent)` sert à quoi ?
- def make_path
- return unless respond_to?(:path) && respond_to?(:parent)
- self.path = generated_path
- end
+ def slug_must_be_unique
+ errors.add(:slug, :taken) if slug_unavailable?(slug)
+ end
- def slug_must_be_unique
- errors.add(:slug, :taken) if slug_unavailable?(slug)
- end
+ def skip_slug_validation?
+ false
end
end
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index 105dd6752..c9e3e51ae 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -60,6 +60,7 @@ class Education::Program < ApplicationRecord
include Contentful
include Sanitizable
include Sluggable
+ include Pathable # Included after Sluggable to make sure slug is correct before anything
include WebsitesLinkable
include WithAccessibility
include WithAlumni
@@ -111,8 +112,6 @@ class Education::Program < ApplicationRecord
validates_presence_of :name
validates :downloadable_summary, size: { less_than: 50.megabytes }
- after_save :update_children_paths, if: :saved_change_to_path?
-
scope :published, -> { where(published: true) }
scope :ordered_by_name, -> { order(:name) }
scope :for_search_term, -> (term) {
@@ -168,13 +167,6 @@ def references
references
end
- def update_children_paths
- children.each do |child|
- child.update_column :path, child.generated_path
- child.update_children_paths
- end
- end
-
#####################
# WebsitesLinkable methods #
#####################
diff --git a/app/views/admin/administration/locations/_form.html.erb b/app/views/admin/administration/locations/_form.html.erb
index fb52e2c28..6bf8db4e8 100644
--- a/app/views/admin/administration/locations/_form.html.erb
+++ b/app/views/admin/administration/locations/_form.html.erb
@@ -23,12 +23,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: location.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#administration_location_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#administration_location_name' %>
<% end %>
<%= render 'admin/application/featured_image/edit', about: location, f: f %>
@@ -42,7 +39,7 @@
value_method: ->(p) { p[:id] } %>
- <%= f.association :schools,
+ <%= f.association :schools,
as: :check_boxes,
collection: current_university.education_schools.ordered %>
diff --git a/app/views/admin/application/slug/_form.html.erb b/app/views/admin/application/slug/_form.html.erb
new file mode 100644
index 000000000..414aa17dd
--- /dev/null
+++ b/app/views/admin/application/slug/_form.html.erb
@@ -0,0 +1,12 @@
+<%
+object ||= f.object
+attribute ||= :slug
+max_length ||= object.class::SLUG_MAX_LENGTH
+%>
+<%= f.input attribute,
+ as: :string,
+ maxlength: max_length,
+ input_html: object.persisted? ? {} : {
+ class: 'js-slug-input',
+ data: { source: source }
+ } %>
\ No newline at end of file
diff --git a/app/views/admin/communication/extranets/documents/categories/_form.html.erb b/app/views/admin/communication/extranets/documents/categories/_form.html.erb
index 1dd744a49..8b2bd35fe 100644
--- a/app/views/admin/communication/extranets/documents/categories/_form.html.erb
+++ b/app/views/admin/communication/extranets/documents/categories/_form.html.erb
@@ -10,12 +10,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: category.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_extranet_document_category_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_extranet_document_category_name' %>
<% end %>
diff --git a/app/views/admin/communication/extranets/documents/kinds/_form.html.erb b/app/views/admin/communication/extranets/documents/kinds/_form.html.erb
index bfb75b8b5..8ee4fe8ae 100644
--- a/app/views/admin/communication/extranets/documents/kinds/_form.html.erb
+++ b/app/views/admin/communication/extranets/documents/kinds/_form.html.erb
@@ -10,12 +10,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: kind.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_extranet_document_kind_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_extranet_document_kind_name' %>
<% end %>
diff --git a/app/views/admin/communication/extranets/posts/_form.html.erb b/app/views/admin/communication/extranets/posts/_form.html.erb
index 36b4fca73..afb95faa5 100644
--- a/app/views/admin/communication/extranets/posts/_form.html.erb
+++ b/app/views/admin/communication/extranets/posts/_form.html.erb
@@ -27,12 +27,9 @@
<%= f.association :author,
collection: @extranet.connected_people.ordered,
label_method: :to_s_alphabetical %>
- <%= f.input :slug,
- as: :string,
- input_html: post.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_extranet_post_title' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_extranet_post_title' %>
<% end %>
<%= render 'admin/application/featured_image/edit', about: @post, f: f %>
diff --git a/app/views/admin/communication/extranets/posts/categories/_form.html.erb b/app/views/admin/communication/extranets/posts/categories/_form.html.erb
index e90cbfdce..24ff6e6a5 100644
--- a/app/views/admin/communication/extranets/posts/categories/_form.html.erb
+++ b/app/views/admin/communication/extranets/posts/categories/_form.html.erb
@@ -10,12 +10,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: category.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_extranet_post_category_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_extranet_post_category_name' %>
<% end %>
diff --git a/app/views/admin/communication/websites/agenda/categories/_form.html.erb b/app/views/admin/communication/websites/agenda/categories/_form.html.erb
index 9cc01d277..fdc3f2267 100644
--- a/app/views/admin/communication/websites/agenda/categories/_form.html.erb
+++ b/app/views/admin/communication/websites/agenda/categories/_form.html.erb
@@ -12,12 +12,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: category.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_website_agenda_category_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_website_agenda_category_name' %>
<% end %>
<%= render 'admin/application/featured_image/edit', about: category, f: f %>
diff --git a/app/views/admin/communication/websites/agenda/events/_form.html.erb b/app/views/admin/communication/websites/agenda/events/_form.html.erb
index f62f29539..955972fc2 100644
--- a/app/views/admin/communication/websites/agenda/events/_form.html.erb
+++ b/app/views/admin/communication/websites/agenda/events/_form.html.erb
@@ -46,12 +46,9 @@
<%= osuny_panel t('metadata') do %>
<%= f.input :published if can? :publish, event %>
- <%= f.input :slug,
- as: :string,
- input_html: event.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_website_agenda_event_title' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_website_agenda_event_title' %>
<% end %>
<%= render 'admin/application/featured_image/edit', about: event, f: f %>
diff --git a/app/views/admin/communication/websites/menus/_form.html.erb b/app/views/admin/communication/websites/menus/_form.html.erb
index f15d5e60d..1a54e1329 100644
--- a/app/views/admin/communication/websites/menus/_form.html.erb
+++ b/app/views/admin/communication/websites/menus/_form.html.erb
@@ -7,11 +7,11 @@
<%= f.input :title %>
- <%= f.input :identifier,
- input_html: menu.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_website_menu_title' }
- } if can?(:create, menu) %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ attribute: :identifier,
+ max_length: Communication::Website::Menu::IDENTIFIER_MAX_LENGTH,
+ source: '#communication_website_menu_title' if can?(:create, menu) %>
<% content_for :action_bar_right do %>
diff --git a/app/views/admin/communication/websites/pages/_form.html.erb b/app/views/admin/communication/websites/pages/_form.html.erb
index 4efb730ce..1e5e108ab 100644
--- a/app/views/admin/communication/websites/pages/_form.html.erb
+++ b/app/views/admin/communication/websites/pages/_form.html.erb
@@ -28,13 +28,9 @@ url = page.new_record? ? admin_communication_website_pages_path
<%= osuny_panel t('metadata') do %>
<%= f.input :published if page.draftable? %>
- <%= f.input :slug,
- as: :string,
- required: true,
- input_html: page.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_website_page_title' }
- } unless page.is_home? %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_website_page_title' unless page.is_home? %>
<%= f.association :parent,
collection: collection_tree(@website.pages.for_language(current_website_language), page),
include_blank: false,
diff --git a/app/views/admin/communication/websites/posts/_form.html.erb b/app/views/admin/communication/websites/posts/_form.html.erb
index d560988d6..1479d202e 100644
--- a/app/views/admin/communication/websites/posts/_form.html.erb
+++ b/app/views/admin/communication/websites/posts/_form.html.erb
@@ -39,12 +39,9 @@
<%= f.association :author,
collection: current_university.people.for_language(current_website_language).ordered,
label_method: :to_s_alphabetical %>
- <%= f.input :slug,
- as: :string,
- input_html: post.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_website_post_title' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_website_post_title' %>
<% end %>
<%= render 'admin/application/featured_image/edit', about: @post, f: f %>
diff --git a/app/views/admin/communication/websites/posts/categories/_form.html.erb b/app/views/admin/communication/websites/posts/categories/_form.html.erb
index ea0a2b5ff..43782ce29 100644
--- a/app/views/admin/communication/websites/posts/categories/_form.html.erb
+++ b/app/views/admin/communication/websites/posts/categories/_form.html.erb
@@ -12,12 +12,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: category.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#communication_website_post_category_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#communication_website_post_category_name' %>
<%= f.association :parent,
collection: collection_tree(@website.post_categories.for_language(current_website_language), category),
label_method: ->(p) { sanitize p[:label] },
diff --git a/app/views/admin/education/diplomas/_form.html.erb b/app/views/admin/education/diplomas/_form.html.erb
index 9529814c6..dcf1876d0 100644
--- a/app/views/admin/education/diplomas/_form.html.erb
+++ b/app/views/admin/education/diplomas/_form.html.erb
@@ -3,7 +3,7 @@
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
- <%= osuny_panel t('metadata') do %>
+ <%= osuny_panel t('content') do %>
<%= f.input :name %>
@@ -22,6 +22,13 @@
<%= render 'admin/application/summary/form', f: f, about: diploma %>
<% end %>
+
+ <%= osuny_panel t('metadata') do %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#education_diploma_name' %>
+ <% end %>
+
<% content_for :action_bar_right do %>
<%= submit f %>
diff --git a/app/views/admin/education/programs/_form.html.erb b/app/views/admin/education/programs/_form.html.erb
index 287a70a27..9cee1942e 100644
--- a/app/views/admin/education/programs/_form.html.erb
+++ b/app/views/admin/education/programs/_form.html.erb
@@ -146,12 +146,9 @@
<%= render 'admin/education/programs/forms/part', part: :technical do %>
<%= f.input :published %>
- <%= f.input :slug,
- as: :string,
- input_html: program.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#education_program_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#education_program_name' %>
<%= f.association :parent,
collection: collection_tree(current_university.education_programs, program),
label_method: ->(p) { sanitize p[:label] },
diff --git a/app/views/admin/research/journals/papers/_form.html.erb b/app/views/admin/research/journals/papers/_form.html.erb
index 7b6673a1c..2efc16d31 100644
--- a/app/views/admin/research/journals/papers/_form.html.erb
+++ b/app/views/admin/research/journals/papers/_form.html.erb
@@ -24,12 +24,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: paper.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#research_journal_paper_title' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#research_journal_paper_title' %>
<%= f.association :volume, collection: @journal.volumes, label: Research::Journal::Volume.model_name.human %>
<%= f.input :published %>
<%= f.input :published_at, html5: true, as: :date %>
diff --git a/app/views/admin/research/journals/papers/kinds/_form.html.erb b/app/views/admin/research/journals/papers/kinds/_form.html.erb
index 27b52e6d0..b085e0c4a 100644
--- a/app/views/admin/research/journals/papers/kinds/_form.html.erb
+++ b/app/views/admin/research/journals/papers/kinds/_form.html.erb
@@ -14,12 +14,9 @@ url = kind.new_record? ? admin_research_journal_kinds_path
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: kind.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#research_journal_paper_kind_title' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#research_journal_paper_kind_title' %>
<% end %>
diff --git a/app/views/admin/research/journals/volumes/_form.html.erb b/app/views/admin/research/journals/volumes/_form.html.erb
index 70c08a827..1d6e03fc2 100644
--- a/app/views/admin/research/journals/volumes/_form.html.erb
+++ b/app/views/admin/research/journals/volumes/_form.html.erb
@@ -13,12 +13,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: volume.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#research_journal_volume_title' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#research_journal_volume_title' %>
<%= f.input :number %>
<%= f.input :published %>
<%= f.input :published_at, html5: true %>
diff --git a/app/views/admin/research/publications/_form.html.erb b/app/views/admin/research/publications/_form.html.erb
index eb11b0e05..0abce16d4 100644
--- a/app/views/admin/research/publications/_form.html.erb
+++ b/app/views/admin/research/publications/_form.html.erb
@@ -9,14 +9,17 @@
<%= f.input :ref, as: :text %>
<%= f.input :authors_list, as: :string %>
<%= f.input :url %>
-
-
+
+
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#research_publication_title' %>
<%= f.input :publication_date, html5: true %>
<%= f.input :doi %>
<%= f.input :journal_title %>
<%= f.input :open_access %>
- <%= f.association :researchers,
- as: :check_boxes,
+ <%= f.association :researchers,
+ as: :check_boxes,
collection: current_university.university_people
.researchers
.for_language(current_language)
diff --git a/app/views/admin/university/organizations/_form.html.erb b/app/views/admin/university/organizations/_form.html.erb
index 290735503..193a598a1 100644
--- a/app/views/admin/university/organizations/_form.html.erb
+++ b/app/views/admin/university/organizations/_form.html.erb
@@ -73,12 +73,9 @@
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: organization.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#university_organization_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#university_organization_name' %>
<%= f.input :active %>
<% end %>
<% if current_university.organization_categories.any? %>
diff --git a/app/views/admin/university/people/_form.html.erb b/app/views/admin/university/people/_form.html.erb
index 2ca25b424..91a9adc88 100644
--- a/app/views/admin/university/people/_form.html.erb
+++ b/app/views/admin/university/people/_form.html.erb
@@ -89,18 +89,15 @@
<% end if current_university.is_really_a_university %>
- <%= f.association :research_laboratories,
+ <%= f.association :research_laboratories,
collection: current_university.research_laboratories,
as: :check_boxes if person.is_researcher %>
<%= osuny_panel t('metadata') do %>
- <%= f.input :slug,
- as: :string,
- input_html: person.persisted? ? {} : {
- class: 'js-slug-input',
- data: { source: '#university_person_first_name, #university_person_last_name' }
- } %>
+ <%= render "admin/application/slug/form",
+ f: f,
+ source: '#university_person_first_name, #university_person_last_name' %>
<%= f.association :user, collection: current_university.users.ordered if can?(:manage, User) %>
<% end %>
<% if current_university.person_categories.any? %>
@@ -124,7 +121,7 @@
input_html: {
data: {
translatable: true,
- 'summernote-config' => 'link'
+ 'summernote-config' => 'link'
}
} %>
<% end %>
diff --git a/config/locales/education/en.yml b/config/locales/education/en.yml
index 29d0290f4..a70d4abcb 100644
--- a/config/locales/education/en.yml
+++ b/config/locales/education/en.yml
@@ -37,6 +37,7 @@ en:
name: Name
programs: Programs
short_name: Short name
+ slug: Slug
education/program:
accessibility: Accessibilité
apprenticeship: Apprenticeship
@@ -75,6 +76,7 @@ en:
roles: Roles
schools: Schools with this formation
short_name: Short name
+ slug: Slug
teachers: Teachers
team: Team
url: Website
@@ -100,7 +102,7 @@ en:
tree:
title: Programs treeview
education:
- description:
+ description:
text: Education is the set of processes and procedures that enable every human child to gradually gain access to culture, access to culture being what distinguishes man from animals.
source: Olivier Reboul, La philosophie de l'éducation, 2018
parts:
diff --git a/config/locales/education/fr.yml b/config/locales/education/fr.yml
index d64aa30c4..6cce16d52 100644
--- a/config/locales/education/fr.yml
+++ b/config/locales/education/fr.yml
@@ -37,6 +37,7 @@ fr:
name: Nom
programs: Formations
short_name: Nom abrégé
+ slug: Identifiant
education/program:
accessibility: Accessibilité
apprenticeship: Apprentissage
@@ -75,6 +76,7 @@ fr:
roles: Rôles
schools: Écoles proposant cette formation
short_name: Nom abrégé
+ slug: Identifiant
teachers: Enseignant·e·s
team: Équipe
url: Site Web
@@ -100,7 +102,7 @@ fr:
tree:
title: Arborescence des formations
education:
- description:
+ description:
text: L’éducation est l’ensemble des processus et des procédés qui permettent à tout enfant humain d’accéder progressivement à la culture, l’accès à la culture étant ce qui distingue l’homme de l’animal.
source: Olivier Reboul, La philosophie de l'éducation, 2018
parts:
diff --git a/config/locales/research/en.yml b/config/locales/research/en.yml
index 5f4b6dbe9..2dcb2548b 100644
--- a/config/locales/research/en.yml
+++ b/config/locales/research/en.yml
@@ -94,6 +94,7 @@ en:
journal_title: In...
open_access: Open access
publication_date: Publication date
+ slug: Slug
title: Title
url: URL
urls: Web URLs
@@ -113,20 +114,20 @@ en:
hal: HAL
osuny: Osuny
research/hal:
- description:
+ description:
text: "HAL signifie Hyper Article en Ligne. C’est une plateforme pluridisciplinaire nationale pour le dépôt et la consultation des écrits, travaux et résultats de recherches scientifiques des chercheur·e·s et enseignant·e·s-chercheur·e·s. HAL est un bien commun pour la recherche : Les plus grands organismes de recherche et la majorité des universités françaises ont choisi et soutiennent HAL, une infrastructure publique, pérenne et responsable."
source: HAL.science
research:
citations:
apa:
label: APA
- mla:
+ mla:
label: MLA
- chicago:
+ chicago:
label: Chicago
- harvard:
+ harvard:
label: Harvard
- iso690:
+ iso690:
label: ISO 690
description:
text: Scientific research is both an approach that creates knowledge motivated by pure curiosity and an activity that generates innovations that increase the means of action and diagnosis on nature, man and society. These two aspects of research, fundamental and applied, far from opposing each other, complement each other. Fundamental research creates the knowledge base from which applications are born and, conversely, technological advances provide the increasingly sophisticated investigative tools that lead to a deepening of our fundamental knowledge.
diff --git a/config/locales/research/fr.yml b/config/locales/research/fr.yml
index 656db4bb7..f24aabbf6 100644
--- a/config/locales/research/fr.yml
+++ b/config/locales/research/fr.yml
@@ -94,6 +94,7 @@ fr:
journal_title: Dans...
open_access: Accès ouvert (open access)
publication_date: Date de publication
+ slug: Identifiant
title: Titre
url: URL
urls: Adresses Web
@@ -113,20 +114,20 @@ fr:
hal: HAL
osuny: Osuny
research/hal:
- description:
+ description:
text: "HAL signifie Hyper Article en Ligne. C’est une plateforme pluridisciplinaire nationale pour le dépôt et la consultation des écrits, travaux et résultats de recherches scientifiques des chercheur·e·s et enseignant·e·s-chercheur·e·s. HAL est un bien commun pour la recherche : Les plus grands organismes de recherche et la majorité des universités françaises ont choisi et soutiennent HAL, une infrastructure publique, pérenne et responsable."
source: HAL.science
research:
citations:
apa:
label: APA
- mla:
+ mla:
label: MLA
- chicago:
+ chicago:
label: Chicago
- harvard:
+ harvard:
label: Harvard
- iso690:
+ iso690:
label: ISO 690
description:
text: La recherche scientifique est, à la fois, une démarche créatrice de connaissances motivée par la curiosité pure et une activité génératrice d’innovations qui augmentent les moyens d’action et de diagnostic sur la nature, l’homme et la société. Ces deux aspects de la recherche, le fondamental et l’appliqué, loin de s’opposer, sont complémentaires l’un de l’autre. La recherche fondamentale crée le socle de connaissances à partir duquel naissent les applications et, inversement, les avancées technologiques procurent les outils d’investigation de plus en plus perfectionnés qui conduisent à approfondir nos connaissances fondamentales.
diff --git a/test/models/communication/website/agenda/category_test.rb b/test/models/communication/website/agenda/category_test.rb
index 2b509fe7f..96685f446 100644
--- a/test/models/communication/website/agenda/category_test.rb
+++ b/test/models/communication/website/agenda/category_test.rb
@@ -1,40 +1,3 @@
-# == Schema Information
-#
-# Table name: communication_website_agenda_categories
-#
-# id :uuid not null, primary key
-# featured_image_alt :string
-# featured_image_credit :text
-# meta_description :text
-# name :string
-# path :string
-# position :integer
-# slug :string
-# summary :text
-# created_at :datetime not null
-# updated_at :datetime not null
-# communication_website_id :uuid not null, indexed
-# language_id :uuid not null, indexed
-# original_id :uuid indexed
-# parent_id :uuid indexed
-# university_id :uuid not null, indexed
-#
-# Indexes
-#
-# idx_communication_website_agenda_cats_on_website_id (communication_website_id)
-# index_communication_website_agenda_categories_on_language_id (language_id)
-# index_communication_website_agenda_categories_on_original_id (original_id)
-# index_communication_website_agenda_categories_on_parent_id (parent_id)
-# index_communication_website_agenda_categories_on_university_id (university_id)
-#
-# Foreign Keys
-#
-# fk_rails_1e1b9fbf33 (original_id => communication_website_agenda_categories.id)
-# fk_rails_692dbf7723 (parent_id => communication_website_agenda_categories.id)
-# fk_rails_6cb9a4b8a1 (university_id => universities.id)
-# fk_rails_7b5ad84dda (communication_website_id => communication_websites.id)
-# fk_rails_b0ddee638d (language_id => languages.id)
-#
require "test_helper"
class Communication::Website::Agenda::CategoryTest < ActiveSupport::TestCase