wordpress_client 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +124 -69
  3. data/Changelog.md +4 -0
  4. data/README.md +36 -13
  5. data/lib/wordpress_client.rb +0 -3
  6. data/lib/wordpress_client/client.rb +20 -74
  7. data/lib/wordpress_client/connection.rb +9 -10
  8. data/lib/wordpress_client/media.rb +15 -1
  9. data/lib/wordpress_client/media_parser.rb +1 -0
  10. data/lib/wordpress_client/post.rb +16 -36
  11. data/lib/wordpress_client/post_parser.rb +9 -37
  12. data/lib/wordpress_client/term.rb +1 -1
  13. data/lib/wordpress_client/version.rb +1 -1
  14. data/spec/client_spec.rb +17 -181
  15. data/spec/connection_spec.rb +8 -11
  16. data/spec/docker/Dockerfile +8 -8
  17. data/spec/docker/README.md +19 -9
  18. data/spec/docker/dbdump.sql.gz +0 -0
  19. data/spec/docker/restore-dbdump.sh +2 -2
  20. data/spec/fixtures/post-with-metadata.json +99 -1
  21. data/spec/fixtures/simple-post.json +324 -1
  22. data/spec/integration/attachments_crud_spec.rb +1 -1
  23. data/spec/integration/posts_crud_spec.rb +1 -1
  24. data/spec/integration/posts_finding_spec.rb +0 -69
  25. data/spec/integration/posts_metadata_spec.rb +11 -11
  26. data/spec/integration/posts_with_attachments_spec.rb +20 -6
  27. data/spec/media_spec.rb +13 -0
  28. data/spec/post_spec.rb +5 -31
  29. data/spec/support/docker_runner.rb +25 -10
  30. data/spec/support/wordpress_server.rb +15 -7
  31. data/wordpress_client.gemspec +11 -12
  32. metadata +5 -15
  33. data/lib/wordpress_client/replace_metadata.rb +0 -82
  34. data/lib/wordpress_client/replace_terms.rb +0 -63
  35. data/spec/fixtures/post-with-forbidden-metadata.json +0 -1
  36. data/spec/integration/category_assignment_spec.rb +0 -29
  37. data/spec/integration/tag_assignment_spec.rb +0 -29
  38. data/spec/replace_metadata_spec.rb +0 -56
  39. data/spec/replace_terms_spec.rb +0 -51
@@ -1,3 +1,7 @@
1
+ # 2.0.0
2
+
3
+ * Switch from WP REST API plugin to native WP API in Wordpress 4.6+.
4
+
1
5
  # 1.0.1
2
6
 
3
7
  * Bugfixes for latest Wordpress
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # WordpressClient
2
2
 
3
- WordpressClient is a very simple client for the Wordpress [WP REST API plugin][api] (version 2 beta 8.0).
3
+ WordpressClient is a very simple client for the Wordpress [REST API][api].
4
4
 
5
5
  [![Circle CI](https://circleci.com/gh/hemnet/wordpress_client.svg?style=svg)](https://circleci.com/gh/hemnet/wordpress_client) [![Code Climate](https://codeclimate.com/repos/5645938269568041da00cded/badges/5e870b57428f23c1f2ff/gpa.svg)](https://codeclimate.com/repos/5645938269568041da00cded/feed) [![Test Coverage](https://codeclimate.com/repos/5645938269568041da00cded/badges/5e870b57428f23c1f2ff/coverage.svg)](https://codeclimate.com/repos/5645938269568041da00cded/coverage) [![Gem Version](https://badge.fury.io/rb/wordpress_client.svg)](https://badge.fury.io/rb/wordpress_client)[![Dependency Status](https://gemnasium.com/hemnet/wordpress_client.svg)](https://gemnasium.com/hemnet/wordpress_client)
6
6
 
@@ -8,17 +8,22 @@ WordpressClient is a very simple client for the Wordpress [WP REST API plugin][a
8
8
 
9
9
  **[Read the full API documentation][docs]**
10
10
 
11
- Initialize a client with a user name, password and API URL. You can then search for posts.
11
+ Initialize a client with a user name, password and API URL. You can then search
12
+ for posts.
12
13
 
13
14
  ```ruby
14
- client = WordpressClient.new(url: "https://example.com/wp-json/", username: "example", password: "example")
15
+ client = WordpressClient.new(
16
+ url: "https://example.com/wp-json/",
17
+ username: "example",
18
+ password: "example",
19
+ )
15
20
 
16
21
  client.posts(per_page: 5) # => [WordpressClient::Post, WordpressClient::Post]
17
22
  ```
18
23
 
19
24
  ### Creating a post
20
25
 
21
- You can create posts by calling `create_post`. If you supply a ID, the article will be created using `PUT` instead of `POST`.
26
+ You can create posts by calling `create_post`.
22
27
 
23
28
  ```ruby
24
29
  data = {
@@ -29,12 +34,13 @@ data = {
29
34
  post = client.create_post(data) # => WordpressClient::Post
30
35
  updated_post = client.update_post(post.id, title: "Updated") # => WordpressClient::Post
31
36
 
37
+ updated_post.author # => "Name"
32
38
  updated_post.title_html # => "Updated"
33
39
  ```
34
40
 
35
41
  ## Running tests
36
42
 
37
- You need to install Docker and set it up for your machine. Note that you need `docker-machine` to run Docker on OS X.
43
+ You need to install Docker and set it up for your machine.
38
44
 
39
45
  Run tests using the normal `rspec` command after installing all bundles.
40
46
 
@@ -42,7 +48,10 @@ Run tests using the normal `rspec` command after installing all bundles.
42
48
  bundle exec rspec
43
49
  ```
44
50
 
45
- You can also run `bundle exec guard` to have tests run automatically when you change files in the repo. If you tag your examples with `focus: true`, Guard will only run those tests. This can help when doing very focused coding, but remember to remove the filter before you commit and let the entire suite run.
51
+ You can also run `bundle exec guard` to have tests run automatically when you
52
+ change files in the repo. If you tag your examples with `focus: true`, Guard
53
+ will only run those tests. This can help when doing very focused coding, but
54
+ remember to remove the filter before you commit and let the entire suite run.
46
55
 
47
56
  ```ruby
48
57
  describe Foo, focus: true do
@@ -50,23 +59,37 @@ describe Foo, focus: true do
50
59
  end
51
60
  ```
52
61
 
53
- The normal `rspec` command will *not* use this filter in case it is ever committed accidentally, so CI can catch any problems.
62
+ The normal `rspec` command will *not* use this filter in case it is ever
63
+ committed accidentally, so CI can catch any problems.
54
64
 
55
65
  ## Releasing a new version
56
66
 
57
67
  The normal gem release cycle works using `rake release`.
58
68
 
59
- If you make changes to the docker image, you can release it using `rake docker:release`.
69
+ If you make changes to the docker image, you can release it using `rake
70
+ docker:release`.
60
71
 
61
72
  ## Copyright & License
62
73
 
63
- Copyright © 2015 Hemnet Service HNS AB
74
+ Copyright © 2015-2017 Hemnet Service HNS AB
64
75
 
65
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
76
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
77
+ this software and associated documentation files (the "Software"), to deal in
78
+ the Software without restriction, including without limitation the rights to
79
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
80
+ of the Software, and to permit persons to whom the Software is furnished to do
81
+ so, subject to the following conditions:
66
82
 
67
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
83
+ The above copyright notice and this permission notice shall be included in all
84
+ copies or substantial portions of the Software.
68
85
 
69
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
86
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
88
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
89
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
90
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
91
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
92
+ SOFTWARE.
70
93
 
71
- [api]: http://v2.wp-api.org/
94
+ [api]: https://developer.wordpress.org/rest-api/
72
95
  [docs]: http://www.rubydoc.info/gems/wordpress_client/
@@ -15,9 +15,6 @@ require "wordpress_client/post_parser"
15
15
  require "wordpress_client/media"
16
16
  require "wordpress_client/media_parser"
17
17
 
18
- require "wordpress_client/replace_terms"
19
- require "wordpress_client/replace_metadata"
20
-
21
18
  module WordpressClient
22
19
  # Initialize a new client using the provided connection details.
23
20
  # You need to provide authentication details, and the user must have +edit+
@@ -8,21 +8,20 @@ module WordpressClient
8
8
 
9
9
  # Find {Post Posts} matching given parameters.
10
10
  #
11
- # @example Finding 5 posts in the Important category
12
- # posts = client.posts(per_page: 5, category_slug: "important")
11
+ # @example Finding 5 posts
12
+ # posts = client.posts(per_page: 5)
13
13
  #
14
14
  # @param page [Fixnum] Current page for pagination. Defaults to 1.
15
15
  # @param per_page [Fixnum] Posts per page. Defaults to 10.
16
- # @param category_slug [String, nil] Find posts belonging to a category with the given slug.
17
- # @param tag_slug [String, nil] Find posts belonging to a tag with the given slug.
18
16
  #
19
17
  # @return {PaginatedCollection[Post]} Paginated collection of the found posts.
20
- def posts(per_page: 10, page: 1, category_slug: nil, tag_slug: nil)
21
- filter = {}
22
- filter[:category_name] = category_slug if category_slug
23
- filter[:tag] = tag_slug if tag_slug
18
+ def posts(per_page: 10, page: 1)
24
19
  connection.get_multiple(
25
- Post, "posts", per_page: per_page, page: page, _embed: nil, context: "edit", filter: filter
20
+ Post,
21
+ "posts",
22
+ per_page: per_page,
23
+ page: page,
24
+ _embed: nil,
26
25
  )
27
26
  end
28
27
 
@@ -32,23 +31,7 @@ module WordpressClient
32
31
  # @raise {NotFoundError}
33
32
  # @raise {subclasses of Error} on other unexpected errors
34
33
  def find_post(id)
35
- connection.get(Post, "posts/#{id.to_i}", _embed: nil, context: "edit")
36
- end
37
-
38
- # Find the first {Post} with the given slug, or raises an error if it cannot be found.
39
- #
40
- # @return {Post}
41
- # @raise {NotFoundError}
42
- # @raise {subclasses of Error} on other unexpected errors
43
- def find_post_by_slug(slug)
44
- posts = connection.get_multiple(
45
- Post, "posts", per_page: 1, page: 1, filter: {name: slug}, _embed: nil
46
- )
47
- if posts.size > 0
48
- posts.first
49
- else
50
- raise NotFoundError, "Could not find post with slug #{slug.to_s.inspect}"
51
- end
34
+ connection.get(Post, "posts/#{id.to_i}", _embed: nil)
52
35
  end
53
36
 
54
37
  # Create a new {Post} with the given attributes in Wordpress and return it.
@@ -73,18 +56,7 @@ module WordpressClient
73
56
  # @raise {ValidationError}
74
57
  # @raise {subclasses of Error} on other unexpected errors
75
58
  def create_post(attributes)
76
- post = connection.create(Post, "posts", attributes, redirect_params: {_embed: nil})
77
-
78
- changes = 0
79
- changes += assign_meta(post, attributes[:meta])
80
- changes += assign_categories(post, attributes[:category_ids])
81
- changes += assign_tags(post, attributes[:tag_ids])
82
-
83
- if changes > 0
84
- find_post(post.id)
85
- else
86
- post
87
- end
59
+ connection.create(Post, "posts", attributes, redirect_params: {_embed: nil})
88
60
  end
89
61
 
90
62
  # Update the {Post} with the given id, setting the supplied attributes in
@@ -116,18 +88,7 @@ module WordpressClient
116
88
  # @raise {ValidationError}
117
89
  # @raise {subclasses of Error} on other unexpected errors
118
90
  def update_post(id, attributes)
119
- post = connection.patch(Post, "posts/#{id.to_i}?_embed", attributes)
120
-
121
- changes = 0
122
- changes += assign_meta(post, attributes[:meta])
123
- changes += assign_categories(post, attributes[:category_ids])
124
- changes += assign_tags(post, attributes[:tag_ids])
125
-
126
- if changes > 0
127
- find_post(post.id)
128
- else
129
- post
130
- end
91
+ connection.put(Post, "posts/#{id.to_i}", attributes)
131
92
  end
132
93
 
133
94
  # Deletes the {Post} with the given ID.
@@ -147,7 +108,7 @@ module WordpressClient
147
108
  #
148
109
  # @return {PaginatedCollection[Category]}
149
110
  def categories(per_page: 10, page: 1)
150
- connection.get_multiple(Category, "terms/category", page: page, per_page: per_page)
111
+ connection.get_multiple(Category, "categories", page: page, per_page: per_page)
151
112
  end
152
113
 
153
114
  # Find {Category} with the given ID.
@@ -156,7 +117,7 @@ module WordpressClient
156
117
  # @raise {NotFoundError}
157
118
  # @raise {subclasses of Error} on other unexpected errors
158
119
  def find_category(id)
159
- connection.get(Category, "terms/category/#{id.to_i}")
120
+ connection.get(Category, "categories/#{id.to_i}")
160
121
  end
161
122
 
162
123
  # Create a new {Category} with the given attributes.
@@ -172,7 +133,7 @@ module WordpressClient
172
133
  # @raise {ValidationError}
173
134
  # @raise {subclasses of Error} on other unexpected errors
174
135
  def create_category(attributes)
175
- connection.create(Category, "terms/category", attributes)
136
+ connection.create(Category, "categories", attributes)
176
137
  end
177
138
 
178
139
  # Update the {Category} with the given id, setting the supplied attributes.
@@ -189,7 +150,7 @@ module WordpressClient
189
150
  # @raise {ValidationError}
190
151
  # @raise {subclasses of Error} on other unexpected errors
191
152
  def update_category(id, attributes)
192
- connection.patch(Category, "terms/category/#{id.to_i}", attributes)
153
+ connection.put(Category, "categories/#{id.to_i}", attributes)
193
154
  end
194
155
 
195
156
  # @!group Tags
@@ -198,7 +159,7 @@ module WordpressClient
198
159
  #
199
160
  # @return {PaginatedCollection[Tag]}
200
161
  def tags(per_page: 10, page: 1)
201
- connection.get_multiple(Tag, "terms/tag", page: page, per_page: per_page)
162
+ connection.get_multiple(Tag, "tags", page: page, per_page: per_page)
202
163
  end
203
164
 
204
165
  # Find {Tag} with the given ID.
@@ -207,7 +168,7 @@ module WordpressClient
207
168
  # @raise {NotFoundError}
208
169
  # @raise {subclasses of Error} on other unexpected errors
209
170
  def find_tag(id)
210
- connection.get(Tag, "terms/tag/#{id.to_i}")
171
+ connection.get(Tag, "tags/#{id.to_i}")
211
172
  end
212
173
 
213
174
  # Create a new {Tag} with the given attributes.
@@ -223,7 +184,7 @@ module WordpressClient
223
184
  # @raise {ValidationError}
224
185
  # @raise {subclasses of Error} on other unexpected errors
225
186
  def create_tag(attributes)
226
- connection.create(Tag, "terms/tag", attributes)
187
+ connection.create(Tag, "tags", attributes)
227
188
  end
228
189
 
229
190
  # Update the {Tag} with the given id, setting the supplied attributes.
@@ -240,7 +201,7 @@ module WordpressClient
240
201
  # @raise {ValidationError}
241
202
  # @raise {subclasses of Error} on other unexpected errors
242
203
  def update_tag(id, attributes)
243
- connection.patch(Tag, "terms/tag/#{id.to_i}", attributes)
204
+ connection.put(Tag, "tags/#{id.to_i}", attributes)
244
205
  end
245
206
 
246
207
  # @!group Media
@@ -322,7 +283,7 @@ module WordpressClient
322
283
  # @raise {ValidationError}
323
284
  # @raise {subclasses of Error} on other unexpected errors
324
285
  def update_media(id, attributes)
325
- connection.patch(Media, "media/#{id.to_i}", attributes)
286
+ connection.put(Media, "media/#{id.to_i}", attributes)
326
287
  end
327
288
 
328
289
  # @!endgroup
@@ -333,20 +294,5 @@ module WordpressClient
333
294
 
334
295
  private
335
296
  attr_reader :connection
336
-
337
- def assign_categories(post, ids)
338
- return 0 unless ids
339
- ReplaceTerms.apply_categories(connection, post, ids)
340
- end
341
-
342
- def assign_tags(post, ids)
343
- return 0 unless ids
344
- ReplaceTerms.apply_tags(connection, post, ids)
345
- end
346
-
347
- def assign_meta(post, meta)
348
- return 0 unless meta
349
- ReplaceMetadata.apply(connection, post, meta)
350
- end
351
297
  end
352
298
  end
@@ -50,14 +50,14 @@ module WordpressClient
50
50
  true
51
51
  end
52
52
 
53
- def patch(model, path, attributes)
53
+ def put(model, path, attributes)
54
54
  model.parse(
55
- parse_json_response(send_json(path, attributes, method: :patch))
55
+ parse_json_response(send_json(path, attributes, method: :put))
56
56
  )
57
57
  end
58
58
 
59
- def patch_without_response(path, attributes)
60
- handle_status_code(send_json(path, attributes, method: :patch))
59
+ def put_without_response(path, attributes)
60
+ handle_status_code(send_json(path, attributes, method: :put))
61
61
  true
62
62
  end
63
63
 
@@ -66,9 +66,7 @@ module WordpressClient
66
66
  response = post_data(path, body, {
67
67
  "Content-Length" => body.size.to_s,
68
68
  "Content-Type" => mime_type,
69
- # WP API does not parse normal Content-Disposition and instead ops to using their own format
70
- # https://github.com/WP-API/WP-API/issues/1744
71
- "Content-Disposition" => "filename=#{filename || "unnamed"}",
69
+ "Content-Disposition" => 'attachment; filename="' + (filename || "unnamed") + '"',
72
70
  })
73
71
 
74
72
  if response.status == 201 # Created
@@ -89,7 +87,7 @@ module WordpressClient
89
87
  end
90
88
 
91
89
  def setup_network_connection
92
- Faraday.new(url: "#{url}/wp/v2") do |conn|
90
+ Faraday.new(url: File.join(url, "wp/v2")) do |conn|
93
91
  conn.request :basic_auth, username, @password
94
92
  conn.adapter :net_http
95
93
  end
@@ -112,8 +110,9 @@ module WordpressClient
112
110
  def get_json_and_response(path, params = {})
113
111
  response = net.get(path, params)
114
112
  [parse_json_response(response), response]
115
- rescue Faraday::TimeoutError
116
- raise TimeoutError
113
+ rescue Faraday::ConnectionFailed => error
114
+ raise TimeoutError if error.cause.class == Net::OpenTimeout
115
+ raise
117
116
  end
118
117
 
119
118
  def send_json(path, data, method: :post)
@@ -2,11 +2,16 @@ module WordpressClient
2
2
  # Represents a media record in Wordpress.
3
3
  class Media
4
4
  attr_accessor(
5
- :id, :slug, :title_html, :description,
5
+ :id, :slug, :media_type, :title_html, :description,
6
6
  :date, :updated_at,
7
7
  :guid, :link, :media_details
8
8
  )
9
9
 
10
+ # @!attribute [r] media_type
11
+ # @return [String] the type of the media
12
+ # @example
13
+ # media.media_type #=> "image"
14
+
10
15
  # @!attribute [rw] title_html
11
16
  # @return [String] the title of the media, HTML escaped
12
17
  # @example
@@ -45,6 +50,7 @@ module WordpressClient
45
50
  def initialize(
46
51
  id: nil,
47
52
  slug: nil,
53
+ media_type: nil,
48
54
  title_html: nil,
49
55
  description: nil,
50
56
  date: nil,
@@ -55,6 +61,7 @@ module WordpressClient
55
61
  )
56
62
  @id = id
57
63
  @slug = slug
64
+ @media_type = media_type
58
65
  @title_html = title_html
59
66
  @date = date
60
67
  @updated_at = updated_at
@@ -65,5 +72,12 @@ module WordpressClient
65
72
  end
66
73
 
67
74
  alias source_url guid
75
+
76
+ # Returns the same +Media+ instance if it is an image, else +nil+.
77
+ def as_image
78
+ if media_type == "image"
79
+ self
80
+ end
81
+ end
68
82
  end
69
83
  end
@@ -27,6 +27,7 @@ module WordpressClient
27
27
 
28
28
  def assign_basic(media)
29
29
  media.id = data.fetch("id")
30
+ media.media_type = data.fetch("media_type")
30
31
  media.slug = data.fetch("slug")
31
32
  media.link = data.fetch("link")
32
33
  media.description = data["description"]
@@ -9,13 +9,14 @@ module WordpressClient
9
9
  :id, :slug, :url, :guid, :status,
10
10
  :title_html, :excerpt_html, :content_html,
11
11
  :updated_at, :date,
12
- :categories, :tags, :meta, :featured_image
12
+ :categories, :tags, :meta, :featured_media,
13
+ :tag_ids, :category_ids, :featured_media_id
13
14
  )
14
15
 
15
16
  # @!attribute [rw] title_html
16
17
  # @return [String] the title of the media, HTML escaped
17
18
  # @example
18
- # post.title_html #=> "Fire & diamonds!"
19
+ # post.title_html #=> "Fire & diamonds!"
19
20
 
20
21
  # @!attribute [rw] date
21
22
  # @return [Time, nil] the date of the post, in UTC if available
@@ -42,7 +43,7 @@ module WordpressClient
42
43
  # @return [Array[Tag]] the {Tag Tags} the post belongs to.
43
44
  # @see Tag
44
45
 
45
- # @!attribute [rw] featured_image
46
+ # @!attribute [rw] featured_media
46
47
  # @return [Media, nil] the featured image, as an instance of {Media}
47
48
  # @see Media
48
49
 
@@ -79,9 +80,10 @@ module WordpressClient
79
80
  date: nil,
80
81
  categories: [],
81
82
  tags: [],
82
- featured_image: nil,
83
- meta: {},
84
- meta_ids: {}
83
+ category_ids: [],
84
+ tag_ids: [],
85
+ featured_media: nil,
86
+ meta: {}
85
87
  )
86
88
  @id = id
87
89
  @slug = slug
@@ -95,39 +97,17 @@ module WordpressClient
95
97
  @date = date
96
98
  @categories = categories
97
99
  @tags = tags
98
- @featured_image = featured_image
100
+ @category_ids = category_ids
101
+ @tag_ids = tag_ids
102
+ @featured_media = featured_media
99
103
  @meta = meta
100
- @meta_ids = meta_ids
101
104
  end
102
105
 
103
- # A list of all category ids for the post.
104
- #
105
- # You can pass this list, with IDs added or removed, to
106
- # {Client#update_post} to change the category list.
107
- #
108
- # @return [Array[Fixnum]] the id of every category associated with this post
109
- # @see Client#update_post
110
- def category_ids() categories.map(&:id) end
111
-
112
- # A list of all tag ids for the post.
113
- #
114
- # You can pass this list, with IDs added or removed, to
115
- # {Client#update_post} to change the tag list.
116
- #
117
- # @return [Array[Fixnum]] the id of every tag associated with this post
118
- # @see Client#update_post
119
- def tag_ids() tags.map(&:id) end
120
-
121
- # @return [Fixnum, nil] ID of the featured image associated with the post.
122
- def featured_image_id
123
- featured_image && featured_image.id
124
- end
125
-
126
- # @api private
127
- # Used to determine the underlying ID of the different meta keys so they
128
- # can be modified by {Client}. You should not use this for anything.
129
- def meta_id_for(key)
130
- @meta_ids[key] || raise(ArgumentError, "Post does not have meta #{key.inspect}")
106
+ # Returns the featured media, if the featured media is an image.
107
+ def featured_image
108
+ if featured_media
109
+ featured_media.as_image
110
+ end
131
111
  end
132
112
  end
133
113
  end