kontent-delivery-sdk-ruby 2.0.22 → 2.0.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +21 -21
  3. data/README.md +603 -602
  4. data/bin/console +14 -14
  5. data/bin/setup +8 -8
  6. data/lib/delivery/builders/image_transformation_builder.rb +272 -272
  7. data/lib/delivery/builders/url_builder.rb +123 -123
  8. data/lib/delivery/client/delivery_client.rb +184 -184
  9. data/lib/delivery/client/delivery_query.rb +302 -302
  10. data/lib/delivery/client/request_manager.rb +126 -127
  11. data/lib/delivery/models/content_item.rb +153 -153
  12. data/lib/delivery/models/content_type.rb +41 -41
  13. data/lib/delivery/models/language.rb +29 -29
  14. data/lib/delivery/models/pagination.rb +22 -22
  15. data/lib/delivery/models/taxonomy_group.rb +39 -39
  16. data/lib/delivery/query_parameters/filters.rb +201 -201
  17. data/lib/delivery/query_parameters/parameter_base.rb +56 -56
  18. data/lib/delivery/query_parameters/query_string.rb +78 -78
  19. data/lib/delivery/resolvers/content_link_resolver.rb +102 -102
  20. data/lib/delivery/resolvers/inline_content_item_resolver.rb +75 -75
  21. data/lib/delivery/resolvers/linked_item_resolver.rb +43 -37
  22. data/lib/delivery/responses/delivery_element_response.rb +34 -34
  23. data/lib/delivery/responses/delivery_item_listing_response.rb +54 -54
  24. data/lib/delivery/responses/delivery_item_response.rb +40 -40
  25. data/lib/delivery/responses/delivery_items_feed_response.rb +58 -58
  26. data/lib/delivery/responses/delivery_language_listing_response.rb +44 -44
  27. data/lib/delivery/responses/delivery_taxonomy_listing_response.rb +47 -47
  28. data/lib/delivery/responses/delivery_taxonomy_response.rb +33 -33
  29. data/lib/delivery/responses/delivery_type_listing_response.rb +46 -46
  30. data/lib/delivery/responses/delivery_type_response.rb +32 -32
  31. data/lib/delivery/responses/response_base.rb +39 -39
  32. data/lib/delivery/tests/401.json +5 -5
  33. data/lib/delivery/tests/429.json +4 -4
  34. data/lib/delivery/tests/fake_responder.rb +99 -105
  35. data/lib/delivery/tests/filtering/items_with_count.json +5384 -5384
  36. data/lib/delivery/tests/filtering/pagination.json +761 -761
  37. data/lib/delivery/tests/generic/items.json +5383 -5383
  38. data/lib/delivery/tests/generic/items/about_us.json +276 -276
  39. data/lib/delivery/tests/generic/items/aeropress_filters.json +155 -155
  40. data/lib/delivery/tests/generic/items/coffee_processing_techniques.json +565 -565
  41. data/lib/delivery/tests/generic/items/where_does_coffee_come_from_.json +598 -598
  42. data/lib/delivery/tests/generic/languages.json +23 -23
  43. data/lib/delivery/tests/generic/taxonomies.json +203 -203
  44. data/lib/delivery/tests/generic/taxonomies/manufacturer.json +29 -29
  45. data/lib/delivery/tests/generic/types.json +835 -835
  46. data/lib/delivery/tests/generic/types/brewer.json +88 -88
  47. data/lib/delivery/tests/generic/types/brewer/elements/product_status.json +5 -5
  48. data/lib/delivery/tests/items_feed/articles_feed_1.json +39 -39
  49. data/lib/delivery/tests/items_feed/articles_feed_2.json +78 -78
  50. data/lib/delivery/tests/items_feed/articles_feed_3.json +104 -104
  51. data/lib/kontent-delivery-sdk-ruby.rb +22 -22
  52. metadata +13 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b93d8bae053c876e19256fc6695fa2dd593dc9479f89da1ede61ec166316a0cb
4
- data.tar.gz: 21721f7c4105cc9c07e62009b01b5d380f485082d807a1337002d44eaebc52fc
3
+ metadata.gz: dac7b2b9ebb47487d7a22b37effbfa45a5d2c2ade128b62e409b827e93df3498
4
+ data.tar.gz: d0e7decff7b864069346fd3b48464acee148bf7b60768454bc37598f22cbb96a
5
5
  SHA512:
6
- metadata.gz: 8df410c1f68405b40824f82fe7ac866de358e8df90042419bc52406807bd89610adabdbd5dcaf8c4a9bf751bc56882ff670c2d4c704bd1bc5e21ee49bea8927a
7
- data.tar.gz: 15b2ebbe2e3a98b5a4f5e66e6d7af39c04c6db4d8652cd061f9bf9c0824c4dda87e522f4e7d4b812d2e84a378e9348e2a62c132018ad8032fb6b01b1801be750
6
+ metadata.gz: 28d17621f9ac8698148baff4a88810b67c5be9bcfe2f03d039e831a9a345ea18e436c78fe071277ce411a44d5c2789fbc4b7a40e3abcfdb6f79df852bd6900b3
7
+ data.tar.gz: 6aa573d2f9a2e8f3d49c5f30570bbfa288c57c973dd22ed1f6124cbfb7e3ae970921cc7f62ccf179e17043be05db29c05701689790205000c0338bcb511e7500
data/LICENSE.md CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2019 Eric Dugre
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Eric Dugre
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,602 +1,603 @@
1
- ![build](https://github.com/Kentico/kontent-delivery-sdk-ruby/actions/workflows/build.yml/badge.svg)
2
- [![Join the chat at https://kentico-community.slack.com](https://img.shields.io/badge/join-slack-E6186D.svg)](https://kentico-community.slack.com)
3
- [![Stack Overflow](https://img.shields.io/badge/Stack%20Overflow-ASK%20NOW-FE7A16.svg?logo=stackoverflow&logoColor=white)](https://stackoverflow.com/tags/kentico-kontent)
4
- [![Version](https://img.shields.io/gem/v/kontent-delivery-sdk-ruby.svg?style=flat)](https://rubygems.org/gems/kontent-delivery-sdk-ruby)
5
-
6
- # Delivery Ruby SDK
7
-
8
- ![Banner](/banner.png)
9
-
10
- The Delivery Ruby SDK can be used in Ruby/Rails projects to retrieve content from Kentico Kontent. This is a community project and not an official Kentico SDK. If you find a bug in the SDK or have a feature request, please submit a GitHub issue.
11
-
12
- See [How to setup a development environment on Windows](https://github.com/Kentico/kontent-delivery-sdk-ruby/wiki/How-to-setup-development-environment-on-Windows) for local development, and check out the [Kentico Kontent Blog](https://kontent.ai/blog/creating-a-kentico-cloud-ruby-on-rails-application) for a tutorial on creating a Rails application.
13
-
14
- ## Table of contents
15
-
16
- - [Installation](#installation)
17
- - [Creating a client](#creating-a-client)
18
- - [Previewing unpublished content](#previewing-unpublished-content)
19
- - [Making secure requests](#making-secure-requests)
20
- - [Retry policy](#retry-policy)
21
- - [Custom URLs](#custom-urls)
22
- - [Listing items](#listing-items)
23
- - [Filtering](#filtering)
24
- - [Parameters](#parameters)
25
- - [Responses](#responses)
26
- - [Requesting the latest content](#requesting-the-latest-content)
27
- - [Providing custom headers](#providing-custom-headers)
28
- - [Pagination](#pagination)
29
- - [Working with content items](#working-with-content-items)
30
- - [Assets](#assets)
31
- - [Linked items](#linked-items)
32
- - [Resolving inline content](#resolving-inline-content)
33
- - [Resolving links](#resolving-links)
34
- - [Items feed](#items-feed)
35
- - [Retrieving content types](#retrieving-content-types)
36
- - [Retrieving taxonomy](#retrieving-taxonomy)
37
- - [Retrieving content type elements](#retrieving-content-type-elements)
38
- - [Retrieving languages](#retrieving-languages)
39
- - [Image transformation](#image-transformation)
40
-
41
- ## Installation
42
-
43
- To use the SDK in your own project, add the gem to your Gemfile:
44
-
45
- ```ruby
46
- gem 'kontent-delivery-sdk-ruby'
47
- ```
48
-
49
- Then run `bundle install`. You can also download the gem from [RubyGems.org](https://rubygems.org/gems/kontent-delivery-sdk-ruby). To use the SDK in an `.rb` file, you need to require it:
50
-
51
- ```ruby
52
- require 'kontent-delivery-sdk-ruby'
53
- ```
54
-
55
- ## Creating a client
56
-
57
- You will use `Kentico::Kontent::Delivery::DeliveryClient` to obtain content from Kentico Kontent. Create an instance of the client and pass your project ID:
58
-
59
- ```ruby
60
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
61
- ```
62
-
63
- :gem: **Pro tip:** You can alias namespaces to make them shorter, e.g.
64
-
65
- ```ruby
66
- KK = Kentico::Kontent::Delivery
67
- delivery_client = KK::DeliveryClient.new project_id: '<your-project-id>'
68
- ```
69
-
70
- ### Previewing unpublished content
71
-
72
- To [enable preview](https://docs.kontent.ai/tutorials/develop-apps/get-content/configuring-preview-for-content-items "See how to configure your app and Kontent project to enable content preview"), pass the Preview API Key to the constructor:
73
-
74
- ```ruby
75
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
76
- preview_key: '<your-preview-key>'
77
- ```
78
-
79
- This enables preview, but you can toggle preview at any time by setting the `use_preview` attribute of `DeliveryClient` which is propagated to all queries created by the client, _or_ per-query by setting its `use_preview` attribute:
80
-
81
- ```ruby
82
- # For all queries created by client
83
- delivery_client.use_preview = false
84
-
85
- # Per-query
86
- query = delivery_client.items
87
- query.use_preview = false
88
- query.execute do |response|
89
- # Do something
90
- end
91
- ```
92
-
93
- ### Making secure requests
94
-
95
- If you've [secured access](https://docs.kontent.ai/tutorials/develop-apps/get-content/securing-public-access "See how to enable secured access for your Kontent project") to your project, you need to provide the `DeliveryClient` with either the primary or secondary key:
96
-
97
- ```ruby
98
- Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
99
- secure_key: '<your-secure-key>'
100
- ```
101
-
102
- You can then securely request published content in your project. Be sure to not expose the key if the file(s) it appears in are publicly available.
103
-
104
- ### Retry policy
105
-
106
- By default, the SDK uses a retry policy, asking for requested content again in case of an error. The default policy retries the HTTP request if the following status codes are returned:
107
-
108
- * 408 - `RequestTimeout`
109
- * 429 - `TooManyRequests`
110
- * 500 - `InternalServerError`
111
- * 502 - `BadGateway`
112
- * 503 - `ServiceUnavailable`
113
- * 504 - `GatewayTimeout`
114
-
115
- The SDK will perform a total of 6 attempts at a maximum of 30 seconds to retrieve content before returning a `ResponseBase` object containing the error. The consecutive attempts are delayed with [exponential backoff and jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/).
116
-
117
- To disable the retry policy, you can use the `with_retry_policy` argument:
118
-
119
- ```ruby
120
- Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
121
- secure_key: '<your-secure-key>',
122
- with_retry_policy: false
123
- ```
124
-
125
- ### Custom URLs
126
-
127
- When you have a URL (i.e. `next_page` for paging, for testing purposes, or if you prefer to build it on your own) and still want to leverage SDK functionality such as rich text resolving, use the .url method:
128
-
129
- ```ruby
130
- delivery_client.items
131
- .url('https://deliver.kontent.ai/<your-project-id>/items?system.type=grinder')
132
- .execute do |response|
133
- # Do something
134
- end
135
- ```
136
-
137
- ## Listing items
138
-
139
-
140
- Use `.item` or `.items` to create a `Kentico::Kontent::Delivery::DeliveryQuery`, then call `.execute` to perform the request.
141
-
142
- ```ruby
143
- delivery_client.items.execute do |response|
144
- response.items.each do |item|
145
- # Do something
146
- end
147
- end
148
- ```
149
-
150
- You can also execute the query without a block and just get the response:
151
-
152
- ```ruby
153
- response = delivery_client.items.execute
154
- ```
155
-
156
- ### Filtering
157
-
158
- You can use [filtering](https://docs.kontent.ai/reference/delivery-api#tag/Filtering-content "See content filtering options in Delivery API") to retrieve particular items. The filtering methods are applied directly to a string and the available methods are:
159
-
160
- |Method|Example|REST equivalent|
161
- |--|--|--|
162
- |all|`'elements.product_status'.all %w[bestseller on_sale]`|?elements.product_status[all]=bestseller,on_sale|
163
- |any|`'elements.processing'.any %w[dry__natural_ semi_dry]`|?elements.processing[any]=dry__natural_,semi_dry|
164
- |contains|`'elements.related_articles'.contains 'on_roasts'`|?elements.related_articles[contains]=on_roasts|
165
- |eq|`'system.type'.eq 'grinder'`|?system.type=grinder|
166
- |not_eq|`'elements.region'.not_eq 'USA'`|?elements.region[neq]=USA|
167
- |gt|`'elements.price'.gt 20`|?elements.price[gt]=20|
168
- |gt_or_eq|`'elements.price'.gt_or_eq 20`|?elements.price[gte]=20|
169
- |in|`'system.type'.in %w[coffee brewer]`|?system.type[in]=coffee,brewer|
170
- |not_in|`'elements.author'.not_in %w[mberry ericd anthonym]`|?elements.author[nin]=mberry,ericd,anthonym|
171
- |lt|`'elements.price'.lt 20`|?elements.price[lt]=20|
172
- |lt_or_eq|`'elements.price'.lt_or_eq 20`|?elements.price[lte]=20|
173
- |range|`'system.last_modified'.range %w[2018-02-01 2018-03-31]`|?system.last_modified[range]=2018-02-01,2018-03-31|
174
- |empty|`'elements.banned_reason'.empty`|?elements.banned_reason[empty]|
175
- |not_empty|`'elements.status'.not_empty`|?elements.status[nempty]|
176
-
177
- You can pass a single filter or multiple filters in the DeliveryClient methods. For example:
178
-
179
- ```ruby
180
- # Single filter
181
- delivery_client.items('elements.price'.gt 20)
182
-
183
- # Multiple filters
184
- delivery_client.items [
185
- ('elements.price'.gt 20),
186
- ('system.type'.eq 'grinder')
187
- ]
188
- ```
189
-
190
- ### Parameters
191
-
192
- The `.item` and `.items` methods return a `Kentico::Kontent::Delivery::DeliveryQuery` object which you can further configure before executing. The methods you can call are:
193
-
194
- |Method|Example|REST equivalent
195
- |--|--|--|
196
- |[order_by](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "order_by")|`order_by 'system.last_modified' '[desc]'`|?order=system.last_modified[desc]
197
- |[skip](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "skip")|`skip 5`|?skip=5
198
- |[limit](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "limit")|`limit 5`|?limit=5
199
- |[elements](https://docs.kontent.ai/reference/delivery-api#tag/Projection "elements")|`elements %w[price product_name image]`|?elements=price,product_name,image
200
- |[depth](https://docs.kontent.ai/reference/delivery-api#tag/Linked-content-and-components/linked-content-depth "depth")|`depth 0`|?depth=0
201
- |[language](https://docs.kontent.ai/tutorials/set-up-projects/set-up-languages/localization-in-kentico-kontent#a-understanding-language-fallbacks "language")|`language 'en'`|?language=en
202
-
203
- For example:
204
-
205
- ```ruby
206
- delivery_client.items('system.type'.eq 'coffee')
207
- .depth(0)
208
- .limit(5)
209
- .elements(%W[price product_name])
210
- .execute do |response|
211
- # Do something
212
- end
213
- ```
214
-
215
- ### Responses
216
-
217
- All responses from the `.execute` method will be/extend the `Kentico::Kontent::Delivery::Responses::ResponseBase` class which contains the following attributes:
218
-
219
- - **http_code**: The HTTP status code of the response
220
- - **headers**: The headers of the response
221
- - **json**: The full JSON body of the response
222
-
223
- You can check the response code to determine if the request was successful:
224
-
225
- ```ruby
226
- delivery_client.items.execute do |response|
227
- case response.http_code
228
- when 200
229
- # Success!
230
- when 401
231
- # Did you forget the secure key?
232
- else
233
- # to_s displays a friendly message with details of the response
234
- puts response.to_s
235
- end
236
- end
237
- ```
238
-
239
- For successful content item queries, you will get either `DeliveryItemResponse` for single item queries, or `DeliveryItemListingResponse` for multiple item queries. You can access the returned content item(s) at `.item` or `.items` respectively.
240
-
241
- The `ContentItem` object gives you access to all system elements and content type elements at the `.system` and `.elements` properies. These are dynamic objects, so you can simply type the name of the element you need:
242
-
243
- ```ruby
244
- price = response.item.elements.price.value
245
- ```
246
-
247
- ### Requesting the latest content
248
-
249
- Kentico caches content using Fastly, so requests made to Kentico Kontent may not be up-to-date. In some cases, such as when reacting to [webhook](https://docs.kontent.ai/tutorials/develop-apps/integrate/using-webhooks-for-automatic-updates) notifications, you might want to request the latest content from your Kentico Kontent project.
250
-
251
- You can check the headers of the response for the **X-Stale-Content** header to check if the response was served from cache:
252
-
253
- ```ruby
254
- delivery_client.item('about_us').execute do |response|
255
- if response.headers[:x_stale_content].eq 1
256
- ## Content is stale
257
- end
258
- end
259
- ```
260
-
261
- You can bypass the cache and get the latest content using `request_latest_content`
262
-
263
- ```ruby
264
- delivery_client.item('about_us')
265
- .request_latest_content
266
- .execute
267
- ```
268
-
269
- ### Providing custom headers
270
-
271
- If you want to pass custom headers in the request, you can use `custom_headers`. This could be useful when you are developing your package on top of the SDK.
272
-
273
- Note that you can not override internal headers such as `Authorization`. If headers with an existing key are passed into the method, they will be ignored.
274
-
275
- ```ruby
276
- delivery_client.items
277
- .custom_headers({ 'MY-HEADER' => 'HEADER VALUE' })
278
- .execute
279
- ```
280
-
281
- ### Pagination
282
-
283
- Most responses also contain a `pagination` attribute to access the [paging](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "paging") data for the Delivery query. This object contains the following attributes:
284
-
285
- - **skip**
286
- - **limit**
287
- - **count**
288
- - **next_page**
289
- - **total_count** (only if `include_total_count` is called)
290
-
291
- For example, to access the next page URL you can use:
292
-
293
- ```ruby
294
- delivery_client.items
295
- .skip(0)
296
- .limit(5)
297
- .include_total_count
298
- .execute do |response|
299
- next_page_url = response.pagination.next_page
300
- end
301
- ```
302
-
303
- :warning: Note that using the `include_total_count` method may increase the response time and should only be used if necessary.
304
-
305
- ## Working with content items
306
-
307
- ### Assets
308
-
309
- You can use `.get_assets(code_name)` to get one or more assets from the specified element. This method will always return an array, so use `.first` to get the first asset:
310
-
311
- ```ruby
312
- url = response.item.get_assets('teaser_image').first.url
313
- ```
314
-
315
- ### Linked items
316
-
317
- You can get a simple array of code names by accessing the element's value:
318
-
319
- ```ruby
320
- links = response.item.elements.facts.value
321
- ```
322
-
323
- The `.get_links(element)` method will return an array of ContentItems instead:
324
-
325
- ```ruby
326
- response.item.get_links('facts').each do |link|
327
- title = link.elements.title.value
328
- end
329
- ```
330
- ### Resolving inline content
331
-
332
- Existing content items can be inserted into a rich text element, or you can create new content items as components. You need to resolve these in your application just as with content links. You can register a resolver when you instantiate the client by passing it with the hash key `inline_content_item_resolver`:
333
-
334
- ```ruby
335
- item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
336
- return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
337
- return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
338
- end)
339
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
340
- inline_content_item_resolver: item_resolver
341
- ```
342
-
343
- The object passed to the resolving method is a complete ContentItem. Similar to content link resolvers, you can create your own class which extends `Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver` and implements the `resolve_item` method:
344
-
345
- ```ruby
346
- class MyItemResolver < Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver
347
- def resolve_item(item)
348
- return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
349
- return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
350
- end
351
- end
352
- ```
353
-
354
- You can also set the inline content resolver per-query:
355
-
356
- ```ruby
357
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
358
- # Client doesn't use InlineContentItemResolver, but query below will
359
- delivery_client.items
360
- .with_inline_content_item_resolver MyItemResolver.new
361
- ```
362
-
363
- To resolve inline content in elements, you must call `get_string` similar to content item links:
364
-
365
- ```ruby
366
- item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
367
- return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
368
- end)
369
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: PROJECT_ID,
370
- inline_content_item_resolver: item_resolver
371
- delivery_client.item('our_brewers').execute do |response|
372
- text = response.item.get_string 'body_copy'
373
- end
374
- ```
375
-
376
- ### Resolving links
377
-
378
- If a rich text element contains links to other content items, you will need to generate the URLs to those items. You can do this by registering a `Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver` when you instantiate the DeliveryClient. When you create a ContentLinkResolver, you must pass a method that will return the URL, and you may pass another method that will be called if the content contains a link, but the content item is not present in the response:
379
-
380
- ```ruby
381
- link_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
382
- # Link valid
383
- return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
384
- return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
385
- end, lambda do |id|
386
- # Link broken
387
- return "/notfound?id=#{id}"
388
- end)
389
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
390
- content_link_url_resolver: link_resolver
391
- ```
392
-
393
- You can also build the logic for your resolver in a separate class and register an instance of that class in the DeliveryClient. The class must extend `Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver` and contain a `resolve_link(link)` method, as well as the `resolve_404(id)` method for broken links. For example, you can create `MyLinkResolver.rb`:
394
-
395
- ```ruby
396
- class MyLinkResolver < Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver
397
- def resolve_link(link)
398
- return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
399
- return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
400
- end
401
-
402
- def resolve_404(id)
403
- "/notfound?id=#{id}"
404
- end
405
- end
406
- ```
407
-
408
- Then create an object of this class when instantiating the DeliveryClient:
409
-
410
- ```ruby
411
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
412
- content_link_url_resolver: MyLinkResolver.new
413
- ```
414
-
415
- You can pass a `ContentLinkResolver` to the DeliveryQuery instead of the client if you only want to resolve links for that query, or they should be resolved differently:
416
-
417
- ```ruby
418
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
419
- # Client doesn't use ContentLinkResolver, but query below will
420
- delivery_client.items
421
- .with_link_resolver MyLinkResolver.new
422
- ```
423
-
424
- The `ContentLink` object that is passed to your resolver contains the following attributes:
425
-
426
- - **id**: the system.id of the linked content item
427
- - **code_name**: the system.codename of the linked content item
428
- - **type**: the content type of the linked content item
429
- - **url_slug**: the URL slug of the linked content item, or nil if there is none
430
-
431
- To resolve links in rich text elements, you must retrieve the text using `get_string`:
432
-
433
- ```ruby
434
- item_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
435
- return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
436
- return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
437
- end)
438
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
439
- content_link_url_resolver: item_resolver
440
- delivery_client.item('coffee_processing_techniques').execute do |response|
441
- text = response.item.get_string 'body_copy'
442
- end
443
- ```
444
-
445
- ## Items feed
446
-
447
- Use the `items_feed` method to retrieve a dynamically paginated list of content items in your project. The result will have a `more_results?` method which indicates that more items can be retrieved from the feed, using the `next_result` method.
448
-
449
- This method accepts all [filtering](#filtering) and [parameters](https://github.com/Kentico/kontent-delivery-sdk-ruby#parameters) except _depth_, _skip_, and _limit_. You can read more about the /items-feed endpoint in the [Kontent documentation](https://docs.kontent.ai/reference/delivery-api#operation/enumerate-content-items)
450
-
451
- Below is an example that will load all content items of a project into a single array:
452
-
453
- ```ruby
454
- result = delivery_client.items_feed.execute
455
- items = result.items
456
- if result.more_results?
457
- loop do
458
- result = result.next_result
459
- items.push *result.items
460
- break unless result.more_results?
461
- end
462
- end
463
- ```
464
-
465
- ## Retrieving content types
466
-
467
- You can use the `.type` and `.types` methods to request your content types from Kentico Kontent:
468
-
469
- ```ruby
470
- delivery_client.types.execute do |response|
471
- # Do something
472
- end
473
- delivery_client.type('coffee').execute do |response|
474
- # Do something
475
- end
476
- ```
477
-
478
- As with content item queries, all content type queries will return a `Kentico::Kontent::Delivery::Responses::ResponseBase` of the class `DeliveryTypeResponse` or `DeliveryTypeListingResponse` for single and multiple type queries, respectively.
479
-
480
- For multiple type queries, you can access the array of `ContentType` objects at `.types`, and at `.type` for singe type queries. You can access information about the type(s) dynamically:
481
-
482
- ```ruby
483
- delivery_client.type('coffee').execute do |response|
484
- field_type = response.type.elements.product_status.type # taxonomy
485
- end
486
- ```
487
- The DeliveryTypeListingResponse also contains pagination data, similar to DeliveryItemListingResponse.
488
-
489
- ## Retrieving taxonomy
490
-
491
- Use the `.taxonomies` and `.taxonomy(code_name)` endpoints to get information about the taxonomy in your project:
492
-
493
- ```ruby
494
- # Get all taxonomies
495
- delivery_client.taxonomies.execute do |response|
496
- response.taxonomies.each do |tax|
497
- puts "#{tax.system.name} (#{tax.terms.length})"
498
- end
499
- end
500
-
501
- # Get terms of specific taxonomy
502
- delivery_client.taxonomy('personas').execute do |response|
503
- puts response.taxonomy.terms.length
504
- end
505
- ```
506
-
507
- Each response will return either a single `Kentico::Kontent::Delivery::TaxonomyGroup` or an array of groups. The taxonomy group(s) are accessible at `.taxonomy` and `.taxonomies` for single and multiple queries, respectively.
508
-
509
- The `TaxonomyGroup` object contains two attributes `.system` and `.terms` which are dynamic OStruct objects containing the same elements as a standard JSON reponse. For example, given a successful query you could access information about the first term of a group using:
510
-
511
- ```ruby
512
- taxonomy_group.terms[0].codename
513
- ```
514
-
515
- Note that the terms of a taxonomy group may also contain terms, for example in Dancing Goat's __Personas__ taxonomy group, which looks like this:
516
-
517
- - Coffee expert
518
- - Barista
519
- - Cafe owner
520
- - Coffee enthusiast
521
- - Coffee lover
522
- - Coffee blogger
523
-
524
- To get the code name of the first term under the "Coffee expert" term, you could do this:
525
-
526
- ```ruby
527
- delivery_client.taxonomy('personas').execute do |response|
528
- puts response.taxonomy.terms[0].terms[0].codename
529
- end
530
- ```
531
-
532
- ## Retrieving content type elements
533
-
534
- Kentico Kontent provides an [endpoint](https://docs.kontent.ai/reference/delivery-api#operation/retrieve-a-content-element) for obtaining details about a specific element of a content type. In the Ruby SDK, you can use the `.element` method:
535
-
536
- ```ruby
537
- delivery_client.element('brewer', 'product_status').execute do |response|
538
- puts response.element.type # taxonomy
539
- end
540
- ```
541
-
542
- This returns a `Kentico::Kontent::Delivery::Responses::DeliveryElementResponse` where the `element` attribute is a dynamic OStruct representation of the JSON response. This means that you can access any property of the element by simply typing the name as in the above example.
543
-
544
- The element will always contain __codename__, __type__, and __name__, but multiple choice elements will also contain __options__ and taxonomy elements will contain __taxonomy_group__. The Ruby SDK fully supports obtaining [custom elements](https://docs.kontent.ai/reference/custom-elements-js-api) using this approach and any other methods.
545
-
546
- ## Retrieving languages
547
-
548
- Use the `.languages` method to list all of the languages in the project:
549
-
550
- ```ruby
551
- delivery_client.languages.execute do |response|
552
- puts response.languages.length # number of languages
553
- end
554
- ```
555
-
556
- The response is a `Kentico::Kontent::Delivery::Responses::DeliveryLanguageListingResponse` where `languages` is an array of all langauges. You can access the system properties of each language as they are returned by Kontent:
557
-
558
- ```ruby
559
- delivery_client.languages.execute do |response|
560
- puts response.languages[0].system.codename # en-us
561
- end
562
- ```
563
-
564
- ## Image transformation
565
-
566
- When you've obtained the URL for an asset, you can use our [Image Transformation API](https://docs.kontent.ai/reference/image-transformation) to make on-the-fly modifications to the image. To do this, use the static `.transform` method of `Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder`, then call the transformation methods. When you're done, call the `.url` method to get the new URL:
567
-
568
- ```ruby
569
- url = response.item.get_assets('teaser_image').first.url
570
- url = Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder.transform(url)
571
- # methods...
572
- .url
573
- ```
574
-
575
- The available methods are:
576
-
577
- |Method|Possible values|REST example
578
- |--|--|--|
579
- |`.with_width`| positive integer, or float between 0 and 1| ?w=200
580
- |`.with_height`| positive integer, or float between 0 and 1| ?h=200
581
- |`.with_pixel_ratio`| float greater than 0 but less than 5| ?dpr=1.5
582
- |`.with_fit_mode`| constants available at `Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder` <ul><li>FITMODE_CROP</li><li>FITMODE_CLIP</li><li>FITMODE_SCALE</li></ul>| ?fit=crop
583
- |`.with_rect`| 4 integer values representing pixels or floats representing percentages|rect=100,100,0.7,0.7
584
- |`.with_focal_point`| 2 floats between 0 and 1 and one integer between 1 and 100| ?fp-x=0.2&fp-y=0.7&fp-z=5
585
- |`.with_background_color`| string containing 3, 4, 6, or 8 characters | ?bg=7A0099EE
586
- |`.with_output_format`| constants available at `Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder` <ul><li>FORMAT_GIF</li><li>FORMAT_PNG</li><li>FORMAT_PNG8</li><li>FORMAT_JPG</li><li>FORMAT_PJPG</li><li>FORMAT_WEBP</li></ul> | ?fm=webp
587
- |`.with_quality`| integer between 1 to 100 | ?quality=50
588
- |`.with_lossless`| 'true', 'false', 0, or 1| ?lossless=1
589
- |`.with_auto_format_selection`| 'true', 'false', 0, or 1 | ?auto=format
590
-
591
- ## Feedback & Contributing
592
-
593
- Check out the [contributing](https://github.com/Kentico/kontent-delivery-sdk-ruby/blob/master/CONTRIBUTING.md) page to see the best places to file issues, start discussions, and begin contributing.
594
-
595
- ## License
596
-
597
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
598
-
599
- ## Code of Conduct
600
-
601
- Everyone interacting in the Delivery project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Kentico/kontent-delivery-sdk-net/blob/master/CODE_OF_CONDUCT.md).
602
-
1
+ ![build](https://github.com/Kentico/kontent-delivery-sdk-ruby/actions/workflows/build.yml/badge.svg)
2
+ [![Join the chat at https://kentico-community.slack.com](https://img.shields.io/badge/join-slack-E6186D.svg)](https://kentico-community.slack.com)
3
+ [![Stack Overflow](https://img.shields.io/badge/Stack%20Overflow-ASK%20NOW-FE7A16.svg?logo=stackoverflow&logoColor=white)](https://stackoverflow.com/tags/kentico-kontent)
4
+ [![Version](https://img.shields.io/gem/v/kontent-delivery-sdk-ruby.svg?style=flat)](https://rubygems.org/gems/kontent-delivery-sdk-ruby)
5
+
6
+ # Delivery Ruby SDK
7
+
8
+ ![Banner](/banner.png)
9
+
10
+ The Delivery Ruby SDK can be used in Ruby/Rails projects to retrieve content from Kentico Kontent. This is a community project and not an official Kentico SDK. If you find a bug in the SDK or have a feature request, please submit a GitHub issue.
11
+
12
+ See [How to setup a development environment on Windows](https://github.com/Kentico/kontent-delivery-sdk-ruby/wiki/How-to-setup-development-environment-on-Windows) for local development, and check out the [Kentico Kontent Blog](https://kontent.ai/blog/creating-a-kentico-cloud-ruby-on-rails-application) for a tutorial on creating a Rails application.
13
+
14
+ ## Table of contents
15
+
16
+ - [Installation](#installation)
17
+ - [Creating a client](#creating-a-client)
18
+ - [Previewing unpublished content](#previewing-unpublished-content)
19
+ - [Making secure requests](#making-secure-requests)
20
+ - [Retry policy](#retry-policy)
21
+ - [Custom URLs](#custom-urls)
22
+ - [Listing items](#listing-items)
23
+ - [Filtering](#filtering)
24
+ - [Parameters](#parameters)
25
+ - [Responses](#responses)
26
+ - [Requesting the latest content](#requesting-the-latest-content)
27
+ - [Providing custom headers](#providing-custom-headers)
28
+ - [Pagination](#pagination)
29
+ - [Working with content items](#working-with-content-items)
30
+ - [Assets](#assets)
31
+ - [Linked items](#linked-items)
32
+ - [Resolving links](#resolving-links)
33
+ - [Resolving inline content](#resolving-inline-content)
34
+ - [Items feed](#items-feed)
35
+ - [Retrieving content types](#retrieving-content-types)
36
+ - [Retrieving taxonomy](#retrieving-taxonomy)
37
+ - [Retrieving content type elements](#retrieving-content-type-elements)
38
+ - [Retrieving languages](#retrieving-languages)
39
+ - [Image transformation](#image-transformation)
40
+
41
+ ## Installation
42
+
43
+ To use the SDK in your own project, add the gem to your Gemfile:
44
+
45
+ ```ruby
46
+ gem 'kontent-delivery-sdk-ruby'
47
+ ```
48
+
49
+ Then run `bundle install`. You can also download the gem from [RubyGems.org](https://rubygems.org/gems/kontent-delivery-sdk-ruby). To use the SDK in an `.rb` file, you need to require it:
50
+
51
+ ```ruby
52
+ require 'kontent-delivery-sdk-ruby'
53
+ ```
54
+
55
+ ## Creating a client
56
+
57
+ You will use `Kentico::Kontent::Delivery::DeliveryClient` to obtain content from Kentico Kontent. Create an instance of the client and pass your project ID:
58
+
59
+ ```ruby
60
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
61
+ ```
62
+
63
+ :gem: **Pro tip:** You can alias namespaces to make them shorter, e.g.
64
+
65
+ ```ruby
66
+ KK = Kentico::Kontent::Delivery
67
+ delivery_client = KK::DeliveryClient.new project_id: '<your-project-id>'
68
+ ```
69
+
70
+ ### Previewing unpublished content
71
+
72
+ To [enable preview](https://docs.kontent.ai/tutorials/develop-apps/get-content/configuring-preview-for-content-items "See how to configure your app and Kontent project to enable content preview"), pass the Preview API Key to the constructor:
73
+
74
+ ```ruby
75
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
76
+ preview_key: '<your-preview-key>'
77
+ ```
78
+
79
+ This enables preview, but you can toggle preview at any time by setting the `use_preview` attribute of `DeliveryClient` which is propagated to all queries created by the client, _or_ per-query by setting its `use_preview` attribute:
80
+
81
+ ```ruby
82
+ # For all queries created by client
83
+ delivery_client.use_preview = false
84
+
85
+ # Per-query
86
+ query = delivery_client.items
87
+ query.use_preview = false
88
+ query.execute do |response|
89
+ # Do something
90
+ end
91
+ ```
92
+
93
+ ### Making secure requests
94
+
95
+ If you've [secured access](https://docs.kontent.ai/tutorials/develop-apps/get-content/securing-public-access "See how to enable secured access for your Kontent project") to your project, you need to provide the `DeliveryClient` with either the primary or secondary key:
96
+
97
+ ```ruby
98
+ Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
99
+ secure_key: '<your-secure-key>'
100
+ ```
101
+
102
+ You can then securely request published content in your project. Be sure to not expose the key if the file(s) it appears in are publicly available.
103
+
104
+ ### Retry policy
105
+
106
+ By default, the SDK uses a retry policy, asking for requested content again in case of an error. The default policy retries the HTTP request if the following status codes are returned:
107
+
108
+ * 408 - `RequestTimeout`
109
+ * 429 - `TooManyRequests`
110
+ * 500 - `InternalServerError`
111
+ * 502 - `BadGateway`
112
+ * 503 - `ServiceUnavailable`
113
+ * 504 - `GatewayTimeout`
114
+
115
+ The SDK will perform a total of 6 attempts at a maximum of 30 seconds to retrieve content before returning a `ResponseBase` object containing the error. The consecutive attempts are delayed with [exponential backoff and jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/).
116
+
117
+ To disable the retry policy, you can use the `with_retry_policy` argument:
118
+
119
+ ```ruby
120
+ Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
121
+ secure_key: '<your-secure-key>',
122
+ with_retry_policy: false
123
+ ```
124
+
125
+ ### Custom URLs
126
+
127
+ When you have a URL (i.e. `next_page` for paging, for testing purposes, or if you prefer to build it on your own) and still want to leverage SDK functionality such as rich text resolving, use the .url method:
128
+
129
+ ```ruby
130
+ delivery_client.items
131
+ .url('https://deliver.kontent.ai/<your-project-id>/items?system.type=grinder')
132
+ .execute do |response|
133
+ # Do something
134
+ end
135
+ ```
136
+
137
+ ## Listing items
138
+
139
+
140
+ Use `.item` or `.items` to create a `Kentico::Kontent::Delivery::DeliveryQuery`, then call `.execute` to perform the request.
141
+
142
+ ```ruby
143
+ delivery_client.items.execute do |response|
144
+ response.items.each do |item|
145
+ # Do something
146
+ end
147
+ end
148
+ ```
149
+
150
+ You can also execute the query without a block and just get the response:
151
+
152
+ ```ruby
153
+ response = delivery_client.items.execute
154
+ ```
155
+
156
+ ### Filtering
157
+
158
+ You can use [filtering](https://docs.kontent.ai/reference/delivery-api#tag/Filtering-content "See content filtering options in Delivery API") to retrieve particular items. The filtering methods are applied directly to a string and the available methods are:
159
+
160
+ |Method|Example|REST equivalent|
161
+ |--|--|--|
162
+ |all|`'elements.product_status'.all %w[bestseller on_sale]`|?elements.product_status[all]=bestseller,on_sale|
163
+ |any|`'elements.processing'.any %w[dry__natural_ semi_dry]`|?elements.processing[any]=dry__natural_,semi_dry|
164
+ |contains|`'elements.related_articles'.contains 'on_roasts'`|?elements.related_articles[contains]=on_roasts|
165
+ |eq|`'system.type'.eq 'grinder'`|?system.type=grinder|
166
+ |not_eq|`'elements.region'.not_eq 'USA'`|?elements.region[neq]=USA|
167
+ |gt|`'elements.price'.gt 20`|?elements.price[gt]=20|
168
+ |gt_or_eq|`'elements.price'.gt_or_eq 20`|?elements.price[gte]=20|
169
+ |in|`'system.type'.in %w[coffee brewer]`|?system.type[in]=coffee,brewer|
170
+ |not_in|`'elements.author'.not_in %w[mberry ericd anthonym]`|?elements.author[nin]=mberry,ericd,anthonym|
171
+ |lt|`'elements.price'.lt 20`|?elements.price[lt]=20|
172
+ |lt_or_eq|`'elements.price'.lt_or_eq 20`|?elements.price[lte]=20|
173
+ |range|`'system.last_modified'.range %w[2018-02-01 2018-03-31]`|?system.last_modified[range]=2018-02-01,2018-03-31|
174
+ |empty|`'elements.banned_reason'.empty`|?elements.banned_reason[empty]|
175
+ |not_empty|`'elements.status'.not_empty`|?elements.status[nempty]|
176
+
177
+ You can pass a single filter or multiple filters in the DeliveryClient methods. For example:
178
+
179
+ ```ruby
180
+ # Single filter
181
+ delivery_client.items('elements.price'.gt 20)
182
+
183
+ # Multiple filters
184
+ delivery_client.items [
185
+ ('elements.price'.gt 20),
186
+ ('system.type'.eq 'grinder')
187
+ ]
188
+ ```
189
+
190
+ ### Parameters
191
+
192
+ The `.item` and `.items` methods return a `Kentico::Kontent::Delivery::DeliveryQuery` object which you can further configure before executing. The methods you can call are:
193
+
194
+ |Method|Example|REST equivalent
195
+ |--|--|--|
196
+ |[order_by](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "order_by")|`order_by 'system.last_modified' '[desc]'`|?order=system.last_modified[desc]
197
+ |[skip](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "skip")|`skip 5`|?skip=5
198
+ |[limit](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "limit")|`limit 5`|?limit=5
199
+ |[elements](https://docs.kontent.ai/reference/delivery-api#tag/Projection "elements")|`elements %w[price product_name image]`|?elements=price,product_name,image
200
+ |[depth](https://docs.kontent.ai/reference/delivery-api#tag/Linked-content-and-components/linked-content-depth "depth")|`depth 0`|?depth=0
201
+ |[language](https://docs.kontent.ai/tutorials/set-up-projects/set-up-languages/localization-in-kentico-kontent#a-understanding-language-fallbacks "language")|`language 'en'`|?language=en
202
+
203
+ For example:
204
+
205
+ ```ruby
206
+ delivery_client.items('system.type'.eq 'coffee')
207
+ .depth(0)
208
+ .limit(5)
209
+ .elements(%W[price product_name])
210
+ .execute do |response|
211
+ # Do something
212
+ end
213
+ ```
214
+
215
+ ### Responses
216
+
217
+ All responses from the `.execute` method will be/extend the `Kentico::Kontent::Delivery::Responses::ResponseBase` class which contains the following attributes:
218
+
219
+ - **http_code**: The HTTP status code of the response
220
+ - **headers**: The headers of the response
221
+ - **json**: The full JSON body of the response
222
+
223
+ You can check the response code to determine if the request was successful:
224
+
225
+ ```ruby
226
+ delivery_client.items.execute do |response|
227
+ case response.http_code
228
+ when 200
229
+ # Success!
230
+ when 401
231
+ # Did you forget the secure key?
232
+ else
233
+ # to_s displays a friendly message with details of the response
234
+ puts response.to_s
235
+ end
236
+ end
237
+ ```
238
+
239
+ For successful content item queries, you will get either `DeliveryItemResponse` for single item queries, or `DeliveryItemListingResponse` for multiple item queries. You can access the returned content item(s) at `.item` or `.items` respectively.
240
+
241
+ The `ContentItem` object gives you access to all system elements and content type elements at the `.system` and `.elements` properies. These are dynamic objects, so you can simply type the name of the element you need:
242
+
243
+ ```ruby
244
+ price = response.item.elements.price.value
245
+ ```
246
+
247
+ ### Requesting the latest content
248
+
249
+ Kentico caches content using Fastly, so requests made to Kentico Kontent may not be up-to-date. In some cases, such as when reacting to [webhook](https://docs.kontent.ai/tutorials/develop-apps/integrate/using-webhooks-for-automatic-updates) notifications, you might want to request the latest content from your Kentico Kontent project.
250
+
251
+ You can check the headers of the response for the **X-Stale-Content** header to check if the response was served from cache:
252
+
253
+ ```ruby
254
+ delivery_client.item('about_us').execute do |response|
255
+ if response.headers[:x_stale_content].eq 1
256
+ ## Content is stale
257
+ end
258
+ end
259
+ ```
260
+
261
+ You can bypass the cache and get the latest content using `request_latest_content`
262
+
263
+ ```ruby
264
+ delivery_client.item('about_us')
265
+ .request_latest_content
266
+ .execute
267
+ ```
268
+
269
+ ### Providing custom headers
270
+
271
+ If you want to pass custom headers in the request, you can use `custom_headers`. This could be useful when you are developing your package on top of the SDK.
272
+
273
+ Note that you can not override internal headers such as `Authorization`. If headers with an existing key are passed into the method, they will be ignored.
274
+
275
+ ```ruby
276
+ delivery_client.items
277
+ .custom_headers({ 'MY-HEADER' => 'HEADER VALUE' })
278
+ .execute
279
+ ```
280
+
281
+ ### Pagination
282
+
283
+ Most responses also contain a `pagination` attribute to access the [paging](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "paging") data for the Delivery query. This object contains the following attributes:
284
+
285
+ - **skip**
286
+ - **limit**
287
+ - **count**
288
+ - **next_page**
289
+ - **total_count** (only if `include_total_count` is called)
290
+
291
+ For example, to access the next page URL you can use:
292
+
293
+ ```ruby
294
+ delivery_client.items
295
+ .skip(0)
296
+ .limit(5)
297
+ .include_total_count
298
+ .execute do |response|
299
+ next_page_url = response.pagination.next_page
300
+ end
301
+ ```
302
+
303
+ :warning: Note that using the `include_total_count` method may increase the response time and should only be used if necessary.
304
+
305
+ ## Working with content items
306
+
307
+ ### Assets
308
+
309
+ You can use `.get_assets(code_name)` to get one or more assets from the specified element. This method will always return an array, so use `.first` to get the first asset:
310
+
311
+ ```ruby
312
+ url = response.item.get_assets('teaser_image').first.url
313
+ ```
314
+
315
+ ### Linked items
316
+
317
+ You can get a simple array of code names by accessing the element's value:
318
+
319
+ ```ruby
320
+ links = response.item.elements.facts.value
321
+ ```
322
+
323
+ The `.get_links(element)` method will return an array of ContentItems instead:
324
+
325
+ ```ruby
326
+ response.item.get_links('facts').each do |link|
327
+ title = link.elements.title.value
328
+ end
329
+ ```
330
+
331
+ ### Resolving links
332
+
333
+ If a rich text element contains links to other content items, you will need to generate the URLs to those items. You can do this by registering a `Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver` when you instantiate the DeliveryClient. When you create a ContentLinkResolver, you must pass a method that will return the URL, and you may pass another method that will be called if the content contains a link, but the content item is not present in the response:
334
+
335
+ ```ruby
336
+ link_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
337
+ # Link valid
338
+ return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
339
+ return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
340
+ end, lambda do |id|
341
+ # Link broken
342
+ return "/notfound?id=#{id}"
343
+ end)
344
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
345
+ content_link_url_resolver: link_resolver
346
+ ```
347
+
348
+ You can also build the logic for your resolver in a separate class and register an instance of that class in the DeliveryClient. The class must extend `Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver` and contain a `resolve_link(link)` method, as well as the `resolve_404(id)` method for broken links. For example, you can create `MyLinkResolver.rb`:
349
+
350
+ ```ruby
351
+ class MyLinkResolver < Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver
352
+ def resolve_link(link)
353
+ return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
354
+ return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
355
+ end
356
+
357
+ def resolve_404(id)
358
+ "/notfound?id=#{id}"
359
+ end
360
+ end
361
+ ```
362
+
363
+ Then create an object of this class when instantiating the DeliveryClient:
364
+
365
+ ```ruby
366
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
367
+ content_link_url_resolver: MyLinkResolver.new
368
+ ```
369
+
370
+ You can pass a `ContentLinkResolver` to the DeliveryQuery instead of the client if you only want to resolve links for that query, or they should be resolved differently:
371
+
372
+ ```ruby
373
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
374
+ # Client doesn't use ContentLinkResolver, but query below will
375
+ delivery_client.items
376
+ .with_link_resolver MyLinkResolver.new
377
+ ```
378
+
379
+ The `ContentLink` object that is passed to your resolver contains the following attributes:
380
+
381
+ - **id**: the system.id of the linked content item
382
+ - **code_name**: the system.codename of the linked content item
383
+ - **type**: the content type of the linked content item
384
+ - **url_slug**: the URL slug of the linked content item, or nil if there is none
385
+
386
+ To resolve links in rich text elements, you must retrieve the text using `get_string`:
387
+
388
+ ```ruby
389
+ item_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
390
+ return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
391
+ return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
392
+ end)
393
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
394
+ content_link_url_resolver: item_resolver
395
+ delivery_client.item('coffee_processing_techniques').execute do |response|
396
+ text = response.item.get_string 'body_copy'
397
+ end
398
+ ```
399
+
400
+ ### Resolving inline content
401
+
402
+ Existing content items can be inserted into a rich text element, or you can create new content items as components. You need to resolve these in your application just as with content links. You can register a resolver when you instantiate the client by passing it with the hash key `inline_content_item_resolver`:
403
+
404
+ ```ruby
405
+ item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
406
+ return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
407
+ return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
408
+ end)
409
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
410
+ inline_content_item_resolver: item_resolver
411
+ ```
412
+
413
+ The object passed to the resolving method is a complete ContentItem. Similar to content link resolvers, you can create your own class which extends `Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver` and implements the `resolve_item` method:
414
+
415
+ ```ruby
416
+ class MyItemResolver < Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver
417
+ def resolve_item(item)
418
+ return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
419
+ return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
420
+ end
421
+ end
422
+ ```
423
+
424
+ You can also set the inline content resolver per-query:
425
+
426
+ ```ruby
427
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
428
+ # Client doesn't use InlineContentItemResolver, but query below will
429
+ delivery_client.items
430
+ .with_inline_content_item_resolver MyItemResolver.new
431
+ ```
432
+
433
+ To resolve inline content in elements, you must call `get_string` similar to content item links:
434
+
435
+ ```ruby
436
+ item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
437
+ return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
438
+ end)
439
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: PROJECT_ID,
440
+ inline_content_item_resolver: item_resolver
441
+ delivery_client.item('our_brewers').execute do |response|
442
+ text = response.item.get_string 'body_copy'
443
+ end
444
+ ```
445
+
446
+ ## Items feed
447
+
448
+ Use the `items_feed` method to retrieve a dynamically paginated list of content items in your project. The result will have a `more_results?` method which indicates that more items can be retrieved from the feed, using the `next_result` method.
449
+
450
+ This method accepts all [filtering](#filtering) and [parameters](https://github.com/Kentico/kontent-delivery-sdk-ruby#parameters) except _depth_, _skip_, and _limit_. You can read more about the /items-feed endpoint in the [Kontent documentation](https://docs.kontent.ai/reference/delivery-api#operation/enumerate-content-items)
451
+
452
+ Below is an example that will load all content items of a project into a single array:
453
+
454
+ ```ruby
455
+ result = delivery_client.items_feed.execute
456
+ items = result.items
457
+ if result.more_results?
458
+ loop do
459
+ result = result.next_result
460
+ items.push *result.items
461
+ break unless result.more_results?
462
+ end
463
+ end
464
+ ```
465
+
466
+ ## Retrieving content types
467
+
468
+ You can use the `.type` and `.types` methods to request your content types from Kentico Kontent:
469
+
470
+ ```ruby
471
+ delivery_client.types.execute do |response|
472
+ # Do something
473
+ end
474
+ delivery_client.type('coffee').execute do |response|
475
+ # Do something
476
+ end
477
+ ```
478
+
479
+ As with content item queries, all content type queries will return a `Kentico::Kontent::Delivery::Responses::ResponseBase` of the class `DeliveryTypeResponse` or `DeliveryTypeListingResponse` for single and multiple type queries, respectively.
480
+
481
+ For multiple type queries, you can access the array of `ContentType` objects at `.types`, and at `.type` for singe type queries. You can access information about the type(s) dynamically:
482
+
483
+ ```ruby
484
+ delivery_client.type('coffee').execute do |response|
485
+ field_type = response.type.elements.product_status.type # taxonomy
486
+ end
487
+ ```
488
+ The DeliveryTypeListingResponse also contains pagination data, similar to DeliveryItemListingResponse.
489
+
490
+ ## Retrieving taxonomy
491
+
492
+ Use the `.taxonomies` and `.taxonomy(code_name)` endpoints to get information about the taxonomy in your project:
493
+
494
+ ```ruby
495
+ # Get all taxonomies
496
+ delivery_client.taxonomies.execute do |response|
497
+ response.taxonomies.each do |tax|
498
+ puts "#{tax.system.name} (#{tax.terms.length})"
499
+ end
500
+ end
501
+
502
+ # Get terms of specific taxonomy
503
+ delivery_client.taxonomy('personas').execute do |response|
504
+ puts response.taxonomy.terms.length
505
+ end
506
+ ```
507
+
508
+ Each response will return either a single `Kentico::Kontent::Delivery::TaxonomyGroup` or an array of groups. The taxonomy group(s) are accessible at `.taxonomy` and `.taxonomies` for single and multiple queries, respectively.
509
+
510
+ The `TaxonomyGroup` object contains two attributes `.system` and `.terms` which are dynamic OStruct objects containing the same elements as a standard JSON reponse. For example, given a successful query you could access information about the first term of a group using:
511
+
512
+ ```ruby
513
+ taxonomy_group.terms[0].codename
514
+ ```
515
+
516
+ Note that the terms of a taxonomy group may also contain terms, for example in Dancing Goat's __Personas__ taxonomy group, which looks like this:
517
+
518
+ - Coffee expert
519
+ - Barista
520
+ - Cafe owner
521
+ - Coffee enthusiast
522
+ - Coffee lover
523
+ - Coffee blogger
524
+
525
+ To get the code name of the first term under the "Coffee expert" term, you could do this:
526
+
527
+ ```ruby
528
+ delivery_client.taxonomy('personas').execute do |response|
529
+ puts response.taxonomy.terms[0].terms[0].codename
530
+ end
531
+ ```
532
+
533
+ ## Retrieving content type elements
534
+
535
+ Kentico Kontent provides an [endpoint](https://docs.kontent.ai/reference/delivery-api#operation/retrieve-a-content-element) for obtaining details about a specific element of a content type. In the Ruby SDK, you can use the `.element` method:
536
+
537
+ ```ruby
538
+ delivery_client.element('brewer', 'product_status').execute do |response|
539
+ puts response.element.type # taxonomy
540
+ end
541
+ ```
542
+
543
+ This returns a `Kentico::Kontent::Delivery::Responses::DeliveryElementResponse` where the `element` attribute is a dynamic OStruct representation of the JSON response. This means that you can access any property of the element by simply typing the name as in the above example.
544
+
545
+ The element will always contain __codename__, __type__, and __name__, but multiple choice elements will also contain __options__ and taxonomy elements will contain __taxonomy_group__. The Ruby SDK fully supports obtaining [custom elements](https://docs.kontent.ai/reference/custom-elements-js-api) using this approach and any other methods.
546
+
547
+ ## Retrieving languages
548
+
549
+ Use the `.languages` method to list all of the languages in the project:
550
+
551
+ ```ruby
552
+ delivery_client.languages.execute do |response|
553
+ puts response.languages.length # number of languages
554
+ end
555
+ ```
556
+
557
+ The response is a `Kentico::Kontent::Delivery::Responses::DeliveryLanguageListingResponse` where `languages` is an array of all langauges. You can access the system properties of each language as they are returned by Kontent:
558
+
559
+ ```ruby
560
+ delivery_client.languages.execute do |response|
561
+ puts response.languages[0].system.codename # en-us
562
+ end
563
+ ```
564
+
565
+ ## Image transformation
566
+
567
+ When you've obtained the URL for an asset, you can use our [Image Transformation API](https://docs.kontent.ai/reference/image-transformation) to make on-the-fly modifications to the image. To do this, use the static `.transform` method of `Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder`, then call the transformation methods. When you're done, call the `.url` method to get the new URL:
568
+
569
+ ```ruby
570
+ url = response.item.get_assets('teaser_image').first.url
571
+ url = Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder.transform(url)
572
+ # methods...
573
+ .url
574
+ ```
575
+
576
+ The available methods are:
577
+
578
+ |Method|Possible values|REST example
579
+ |--|--|--|
580
+ |`.with_width`| positive integer, or float between 0 and 1| ?w=200
581
+ |`.with_height`| positive integer, or float between 0 and 1| ?h=200
582
+ |`.with_pixel_ratio`| float greater than 0 but less than 5| ?dpr=1.5
583
+ |`.with_fit_mode`| constants available at `Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder` <ul><li>FITMODE_CROP</li><li>FITMODE_CLIP</li><li>FITMODE_SCALE</li></ul>| ?fit=crop
584
+ |`.with_rect`| 4 integer values representing pixels or floats representing percentages|rect=100,100,0.7,0.7
585
+ |`.with_focal_point`| 2 floats between 0 and 1 and one integer between 1 and 100| ?fp-x=0.2&fp-y=0.7&fp-z=5
586
+ |`.with_background_color`| string containing 3, 4, 6, or 8 characters | ?bg=7A0099EE
587
+ |`.with_output_format`| constants available at `Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder` <ul><li>FORMAT_GIF</li><li>FORMAT_PNG</li><li>FORMAT_PNG8</li><li>FORMAT_JPG</li><li>FORMAT_PJPG</li><li>FORMAT_WEBP</li></ul> | ?fm=webp
588
+ |`.with_quality`| integer between 1 to 100 | ?quality=50
589
+ |`.with_lossless`| 'true', 'false', 0, or 1| ?lossless=1
590
+ |`.with_auto_format_selection`| 'true', 'false', 0, or 1 | ?auto=format
591
+
592
+ ## Feedback & Contributing
593
+
594
+ Check out the [contributing](https://github.com/Kentico/kontent-delivery-sdk-ruby/blob/master/CONTRIBUTING.md) page to see the best places to file issues, start discussions, and begin contributing.
595
+
596
+ ## License
597
+
598
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
599
+
600
+ ## Code of Conduct
601
+
602
+ Everyone interacting in the Delivery project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Kentico/kontent-delivery-sdk-net/blob/master/CODE_OF_CONDUCT.md).
603
+