diff --git a/app/lib/decidim/exporters/csv_overrides.rb b/app/lib/decidim/exporters/csv_overrides.rb new file mode 100644 index 00000000..bb18d664 --- /dev/null +++ b/app/lib/decidim/exporters/csv_overrides.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Decidim + module Exporters + # Overrides Decidim::Exporters::CSV#export to prepend the UTF-8 byte order + # mark to the generated CSV, so spreadsheet software (notably Microsoft + # Excel) detects the encoding and renders non-ASCII characters correctly. + # + # Upstream Decidim does not include the BOM and the maintainers won't accept + # this change, so it is applied locally as an override instead of forking. + module CsvOverrides + # UTF-8 byte order mark. + BOM = "" + + # Public: Exports a CSV serialized version of the collection, prepending + # the UTF-8 BOM to the output. + # + # Returns an ExportData instance. + def export(col_sep = Decidim.default_csv_col_sep) + data = ::CSV.generate(BOM.dup, headers:, write_headers: true, col_sep:) do |csv| + processed_collection.each do |resource| + csv << headers.map { |header| custom_sanitize(resource[header]) } + end + end + ExportData.new(data, "csv") + end + end + end +end diff --git a/config/initializers/lib_overrides.rb b/config/initializers/lib_overrides.rb new file mode 100644 index 00000000..548dd0ed --- /dev/null +++ b/config/initializers/lib_overrides.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Rails.application.config.to_prepare do + Decidim::Exporters::CSV.prepend(Decidim::Exporters::CsvOverrides) +end diff --git a/spec/lib/overrides_spec.rb b/spec/lib/overrides_spec.rb index 66bde916..f2432bfc 100644 --- a/spec/lib/overrides_spec.rb +++ b/spec/lib/overrides_spec.rb @@ -10,7 +10,10 @@ files: { "/app/cells/decidim/newsletter_templates/basic_only_text/show.erb" => "7d9d4f2ab8897143fe66e8ac8db2cedb", "/app/cells/decidim/newsletter_templates/basic_only_text_settings_form/show.erb" => "cc8e26ddc53c0b65eddf472ed4c5614e", - "/app/cells/decidim/newsletter_templates/image_text_cta/show.erb" => "08881fe2df7d87db0497376b08821594" + "/app/cells/decidim/newsletter_templates/image_text_cta/show.erb" => "08881fe2df7d87db0497376b08821594", + # Overridden by Decidim::Exporters::CsvOverrides (config/initializers/lib_overrides.rb) + # to prepend the UTF-8 BOM. If this checksum changes, review the override. + "/lib/decidim/exporters/csv.rb" => "26eeaecb13dbb4dbce28e39e8dc7a3fd" } } ]