Class: CocinaDisplay::TitleBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/cocina_display/title_builder.rb

Overview

Select and format title data as a string for display or indexing.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(strategy:, add_punctuation:, only_one_parallel_value: true, part_label: nil, sortable: false) ⇒ TitleBuilder

primary, untyped, first occurrence. “:all” returns an array containing all the values. value coming from a MARC record, which is designed for catalog cards.) of primary, untyped, first occurrence. When false, return an array containing all the parallel values. Why? Think of e.g. title displayed in blacklight search results vs boosting values for ranking of search results

Parameters:

  • strategy (Symbol)

    “:first” selects a single title value based on precedence of

  • add_punctuation (boolean)

    whether the title should be formatted with punctuation (think of a structured

  • only_one_parallel_value (boolean) (defaults to: true)

    when true, choose one of the parallel values according to precedence

  • part_label (String) (defaults to: nil)

    the partLabel to add for digital serials display

  • sortable (boolean) (defaults to: false)

    whether the title is intended for sorting, and should have non-sorting parts removed



68
69
70
71
72
73
74
# File 'lib/cocina_display/title_builder.rb', line 68

def initialize(strategy:, add_punctuation:, only_one_parallel_value: true, part_label: nil, sortable: false)
  @strategy = strategy
  @add_punctuation = add_punctuation
  @only_one_parallel_value = only_one_parallel_value
  @part_label = part_label
  @sortable = sortable
end

Class Method Details

.additional_titles(titles) ⇒ Array<String>

“additional titles” are all title data except for full_title. We want to able able to index it separately so we can boost matches on it in search results (boost matching these strings lower than other titles present)

Parameters:

  • titles (Array<Hash>)

    The titles to consider.

Returns:

  • (Array<String>)

    The values for Solr.



45
46
47
# File 'lib/cocina_display/title_builder.rb', line 45

def self.additional_titles(titles)
  [new(strategy: :all, add_punctuation: false).build(titles)].flatten - full_title(titles)
end

.build(titles, catalog_links: [], strategy: :first, add_punctuation: true) ⇒ String, Array

Returns The title value for Solr - for :first strategy, a string; for :all strategy, an array. (e.g. title displayed in blacklight search results vs boosting values for search result rankings).

Parameters:

  • titles (Array<Hash>)

    The titles to consider.

  • catalog_links (Array<Hash>) (defaults to: [])

    The folio catalog links to check for digital serials part labels.

  • strategy (Symbol) (defaults to: :first)

    “:first” is the strategy for selection when primary or display title are missing.

  • add_punctuation (Boolean) (defaults to: true)

    Determines if the title should be formatted with punctuation.

Returns:

  • (String, Array)

    The title value for Solr - for :first strategy, a string; for :all strategy, an array. (e.g. title displayed in blacklight search results vs boosting values for search result rankings)



17
18
19
20
# File 'lib/cocina_display/title_builder.rb', line 17

def self.build(titles, catalog_links: [], strategy: :first, add_punctuation: true)
  part_label = catalog_links.find { |link| link["catalog"] == "folio" }&.fetch("partLabel", nil)
  new(strategy: strategy, add_punctuation: add_punctuation, part_label: part_label).build(titles)
end

.full_title(titles, catalog_links: []) ⇒ Array<String>

the “full title” is the title WITH subtitle, part name, etc. We want to able able to index it separately so we can boost matches on it in search results (boost matching this string higher than other titles present)

Parameters:

  • titles (Array<Hash>)

    The titles to consider.

  • catalog_links (Array<Hash>) (defaults to: [])

    The folio catalog links to check for digital serials part labels.

Returns:

  • (Array<String>)

    The full title value(s) for Solr - array due to possible parallelValue



36
37
38
39
# File 'lib/cocina_display/title_builder.rb', line 36

def self.full_title(titles, catalog_links: [])
  part_label = catalog_links.find { |link| link["catalog"] == "folio" }&.fetch("partLabel", nil)
  [new(strategy: :first, add_punctuation: false, only_one_parallel_value: false, part_label: part_label).build(titles)].flatten.compact
end

.main_title(titles) ⇒ Array<String>

the “main title” is the title withOUT subtitle, part name, etc. We want to index it separately so we can boost matches on it in search results (boost matching this string higher than matching full title string) e.g. “The Hobbit” (main_title) vs “The Hobbit, or, There and Back Again (full_title)

Parameters:

  • titles (Array<Hash>)

    The titles to consider.

Returns:

  • (Array<String>)

    The main title value(s) for Solr - array due to possible parallelValue



27
28
29
# File 'lib/cocina_display/title_builder.rb', line 27

def self.main_title(titles)
  new(strategy: :first, add_punctuation: false).main_title(titles)
end

.sort_title(titles, catalog_links: []) ⇒ Array<String>

Like the full title, but with any non-sorting characters and punctuation removed.

Parameters:

  • titles (Array<Hash>)

    The titles to consider.

  • catalog_links (Array<Hash>) (defaults to: [])

    The folio catalog links to check for digital serials part labels.

Returns:

  • (Array<String>)

    The sort title value(s) for Solr - array due to possible parallelValue



53
54
55
56
57
# File 'lib/cocina_display/title_builder.rb', line 53

def self.sort_title(titles, catalog_links: [])
  part_label = catalog_links.find { |link| link["catalog"] == "folio" }&.fetch("partLabel", nil)
  [new(strategy: :first, add_punctuation: false, only_one_parallel_value: false, part_label: part_label, sortable: true).build(titles)]
    .flatten.compact.map { |title| title.gsub(/[[:punct:]]*/, "").squeeze(" ").strip }
end

Instance Method Details

#build(cocina_titles) ⇒ String, Array

(e.g. title displayed in blacklight search results vs boosting values for search result rankings) rubocop:disable Metrics/PerceivedComplexity

Parameters:

  • cocina_titles (Array<Hash>)

    the titles to consider

Returns:

  • (String, Array)

    the title value for Solr - for :first strategy, a string; for :all strategy, an array



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/cocina_display/title_builder.rb', line 80

def build(cocina_titles)
  cocina_title = primary_title(cocina_titles) || untyped_title(cocina_titles)
  cocina_title = other_title(cocina_titles) if cocina_title.blank?
  if strategy == :first
    result = extract_title(cocina_title)
    result = add_part_label(result) if part_label.present?
    result
  else
    result = cocina_titles.map { |ctitle| extract_title(ctitle) }.flatten
    if only_one_parallel_value? && result.length == 1
      result.first
    else
      result
    end
  end
end

#main_title(titles) ⇒ Array<String>

this is the single “short title” - the title without subtitle, part name, etc. this may be useful for boosting and exact matching for search results

Returns:

  • (Array<String>)

    the main title value(s) for Solr - can be array due to parallel titles



101
102
103
104
105
106
# File 'lib/cocina_display/title_builder.rb', line 101

def main_title(titles)
  cocina_title = primary_title(titles) || untyped_title(titles)
  cocina_title = other_title(titles) if cocina_title.blank?

  extract_main_title(cocina_title)
end