{"id":338,"date":"2019-02-27T20:01:45","date_gmt":"2019-02-27T20:01:45","guid":{"rendered":"https:\/\/jmrowe.com\/blog\/?p=338"},"modified":"2019-02-27T21:36:24","modified_gmt":"2019-02-27T21:36:24","slug":"wp-rest-api-and-custom-post-types","status":"publish","type":"post","link":"https:\/\/jmrowe.com\/blog\/wp-rest-api-and-custom-post-types\/","title":{"rendered":"WordPress REST API and Custom Post Types"},"content":{"rendered":"<p>In my examples, I will be using a custom post type of &#8220;recipes&#8221;<\/p>\n<p>In order to get a custom post type to show on the REST API (i.e. https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/recipes ) , two options when using register_post_type can be set.<\/p>\n<p><em><tt>show_in_rest\u00a0 <\/tt><\/em>(<a title=\"How to Pass Tag Parameters\" href=\"https:\/\/codex.wordpress.org\/How_to_Pass_Tag_Parameters#Boolean\"><i>boolean<\/i><\/a>) (<i>optional<\/i>) Whether to expose this post type in the REST API.<\/p>\n<p><tt><em>rest_base<\/em> <\/tt>(<a title=\"How to Pass Tag Parameters\" href=\"https:\/\/codex.wordpress.org\/How_to_Pass_Tag_Parameters#String\"><i>string<\/i><\/a>) (<i>optional<\/i>) The base slug that this post type will use when accessed using the REST API. Default: $post_type<\/p>\n<p><em>show_in_rest <\/em>must be set to true<\/p>\n<p><em>rest_base <\/em>will be the &#8220;base&#8221; of the url when calling it in the rest API.\u00a0 So if nothing is set, the $post_type slug will be used.. i.e. recipes. If <em>rest_base<\/em> is changed to say &#8220;recipes-api&#8221; then to call it via the REST api it would look like: https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/recipes-api<\/p>\n<p><strong>Sending the rest_url from WordPress to Javascript<\/strong><\/p>\n<p>wp_localize_script should be used to send the rest api url to javascript in a portable way such as:<\/p>\n<pre class=\"lang:php decode:true\">wp_localize_script('registered-js-handle','site_variables', \r\narray('rest_url'=&gt;rest_url('wp\/v2\/recipes-api\/'))\r\n);\r\n\r\n\/\/ Now the rest url for recipes-api can be used in javascript \r\n\/\/ such as console.log(site_variables.rest_url);<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Creating new fields in the REST responses<\/strong><\/p>\n<p>To add more\/custom fields in the REST response. A function that does so must be added to the hook &#8220;rest_api_init&#8221; so..<\/p>\n<pre class=\"lang:php decode:true \">add_action('rest_api_init','function_name_that_adds_custom_fields');<\/pre>\n<p>register_rest_field() is used to register\/add the custom field in the rest response<\/p>\n<pre class=\"lang:php decode:true \">add_action( 'rest_api_init', 'create_api_posts_meta_field' );\r\n \r\nfunction create_api_posts_meta_field() {\r\n \r\n    \/\/ register_rest_field ( 'name-of-post-type', 'name-of-field-to-return', array-of-callbacks-and-schema() )\r\n    register_rest_field( 'post', 'post-meta-fields', array(\r\n           'get_callback'    =&gt; 'get_post_meta_for_api',\r\n           'schema'          =&gt; null,\r\n        )\r\n    );\r\n}\r\n\r\n\/\/ function below is \"callback\" which provides what the\r\n\/\/ value of the new rest field will be.\r\n\/\/ in this case, it simply adds all post meta for an ID\r\n\/\/ to the rest field 'post-meta-fields'\r\n\r\n\/\/ the callback gives you access to the post object \r\n\/\/ so you can retrieve the post id\r\n \r\nfunction get_post_meta_for_api( $object ) {\r\n    \/\/get the id of the post object array\r\n    $post_id = $object['id'];\r\n \r\n    \/\/return the post meta\r\n    return get_post_meta( $post_id );\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>A good reference for using nonces in custom REST endpoints:<\/strong> <a href=\"https:\/\/viastudio.com\/wordpress-rest-api-secure-ajax-calls-custom-endpoints\/\">https:\/\/viastudio.com\/wordpress-rest-api-secure-ajax-calls-custom-endpoints\/<\/a><\/p>\n<p>One thing to note from this example is that WordPress suggest passing the nonce via the header and not the request content data. So, below is the better way of passing the nonce from js back to WordPress:<\/p>\n<pre class=\"lang:js decode:true \">$.ajax( {\r\n    url: site_variables.root + 'wp\/v2\/posts\/1',\r\n    method: 'POST',\r\n    beforeSend: function ( xhr ) {\r\n\r\n \/\/ this is \"safer\" way to send the nonce via ajax rather then\r\n\/\/ in a $GET or $POST field.\r\n\r\n        xhr.setRequestHeader( 'X-WP-Nonce', site_variables.nonce );\r\n    },\r\n    data:{\r\n        'title' : 'Hello Moon'\r\n    }\r\n} ).done( function ( response ) {\r\n    console.log( response );\r\n} );<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my examples, I will be using a custom post type of &#8220;recipes&#8221; In order to get a custom post type to show on the REST API (i.e. https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/recipes ) , two options when using register_post_type can be set. show_in_rest\u00a0 (boolean) (optional) Whether to expose this post type in the REST API. rest_base (string) (optional) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-338","post","type-post","status-publish","format-standard","hentry","category-wordpress"],"_links":{"self":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts\/338","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/comments?post=338"}],"version-history":[{"count":12,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts\/338\/revisions"}],"predecessor-version":[{"id":351,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/posts\/338\/revisions\/351"}],"wp:attachment":[{"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/media?parent=338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/categories?post=338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jmrowe.com\/blog\/wp-json\/wp\/v2\/tags?post=338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}