kontent-delivery-sdk-ruby 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +21 -0
  3. data/README.md +511 -0
  4. data/bin/console +14 -0
  5. data/bin/setup +8 -0
  6. data/lib/delivery/builders/image_transformation_builder.rb +271 -0
  7. data/lib/delivery/builders/url_builder.rb +117 -0
  8. data/lib/delivery/client/delivery_client.rb +155 -0
  9. data/lib/delivery/client/delivery_query.rb +249 -0
  10. data/lib/delivery/client/request_manager.rb +108 -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/pagination.rb +21 -0
  14. data/lib/delivery/models/taxonomy_group.rb +39 -0
  15. data/lib/delivery/query_parameters/filters.rb +158 -0
  16. data/lib/delivery/query_parameters/parameter_base.rb +44 -0
  17. data/lib/delivery/query_parameters/query_string.rb +78 -0
  18. data/lib/delivery/resolvers/content_link_resolver.rb +102 -0
  19. data/lib/delivery/resolvers/inline_content_item_resolver.rb +75 -0
  20. data/lib/delivery/resolvers/linked_item_resolver.rb +37 -0
  21. data/lib/delivery/responses/delivery_element_response.rb +33 -0
  22. data/lib/delivery/responses/delivery_item_listing_response.rb +53 -0
  23. data/lib/delivery/responses/delivery_item_response.rb +39 -0
  24. data/lib/delivery/responses/delivery_taxonomy_listing_response.rb +46 -0
  25. data/lib/delivery/responses/delivery_taxonomy_response.rb +32 -0
  26. data/lib/delivery/responses/delivery_type_listing_response.rb +45 -0
  27. data/lib/delivery/responses/delivery_type_response.rb +31 -0
  28. data/lib/delivery/responses/response_base.rb +36 -0
  29. data/lib/delivery/tests/401.json +6 -0
  30. data/lib/delivery/tests/fake_responder.rb +67 -0
  31. data/lib/delivery/tests/filtering/items_gt.json +566 -0
  32. data/lib/delivery/tests/filtering/multiple.json +283 -0
  33. data/lib/delivery/tests/filtering/pagination_about_us.json +647 -0
  34. data/lib/delivery/tests/generic/items.json +4985 -0
  35. data/lib/delivery/tests/generic/items/about_us.json +228 -0
  36. data/lib/delivery/tests/generic/items/aeropress_filters.json +139 -0
  37. data/lib/delivery/tests/generic/items/coffee_processing_techniques.json +169 -0
  38. data/lib/delivery/tests/generic/items/where_does_coffee_come_from_.json +621 -0
  39. data/lib/delivery/tests/generic/taxonomies.json +127 -0
  40. data/lib/delivery/tests/generic/types.json +781 -0
  41. data/lib/delivery/tests/generic/types/brewer/elements/product_status.json +6 -0
  42. data/lib/delivery/version.rb +7 -0
  43. data/lib/kontent-delivery-sdk-ruby.rb +19 -0
  44. metadata +200 -0
@@ -0,0 +1,41 @@
1
+ require 'ostruct'
2
+
3
+ module Kentico
4
+ module Kontent
5
+ module Delivery
6
+ class ContentType
7
+ # Parses the 'elements' JSON object as a dynamic OpenStruct object.
8
+ #
9
+ # * *Returns*:
10
+ # - +OpenStruct+ The elements of the content type
11
+ def elements
12
+ @elements unless @elements.nil?
13
+ @elements = JSON.parse(
14
+ JSON.generate(@source['elements']),
15
+ object_class: OpenStruct
16
+ )
17
+ end
18
+
19
+ # Parses the 'system' JSON object as a dynamic OpenStruct object.
20
+ #
21
+ # * *Returns*:
22
+ # - +OpenStruct+ The system properties of the content type
23
+ def system
24
+ @system unless @system.nil?
25
+ @system = JSON.parse(
26
+ JSON.generate(@source['system']),
27
+ object_class: OpenStruct
28
+ )
29
+ end
30
+
31
+ # Constructor.
32
+ #
33
+ # * *Args*:
34
+ # - *source* (+JSON+) The response from a REST request for content types
35
+ def initialize(source)
36
+ @source = source
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ module Kentico
2
+ module Kontent
3
+ module Delivery
4
+ # Holds pagination data from listing responses
5
+ class Pagination
6
+ attr_accessor :skip, :limit, :count, :next_page
7
+
8
+ # Constructor.
9
+ #
10
+ # * *Args*:
11
+ # - *json* (+JSON+) The 'pagination' node of a listing reponse's JSON object
12
+ def initialize(json)
13
+ self.skip = json['skip']
14
+ self.limit = json['limit']
15
+ self.count = json['count']
16
+ self.next_page = json['next_page']
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module Kentico
2
+ module Kontent
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,158 @@
1
+ require 'delivery/query_parameters/parameter_base'
2
+
3
+ module Kentico
4
+ module Kontent
5
+ module Delivery
6
+ module QueryParameters
7
+ # Provides the base class for filter implementations.
8
+ # See https://developer.kenticocloud.com/v1/reference#content-filtering
9
+ class Filter < ParameterBase
10
+ # Constructor.
11
+ #
12
+ # * *Args*:
13
+ # - *key* (+string+) The field to filter upon
14
+ # - *operator* (+string+) The Kentico Kontent 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
+ def initialize(key, operator, values)
17
+ super(key, operator, values)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ # Extend String class to allow semantic typing of filters
26
+ class String
27
+ # Represents a filter that matches a content item if the specified content
28
+ # element or system attribute has a value that contains all the specified
29
+ # values. This filter is applicable to array values only, such as sitemap
30
+ # location or value of Linked Items, Taxonomy and Multiple choice content elements.
31
+ #
32
+ # * *Args*:
33
+ # - +Object+ One or more objects representing the values that must appear in the field
34
+ #
35
+ # * *Returns*:
36
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
37
+ def all(*args)
38
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[all]', *args)
39
+ end
40
+
41
+ # Represents a filter that matches a content item if the specified content
42
+ # element or system attribute has a value that contains any the specified
43
+ # values. This filter is applicable to array values only, such as sitemap
44
+ # location or value of Linked Items, Taxonomy and Multiple choice content elements.
45
+ #
46
+ # * *Args*:
47
+ # - +Object+ One or more objects representing the values that may appear in the field
48
+ #
49
+ # * *Returns*:
50
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
51
+ def any(*args)
52
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[any]', *args)
53
+ end
54
+
55
+ # Represents a filter that matches a content item if the specified content element
56
+ # or system attribute has a value that contains the specified value.
57
+ # This filter is applicable to array values only, such as sitemap location or value
58
+ # of Linked Items, Taxonomy and Multiple choice content elements.
59
+ #
60
+ # * *Args*:
61
+ # - +Object+ An object representing the value that must appear in the field
62
+ #
63
+ # * *Returns*:
64
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
65
+ def contains(*args)
66
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[contains]', *args)
67
+ end
68
+
69
+ # Represents a filter that matches a content item if the specified
70
+ # content element or system attribute has the specified value.
71
+ #
72
+ # * *Args*:
73
+ # - +Object+ An object representing the value that must equal the value in the field
74
+ #
75
+ # * *Returns*:
76
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
77
+ def eq(*args)
78
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '', *args)
79
+ end
80
+
81
+ # Represents a filter that matches a content item if the specified content
82
+ # element or system attribute has a value that is greater than the
83
+ # specified value.
84
+ #
85
+ # * *Args*:
86
+ # - +Object+ An object representing the lowest possible value of the field, non-inclusive
87
+ #
88
+ # * *Returns*:
89
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
90
+ def gt(*args)
91
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[gt]', *args)
92
+ end
93
+
94
+ # Represents a filter that matches a content item if the specified content
95
+ # element or system attribute has a value that is greater than or equal to
96
+ # the specified value.
97
+ #
98
+ # * *Args*:
99
+ # - +Object+ An object representing the lowest possible value of the field
100
+ #
101
+ # * *Returns*:
102
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
103
+ def gt_or_eq(*args)
104
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[gte]', *args)
105
+ end
106
+
107
+ # Represents a filter that matches a content item if the specified
108
+ # content element or system attribute has a value that matches a
109
+ # value in the specified list.
110
+ #
111
+ # * *Args*:
112
+ # - +Object+ One or more objects representing the required values of the field
113
+ #
114
+ # * *Returns*:
115
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
116
+ def in(*args)
117
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[in]', *args)
118
+ end
119
+
120
+ # Represents a filter that matches a content item if the specified content
121
+ # element or system attribute has a value that is less than the
122
+ # specified value.
123
+ #
124
+ # * *Args*:
125
+ # - +Object+ An object representing the highest possible value of the field, non-inclusive
126
+ #
127
+ # * *Returns*:
128
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
129
+ def lt(*args)
130
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[lt]', *args)
131
+ end
132
+
133
+ # Represents a filter that matches a content item if the specified content
134
+ # element or system attribute has a value that is less than or equal to
135
+ # the specified value.
136
+ #
137
+ # * *Args*:
138
+ # - +Object+ An object representing the highest possible value of the field
139
+ #
140
+ # * *Returns*:
141
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
142
+ def lt_or_eq(*args)
143
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[lte]', *args)
144
+ end
145
+
146
+ # Represents a filter that matches a content item if the specified
147
+ # content element or system attribute has a value that falls within
148
+ # the specified range of values (both inclusive).
149
+ #
150
+ # * *Args*:
151
+ # - +Object+ An object representing the lowest and highest possible values of the field
152
+ #
153
+ # * *Returns*:
154
+ # - Kentico::Kontent::Delivery::QueryParameters::Filter
155
+ def range(*args)
156
+ Kentico::Kontent::Delivery::QueryParameters::Filter.new(self, '[range]', *args)
157
+ end
158
+ end
@@ -0,0 +1,44 @@
1
+ module Kentico
2
+ module Kontent
3
+ module Delivery
4
+ module QueryParameters
5
+ # Base class for all parameters added to a DeliveryQuery. All
6
+ # QueryParameters will appear in the query string.
7
+ class ParameterBase
8
+ attr_accessor :key
9
+ SEPARATOR = CGI.escape(',')
10
+
11
+ # Constructor.
12
+ #
13
+ # * *Args*:
14
+ # - *key* (+string+) The field to filter upon
15
+ # - *operator* (+string+) The Kentico Kontent filter being applied to the field, in brackets
16
+ # - *values* (+Object+) One or more values which will appear as the value of the query string parameter
17
+ def initialize(key, operator, values)
18
+ self.key = key
19
+ values = [values] unless values.respond_to? :each
20
+ @values = values
21
+ @operator = operator
22
+ end
23
+
24
+ # Converts the object into a valid query string parameter for use in
25
+ # a request to Delivery. The key, operator, and values are all escaped
26
+ # and if there are multiple values, they are joined with commas.
27
+ #
28
+ # * *Returns*:
29
+ # - +string+ A query string parameter without any additional characters (e.g. '&')
30
+ def provide_query_string_parameter
31
+ escaped_values = []
32
+ @values.each { |n| escaped_values << CGI.escape(n.to_s) }
33
+ format(
34
+ '%<k>s%<o>s=%<v>s',
35
+ k: CGI.escape(key),
36
+ o: CGI.escape(@operator),
37
+ v: escaped_values.join(SEPARATOR)
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,78 @@
1
+ require 'delivery/query_parameters/parameter_base'
2
+
3
+ module Kentico
4
+ module Kontent
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 Kentico::Kontent::Delivery::QueryParameters::ParameterBase object
17
+ # - *values* (+string+) A string or array of strings representing the values for the parameter
18
+ # - *operator* (+string+) Kentico Kontent 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
+ Kentico::Kontent::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 Kentico::Kontent::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
+ # Kentico::Kontent::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 Kentico
4
+ module Kontent
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/Kentico/kontent-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 Kentico::Kontent::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