Class: Nanoc::Core::IdentifiableCollectionView

Inherits:
View
  • Object
show all
Includes:
Enumerable
Defined in:
lib/nanoc/core/identifiable_collection_view.rb

Constant Summary collapse

NOTHING =
Object.new

Instance Method Summary collapse

Methods inherited from View

#_context, #frozen?, #inspect

Methods included from ContractsSupport

enabled?, included, setup_once, warn_about_performance

Constructor Details

#initialize(objects, context) ⇒ IdentifiableCollectionView

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of IdentifiableCollectionView.



11
12
13
14
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 11

def initialize(objects, context)
  super(context)
  @objects = objects
end

Instance Method Details

#[](string) ⇒ nil, #identifier #[](regex) ⇒ nil, #identifier

Overloads:

  • #[](string) ⇒ nil, #identifier

    Finds the object whose identifier matches the given string.

    If the glob syntax is enabled, the string can be a glob, in which case this method finds the first object that matches the given glob.

    Parameters:

    Returns:

    • (nil)

      if no object matches the string

    • (#identifier)

      if an object was found

  • #[](regex) ⇒ nil, #identifier

    Finds the object whose identifier matches the given regular expression.

    Parameters:

    • regex (Regex)

    Returns:

    • (nil)

      if no object matches the regex

    • (#identifier)

      if an object was found



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 122

def [](arg)
  # The argument to #[] fall in two categories: exact matches, and
  # patterns. An example of an exact match is '/about.md', while an
  # example of a pattern is '/about.*'.
  #
  # If a Nanoc::Core::Identifier is given, we know it will need to be an
  # exact match. If a String is given, it could be either. If a Regexp is
  # given, we know it’s a pattern match.
  #
  # If we have a pattern match, create a dependency on the item
  # collection, with a `raw_content` property that contains the pattern.
  # If we have an exact match, do nothing -- there is no reason to create
  # a dependency on the item itself, because accessing that item
  # (attributes, compiled content, …) will create the dependency later.

  object_from_exact_match = nil
  object_from_pattern_match = nil

  case arg
  when Nanoc::Core::Identifier
    # Can only be an exact match
    object_from_exact_match = @objects.object_with_identifier(arg)
  when String
    # Can be an exact match, or a pattern match
    tmp = @objects.object_with_identifier(arg)
    if tmp
      object_from_exact_match = tmp
    else
      object_from_pattern_match = @objects.object_matching_glob(arg)
    end
  when Regexp
    # Can only be a pattern match
    object_from_pattern_match = @objects.find { |i| i.identifier.to_s =~ arg }
  else
    raise ArgumentError, "Unexpected argument #{arg.class} to []: Can only pass strings, identfiers, and regular expressions"
  end

  unless object_from_exact_match
    # We got this object from a pattern match. Create a dependency with
    # this pattern, because if the objects matching this pattern change,
    # then the result of #[] will change too.
    #
    # NOTE: object_from_exact_match can also be nil, but in that case
    # we still need to create a dependency.

    prop_attribute =
      case arg
      when Identifier
        [arg.to_s]
      when String, Regexp
        [arg]
      end

    @context.dependency_tracker.bounce(_unwrap, raw_content: prop_attribute)
  end

  object = object_from_exact_match || object_from_pattern_match
  object && view_class.new(object, @context)
end

#_unwrapObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



17
18
19
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 17

def _unwrap
  @objects
end

#each {|object| ... } ⇒ self

Calls the given block once for each object, passing that object as a parameter.

Yield Parameters:

  • object (#identifier)

Yield Returns:

  • (void)

Returns:

  • (self)


35
36
37
38
39
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 35

def each
  @context.dependency_tracker.bounce(_unwrap, raw_content: true)
  @objects.each { |i| yield view_class.new(i, @context) }
  self
end

#find_all(arg = NOTHING) ⇒ Enumerable

Finds all objects whose identifier matches the given argument.

Parameters:

  • arg (String, Regex) (defaults to: NOTHING)

Returns:

  • (Enumerable)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 52

def find_all(arg = NOTHING, &)
  if NOTHING.equal?(arg)
    @context.dependency_tracker.bounce(_unwrap, raw_content: true)
    return @objects.map { |i| view_class.new(i, @context) }.select(&)
  end

  prop_attribute =
    case arg
    when String, Nanoc::Core::Identifier
      [arg.to_s]
    when Regexp
      [arg]
    else
      true
    end

  @context.dependency_tracker.bounce(_unwrap, raw_content: prop_attribute)
  @objects.find_all(arg).map { |i| view_class.new(i, @context) }
end

#sizeInteger

Returns:

  • (Integer)


42
43
44
45
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 42

def size
  @context.dependency_tracker.bounce(_unwrap, raw_content: true)
  @objects.size
end

#view_classObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method is abstract.

Raises:

  • (NotImplementedError)


24
25
26
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 24

def view_class
  raise NotImplementedError
end

#where(**hash) ⇒ Enumerable

Finds all objects that have the given attribute key/value pair.

Examples:


@items.where(kind: 'article')
@items.where(kind: 'article', year: 2020)

Returns:

  • (Enumerable)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/nanoc/core/identifiable_collection_view.rb', line 80

def where(**hash)
  unless Nanoc::Core::Feature.enabled?(Nanoc::Core::Feature::WHERE)
    raise(
      Nanoc::Core::TrivialError,
      '#where is experimental, and not yet available unless the corresponding feature flag is turned on. Set the `NANOC_FEATURES` environment variable to `where` to enable its usage. (Alternatively, set the environment variable to `all` to turn on all feature flags.)',
    )
  end

  @context.dependency_tracker.bounce(_unwrap, attributes: hash)

  # IDEA: Nanoc could remember (from the previous compilation) how many
  # times #where is called with a given attribute key, and memoize the
  # key-to-identifiers list.
  found_objects = @objects.select do |i|
    hash.all? { |k, v| i.attributes[k] == v }
  end

  found_objects.map { |i| view_class.new(i, @context) }
end