kontent-delivery-sdk-ruby 2.0.19 → 2.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +21 -21
  3. data/README.md +583 -575
  4. data/bin/console +14 -14
  5. data/bin/setup +8 -8
  6. data/lib/delivery/builders/image_transformation_builder.rb +271 -271
  7. data/lib/delivery/builders/url_builder.rb +120 -120
  8. data/lib/delivery/client/delivery_client.rb +176 -176
  9. data/lib/delivery/client/delivery_query.rb +302 -302
  10. data/lib/delivery/client/request_manager.rb +125 -125
  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/pagination.rb +22 -22
  14. data/lib/delivery/models/taxonomy_group.rb +39 -39
  15. data/lib/delivery/query_parameters/filters.rb +201 -158
  16. data/lib/delivery/query_parameters/parameter_base.rb +56 -46
  17. data/lib/delivery/query_parameters/query_string.rb +78 -78
  18. data/lib/delivery/resolvers/content_link_resolver.rb +102 -102
  19. data/lib/delivery/resolvers/inline_content_item_resolver.rb +75 -75
  20. data/lib/delivery/resolvers/linked_item_resolver.rb +37 -37
  21. data/lib/delivery/responses/delivery_element_response.rb +34 -34
  22. data/lib/delivery/responses/delivery_item_listing_response.rb +54 -54
  23. data/lib/delivery/responses/delivery_item_response.rb +40 -40
  24. data/lib/delivery/responses/delivery_items_feed_response.rb +58 -58
  25. data/lib/delivery/responses/delivery_taxonomy_listing_response.rb +47 -47
  26. data/lib/delivery/responses/delivery_taxonomy_response.rb +33 -33
  27. data/lib/delivery/responses/delivery_type_listing_response.rb +46 -46
  28. data/lib/delivery/responses/delivery_type_response.rb +32 -32
  29. data/lib/delivery/responses/response_base.rb +39 -39
  30. data/lib/delivery/tests/401.json +5 -5
  31. data/lib/delivery/tests/429.json +4 -4
  32. data/lib/delivery/tests/fake_responder.rb +105 -110
  33. data/lib/delivery/tests/filtering/items_with_count.json +5385 -4986
  34. data/lib/delivery/tests/filtering/{pagination_about_us.json → pagination.json} +761 -646
  35. data/lib/delivery/tests/generic/items.json +5383 -4984
  36. data/lib/delivery/tests/generic/items/about_us.json +276 -227
  37. data/lib/delivery/tests/generic/items/aeropress_filters.json +155 -138
  38. data/lib/delivery/tests/generic/items/coffee_processing_techniques.json +565 -168
  39. data/lib/delivery/tests/generic/items/where_does_coffee_come_from_.json +517 -621
  40. data/lib/delivery/tests/generic/taxonomies.json +203 -126
  41. data/lib/delivery/tests/generic/types.json +836 -781
  42. data/lib/delivery/tests/generic/types/brewer/elements/product_status.json +5 -5
  43. data/lib/delivery/tests/items_feed/articles_feed_1.json +39 -39
  44. data/lib/delivery/tests/items_feed/articles_feed_2.json +78 -78
  45. data/lib/delivery/tests/items_feed/articles_feed_3.json +104 -104
  46. data/lib/kontent-delivery-sdk-ruby.rb +20 -20
  47. metadata +20 -24
  48. data/lib/delivery/tests/filtering/items_gt.json +0 -566
  49. data/lib/delivery/tests/filtering/multiple.json +0 -283
  50. data/lib/delivery/version.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82042f7b363a6d954d983e54e5209b3dcf27d0e3dcc9628f729b4f0e336e1ab6
4
- data.tar.gz: 337c570cf56a893240ad80175515de15ac4939722a5b8aa8d1b8f1d2091de2b0
3
+ metadata.gz: af3dcd9bd3ea7acae77b689d726beeb55f6956e82c77cebe84c18d0ef3ffb2a7
4
+ data.tar.gz: dd48c610c1366536ce9a643ae441446c4bb77059b904cbd0b96909b012ab93a3
5
5
  SHA512:
6
- metadata.gz: d8868b9d56da54b7e1fe0d0f5bc94cf90d4d755d0a8ffddc10cd1c4ab8fb695ecfb1f77d09068b67ddfe0fe4041a557690773deda9f156cb810b308060773855
7
- data.tar.gz: aac1c71a914f6b65cf1eb273976364d37d6a76dea54f4500bb322afa4bf7803103c5f7f17c9bd2aa22376597819923ae9c164a174441974aee00a3f00af660e1
6
+ metadata.gz: f7fa9688e3f1a456afee73041d40a11bf7be713a1dd44d01e07ba00abd96901781b33d9547859b4634049d3fe1afafb4908e3281de3aa54e3ca5f2d8843f2d5a
7
+ data.tar.gz: 2813f8cedba1c23a362b8cf030ce730f073fe1335f3587ba31585c89d765d1cb0deb40648d9cd879349655d018f130a24c5574f5d0fad855f74e577ee5c7a533
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,575 +1,583 @@
1
- [![Build Status](https://api.travis-ci.com/Kentico/kontent-delivery-sdk-ruby.svg?branch=master)](https://travis-ci.com/Kentico/kontent-delivery-sdk-ruby)
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
- [![Maintainability](https://api.codeclimate.com/v1/badges/c83f2067f9cae9bde737/maintainability)](https://codeclimate.com/github/Kentico/kontent-delivery-sdk-ruby/maintainability)
6
- [![Test Coverage](https://api.codeclimate.com/v1/badges/c83f2067f9cae9bde737/test_coverage)](https://codeclimate.com/github/Kentico/kontent-delivery-sdk-ruby/test_coverage)
7
-
8
- # Delivery Ruby SDK
9
-
10
- ![Banner](https://github.com/Kentico/kontent-delivery-sdk-ruby/blob/master/banner.png)
11
-
12
- 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.
13
-
14
- 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.
15
-
16
-
17
- ## Demo Rails application
18
-
19
- This repository contains a very basic Rails application that you can run locally to see how the SDK can be used. To run the Dancing Goat demo application, clone this repository and open `/dancing_goat/app/controllers/application_controller.rb`. Add your project ID to the file here:
20
-
21
- ```ruby
22
- class ApplicationController < ActionController::Base
23
- PROJECT_ID = '<your-project-id>'.freeze
24
- ```
25
-
26
- If you don't have the sample project installed in Kentico Kontent, you can [generate a new sample project](https://docs.kontent.ai/tutorials/set-up-projects/manage-projects/managing-projects#a-creating-a-sample-project). Save the file, then open a terminal in the `/dancing_goat` directory and run the following commands:
27
-
28
- ```
29
- bundle install
30
- rails server
31
- ```
32
-
33
- The site should be accessible at localhost:3000. You can also follow a step-by-step guide to creating a basic Rails application on the [Kentico Kontent Blog](https://kontent.ai/blog/creating-a-kentico-cloud-ruby-on-rails-application).
34
-
35
- ## Installation
36
-
37
- To use the SDK in your own project, add the gem to your Gemfile:
38
-
39
- ```ruby
40
- gem 'kontent-delivery-sdk-ruby'
41
- ```
42
-
43
- Then run `bundle install`. You can also download the gem from [RubyGems.org](https://rubygems.org/gems/delivery-sdk-ruby). To use the SDK in an `.rb` file, you need to require it:
44
-
45
- ```ruby
46
- require 'kontent-delivery-sdk-ruby'
47
- ```
48
-
49
- ## Creating a client
50
-
51
- You will use `Kentico::Kontent::Delivery::DeliveryClient` to obtain content from Kentico Kontent. Create an instance of the client and pass your project ID:
52
-
53
- ```ruby
54
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
55
- ```
56
-
57
- :gem: **Pro tip:** You can alias namespaces to make them shorter, e.g.
58
-
59
- ```ruby
60
- KK = Kentico::Kontent::Delivery
61
- delivery_client = KK::DeliveryClient.new project_id: '<your-project-id>'
62
- ```
63
-
64
- ### Previewing unpublished content
65
-
66
- 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:
67
-
68
- ```ruby
69
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
70
- preview_key: '<your-preview-key>'
71
- ```
72
-
73
- 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:
74
-
75
- ```ruby
76
- # For all queries created by client
77
- delivery_client.use_preview = false
78
-
79
- # Per-query
80
- query = delivery_client.items
81
- query.use_preview = false
82
- query.execute do |response|
83
- # Do something
84
- end
85
- ```
86
-
87
- ### Making secure requests
88
-
89
- 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:
90
-
91
- ```ruby
92
- Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
93
- secure_key: '<your-secure-key>'
94
- ```
95
-
96
- 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.
97
-
98
- ### Retry policy
99
-
100
- 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:
101
-
102
- * 408 - `RequestTimeout`
103
- * 429 - `TooManyRequests`
104
- * 500 - `InternalServerError`
105
- * 502 - `BadGateway`
106
- * 503 - `ServiceUnavailable`
107
- * 504 - `GatewayTimeout`
108
-
109
- 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/).
110
-
111
- To disable the retry policy, you can use the `with_retry_policy` argument:
112
-
113
- ```ruby
114
- Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
115
- secure_key: '<your-secure-key>',
116
- with_retry_policy: false
117
- ```
118
-
119
- ## Listing items
120
-
121
-
122
- Use `.item` or `.items` to create a `Kentico::Kontent::Delivery::DeliveryQuery`, then call `.execute` to perform the request.
123
-
124
- ```ruby
125
- delivery_client.items.execute do |response|
126
- response.items.each do |item|
127
- # Do something
128
- end
129
- end
130
- ```
131
-
132
- You can also execute the query without a block and just get the response:
133
-
134
- ```ruby
135
- response = delivery_client.items.execute
136
- ```
137
-
138
- ### Filtering
139
-
140
- 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:
141
-
142
- |Method|Example|REST equivalent|
143
- |--|--|--|
144
- |all|`'elements.product_status'.all %w[bestseller on_sale]`|?elements.product_status[all]=bestseller,on_sale|
145
- |any|`'elements.processing'.any %w[dry__natural_ semi_dry]`|?elements.processing[any]=dry__natural_,semi_dry|
146
- |contains|`'elements.related_articles'.contains 'on_roasts'`|?elements.related_articles[contains]=on_roasts|
147
- |eq|`'system.type'.eq 'grinder'`|?system.type=grinder|
148
- |gt|`'elements.price'.gt 20`|?elements.price[gt]=20|
149
- |gt_or_eq|`'elements.price'.gt_or_eq 20`|?elements.price[gte]=20|
150
- |in|`'system.type'.in %w[coffee brewer]`|?system.type[in]=coffee,brewer|
151
- |lt|`'elements.price'.lt 20`|?elements.price[lt]=20|
152
- |lt_or_eq|`'elements.price'.lt_or_eq 20`|?elements.price[lte]=20|
153
- |range|`'system.last_modified'.range %w[2018-02-01 2018-03-31]`|?system.last_modified[range]=2018-02-01,2018-03-31|
154
-
155
- You can pass a single filter or multiple filters in the DeliveryClient methods. For example:
156
-
157
- ```ruby
158
- # Single filter
159
- delivery_client.items('elements.price'.gt 20)
160
-
161
- # Multiple filters
162
- delivery_client.items [
163
- ('elements.price'.gt 20),
164
- ('system.type'.eq 'grinder')
165
- ]
166
- ```
167
-
168
- ### Parameters
169
-
170
- 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:
171
-
172
- |Method|Example|REST equivalent
173
- |--|--|--|
174
- |[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]
175
- |[skip](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "skip")|`skip 5`|?skip=5
176
- |[limit](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "limit")|`limit 5`|?limit=5
177
- |[elements](https://docs.kontent.ai/reference/delivery-api#tag/Projection "elements")|`elements %w[price product_name image]`|?elements=price,product_name,image
178
- |[depth](https://docs.kontent.ai/reference/delivery-api#tag/Linked-content-and-components/linked-content-depth "depth")|`depth 0`|?depth=0
179
- |[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
180
-
181
- For example:
182
-
183
- ```ruby
184
- delivery_client.items('system.type'.eq 'coffee')
185
- .depth(0)
186
- .limit(5)
187
- .elements(%W[price product_name])
188
- .execute do |response|
189
- # Do something
190
- end
191
- ```
192
-
193
- ### Responses
194
-
195
- All responses from the `.execute` method will be/extend the `Kentico::Kontent::Delivery::Responses::ResponseBase` class which contains the following attributes:
196
-
197
- - **http_code**: The HTTP status code of the response
198
- - **headers**: The headers of the response
199
- - **json**: The full JSON body of the response
200
-
201
- You can check the response code to determine if the request was successful:
202
-
203
- ```ruby
204
- delivery_client.items.execute do |response|
205
- case response.http_code
206
- when 200
207
- # Success!
208
- when 401
209
- # Did you forget the secure key?
210
- else
211
- # to_s displays a friendly message with details of the response
212
- puts response.to_s
213
- end
214
- end
215
- ```
216
-
217
- 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.
218
-
219
- 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:
220
-
221
- ```ruby
222
- price = response.item.elements.price.value
223
- ```
224
-
225
- ### Requesting the latest content
226
-
227
- 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.
228
-
229
- You can check the headers of the response for the **X-Stale-Content** header to check if the response was served from cache:
230
-
231
- ```ruby
232
- delivery_client.item('about_us').execute do |response|
233
- if response.headers[:x_stale_content].eq 1
234
- ## Content is stale
235
- end
236
- end
237
- ```
238
-
239
- You can bypass the cache and get the latest content using `request_latest_content`
240
-
241
- ```ruby
242
- delivery_client.item('about_us')
243
- .request_latest_content
244
- .execute
245
- ```
246
-
247
- ### Providing custom headers
248
-
249
- 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.
250
-
251
- 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.
252
-
253
- ```ruby
254
- delivery_client.items
255
- .custom_headers({ 'MY-HEADER' => 'HEADER VALUE' })
256
- .execute
257
- ```
258
-
259
- ### Custom URLs
260
-
261
- 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:
262
-
263
- ```ruby
264
- delivery_client.items
265
- .url('https://deliver.kontent.ai/<your-project-id>/items?system.type=grinder')
266
- .execute do |response|
267
- # Do something
268
- end
269
- ```
270
-
271
- ### Assets
272
-
273
- 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:
274
-
275
- ```ruby
276
- url = response.item.get_assets('teaser_image').first.url
277
- ```
278
-
279
- ### Linked items
280
-
281
- You can get a simple array of code names by accessing the element's value:
282
-
283
- ```ruby
284
- links = response.item.elements.facts.value
285
- ```
286
-
287
- The `.get_links(element)` method will return an array of ContentItems instead:
288
-
289
- ```ruby
290
- response.item.get_links('facts').each do |link|
291
- title = link.elements.title.value
292
- end
293
- ```
294
-
295
- ### Pagination
296
-
297
- The `DeliveryItemListingResponse` also contains 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:
298
-
299
- - **skip**
300
- - **limit**
301
- - **count**
302
- - **next_page**
303
- - **total_count** (only if `include_total_count` is called)
304
-
305
- For example, to access the next page URL you can use:
306
-
307
- ```ruby
308
- delivery_client.items
309
- .skip(0)
310
- .limit(5)
311
- .include_total_count
312
- .execute do |response|
313
- next_page_url = response.pagination.next_page
314
- end
315
- ```
316
-
317
- :warning: Note that using the `include_total_count` method may increase the response time and should only be used if necessary.
318
-
319
- ## Items feed
320
-
321
- 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.
322
-
323
- 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)
324
-
325
- Below is an example that will load all content items of a project into a single array:
326
-
327
- ```ruby
328
- result = delivery_client.items_feed.execute
329
- items = result.items
330
- if result.more_results?
331
- loop do
332
- result = result.next_result
333
- items.push *result.items
334
- break unless result.more_results?
335
- end
336
- end
337
- ```
338
-
339
- ## Retrieving content types
340
-
341
- You can use the `.type` and `.types` methods to request your content types from Kentico Kontent:
342
-
343
- ```ruby
344
- delivery_client.types.execute do |response|
345
- # Do something
346
- end
347
- delivery_client.type('coffee').execute do |response|
348
- # Do something
349
- end
350
- ```
351
-
352
- ### Responses
353
-
354
- 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.
355
-
356
- 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:
357
-
358
- ```ruby
359
- delivery_client.type('coffee').execute do |response|
360
- field_type = response.type.elements.product_status.type # taxonomy
361
- end
362
- ```
363
- The DeliveryTypeListingResponse also contains pagination data, similar to DeliveryItemListingResponse.
364
-
365
- ## Taxonomy
366
-
367
- Use the `.taxonomies` and `.taxonomy(code_name)` endpoints to get information about the taxonomy in your project:
368
-
369
- ```ruby
370
- # Get all taxonomies
371
- delivery_client.taxonomies.execute do |response|
372
- response.taxonomies.each do |tax|
373
- puts "#{tax.system.name} (#{tax.terms.length})"
374
- end
375
- end
376
-
377
- # Get terms of specific taxonomy
378
- delivery_client.taxonomy('personas').execute do |response|
379
- puts response.taxonomy.terms.length
380
- end
381
- ```
382
-
383
- 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.
384
-
385
- 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:
386
-
387
- ```ruby
388
- taxonomy_group.terms[0].codename
389
- ```
390
-
391
- 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:
392
-
393
- - Coffee expert
394
- - Barista
395
- - Cafe owner
396
- - Coffee enthusiast
397
- - Coffee lover
398
- - Coffee blogger
399
-
400
- To get the code name of the first term under the "Coffee expert" term, you could do this:
401
-
402
- ```ruby
403
- delivery_client.taxonomy('personas').execute do |response|
404
- puts response.taxonomy.terms[0].terms[0].codename
405
- end
406
- ```
407
-
408
- ## Retrieving content type elements
409
-
410
- 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:
411
-
412
- ```ruby
413
- delivery_client.element('brewer', 'product_status').execute do |response|
414
- puts response.element.type # taxonomy
415
- end
416
- ```
417
-
418
- 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.
419
-
420
- 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.
421
-
422
- ## Resolving links
423
-
424
- 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:
425
-
426
- ```ruby
427
- link_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
428
- # Link valid
429
- return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
430
- return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
431
- end, lambda do |id|
432
- # Link broken
433
- return "/notfound?id=#{id}"
434
- end)
435
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
436
- content_link_url_resolver: link_resolver
437
- ```
438
-
439
- 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`:
440
-
441
- ```ruby
442
- class MyLinkResolver < Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver
443
- def resolve_link(link)
444
- return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
445
- return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
446
- end
447
-
448
- def resolve_404(id)
449
- "/notfound?id=#{id}"
450
- end
451
- end
452
- ```
453
-
454
- Then create an object of this class when instantiating the DeliveryClient:
455
-
456
- ```ruby
457
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
458
- content_link_url_resolver: MyLinkResolver.new
459
- ```
460
-
461
- 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:
462
-
463
- ```ruby
464
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
465
- # Client doesn't use ContentLinkResolver, but query below will
466
- delivery_client.items
467
- .with_link_resolver MyLinkResolver.new
468
- ```
469
-
470
- The `ContentLink` object that is passed to your resolver contains the following attributes:
471
-
472
- - **id**: the system.id of the linked content item
473
- - **code_name**: the system.codename of the linked content item
474
- - **type**: the content type of the linked content item
475
- - **url_slug**: the URL slug of the linked content item, or nil if there is none
476
-
477
- To resolve links in rich text elements, you must retrieve the text using `get_string`:
478
-
479
- ```ruby
480
- item_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
481
- return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
482
- return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
483
- end)
484
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
485
- content_link_url_resolver: item_resolver
486
- delivery_client.item('coffee_processing_techniques').execute do |response|
487
- text = response.item.get_string 'body_copy'
488
- end
489
- ```
490
-
491
- ## Resolving inline content
492
-
493
- 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`:
494
-
495
- ```ruby
496
- item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
497
- return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
498
- return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
499
- end)
500
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
501
- inline_content_item_resolver: item_resolver
502
- ```
503
-
504
- 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:
505
-
506
- ```ruby
507
- class MyItemResolver < Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver
508
- def resolve_item(item)
509
- return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
510
- return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
511
- end
512
- end
513
- ```
514
-
515
- You can also set the inline content resolver per-query:
516
-
517
- ```ruby
518
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
519
- # Client doesn't use InlineContentItemResolver, but query below will
520
- delivery_client.items
521
- .with_inline_content_item_resolver MyItemResolver.new
522
- ```
523
-
524
- To resolve inline content in elements, you must call `get_string` similar to content item links:
525
-
526
- ```ruby
527
- item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
528
- return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
529
- end)
530
- delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: PROJECT_ID,
531
- inline_content_item_resolver: item_resolver
532
- delivery_client.item('our_brewers').execute do |response|
533
- text = response.item.get_string 'body_copy'
534
- end
535
- ```
536
-
537
- ## Image transformation
538
-
539
- 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:
540
-
541
- ```ruby
542
- url = response.item.get_assets('teaser_image').first.url
543
- url = Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder.transform(url)
544
- # methods...
545
- .url
546
- ```
547
-
548
- The available methods are:
549
-
550
- |Method|Possible values|REST example
551
- |--|--|--|
552
- |`.with_width`| positive integer, or float between 0 and 1| ?w=200
553
- |`.with_height`| positive integer, or float between 0 and 1| ?h=200
554
- |`.with_pixel_ratio`| float greater than 0 but less than 5| ?dpr=1.5
555
- |`.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
556
- |`.with_rect`| 4 integer values representing pixels or floats representing percentages|rect=100,100,0.7,0.7
557
- |`.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
558
- |`.with_background_color`| string containing 3, 4, 6, or 8 characters | ?bg=7A0099EE
559
- |`.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
560
- |`.with_quality`| integer between 1 to 100 | ?quality=50
561
- |`.with_lossless`| 'true', 'false', 0, or 1| ?lossless=1
562
- |`.with_auto_format_selection`| 'true', 'false', 0, or 1 | ?auto=format
563
-
564
- ## Feedback & Contributing
565
-
566
- 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.
567
-
568
- ## License
569
-
570
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
571
-
572
- ## Code of Conduct
573
-
574
- 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).
575
-
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
+ - [Listing items](#listing-items)
22
+ - [Filtering](#filtering)
23
+ - [Parameters](#parameters)
24
+ - [Responses](#responses)
25
+ - [Requesting the latest content](#requesting-the-latest-content)
26
+ - [Providing custom headers](#providing-custom-headers)
27
+ - [Custom URLs](#custom-urls)
28
+ - [Assets](#assets)
29
+ - [Linked items](#linked-items)
30
+ - [Pagination](#pagination)
31
+ - [Items feed](#items-feed)
32
+ - [Retrieving content types](#retrieving-content-types)
33
+ - [Taxonomy](#taxonomy)
34
+ - [Retrieving content type elements](#retrieving-content-type-elements)
35
+ - [Resolving links](#resolving-links)
36
+ - [Resolving inline content](#resolving-inline-content)
37
+ - [Image transformation](#image-transformation)
38
+
39
+ ## Installation
40
+
41
+ To use the SDK in your own project, add the gem to your Gemfile:
42
+
43
+ ```ruby
44
+ gem 'kontent-delivery-sdk-ruby'
45
+ ```
46
+
47
+ 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:
48
+
49
+ ```ruby
50
+ require 'kontent-delivery-sdk-ruby'
51
+ ```
52
+
53
+ ## Creating a client
54
+
55
+ You will use `Kentico::Kontent::Delivery::DeliveryClient` to obtain content from Kentico Kontent. Create an instance of the client and pass your project ID:
56
+
57
+ ```ruby
58
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
59
+ ```
60
+
61
+ :gem: **Pro tip:** You can alias namespaces to make them shorter, e.g.
62
+
63
+ ```ruby
64
+ KK = Kentico::Kontent::Delivery
65
+ delivery_client = KK::DeliveryClient.new project_id: '<your-project-id>'
66
+ ```
67
+
68
+ ### Previewing unpublished content
69
+
70
+ 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:
71
+
72
+ ```ruby
73
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
74
+ preview_key: '<your-preview-key>'
75
+ ```
76
+
77
+ 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:
78
+
79
+ ```ruby
80
+ # For all queries created by client
81
+ delivery_client.use_preview = false
82
+
83
+ # Per-query
84
+ query = delivery_client.items
85
+ query.use_preview = false
86
+ query.execute do |response|
87
+ # Do something
88
+ end
89
+ ```
90
+
91
+ ### Making secure requests
92
+
93
+ 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:
94
+
95
+ ```ruby
96
+ Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
97
+ secure_key: '<your-secure-key>'
98
+ ```
99
+
100
+ 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.
101
+
102
+ ### Retry policy
103
+
104
+ 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:
105
+
106
+ * 408 - `RequestTimeout`
107
+ * 429 - `TooManyRequests`
108
+ * 500 - `InternalServerError`
109
+ * 502 - `BadGateway`
110
+ * 503 - `ServiceUnavailable`
111
+ * 504 - `GatewayTimeout`
112
+
113
+ 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/).
114
+
115
+ To disable the retry policy, you can use the `with_retry_policy` argument:
116
+
117
+ ```ruby
118
+ Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
119
+ secure_key: '<your-secure-key>',
120
+ with_retry_policy: false
121
+ ```
122
+
123
+ ## Listing items
124
+
125
+
126
+ Use `.item` or `.items` to create a `Kentico::Kontent::Delivery::DeliveryQuery`, then call `.execute` to perform the request.
127
+
128
+ ```ruby
129
+ delivery_client.items.execute do |response|
130
+ response.items.each do |item|
131
+ # Do something
132
+ end
133
+ end
134
+ ```
135
+
136
+ You can also execute the query without a block and just get the response:
137
+
138
+ ```ruby
139
+ response = delivery_client.items.execute
140
+ ```
141
+
142
+ ### Filtering
143
+
144
+ 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:
145
+
146
+ |Method|Example|REST equivalent|
147
+ |--|--|--|
148
+ |all|`'elements.product_status'.all %w[bestseller on_sale]`|?elements.product_status[all]=bestseller,on_sale|
149
+ |any|`'elements.processing'.any %w[dry__natural_ semi_dry]`|?elements.processing[any]=dry__natural_,semi_dry|
150
+ |contains|`'elements.related_articles'.contains 'on_roasts'`|?elements.related_articles[contains]=on_roasts|
151
+ |eq|`'system.type'.eq 'grinder'`|?system.type=grinder|
152
+ |not_eq|`'elements.region'.not_eq 'USA'`|?elements.region[neq]=USA|
153
+ |gt|`'elements.price'.gt 20`|?elements.price[gt]=20|
154
+ |gt_or_eq|`'elements.price'.gt_or_eq 20`|?elements.price[gte]=20|
155
+ |in|`'system.type'.in %w[coffee brewer]`|?system.type[in]=coffee,brewer|
156
+ |not_in|`'elements.author'.not_in %w[mberry ericd anthonym]`|?elements.author[nin]=mberry,ericd,anthonym|
157
+ |lt|`'elements.price'.lt 20`|?elements.price[lt]=20|
158
+ |lt_or_eq|`'elements.price'.lt_or_eq 20`|?elements.price[lte]=20|
159
+ |range|`'system.last_modified'.range %w[2018-02-01 2018-03-31]`|?system.last_modified[range]=2018-02-01,2018-03-31|
160
+ |empty|`'elements.banned_reason'.empty`|?elements.banned_reason[empty]|
161
+ |not_empty|`'elements.status'.not_empty`|?elements.status[nempty]|
162
+
163
+ You can pass a single filter or multiple filters in the DeliveryClient methods. For example:
164
+
165
+ ```ruby
166
+ # Single filter
167
+ delivery_client.items('elements.price'.gt 20)
168
+
169
+ # Multiple filters
170
+ delivery_client.items [
171
+ ('elements.price'.gt 20),
172
+ ('system.type'.eq 'grinder')
173
+ ]
174
+ ```
175
+
176
+ ### Parameters
177
+
178
+ 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:
179
+
180
+ |Method|Example|REST equivalent
181
+ |--|--|--|
182
+ |[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]
183
+ |[skip](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "skip")|`skip 5`|?skip=5
184
+ |[limit](https://docs.kontent.ai/reference/delivery-api#operation/list-content-items "limit")|`limit 5`|?limit=5
185
+ |[elements](https://docs.kontent.ai/reference/delivery-api#tag/Projection "elements")|`elements %w[price product_name image]`|?elements=price,product_name,image
186
+ |[depth](https://docs.kontent.ai/reference/delivery-api#tag/Linked-content-and-components/linked-content-depth "depth")|`depth 0`|?depth=0
187
+ |[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
188
+
189
+ For example:
190
+
191
+ ```ruby
192
+ delivery_client.items('system.type'.eq 'coffee')
193
+ .depth(0)
194
+ .limit(5)
195
+ .elements(%W[price product_name])
196
+ .execute do |response|
197
+ # Do something
198
+ end
199
+ ```
200
+
201
+ ### Responses
202
+
203
+ All responses from the `.execute` method will be/extend the `Kentico::Kontent::Delivery::Responses::ResponseBase` class which contains the following attributes:
204
+
205
+ - **http_code**: The HTTP status code of the response
206
+ - **headers**: The headers of the response
207
+ - **json**: The full JSON body of the response
208
+
209
+ You can check the response code to determine if the request was successful:
210
+
211
+ ```ruby
212
+ delivery_client.items.execute do |response|
213
+ case response.http_code
214
+ when 200
215
+ # Success!
216
+ when 401
217
+ # Did you forget the secure key?
218
+ else
219
+ # to_s displays a friendly message with details of the response
220
+ puts response.to_s
221
+ end
222
+ end
223
+ ```
224
+
225
+ 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.
226
+
227
+ 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:
228
+
229
+ ```ruby
230
+ price = response.item.elements.price.value
231
+ ```
232
+
233
+ ### Requesting the latest content
234
+
235
+ 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.
236
+
237
+ You can check the headers of the response for the **X-Stale-Content** header to check if the response was served from cache:
238
+
239
+ ```ruby
240
+ delivery_client.item('about_us').execute do |response|
241
+ if response.headers[:x_stale_content].eq 1
242
+ ## Content is stale
243
+ end
244
+ end
245
+ ```
246
+
247
+ You can bypass the cache and get the latest content using `request_latest_content`
248
+
249
+ ```ruby
250
+ delivery_client.item('about_us')
251
+ .request_latest_content
252
+ .execute
253
+ ```
254
+
255
+ ### Providing custom headers
256
+
257
+ 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.
258
+
259
+ 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.
260
+
261
+ ```ruby
262
+ delivery_client.items
263
+ .custom_headers({ 'MY-HEADER' => 'HEADER VALUE' })
264
+ .execute
265
+ ```
266
+
267
+ ### Custom URLs
268
+
269
+ 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:
270
+
271
+ ```ruby
272
+ delivery_client.items
273
+ .url('https://deliver.kontent.ai/<your-project-id>/items?system.type=grinder')
274
+ .execute do |response|
275
+ # Do something
276
+ end
277
+ ```
278
+
279
+ ## Assets
280
+
281
+ 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:
282
+
283
+ ```ruby
284
+ url = response.item.get_assets('teaser_image').first.url
285
+ ```
286
+
287
+ ## Linked items
288
+
289
+ You can get a simple array of code names by accessing the element's value:
290
+
291
+ ```ruby
292
+ links = response.item.elements.facts.value
293
+ ```
294
+
295
+ The `.get_links(element)` method will return an array of ContentItems instead:
296
+
297
+ ```ruby
298
+ response.item.get_links('facts').each do |link|
299
+ title = link.elements.title.value
300
+ end
301
+ ```
302
+
303
+ ## Pagination
304
+
305
+ The `DeliveryItemListingResponse` also contains 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:
306
+
307
+ - **skip**
308
+ - **limit**
309
+ - **count**
310
+ - **next_page**
311
+ - **total_count** (only if `include_total_count` is called)
312
+
313
+ For example, to access the next page URL you can use:
314
+
315
+ ```ruby
316
+ delivery_client.items
317
+ .skip(0)
318
+ .limit(5)
319
+ .include_total_count
320
+ .execute do |response|
321
+ next_page_url = response.pagination.next_page
322
+ end
323
+ ```
324
+
325
+ :warning: Note that using the `include_total_count` method may increase the response time and should only be used if necessary.
326
+
327
+ ## Items feed
328
+
329
+ 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.
330
+
331
+ 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)
332
+
333
+ Below is an example that will load all content items of a project into a single array:
334
+
335
+ ```ruby
336
+ result = delivery_client.items_feed.execute
337
+ items = result.items
338
+ if result.more_results?
339
+ loop do
340
+ result = result.next_result
341
+ items.push *result.items
342
+ break unless result.more_results?
343
+ end
344
+ end
345
+ ```
346
+
347
+ ## Retrieving content types
348
+
349
+ You can use the `.type` and `.types` methods to request your content types from Kentico Kontent:
350
+
351
+ ```ruby
352
+ delivery_client.types.execute do |response|
353
+ # Do something
354
+ end
355
+ delivery_client.type('coffee').execute do |response|
356
+ # Do something
357
+ end
358
+ ```
359
+
360
+ ### Responses
361
+
362
+ 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.
363
+
364
+ 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:
365
+
366
+ ```ruby
367
+ delivery_client.type('coffee').execute do |response|
368
+ field_type = response.type.elements.product_status.type # taxonomy
369
+ end
370
+ ```
371
+ The DeliveryTypeListingResponse also contains pagination data, similar to DeliveryItemListingResponse.
372
+
373
+ ## Taxonomy
374
+
375
+ Use the `.taxonomies` and `.taxonomy(code_name)` endpoints to get information about the taxonomy in your project:
376
+
377
+ ```ruby
378
+ # Get all taxonomies
379
+ delivery_client.taxonomies.execute do |response|
380
+ response.taxonomies.each do |tax|
381
+ puts "#{tax.system.name} (#{tax.terms.length})"
382
+ end
383
+ end
384
+
385
+ # Get terms of specific taxonomy
386
+ delivery_client.taxonomy('personas').execute do |response|
387
+ puts response.taxonomy.terms.length
388
+ end
389
+ ```
390
+
391
+ 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.
392
+
393
+ 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:
394
+
395
+ ```ruby
396
+ taxonomy_group.terms[0].codename
397
+ ```
398
+
399
+ 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:
400
+
401
+ - Coffee expert
402
+ - Barista
403
+ - Cafe owner
404
+ - Coffee enthusiast
405
+ - Coffee lover
406
+ - Coffee blogger
407
+
408
+ To get the code name of the first term under the "Coffee expert" term, you could do this:
409
+
410
+ ```ruby
411
+ delivery_client.taxonomy('personas').execute do |response|
412
+ puts response.taxonomy.terms[0].terms[0].codename
413
+ end
414
+ ```
415
+
416
+ ## Retrieving content type elements
417
+
418
+ 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:
419
+
420
+ ```ruby
421
+ delivery_client.element('brewer', 'product_status').execute do |response|
422
+ puts response.element.type # taxonomy
423
+ end
424
+ ```
425
+
426
+ 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.
427
+
428
+ 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.
429
+
430
+ ## Resolving links
431
+
432
+ 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:
433
+
434
+ ```ruby
435
+ link_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
436
+ # Link valid
437
+ return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
438
+ return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
439
+ end, lambda do |id|
440
+ # Link broken
441
+ return "/notfound?id=#{id}"
442
+ end)
443
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
444
+ content_link_url_resolver: link_resolver
445
+ ```
446
+
447
+ 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`:
448
+
449
+ ```ruby
450
+ class MyLinkResolver < Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver
451
+ def resolve_link(link)
452
+ return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
453
+ return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
454
+ end
455
+
456
+ def resolve_404(id)
457
+ "/notfound?id=#{id}"
458
+ end
459
+ end
460
+ ```
461
+
462
+ Then create an object of this class when instantiating the DeliveryClient:
463
+
464
+ ```ruby
465
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
466
+ content_link_url_resolver: MyLinkResolver.new
467
+ ```
468
+
469
+ 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:
470
+
471
+ ```ruby
472
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
473
+ # Client doesn't use ContentLinkResolver, but query below will
474
+ delivery_client.items
475
+ .with_link_resolver MyLinkResolver.new
476
+ ```
477
+
478
+ The `ContentLink` object that is passed to your resolver contains the following attributes:
479
+
480
+ - **id**: the system.id of the linked content item
481
+ - **code_name**: the system.codename of the linked content item
482
+ - **type**: the content type of the linked content item
483
+ - **url_slug**: the URL slug of the linked content item, or nil if there is none
484
+
485
+ To resolve links in rich text elements, you must retrieve the text using `get_string`:
486
+
487
+ ```ruby
488
+ item_resolver = Kentico::Kontent::Delivery::Resolvers::ContentLinkResolver.new(lambda do |link|
489
+ return "/coffees/#{link.url_slug}" if link.type.eql? 'coffee'
490
+ return "/brewers/#{link.url_slug}" if link.type.eql? 'brewer'
491
+ end)
492
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
493
+ content_link_url_resolver: item_resolver
494
+ delivery_client.item('coffee_processing_techniques').execute do |response|
495
+ text = response.item.get_string 'body_copy'
496
+ end
497
+ ```
498
+
499
+ ## Resolving inline content
500
+
501
+ 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`:
502
+
503
+ ```ruby
504
+ item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
505
+ return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
506
+ return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
507
+ end)
508
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>',
509
+ inline_content_item_resolver: item_resolver
510
+ ```
511
+
512
+ 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:
513
+
514
+ ```ruby
515
+ class MyItemResolver < Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver
516
+ def resolve_item(item)
517
+ return "<h1>#{item.elements.zip_code.value}</h1>" if item.system.type.eql? 'cafe'
518
+ return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
519
+ end
520
+ end
521
+ ```
522
+
523
+ You can also set the inline content resolver per-query:
524
+
525
+ ```ruby
526
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<your-project-id>'
527
+ # Client doesn't use InlineContentItemResolver, but query below will
528
+ delivery_client.items
529
+ .with_inline_content_item_resolver MyItemResolver.new
530
+ ```
531
+
532
+ To resolve inline content in elements, you must call `get_string` similar to content item links:
533
+
534
+ ```ruby
535
+ item_resolver = Kentico::Kontent::Delivery::Resolvers::InlineContentItemResolver.new(lambda do |item|
536
+ return "<div>$#{item.elements.price.value}</div>" if item.system.type.eql? 'brewer'
537
+ end)
538
+ delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: PROJECT_ID,
539
+ inline_content_item_resolver: item_resolver
540
+ delivery_client.item('our_brewers').execute do |response|
541
+ text = response.item.get_string 'body_copy'
542
+ end
543
+ ```
544
+
545
+ ## Image transformation
546
+
547
+ 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:
548
+
549
+ ```ruby
550
+ url = response.item.get_assets('teaser_image').first.url
551
+ url = Kentico::Kontent::Delivery::Builders::ImageTransformationBuilder.transform(url)
552
+ # methods...
553
+ .url
554
+ ```
555
+
556
+ The available methods are:
557
+
558
+ |Method|Possible values|REST example
559
+ |--|--|--|
560
+ |`.with_width`| positive integer, or float between 0 and 1| ?w=200
561
+ |`.with_height`| positive integer, or float between 0 and 1| ?h=200
562
+ |`.with_pixel_ratio`| float greater than 0 but less than 5| ?dpr=1.5
563
+ |`.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
564
+ |`.with_rect`| 4 integer values representing pixels or floats representing percentages|rect=100,100,0.7,0.7
565
+ |`.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
566
+ |`.with_background_color`| string containing 3, 4, 6, or 8 characters | ?bg=7A0099EE
567
+ |`.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
568
+ |`.with_quality`| integer between 1 to 100 | ?quality=50
569
+ |`.with_lossless`| 'true', 'false', 0, or 1| ?lossless=1
570
+ |`.with_auto_format_selection`| 'true', 'false', 0, or 1 | ?auto=format
571
+
572
+ ## Feedback & Contributing
573
+
574
+ 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.
575
+
576
+ ## License
577
+
578
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
579
+
580
+ ## Code of Conduct
581
+
582
+ 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).
583
+