kontent-ai-delivery 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +21 -0
  3. data/README.md +617 -0
  4. data/bin/console +14 -0
  5. data/bin/setup +8 -0
  6. data/lib/delivery/builders/image_transformation_builder.rb +272 -0
  7. data/lib/delivery/builders/url_builder.rb +123 -0
  8. data/lib/delivery/client/delivery_client.rb +184 -0
  9. data/lib/delivery/client/delivery_query.rb +308 -0
  10. data/lib/delivery/client/request_manager.rb +127 -0
  11. data/lib/delivery/models/content_item.rb +153 -0
  12. data/lib/delivery/models/content_type.rb +41 -0
  13. data/lib/delivery/models/language.rb +29 -0
  14. data/lib/delivery/models/pagination.rb +22 -0
  15. data/lib/delivery/models/taxonomy_group.rb +39 -0
  16. data/lib/delivery/query_parameters/filters.rb +201 -0
  17. data/lib/delivery/query_parameters/parameter_base.rb +56 -0
  18. data/lib/delivery/query_parameters/query_string.rb +78 -0
  19. data/lib/delivery/resolvers/content_link_resolver.rb +102 -0
  20. data/lib/delivery/resolvers/inline_content_item_resolver.rb +75 -0
  21. data/lib/delivery/resolvers/linked_item_resolver.rb +43 -0
  22. data/lib/delivery/responses/delivery_element_response.rb +34 -0
  23. data/lib/delivery/responses/delivery_item_listing_response.rb +54 -0
  24. data/lib/delivery/responses/delivery_item_response.rb +40 -0
  25. data/lib/delivery/responses/delivery_items_feed_response.rb +58 -0
  26. data/lib/delivery/responses/delivery_language_listing_response.rb +44 -0
  27. data/lib/delivery/responses/delivery_taxonomy_listing_response.rb +47 -0
  28. data/lib/delivery/responses/delivery_taxonomy_response.rb +33 -0
  29. data/lib/delivery/responses/delivery_type_listing_response.rb +46 -0
  30. data/lib/delivery/responses/delivery_type_response.rb +32 -0
  31. data/lib/delivery/responses/response_base.rb +39 -0
  32. data/lib/delivery/tests/401.json +6 -0
  33. data/lib/delivery/tests/429.json +5 -0
  34. data/lib/delivery/tests/fake_responder.rb +99 -0
  35. data/lib/delivery/tests/filtering/items_with_count.json +5385 -0
  36. data/lib/delivery/tests/filtering/pagination.json +762 -0
  37. data/lib/delivery/tests/generic/items/about_us.json +277 -0
  38. data/lib/delivery/tests/generic/items/aeropress_filters.json +156 -0
  39. data/lib/delivery/tests/generic/items/coffee_processing_techniques.json +566 -0
  40. data/lib/delivery/tests/generic/items/empty_rich_text.json +24 -0
  41. data/lib/delivery/tests/generic/items/rich_text_complex_tables.json +81 -0
  42. data/lib/delivery/tests/generic/items/where_does_coffee_come_from_.json +599 -0
  43. data/lib/delivery/tests/generic/items.json +5384 -0
  44. data/lib/delivery/tests/generic/languages.json +24 -0
  45. data/lib/delivery/tests/generic/taxonomies/manufacturer.json +30 -0
  46. data/lib/delivery/tests/generic/taxonomies.json +204 -0
  47. data/lib/delivery/tests/generic/types/brewer/elements/product_status.json +6 -0
  48. data/lib/delivery/tests/generic/types/brewer.json +89 -0
  49. data/lib/delivery/tests/generic/types.json +836 -0
  50. data/lib/delivery/tests/items_feed/articles_feed_1.json +39 -0
  51. data/lib/delivery/tests/items_feed/articles_feed_2.json +78 -0
  52. data/lib/delivery/tests/items_feed/articles_feed_3.json +104 -0
  53. data/lib/kontent-ai-delivery.rb +22 -0
  54. metadata +221 -0
@@ -0,0 +1,39 @@
1
+ module Kontent
2
+ module Ai
3
+ module Delivery
4
+ class TaxonomyGroup
5
+ # Parses the 'terms' JSON node as a dynamic OpenStruct object.
6
+ #
7
+ # * *Returns*:
8
+ # - +OpenStruct+ The terms of the taxonomy group as a dynamic object
9
+ def terms
10
+ @terms unless @terms.nil?
11
+ @terms = JSON.parse(
12
+ JSON.generate(@source['terms']),
13
+ object_class: OpenStruct
14
+ )
15
+ end
16
+
17
+ # Parses the 'system' JSON node as a dynamic OpenStruct object.
18
+ #
19
+ # * *Returns*:
20
+ # - +OpenStruct+ The system properties of the taxonomy group
21
+ def system
22
+ @system unless @system.nil?
23
+ @system = JSON.parse(
24
+ JSON.generate(@source['system']),
25
+ object_class: OpenStruct
26
+ )
27
+ end
28
+
29
+ # Constructor.
30
+ #
31
+ # * *Args*:
32
+ # - *json* (+JSON+) A JSON node representing a taxonomy group
33
+ def initialize(source)
34
+ @source = source
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,201 @@
1
+ require 'delivery/query_parameters/parameter_base'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module QueryParameters
7
+ # Provides the base class for filter implementations.
8
+ # See https://kontent.ai/learn/reference/delivery-api/#tag/Filtering-content
9
+ class Filter < ParameterBase
10
+ # Constructor.
11
+ #
12
+ # * *Args*:
13
+ # - *key* (+string+) The field to filter upon
14
+ # - *operator* (+string+) The Kontent.ai filter being applied to the field, in brackets
15
+ # - *values* (+Object+) One or more values which will appear as the value of the query string parameter
16
+ # - *eq_sign* (+boolean+) If false, the equals sign is not generated in the parameter
17
+ def initialize(key, operator, values, eq_sign = true)
18
+ super(key, operator, values, eq_sign)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ # Extend String class to allow semantic typing of filters
27
+ class String
28
+ # Represents a filter that matches a content item if the specified content
29
+ # element or system attribute has a value that contains all the specified
30
+ # values. This filter is applicable to array values only, such as sitemap
31
+ # location or value of Linked Items, Taxonomy and Multiple choice content elements.
32
+ #
33
+ # * *Args*:
34
+ # - +Object+ One or more objects representing the values that must appear in the field
35
+ #
36
+ # * *Returns*:
37
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
38
+ def all(*args)
39
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[all]', *args)
40
+ end
41
+
42
+ # Represents a filter that matches a content item if the specified content
43
+ # element or system attribute has a value that contains any the specified
44
+ # values. This filter is applicable to array values only, such as sitemap
45
+ # location or value of Linked Items, Taxonomy and Multiple choice content elements.
46
+ #
47
+ # * *Args*:
48
+ # - +Object+ One or more objects representing the values that may appear in the field
49
+ #
50
+ # * *Returns*:
51
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
52
+ def any(*args)
53
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[any]', *args)
54
+ end
55
+
56
+ # Represents a filter that matches a content item if the specified content element
57
+ # or system attribute has a value that contains the specified value.
58
+ # This filter is applicable to array values only, such as sitemap location or value
59
+ # of Linked Items, Taxonomy and Multiple choice content elements.
60
+ #
61
+ # * *Args*:
62
+ # - +Object+ An object representing the value that must appear in the field
63
+ #
64
+ # * *Returns*:
65
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
66
+ def contains(*args)
67
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[contains]', *args)
68
+ end
69
+
70
+ # Represents a filter that matches a content item if the specified
71
+ # content element or system attribute has the specified value.
72
+ #
73
+ # * *Args*:
74
+ # - +Object+ An object representing the value that must equal the value in the field
75
+ #
76
+ # * *Returns*:
77
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
78
+ def eq(*args)
79
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '', *args)
80
+ end
81
+
82
+ # Represents a filter that matches a content item if the specified
83
+ # content element or system attribute does not have the specified value.
84
+ #
85
+ # * *Args*:
86
+ # - +Object+ An object representing the value that cannot exist in the element
87
+ #
88
+ # * *Returns*:
89
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
90
+ def not_eq(*args)
91
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[neq]', *args)
92
+ end
93
+
94
+ # Represents a filter that matches a content item if the specified
95
+ # content element or system attribute does not have any value.
96
+ #
97
+ # * *Returns*:
98
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
99
+ def empty
100
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[empty]', nil, false)
101
+ end
102
+
103
+ # Represents a filter that matches a content item if the specified
104
+ # content element or system attribute has any value.
105
+ #
106
+ # * *Returns*:
107
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
108
+ def not_empty
109
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[nempty]', nil, false)
110
+ end
111
+
112
+ # Represents a filter that matches a content item if the specified
113
+ # content element or system attribute does not have the specified value.
114
+ #
115
+ # * *Args*:
116
+ # - +Object+ An object representing the value that cannot exist in the element
117
+ #
118
+ # * *Returns*:
119
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
120
+ def not_in(*args)
121
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[nin]', *args)
122
+ end
123
+
124
+ # Represents a filter that matches a content item if the specified content
125
+ # element or system attribute has a value that is greater than the
126
+ # specified value.
127
+ #
128
+ # * *Args*:
129
+ # - +Object+ An object representing the lowest possible value of the field, non-inclusive
130
+ #
131
+ # * *Returns*:
132
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
133
+ def gt(*args)
134
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[gt]', *args)
135
+ end
136
+
137
+ # Represents a filter that matches a content item if the specified content
138
+ # element or system attribute has a value that is greater than or equal to
139
+ # the specified value.
140
+ #
141
+ # * *Args*:
142
+ # - +Object+ An object representing the lowest possible value of the field
143
+ #
144
+ # * *Returns*:
145
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
146
+ def gt_or_eq(*args)
147
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[gte]', *args)
148
+ end
149
+
150
+ # Represents a filter that matches a content item if the specified
151
+ # content element or system attribute has a value that matches a
152
+ # value in the specified list.
153
+ #
154
+ # * *Args*:
155
+ # - +Object+ One or more objects representing the required values of the field
156
+ #
157
+ # * *Returns*:
158
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
159
+ def in(*args)
160
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[in]', *args)
161
+ end
162
+
163
+ # Represents a filter that matches a content item if the specified content
164
+ # element or system attribute has a value that is less than the
165
+ # specified value.
166
+ #
167
+ # * *Args*:
168
+ # - +Object+ An object representing the highest possible value of the field, non-inclusive
169
+ #
170
+ # * *Returns*:
171
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
172
+ def lt(*args)
173
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[lt]', *args)
174
+ end
175
+
176
+ # Represents a filter that matches a content item if the specified content
177
+ # element or system attribute has a value that is less than or equal to
178
+ # the specified value.
179
+ #
180
+ # * *Args*:
181
+ # - +Object+ An object representing the highest possible value of the field
182
+ #
183
+ # * *Returns*:
184
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
185
+ def lt_or_eq(*args)
186
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[lte]', *args)
187
+ end
188
+
189
+ # Represents a filter that matches a content item if the specified
190
+ # content element or system attribute has a value that falls within
191
+ # the specified range of values (both inclusive).
192
+ #
193
+ # * *Args*:
194
+ # - +Object+ An object representing the lowest and highest possible values of the field
195
+ #
196
+ # * *Returns*:
197
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
198
+ def range(*args)
199
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[range]', *args)
200
+ end
201
+ end
@@ -0,0 +1,56 @@
1
+ require 'cgi'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module QueryParameters
7
+ # Base class for all parameters added to a DeliveryQuery. All
8
+ # QueryParameters will appear in the query string.
9
+ class ParameterBase
10
+ attr_accessor :key
11
+ SEPARATOR = CGI::escape(',')
12
+
13
+ # Constructor.
14
+ #
15
+ # * *Args*:
16
+ # - *key* (+string+) The field to filter upon
17
+ # - *operator* (+string+) The Kontent.ai filter being applied to the field, in brackets
18
+ # - *values* (+Object+) One or more values which will appear as the value of the query string parameter
19
+ # - *eq_sign* (+boolean+) If false, the equals sign is not generated in the parameter
20
+ def initialize(key, operator, values, eq_sign = true)
21
+ self.key = key
22
+ values = [values] unless values.respond_to? :each
23
+ @values = values
24
+ @operator = operator
25
+ @eq_sign = eq_sign
26
+ end
27
+
28
+ # Converts the object into a valid query string parameter for use in
29
+ # a request to Delivery. The key, operator, and values are all escaped
30
+ # and if there are multiple values, they are joined with commas.
31
+ #
32
+ # * *Returns*:
33
+ # - +string+ A query string parameter without any additional characters (e.g. '&')
34
+ def provide_query_string_parameter
35
+ escaped_values = []
36
+ @values.each { |n| escaped_values << CGI.escape(n.to_s) }
37
+ if @eq_sign
38
+ format(
39
+ '%<k>s%<o>s=%<v>s',
40
+ k: CGI.escape(key),
41
+ o: CGI.escape(@operator),
42
+ v: escaped_values.join(SEPARATOR)
43
+ )
44
+ else
45
+ format(
46
+ '%<k>s%<o>s',
47
+ k: CGI.escape(key),
48
+ o: CGI.escape(@operator)
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,78 @@
1
+ require 'delivery/query_parameters/parameter_base'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module QueryParameters
7
+ # Represents the entire query string for a request to Delivery.
8
+ class QueryString
9
+ def initialize
10
+ @params = []
11
+ end
12
+
13
+ # Adds a parameter to the query string
14
+ #
15
+ # * *Args*:
16
+ # - *param* (+Object+) Either a string representing the key for the parameter, or a complete Kontent::Ai::Delivery::QueryParameters::ParameterBase object
17
+ # - *values* (+string+) A string or array of strings representing the values for the parameter
18
+ # - *operator* (+string+) Kontent.ai filtering parameter, placed after the key, before the equal sign
19
+ def set_param(param, values = '', operator = '')
20
+ parameter_base =
21
+ if param.is_a? String
22
+ Kontent::Ai::Delivery::QueryParameters::ParameterBase.new(
23
+ param,
24
+ operator,
25
+ values
26
+ )
27
+ else
28
+ param
29
+ end
30
+ # Ensure we have a ParameterBase object
31
+ return unless parameter_base.respond_to? 'provide_query_string_parameter'
32
+
33
+ remove_param parameter_base.key
34
+ @params << parameter_base
35
+ end
36
+
37
+ # Removes all parameters from the query string with a matching key.
38
+ #
39
+ # * *Args*:
40
+ # - *key* (+string+) Parameter key
41
+ def remove_param(key)
42
+ @params.delete_if { |i| i.key.eql? key }
43
+ end
44
+
45
+ # Returns all parameters from the query string with a matching key.
46
+ #
47
+ # * *Args*:
48
+ # - *key* (+string+) Parameter key
49
+ #
50
+ # * *Returns*:
51
+ # - +Object+ One or more Kontent::Ai::Delivery::QueryParameters::ParameterBase objects
52
+ def param(key)
53
+ @params.select { |p| p.key.eql? key }
54
+ end
55
+
56
+ # Checks whether there are any parameters defined.
57
+ #
58
+ # * *Returns*:
59
+ # - +bool+ True if there are no parameters set.
60
+ def empty?
61
+ @params.empty?
62
+ end
63
+
64
+ # Generates a full query string based on the set parameters, with the
65
+ # required '?' character at the start. Accomplished by calling the
66
+ # Kontent::Ai::Delivery::QueryParameters::ParameterBase.provide_query_string_parameter
67
+ # method for each parameter.
68
+ #
69
+ # * *Returns*:
70
+ # - +string+ A complete query string
71
+ def to_s
72
+ '?' + @params.map(&:provide_query_string_parameter).join('&')
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,102 @@
1
+ require 'nokogiri'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module Resolvers
7
+ # Locates <a data-item-id=""> tags in content and calls a user-defined method
8
+ # to supply the href for content item links.
9
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#resolving-links
10
+ class ContentLinkResolver
11
+ # Constructor.
12
+ #
13
+ # * *Args*:
14
+ # - *found_handler* (+lambda+) _optional_ Method to be called when resolving a content link and the content item is present in the response
15
+ # - *not_found_handler* (+lambda+) _optional_ Method to be called when resolving a content link and the content item isn't present in the response
16
+ def initialize(found_handler = nil, not_found_handler = nil)
17
+ @found_handler = found_handler
18
+ @not_found = not_found_handler
19
+ end
20
+
21
+ # Resolves all links in the content.
22
+ #
23
+ # * *Args*:
24
+ # - *content* (+string+) The string value stored in the element
25
+ # - *links* (+Array+) The collection of links from an element's 'links' JSON node
26
+ #
27
+ # * *Returns*:
28
+ # - +string+ The original content passed, with all links resolved
29
+ def resolve(content, links)
30
+ doc = Nokogiri::HTML.parse(content).xpath('//body')
31
+ links = links.map { |link| ContentLink.new link }
32
+ tags = doc.xpath('//a[@data-item-id]')
33
+ # This line performs the link resolving and replaces the tags in doc
34
+ tags.map { |tag| resolve_tag tag, links }
35
+ doc.to_xhtml
36
+ end
37
+
38
+ private
39
+
40
+ # Accepts a tag found in the content and tries to locate matching
41
+ # source link from JSON response. If found, resolves URL and returns
42
+ # the tag with generated HREF.
43
+ #
44
+ # * *Args*:
45
+ # - *tag* (+string+) A <a data-item-id=""> tag found in the content
46
+ # - *links* (+Array+) The collection of links from an element's 'links' JSON node, converted to Kontent::Ai::Delivery::Resolvers::ContentLink objects
47
+ #
48
+ # * *Returns*:
49
+ # - +string+ The <a data-item-id=""> tag with an HREF generated by the +provide_url+ method
50
+ def resolve_tag(tag, links)
51
+ matches = links.select { |link| link.id == tag['data-item-id'].to_s }
52
+ url = provide_url matches, tag['data-item-id']
53
+ tag['href'] = url
54
+ tag
55
+ end
56
+
57
+ # Uses the +resolve_link+ method to generate a URL for a ContentLink
58
+ # object, or +resolve_404+ if the content item was not present in the
59
+ # response.
60
+ #
61
+ # * *Args*:
62
+ # - *matches* (+Array+) The ContentLink objects with an ID matching a particular <a data-item-id=""> tag
63
+ # - *id* (+string+) The ID of the <a data-item-id=""> tag being resolved
64
+ #
65
+ # * *Returns*:
66
+ # - +string+ A url to the item or 404 page
67
+ def provide_url(matches, id)
68
+ if matches.empty?
69
+ if @not_found_handler.nil?
70
+ resolve_404 id
71
+ else
72
+ @not_found_handler.call id
73
+ end
74
+ else
75
+ if @found_handler.nil?
76
+ resolve_link matches[0]
77
+ else
78
+ @found_handler.call matches[0]
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ # Model for links from the JSON response
85
+ class ContentLink
86
+ attr_accessor :code_name, :type, :url_slug, :id
87
+
88
+ # Constructor.
89
+ #
90
+ # * *Args*:
91
+ # - *link* (+JSON+) One link from an element's 'links' JSON node
92
+ def initialize(link)
93
+ self.id = link[0]
94
+ self.code_name = link[1]['codename']
95
+ self.type = link[1]['type']
96
+ self.url_slug = link[1]['url_slug']
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,75 @@
1
+ require 'nokogiri'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module Resolvers
7
+ # Locates <object data-type="item"> tags in content and calls a user-defined
8
+ # method to supply the output for the content item.
9
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#resolving-inline-content
10
+ class InlineContentItemResolver
11
+ def initialize(callback = nil)
12
+ @callback = callback
13
+ end
14
+
15
+ # Resolves all inline content items in the content.
16
+ #
17
+ # * *Args*:
18
+ # - *content* (+string+) The string value stored in the element
19
+ # - *inline_items* (+Array+) ContentItems referenced by the content from the 'modular_content' JSON node
20
+ #
21
+ # * *Returns*:
22
+ # - +string+ The original content passed, with all <object data-type="item"> replaced with custom output
23
+ def resolve(content, inline_items)
24
+ doc = Nokogiri::HTML.parse(content).xpath('//body')
25
+ tags = doc.xpath('//object[@type="application/kenticocloud"][@data-type="item"]')
26
+ tags.each do |tag|
27
+ output = resolve_tag tag, inline_items
28
+ el = doc.at_xpath(
29
+ '//object[@type="application/kenticocloud"][@data-type="item"][@data-codename=$value]',
30
+ nil,
31
+ value: tag['data-codename']
32
+ )
33
+ el.swap(output) unless output.nil?
34
+ end
35
+ doc.inner_html
36
+ end
37
+
38
+ private
39
+
40
+ # Accepts a tag found in the content and tries to locate matching
41
+ # ContentItem from JSON response.
42
+ #
43
+ # * *Args*:
44
+ # - *tag* (+string+) A <object data-type="item"> tag found in the content
45
+ # - *inline_items* (+Array+) ContentItems referenced by the content from the 'modular_content' JSON node
46
+ #
47
+ # * *Returns*:
48
+ # - +string+ The custom output generated by the +provide_output+ method
49
+ def resolve_tag(tag, inline_items)
50
+ matches = inline_items.select { |item| item.system.codename == tag['data-codename'].to_s }
51
+ provide_output matches
52
+ end
53
+
54
+ # Generates custom output for a content item using the +resolve_item+
55
+ # method.
56
+ #
57
+ # * *Args*:
58
+ # - *matches* (+Array+) The ContentItems from the 'modular_content' JSON node which match the code name of a particular <object data-type="item"> tag
59
+ #
60
+ # * *Returns*:
61
+ # - +string+ The custom output generated by the +resolve_item+ method
62
+ def provide_output(matches)
63
+ if !matches.empty?
64
+ if @callback.nil?
65
+ resolve_item matches[0]
66
+ else
67
+ @callback.call matches[0]
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,43 @@
1
+ module Kontent
2
+ module Ai
3
+ module Delivery
4
+ module Resolvers
5
+ # Resolves a content item by its codename. It contains the modular content
6
+ # of item/items response.
7
+ class LinkedItemResolver
8
+ def initialize(modular_content, content_link_url_resolver, inline_content_item_resolver)
9
+ @modular_content = modular_content
10
+ @content_link_url_resolver = content_link_url_resolver
11
+ @inline_content_item_resolver = inline_content_item_resolver
12
+ @resolved_items = {}
13
+ end
14
+
15
+ # Resolves a content item. If the link for a codename was resolved
16
+ # before, it returns the same instance of ContentItem.
17
+ #
18
+ # * *Args*:
19
+ # - *codename* (+string+) Codename of the content item
20
+ #
21
+ # * *Return*:
22
+ # - Kontent::Ai::Delivery::ContentItem
23
+ def resolve(codename)
24
+ @resolved_items[codename] ||= resolve_item(codename)
25
+ end
26
+
27
+ private
28
+
29
+ def resolve_item(codename)
30
+ item = @modular_content.values.find { |i| i['system']['codename'] == codename }
31
+ unless item.nil?
32
+ return ContentItem.new(JSON.parse(JSON.generate(item)),
33
+ @content_link_url_resolver,
34
+ @inline_content_item_resolver,
35
+ self)
36
+ end
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,34 @@
1
+ require 'delivery/responses/response_base'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module Responses
7
+ # The response of a successful query of a content type's element
8
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#retrieving-content-type-elements
9
+ class DeliveryElementResponse < ResponseBase
10
+ # An element's definition from a
11
+ # Kontent::Ai::Delivery::DeliveryClient.element call
12
+ #
13
+ # * *Returns*:
14
+ # - +OpenStruct+ The element of a content item
15
+ def element
16
+ @element unless @element.nil?
17
+ @element = JSON.parse(
18
+ JSON.generate(@response),
19
+ object_class: OpenStruct
20
+ )
21
+ end
22
+
23
+ def initialize(headers, body)
24
+ @response = JSON.parse(body)
25
+ super 200,
26
+ "Success, '#{element.codename}' returned",
27
+ headers,
28
+ JSON.generate(@response)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ require 'delivery/models/content_item'
2
+ require 'delivery/models/pagination'
3
+ require 'delivery/responses/response_base'
4
+
5
+ module Kontent
6
+ module Ai
7
+ module Delivery
8
+ module Responses
9
+ # The response of a successful query for content items.
10
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#listing-items
11
+ class DeliveryItemListingResponse < ResponseBase
12
+ # Parses the 'pagination' JSON node of the response.
13
+ #
14
+ # * *Returns*:
15
+ # - Kontent::Ai::Delivery::Pagination
16
+ def pagination
17
+ @pagination unless @pagination.nil?
18
+ @pagination = Pagination.new @response['pagination']
19
+ end
20
+
21
+ # A collection of Kontent::Ai::Delivery::ContentItem objects from
22
+ # a Kontent::Ai::Delivery::DeliveryClient.items call.
23
+ #
24
+ # * *Returns*:
25
+ # - +Array+ One or more Kontent::Ai::Delivery::ContentItem objects
26
+ def items
27
+ @items unless @items.nil?
28
+ linked_items_resolver = Kontent::Ai::Delivery::Resolvers::LinkedItemResolver.new @response['modular_content'], @content_link_url_resolver, @inline_content_item_resolver
29
+ items = []
30
+ @response['items'].each do |n|
31
+ items << Kontent::Ai::Delivery::ContentItem.new(
32
+ n,
33
+ @content_link_url_resolver,
34
+ @inline_content_item_resolver,
35
+ linked_items_resolver
36
+ )
37
+ end
38
+ @items = items
39
+ end
40
+
41
+ def initialize(headers, body, query)
42
+ @response = JSON.parse(body)
43
+ @content_link_url_resolver = query.content_link_url_resolver
44
+ @inline_content_item_resolver = query.inline_content_item_resolver
45
+ super 200,
46
+ "Success, #{items.length} items returned",
47
+ headers,
48
+ JSON.generate(@response)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end