Class: Bridgetown::Collection

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
bridgetown-core/lib/bridgetown-core/collection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(site, label) ⇒ Collection

Create a new Collection.

Parameters:

  • site (Bridgetown::Site)

    the site to which this collection belongs

  • label (String)

    the name of the collection



18
19
20
21
22
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 18

def initialize(site, label)
  @site     = site
  @label    = sanitize_label(label)
  @metadata = 
end

Instance Attribute Details

#labelObject (readonly)

Returns the value of attribute label.



10
11
12
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 10

def label
  @label
end

#metadataObject (readonly)

Returns the value of attribute metadata.



10
11
12
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 10

def 
  @metadata
end

#resourcesArray<Bridgetown::Resource::Base>

Fetch the Resources in this collection. Defaults to an empty array if no resources have been read in.

Returns:



36
37
38
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 36

def resources
  @resources ||= []
end

#siteBridgetown::Site (readonly)

Returns:



8
9
10
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 8

def site
  @site
end

Instance Method Details

#absolute_pathString Also known as: directory

The full path to the folder containing the collection.

Returns:

  • (String)

    full path where the collection is stored on the filesystem



137
138
139
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 137

def absolute_path
  @absolute_path ||= site.in_source_dir(relative_path)
end

#add_resource_from_model(model) ⇒ Object Also known as: add_model_resource

Parameters:



294
295
296
297
298
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 294

def add_resource_from_model(model)
  model.to_resource.read!.tap do |resource|
    resources << resource if resource.publishable?
  end
end

#builtin?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 24

def builtin?
  @is_builtin ||= label.in?(%w(posts pages data).freeze)
end

#collection_dir(*files) ⇒ String

The full path to the folder containing the collection, with optional subpaths.

Parameters:

  • *files (Array<String>)

    any other path pieces relative to the folder to append to the path

Returns:

  • (String)


148
149
150
151
152
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 148

def collection_dir(*files)
  return absolute_path if files.empty?

  site.in_source_dir(relative_path, *files)
end

#data?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 28

def data?
  @is_data ||= label == "data"
end

Used by Resource’s permalink processor

Returns:

  • (String)


211
212
213
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 211

def default_permalink
  .fetch("permalink", "/:locale/:collection/:path/")
end

#eachObject

Iterate over Resources, support Enumerable



55
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 55

def each(...) = resources.each(...)

#entriesArray<String>

All the entries in this collection.

Returns:

  • (Array<String>)

    file paths to the resources in this collection relative to the collection’s folder



91
92
93
94
95
96
97
98
99
100
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 91

def entries
  return [] unless exists?

  @entries ||= begin
    collection_dir_slash = "#{collection_dir}/"
    Utils.safe_glob(collection_dir, ["**", "*"], File::FNM_DOTMATCH).map do |entry|
      entry.sub(collection_dir_slash, "")
    end
  end
end

#entry_filterBridgetown::EntryFilter

The entry filter for this collection. Creates an instance of Bridgetown::EntryFilter if needed.



165
166
167
168
169
170
171
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 165

def entry_filter
  @entry_filter ||= Bridgetown::EntryFilter.new(
    site,
    base_directory: folder_name,
    include_underscores: true
  )
end

#exists?Boolean

Checks whether the folder “exists” for this collection.

Returns:

  • (Boolean)


157
158
159
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 157

def exists?
  File.directory?(absolute_path)
end

#extract_metadataHashWithDotAccess::Hash

Extract options for this collection from the site configuration.



218
219
220
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 218

def 
  site.config.collections[label] || HashWithDotAccess::Hash.new
end

#filtered_entriesArray<String>

Filtered version of the entries in this collection. See Bridgetown::EntryFilter#filter for more information.

Returns:

  • (Array<String>)

    list of filtered entry paths



106
107
108
109
110
111
112
113
114
115
116
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 106

def filtered_entries
  return [] unless exists?

  @filtered_entries ||=
    Dir.chdir(absolute_path) do
      entry_filter.filter(entries).reject do |f|
        path = collection_dir(f)
        File.directory?(path)
      end
    end
end

#folder_nameString Also known as: relative_directory

The folder name of this Collection, e.g. _posts or _events

Returns:

  • (String)


121
122
123
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 121

def folder_name
  @folder_name ||= "_#{label}"
end

#inspectString

An inspect string.

Returns:

  • (String)


176
177
178
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 176

def inspect
  "#<#{self.class} @label=#{label} resources=#{resources}>"
end

#merge_data_resourcesObject

rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 222

def merge_data_resources # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
  data_contents = {}

  sanitize_filename = ->(name) do
    name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
      .gsub(%r!\s+!, "_")
  end

  resources.each do |data_resource|
    segments = data_resource.relative_path.each_filename.to_a[1..]
    nested = []
    segments.each_with_index do |segment, index|
      sanitized_segment = sanitize_filename.(File.basename(segment, ".*"))
      hsh = nested.empty? ? data_contents : data_contents.dig(*nested)
      if !hsh.is_a?(Hash)
        Bridgetown.logger.error(
          "Error:",
          "#{nested.join("/")} is not a Hash structure, #{segment} cannot be read"
        )
      elsif index == segments.length - 1
        hsh[sanitized_segment] = data_resource.data.rows || data_resource.data
      elsif !hsh.key?(sanitized_segment)
        hsh[sanitized_segment] = {}
      end
      nested << sanitized_segment
    end
  end

  (data_contents).with_dot_access
end

#merge_environment_specific_metadata(data_contents) ⇒ Object



253
254
255
256
257
258
259
260
261
262
263
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 253

def (data_contents)
  if data_contents["site_metadata"]
    data_contents["site_metadata"][Bridgetown.environment]&.each_key do |k|
      data_contents["site_metadata"][k] =
        data_contents["site_metadata"][Bridgetown.environment][k]
    end
    data_contents["site_metadata"].delete(Bridgetown.environment)
  end

  data_contents
end

#readBridgetown::Collection

Read the allowed resources into the collection’s array of resources.

Returns:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 68

def read
  filtered_entries.each do |file_path|
    full_path = collection_dir(file_path)
    next if File.directory?(full_path)

    next if File.basename(file_path).starts_with?("_")

    if label == "data" || FrontMatter::Loaders.front_matter?(full_path)
      read_resource(full_path)
    else
      read_static_file(file_path, full_path)
    end
  end
  site.static_files.concat(static_files)
  sort_resources!

  self
end

#read_resource(full_path, manifest: nil) ⇒ void

This method returns an undefined value.

Read in resource from repo path

Parameters:



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 269

def read_resource(full_path, manifest: nil)
  model_relative_path = relative_model_path_for(full_path, manifest:)
  model = Bridgetown::Model::Base.find(
    model_id_from_relative_path(model_relative_path, manifest:),
    site:
  )

  if model_is_multi_locale?(model, model_relative_path)
    # If the model specifies a locales key, use that to determine the
    # the locale of each resource, otherwise fall back to `site.config.available_locales`
    locales = model.attributes[:locales] || site.config.available_locales

    locales.each do |locale|
      model.locale = locale.to_sym
      add_resource_from_model model
    end

    return
  end

  add_resource_from_model model
  nil
end

#relative_pathString

The relative path to the folder containing the collection.

Returns:

  • (String)

    folder where the collection is stored relative to the configured collections folder (usually the site source)



130
131
132
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 130

def relative_path
  Pathname.new(container).join(folder_name).to_s
end

#resources_by_relative_urlHash<String, Bridgetown::Resource::Base>

Fetch the collection resources and arrange them by relative URL in a hash.

Returns:



50
51
52
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 50

def resources_by_relative_url
  resources.group_by(&:relative_url).transform_values(&:first)
end

#resources_by_slugHash<String, Bridgetown::Resource::Base>

Fetch the collection resources and arrange them by slug in a hash.

Returns:



43
44
45
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 43

def resources_by_slug
  resources.group_by { |item| item.data.slug }.transform_values(&:first)
end

#sanitize_label(label) ⇒ String

Produce a sanitized label name Label names may not contain anything but alphanumeric characters, underscores, and hyphens.

Parameters:

  • label (String)

    the possibly-unsafe label

Returns:

  • (String)

    sanitized version of the label.



186
187
188
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 186

def sanitize_label(label)
  label.gsub(%r![^a-z0-9_\-.]!i, "")
end

#sort_resources!Object



301
302
303
304
305
306
307
308
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 301

def sort_resources!
  if ["sort_by"].is_a?(String)
    sort_resources_by_key!
  else
    resources.sort!
  end
  resources.reverse! if .sort_direction == "descending"
end

#static_filesArray<Bridgetown::StaticFile>

Fetch the static files in this collection. Defaults to an empty array if no static files have been read in.

Returns:



61
62
63
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 61

def static_files
  @static_files ||= []
end

#to_liquidBridgetown::Drops::CollectionDrop

Produce a representation of this Collection for use in Liquid. Exposes two attributes: - label - resources

Returns:



197
198
199
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 197

def to_liquid
  Drops::CollectionDrop.new self
end

#write?Boolean

Whether the collection’s resources ought to be written as individual files in the output.

Returns:

  • (Boolean)

    true if the ‘write’ metadata is true, false otherwise.



205
206
207
# File 'bridgetown-core/lib/bridgetown-core/collection.rb', line 205

def write?
  !!.fetch("output", false)
end