blacklight 5.14.0 → 5.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -10
  3. data/Gemfile +2 -1
  4. data/VERSION +1 -1
  5. data/app/helpers/blacklight/blacklight_helper_behavior.rb +2 -14
  6. data/app/helpers/blacklight/catalog_helper_behavior.rb +31 -0
  7. data/app/views/bookmarks/index.html.erb +2 -0
  8. data/app/views/catalog/_document_default.atom.builder +2 -3
  9. data/app/views/catalog/_search_results.html.erb +1 -1
  10. data/app/views/catalog/index.html.erb +1 -0
  11. data/app/views/saved_searches/index.html.erb +2 -0
  12. data/app/views/search_history/index.html.erb +2 -0
  13. data/app/views/shared/_sitelinks_search_box.html.erb +12 -0
  14. data/config/locales/blacklight.de.yml +8 -0
  15. data/config/locales/blacklight.en.yml +8 -0
  16. data/config/locales/blacklight.es.yml +8 -0
  17. data/config/locales/blacklight.fr.yml +8 -0
  18. data/config/locales/blacklight.it.yml +8 -0
  19. data/config/locales/blacklight.pt-BR.yml +8 -0
  20. data/lib/blacklight.rb +1 -0
  21. data/lib/blacklight/configuration.rb +6 -1
  22. data/lib/blacklight/document_presenter.rb +23 -0
  23. data/lib/blacklight/facet_paginator.rb +121 -0
  24. data/lib/blacklight/search_builder.rb +21 -0
  25. data/lib/blacklight/search_helper.rb +5 -1
  26. data/lib/blacklight/solr/facet_paginator.rb +4 -101
  27. data/lib/blacklight/solr_response/spelling.rb +2 -0
  28. data/spec/features/sitelinks_search_box.rb +12 -0
  29. data/spec/helpers/blacklight_helper_spec.rb +10 -55
  30. data/spec/helpers/catalog_helper_spec.rb +39 -0
  31. data/spec/lib/blacklight/facet_paginator_spec.rb +12 -12
  32. data/spec/lib/blacklight/search_builder_spec.rb +11 -0
  33. data/spec/lib/blacklight/search_helper_spec.rb +21 -0
  34. data/spec/lib/blacklight/solr/facet_paginator_spec.rb +12 -0
  35. data/spec/lib/blacklight/solr_response_spec.rb +30 -9
  36. data/spec/lib/document_presenter_spec.rb +76 -2
  37. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 155a3451e8e922400f8c30a67dd298471dd7c176
4
- data.tar.gz: 70525a0b4e6393a968af18a813f05221b691d921
3
+ metadata.gz: 081be929f259b05c3eb58415ad673efb09ed8b14
4
+ data.tar.gz: 4f26d85908c059106c6699e8a9395933fd95cbd6
5
5
  SHA512:
6
- metadata.gz: 90ce5a38742b9a880f307faaef78687bfa169cbd016af562d9824c84652d883bc19aaf59b6ed2333ea4ccdfbcf98937e394592992863bd34a20036346c942e2c
7
- data.tar.gz: dbe00471126594db517968998e5c705bb434ae5b1f638e460c74e9ce4f36724e275411ac8ee27d43edaa808ec8e37efecd6d369c7d2e9a069f31126c94bc8205
6
+ metadata.gz: b3ba6fdedc8dfbe085e6040c5087229e17d98d7564d9ee51eee33b422c82bf73fb369081c53dee10474b8b4823720617c7df10bede4e96b520f32e5cb77f49d6
7
+ data.tar.gz: 7e6d6cecb7f0432cf007139469a3e0a5b2217285d5d3b9604ef51cecd01f682d8e12aeb7a2dd160cc2d9c04893115a8b55f92a0519aac3b337de36fed61ffc34
data/.travis.yml CHANGED
@@ -5,26 +5,26 @@ notifications:
5
5
  email: false
6
6
 
7
7
  rvm:
8
- - 2.2.2
8
+ - 2.2.3
9
9
 
10
10
  matrix:
11
11
  include:
12
- - rvm: 2.2.2
13
- env: "RAILS_VERSION=4.0.12"
14
- - rvm: 2.2.2
15
- env: "RAILS_VERSION=4.1.9"
16
- - rvm: 2.1.6
17
- env: "RAILS_VERSION=4.2.1"
12
+ - rvm: 2.2.3
13
+ env: "RAILS_VERSION=4.0.13"
14
+ - rvm: 2.2.3
15
+ env: "RAILS_VERSION=4.1.13"
16
+ - rvm: 2.1.7
17
+ env: "RAILS_VERSION=4.2.4"
18
18
  - rvm: jruby
19
- env: "RAILS_VERSION=4.2.1 JRUBY_OPTS=\"-J-Xms512m -J-Xmx1024m\""
19
+ env: "RAILS_VERSION=4.2.4 JRUBY_OPTS=\"-J-Xms512m -J-Xmx1024m\""
20
20
  - rvm: 1.9.3
21
- env: "RAILS_VERSION=4.2.1"
21
+ env: "RAILS_VERSION=4.2.4"
22
22
 
23
23
  before_install:
24
24
  - gem install bundler
25
25
 
26
26
  env:
27
- - "RAILS_VERSION=4.2.1"
27
+ - "RAILS_VERSION=4.2.4"
28
28
 
29
29
  notifications:
30
30
  irc: "irc.freenode.org#blacklight"
data/Gemfile CHANGED
@@ -20,10 +20,11 @@ if File.exists?(file)
20
20
  else
21
21
  gem 'rails', ENV['RAILS_VERSION'] if ENV['RAILS_VERSION']
22
22
 
23
- if ENV['RAILS_VERSION'] and ENV['RAILS_VERSION'] =~ /^4.2/
23
+ if ENV['RAILS_VERSION'].nil? || ENV['RAILS_VERSION'] > "4.2"
24
24
  gem 'responders', "~> 2.0"
25
25
  gem 'sass-rails', ">= 5.0"
26
26
  else
27
+ gem 'bootstrap-sass', '< 3.3.5' # 3.3.5 requires sass 3.3, incompatible with sass-rails 4.x
27
28
  gem 'sass-rails', "< 5.0"
28
29
  end
29
30
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 5.14.0
1
+ 5.15.0
@@ -34,8 +34,7 @@ module Blacklight::BlacklightHelperBehavior
34
34
 
35
35
  ##
36
36
  # Create <link rel="alternate"> links from a documents dynamically
37
- # provided export formats. Currently not used by standard BL layouts,
38
- # but available for your custom layouts to provide link rel alternates.
37
+ # provided export formats.
39
38
  #
40
39
  # Returns empty string if no links available.
41
40
  #
@@ -46,18 +45,7 @@ module Blacklight::BlacklightHelperBehavior
46
45
  # @option options [Array<String>] :exclude array of format shortnames to not include in the output
47
46
  def render_link_rel_alternates(document=@document, options = {})
48
47
  return if document.nil?
49
-
50
- options = { unique: false, exclude: [] }.merge(options)
51
-
52
- seen = Set.new
53
-
54
- safe_join(document.export_formats.map do |format, spec|
55
- next if options[:exclude].include?(format) || (options[:unique] && seen.include?(spec[:content_type]))
56
-
57
- seen.add(spec[:content_type])
58
-
59
- tag(:link, rel: "alternate", title: format, type: spec[:content_type], href: polymorphic_url(document, format: format))
60
- end.compact, "\n")
48
+ presenter(document).link_rel_alternates(options)
61
49
  end
62
50
 
63
51
  ##
@@ -273,4 +273,35 @@ module Blacklight::CatalogHelperBehavior
273
273
  !sms_mappings.blank?
274
274
  end
275
275
 
276
+ def render_search_to_page_title_filter(facet, values)
277
+ facet_config = facet_configuration_for_field(facet)
278
+ filter_label = facet_field_label(facet_config.key)
279
+ filter_value = if values.size < 3
280
+ values.map {|value| facet_display_value(facet, value)}.to_sentence
281
+ else
282
+ t('blacklight.search.page_title.many_constraint_values', values: values.size)
283
+ end
284
+ t('blacklight.search.page_title.constraint', label: filter_label, value: filter_value)
285
+ end
286
+
287
+ def render_search_to_page_title(params)
288
+ constraints = []
289
+
290
+ if params['q'].present?
291
+ q_label = label_for_search_field(params[:search_field]) unless default_search_field && params[:search_field] == default_search_field[:key]
292
+
293
+ if q_label.present?
294
+ constraints += [t('blacklight.search.page_title.constraint', label: q_label, value: params['q'])]
295
+ else
296
+ constraints += [params['q']]
297
+ end
298
+ end
299
+
300
+ if params['f'].present?
301
+ constraints += params['f'].collect{ |key, value| render_search_to_page_title_filter(key, value) } unless params['f'].blank?
302
+ end
303
+
304
+ constraints.join(' / ')
305
+ end
306
+
276
307
  end
@@ -1,3 +1,5 @@
1
+ <% @page_title = t('blacklight.bookmarks.page_title', :application_name => application_name) %>
2
+
1
3
  <div id="content" class="col-md-12">
2
4
  <h1 class='page-heading'><%= t('blacklight.bookmarks.title') %></h1>
3
5
 
@@ -1,7 +1,6 @@
1
1
  xml.entry do
2
-
3
-
4
- xml.title document.to_semantic_values[:title][0] || presenter(document).render_document_index_label(document_show_link_field(document))
2
+
3
+ xml.title presenter(document).render_document_index_label(document_show_link_field(document))
5
4
 
6
5
  # updated is required, for now we'll just set it to now, sorry
7
6
  xml.updated Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")
@@ -1,6 +1,6 @@
1
1
  <h2 class="sr-only top-content-title"><%= t('blacklight.search.search_results_header') %></h2>
2
2
 
3
- <% @page_title = t('blacklight.search.title', :application_name => application_name) %>
3
+ <% @page_title = t('blacklight.search.page_title.title', :constraints => render_search_to_page_title(params), :application_name => application_name) %>
4
4
 
5
5
 
6
6
  <% content_for(:head) do -%>
@@ -6,6 +6,7 @@
6
6
  <% unless has_search_parameters? %>
7
7
  <%# if there are no input/search related params, display the "home" partial -%>
8
8
  <%= render 'home' %>
9
+ <%= render 'shared/sitelinks_search_box' %>
9
10
  <% else %>
10
11
  <%= render 'search_results' %>
11
12
  <% end %>
@@ -1,3 +1,5 @@
1
+ <% @page_title = t('blacklight.saved_searches.page_title', :application_name => application_name) %>
2
+
1
3
  <div id="content" class="col-md-9">
2
4
 
3
5
  <h1 class='page-heading'><%= t('blacklight.saved_searches.title') %></h1>
@@ -1,3 +1,5 @@
1
+ <% @page_title = t('blacklight.search_history.page_title', :application_name => application_name) %>
2
+
1
3
  <div id="content" class="col-md-12">
2
4
  <h1 class='page-heading'><%=t('blacklight.search_history.title')%></h1>
3
5
  <%- if @searches.blank? -%>
@@ -0,0 +1,12 @@
1
+ <script type="application/ld+json">
2
+ {
3
+ "@context": "http://schema.org",
4
+ "@type": "WebSite",
5
+ "url": "<%= root_url %>",
6
+ "potentialAction": {
7
+ "@type": "SearchAction",
8
+ "target": "<%= root_url %>?q={search_term_string}",
9
+ "query-input": "required name=search_term_string"
10
+ }
11
+ }
12
+ </script>
@@ -27,6 +27,7 @@ de:
27
27
 
28
28
  bookmarks:
29
29
  title: 'Lesezeichen'
30
+ page_title: 'Lesezeichen - %{application_name}'
30
31
  no_bookmarks: 'Sie haben keine Lesezeichen'
31
32
  add:
32
33
  button: 'Lesezeichen'
@@ -61,6 +62,7 @@ de:
61
62
  success: 'Dein gespeicherte Suchen gab gelöscht.'
62
63
  failure: 'Es gab ein Problem beim löschen von Suchen.'
63
64
  title: 'Gespeicherte Suchen'
65
+ page_title: 'Gespeicherte Suchen - %{application_name}'
64
66
  need_login: 'Bitte melden Sie sich an, um dein gespeicherte Suchen anschauen und wervalten.'
65
67
  no_searches: 'Sie haben keine gespeicherte Suchen'
66
68
  list_title: 'Dein gespeicherte Suchen'
@@ -73,6 +75,7 @@ de:
73
75
  success: 'Suchverlauf gelöscht.'
74
76
  failure: 'Es gab ein Problem beim löschen von Suchverlauf.'
75
77
  title: 'Suchverlauf'
78
+ page_title: 'Suchverlauf - %{application_name}'
76
79
  no_history: 'Sie haben keine Suchverlauf'
77
80
  recent: 'Deine neueste Suchen'
78
81
  forget: 'vergessen'
@@ -139,7 +142,12 @@ de:
139
142
  back_to_bookmarks: 'Zuruch nach Lesezeichen'
140
143
 
141
144
  search:
145
+ # i18n key 'title' is deprecated and will be removed in Blacklight 6.0
142
146
  title: '%{application_name} Suchergebnisse'
147
+ page_title:
148
+ title: '%{constraints} - %{application_name} Suchergebnisse'
149
+ constraint: '%{label}: %{value}'
150
+ many_constraint_values: '%{values} ausgewählt'
143
151
  search_results_header: 'Suchen'
144
152
  search_results: 'Suchergebnisse'
145
153
  errors:
@@ -27,6 +27,7 @@ en:
27
27
 
28
28
  bookmarks:
29
29
  title: 'Bookmarks'
30
+ page_title: 'Bookmarks - %{application_name}'
30
31
  no_bookmarks: 'You have no bookmarks'
31
32
  add:
32
33
  button: 'Bookmark'
@@ -61,6 +62,7 @@ en:
61
62
  success: 'Cleared your saved searches.'
62
63
  failure: 'There was a problem clearing your searches.'
63
64
  title: 'Saved Searches'
65
+ page_title: 'Saved Searches - %{application_name}'
64
66
  need_login: 'Please log in to manage and view your saved searches.'
65
67
  no_searches: 'You have no saved searches'
66
68
  list_title: 'Your saved searches'
@@ -73,6 +75,7 @@ en:
73
75
  success: 'Cleared your search history.'
74
76
  failure: 'There was a problem clearing your search history.'
75
77
  title: 'Search History'
78
+ page_title: 'Search History - %{application_name}'
76
79
  no_history: 'You have no search history'
77
80
  recent: 'Your recent searches'
78
81
  forget: 'forget'
@@ -139,7 +142,12 @@ en:
139
142
  back_to_bookmarks: 'Back to Bookmarks'
140
143
 
141
144
  search:
145
+ # i18n key 'title' is deprecated and will be removed in Blacklight 6.0
142
146
  title: '%{application_name} Search Results'
147
+ page_title:
148
+ title: '%{constraints} - %{application_name} Search Results'
149
+ constraint: '%{label}: %{value}'
150
+ many_constraint_values: '%{values} selected'
143
151
  search_results_header: 'Search'
144
152
  search_results: 'Search Results'
145
153
  errors:
@@ -27,6 +27,7 @@ es:
27
27
 
28
28
  bookmarks:
29
29
  title: 'Favoritos'
30
+ page_title: 'Favoritos - %{application_name}'
30
31
  no_bookmarks: 'Usted no tiene favoritos'
31
32
  add:
32
33
  button: 'Favoritos'
@@ -61,6 +62,7 @@ es:
61
62
  success: 'Se borraron sus búsquedas guardadas'
62
63
  failure: 'Hubo un problema al borrar sus búsquedas.'
63
64
  title: 'Búsquedas guardadas'
65
+ page_title: 'Búsquedas guardadas - %{application_name}'
64
66
  need_login: 'Por favor, inicie sesión para administrar y ver sus búsquedas guardadas.'
65
67
  no_searches: 'No tienes búsquedas guardadas'
66
68
  list_title: 'Sus búsquedas guardadas'
@@ -73,6 +75,7 @@ es:
73
75
  success: 'Se borro el historial de búsqueda.'
74
76
  failure: 'Hubo un problema al borrar su historial de búsqueda.'
75
77
  title: 'Historia'
78
+ page_title: 'Historia - %{application_name}'
76
79
  no_history: 'Usted no tiene historial de búsqueda'
77
80
  recent: 'Sus búsquedas recientes'
78
81
  forget: 'Olvidar'
@@ -139,7 +142,12 @@ es:
139
142
  back_to_bookmarks: 'Volver a sus favoritos'
140
143
 
141
144
  search:
145
+ # i18n key 'title' is deprecated and will be removed in Blacklight 6.0
142
146
  title: '%{application_name} Resultados de la búsqueda'
147
+ page_title:
148
+ title: '%{constraints} - %{application_name} Resultados de la búsqueda'
149
+ constraint: '%{label}: %{value}'
150
+ many_constraint_values: '%{values} seleccionado'
143
151
  search_results_header: 'Buscar'
144
152
  search_results: 'Resultados de la búsqueda'
145
153
  errors:
@@ -27,6 +27,7 @@ fr:
27
27
 
28
28
  bookmarks:
29
29
  title: 'Favoris'
30
+ page_title: 'Favoris - %{application_name}'
30
31
  no_bookmarks: 'Accédez à votre compte pour conserver des références dans votre panier'
31
32
  add:
32
33
  button: 'Panier'
@@ -61,6 +62,7 @@ fr:
61
62
  success: 'Recherches effacées.'
62
63
  failure: 'Un problème est survenu lors de la suppression.'
63
64
  title: 'Recherches sauvegardées'
65
+ page_title: 'Recherches sauvegardées - %{application_name}'
64
66
  need_login: 'Veuillez vous connecter pour accéder à vos recherches.'
65
67
  no_searches: 'Vous n''avez sauvegardé aucune recherche.'
66
68
  list_title: 'Vos recherches'
@@ -73,6 +75,7 @@ fr:
73
75
  success: 'Votre historique de recherche a bien été effacé.'
74
76
  failure: 'Un problème est survenu lors de la suppression.'
75
77
  title: 'Historique de recherche'
78
+ title: 'Historique de recherche - %{application_name}'
76
79
  no_history: 'Il n''y a aucun historique en cours.'
77
80
  recent: 'Dernières recherches'
78
81
  forget: 'Supprimer'
@@ -142,7 +145,12 @@ fr:
142
145
  back_to_bookmarks: 'Retour aux favoris'
143
146
 
144
147
  search:
148
+ # i18n key 'title' is deprecated and will be removed in Blacklight 6.0
145
149
  title: '%{application_name} Résultats de recherche'
150
+ page_title:
151
+ title: '%{constraints} - %{application_name} Résultats de recherche'
152
+ constraint: '%{label}: %{value}'
153
+ many_constraint_values: '%{values} sélectionné'
146
154
  search_results_header: 'Recherche'
147
155
  search_results: 'Résultats de recherche'
148
156
  errors:
@@ -27,6 +27,7 @@ it:
27
27
 
28
28
  bookmarks:
29
29
  title: 'Preferiti'
30
+ page_title: 'Preferiti - %{application_name}'
30
31
  no_bookmarks: 'Non è stato salvato nessun preferito.'
31
32
  add:
32
33
  button: 'Preferiti'
@@ -61,6 +62,7 @@ it:
61
62
  success: 'Tutte le ricerche salvate sono state cancellate.'
62
63
  failure: 'Si è verificato un errore nel cancellare le ricerche salvate.'
63
64
  title: 'Ricerche salvate'
65
+ page_title: 'Ricerche salvate - %{application_name}'
64
66
  need_login: 'Effettuare il login per gestire e visualizzare le ricerche salvate.'
65
67
  no_searches: 'Non è stata salvata nessuna ricerca.'
66
68
  list_title: 'Ricerche salvate'
@@ -73,6 +75,7 @@ it:
73
75
  success: 'Le ricerche effettuate sono state cancellate.'
74
76
  failure: 'Si è verificato un errore nel cancellare le ricerche effettuate.'
75
77
  title: 'Ricerche effettuate'
78
+ page_title: 'Ricerche effettuate - %{application_name}'
76
79
  no_history: 'Non è stata effettuata nessuna ricerca'
77
80
  recent: 'Ricerche effettuate'
78
81
  forget: 'dimentica'
@@ -139,7 +142,12 @@ it:
139
142
  back_to_bookmarks: 'Torna ai preferiti'
140
143
 
141
144
  search:
145
+ # i18n key 'title' is deprecated and will be removed in Blacklight 6.0
142
146
  title: 'Risultati della ricerca per %{application_name}'
147
+ page_title:
148
+ title: '%{constraints} - %{application_name} Risultati della ricerca'
149
+ constraint: '%{label}: %{value}'
150
+ many_constraint_values: '%{values} selezionato'
143
151
  search_results_header: 'Ricerca'
144
152
  search_results: 'Risultati della ricerca'
145
153
  errors:
@@ -27,6 +27,7 @@ pt-BR:
27
27
 
28
28
  bookmarks:
29
29
  title: 'Favoritos'
30
+ page_title: 'Favoritos - %{application_name}'
30
31
  no_bookmarks: 'Você não salvou nenhum Favorito'
31
32
  add:
32
33
  button: 'Favorito'
@@ -60,6 +61,7 @@ pt-BR:
60
61
  success: 'As buscas foram removidas.'
61
62
  failure: 'Xiii, ocorreu um erro ao remover suas pesquisas.'
62
63
  title: 'Pesquisas Salvas'
64
+ page_title: 'Pesquisas Salvas - %{application_name}'
63
65
  need_login: 'Por favor faça o login para gerenciar suas buscas salvas.'
64
66
  no_searches: 'Você não salvou nenhuma busca'
65
67
  list_title: 'Suas Buscas'
@@ -72,6 +74,7 @@ pt-BR:
72
74
  success: 'Histórico de Busca removido.'
73
75
  failure: 'Xiii, ocorreu um erro ao remover o histórico de busca.'
74
76
  title: 'Histórico de Busca'
77
+ page_title: 'Histórico de Busca - %{application_name}'
75
78
  no_history: 'Não existe nada em seu histórico'
76
79
  recent: 'Buscas Recentes'
77
80
  forget: 'limpar'
@@ -137,7 +140,12 @@ pt-BR:
137
140
  back_to_bookmarks: 'Voltar aos Favoritos'
138
141
 
139
142
  search:
143
+ # i18n key 'title' is deprecated and will be removed in Blacklight 6.0
140
144
  title: '%{application_name} Resultado da Busca'
145
+ page_title:
146
+ title: '%{constraints} - %{application_name} Resultado da Busca'
147
+ constraint: '%{label}: %{value}'
148
+ many_constraint_values: '%{values} selecionado'
141
149
  search_results_header: 'Busca'
142
150
  search_results: 'Resultados da Busca'
143
151
  errors:
data/lib/blacklight.rb CHANGED
@@ -34,6 +34,7 @@ module Blacklight
34
34
 
35
35
  autoload :SolrResponse, 'blacklight/solr_response'
36
36
  autoload :Facet, 'blacklight/facet'
37
+ autoload :FacetPaginator, 'blacklight/facet_paginator'
37
38
 
38
39
  extend SearchFields
39
40
  extend Deprecation
@@ -225,7 +225,12 @@ module Blacklight
225
225
 
226
226
  def locate_search_builder_class
227
227
  ::SearchBuilder
228
- rescue NameError
228
+ rescue NameError => e
229
+ # If the NameError is a result of the SearchBuilder having a
230
+ # NameError (e.g. NoMethodError) within it then raise the error.
231
+ raise e if Object.const_defined? "::SearchBuilder"
232
+
233
+ # Otherwise the NameError was a result of not being able to find SearchBuilder
229
234
  Deprecation.warn(Configuration, "Your application is missing the SearchBuilder. Have you run `rails generate blacklight:search_builder`? Falling back to Blacklight::Solr::SearchBuilder")
230
235
  Blacklight::Solr::SearchBuilder
231
236
  end
@@ -30,6 +30,29 @@ module Blacklight
30
30
  end
31
31
  end
32
32
 
33
+ ##
34
+ # Create <link rel="alternate"> links from a documents dynamically
35
+ # provided export formats. Returns empty string if no links available.
36
+ #
37
+ # @params [SolrDocument] document
38
+ # @params [Hash] options
39
+ # @option options [Boolean] :unique ensures only one link is output for every
40
+ # content type, e.g. as required by atom
41
+ # @option options [Array<String>] :exclude array of format shortnames to not include in the output
42
+ def link_rel_alternates(options = {})
43
+ options = { unique: false, exclude: [] }.merge(options)
44
+
45
+ seen = Set.new
46
+
47
+ safe_join(@document.export_formats.map do |format, spec|
48
+ next if options[:exclude].include?(format) || (options[:unique] && seen.include?(spec[:content_type]))
49
+
50
+ seen.add(spec[:content_type])
51
+
52
+ tag(:link, rel: "alternate", title: format, type: spec[:content_type], href: @controller.polymorphic_url(@document, format: format))
53
+ end.compact, "\n")
54
+ end
55
+
33
56
  ##
34
57
  # Get the document's "title" to display in the <title> element.
35
58
  # (by default, use the #document_heading)