From 020485b7c7b496a6236e08cdd3cd9e5324feb45d Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Mon, 21 Sep 2026 18:04:02 +0900 Subject: [PATCH 3/3] Display the name of the type instead of the MIME type for Microsoft Office and OpenDocument files on the attachment preview page. --- app/helpers/attachments_helper.rb | 47 +++++++++++++++++++ app/views/layouts/_file.html.erb | 3 +- .../functional/attachments_controller_test.rb | 22 +++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/app/helpers/attachments_helper.rb b/app/helpers/attachments_helper.rb index 41c3b16e5..592813828 100644 --- a/app/helpers/attachments_helper.rb +++ b/app/helpers/attachments_helper.rb @@ -88,6 +88,53 @@ module AttachmentsHelper api.created_on attachment.created_on end + # Names that are displayed instead of MIME types. A name should be added + # only for a type that is frequently used but whose MIME type is very long + # and hard to read. The names are not translated, so they should consist + # of the name of the application or the format followed by nouns. + # + # * A template is named by appending "Template" to the corresponding type + # * For Microsoft Office, a macro-enabled type is named by appending "(+macro)" + # + # The keys must be in lowercase because the lookup is case-insensitive. + CONTENT_TYPE_NAMES = { + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'Microsoft Word Document', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'Microsoft Word Document Template', + 'application/vnd.ms-word.document.macroenabled.12' => 'Microsoft Word Document (+macro)', + 'application/vnd.ms-word.template.macroenabled.12' => 'Microsoft Word Document Template (+macro)', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'Microsoft Excel Workbook', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'Microsoft Excel Workbook Template', + 'application/vnd.ms-excel.sheet.macroenabled.12' => 'Microsoft Excel Workbook (+macro)', + 'application/vnd.ms-excel.template.macroenabled.12' => 'Microsoft Excel Workbook Template (+macro)', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'Microsoft PowerPoint Presentation', + 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'Microsoft PowerPoint Presentation Template', + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'Microsoft PowerPoint Slide Show', + 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'Microsoft PowerPoint Presentation (+macro)', + 'application/vnd.ms-powerpoint.template.macroenabled.12' => 'Microsoft PowerPoint Presentation Template (+macro)', + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'Microsoft PowerPoint Slide Show (+macro)', + 'application/vnd.oasis.opendocument.text' => 'OpenDocument Text', + 'application/vnd.oasis.opendocument.text-template' => 'OpenDocument Text Template', + 'application/vnd.oasis.opendocument.spreadsheet' => 'OpenDocument Spreadsheet', + 'application/vnd.oasis.opendocument.spreadsheet-template' => 'OpenDocument Spreadsheet Template', + 'application/vnd.oasis.opendocument.presentation' => 'OpenDocument Presentation', + 'application/vnd.oasis.opendocument.presentation-template' => 'OpenDocument Presentation Template', + 'application/vnd.oasis.opendocument.graphics' => 'OpenDocument Graphics', + 'application/vnd.oasis.opendocument.graphics-template' => 'OpenDocument Graphics Template' + }.freeze + + # Returns a span tag that contains the content type of the attachment, or + # nil if the content type is blank. + # + # For the types listed in CONTENT_TYPE_NAMES, the name of the type is + # displayed and the MIME type is available in the title attribute. + def attachment_content_type_tag(attachment) + content_type = attachment.content_type + return if content_type.blank? + + name = CONTENT_TYPE_NAMES[content_type.downcase] + content_tag(:span, name || content_type, :class => 'content-type', :title => (content_type if name)) + end + def render_file_content(attachment, content) if attachment.is_markdown? render :partial => 'common/markup', :locals => {:markup_text_formatting => 'common_mark', :markup_text => content} diff --git a/app/views/layouts/_file.html.erb b/app/views/layouts/_file.html.erb index e8f776e51..83d3cff21 100644 --- a/app/views/layouts/_file.html.erb +++ b/app/views/layouts/_file.html.erb @@ -8,8 +8,7 @@

<% if @attachment.description.present? %><%= @attachment.description %>
<% end %> - <% content_type = content_tag(:span, @attachment.content_type, :class => 'content-type') if @attachment.content_type.present? %> - <%= safe_join([link_to_user(@attachment.author), format_time(@attachment.created_on), content_type].compact, ', ') %>

+ <%= safe_join([link_to_user(@attachment.author), format_time(@attachment.created_on), attachment_content_type_tag(@attachment)].compact, ', ') %>

<%= yield %> diff --git a/test/functional/attachments_controller_test.rb b/test/functional/attachments_controller_test.rb index 31e58e089..a6ddac384 100644 --- a/test/functional/attachments_controller_test.rb +++ b/test/functional/attachments_controller_test.rb @@ -151,6 +151,28 @@ class AttachmentsControllerTest < Redmine::ControllerTest assert_select 'div.attachments span.author', :text => /, application\/x-ruby\z/ end + def test_show_should_display_name_instead_of_long_content_type + { + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'Microsoft Word Document', + 'application/vnd.oasis.opendocument.spreadsheet' => 'OpenDocument Spreadsheet', + # Content types sent by browsers may contain uppercase letters + 'application/vnd.ms-excel.sheet.macroEnabled.12' => 'Microsoft Excel Workbook (+macro)' + }.each do |content_type, name| + Attachment.find(4).update_column(:content_type, content_type) + + get(:show, :params => {:id => 4}) + assert_response :success + assert_select 'div.attachments span.content-type[title=?]', content_type, :text => name + end + end + + def test_show_should_display_other_content_types_as_is + get(:show, :params => {:id => 4}) + assert_response :success + assert_select 'div.attachments span.content-type', :text => 'application/x-ruby' + assert_select 'div.attachments span.content-type[title]', 0 + end + def test_show_should_not_display_content_type_if_blank get(:show, :params => {:id => 22}) assert_response :success -- 2.55.0