How do I get WordPress' REST API to include user metadata? - wordpress

I've set up a WordPress site and added a couple of users. When I look directly in the wp_usermeta table in the database, there are several records there, so the users do also have some metadata.
According to the documentation, meta should be included when requesting users, but when I request /wp-json/wp/v2/users all the meta fields are an empty array.
What am I missing? How can I get metadata about users through the REST API?

I managed to find an even easier way to accomplish this, based on this part of the docs.
Not sure where it's best practice to put this code. Since I already have an API-related plugin, I just added the code there.
// legend: <type>, <meta_key>, <config>
register_meta('user', 'nickname', array(
"type" => "string",
"show_in_rest" => true // this is the key part
));
Now I just have to figure out which specific keys I need :)

This is not mine, founded at:
https://wordpress.stackexchange.com/questions/270154/getting-user-meta-data-from-wp-rest-api
Wrote here for future reference into StackOverflow:
Look into register_rest_field() to register meta with the rest api.
add_action( 'rest_api_init', 'adding_user_meta_rest' );
function adding_user_meta_rest() {
register_rest_field( 'user',
'collapsed_widgets',
array(
'get_callback' => 'user_meta_callback',
'update_callback' => null,
'schema' => null,
)
);
}
And then put your get_user_meta bit in the callback.
function user_meta_callback( $user, $field_name, $request) {
return get_user_meta( $user[ 'id' ], $field_name, true );
}
The WP_REST_Meta_Fields class may provide more useful insight as well.
Update: on registering custom routes
A quick and dirty partial example. Cobbled out of some stuff sitting in front of me, but it is not a working example.
May help as you read through docs. Follow the connection between the first register_rest_route, it's GET method's callback, my_get_callback, below, and the callback method's use of the WP_Rest_Request class. It should help to draw a connection of the steps. The docs I mentioned in the comments will get into other args, params, etc., and of course the permissions_callback stuff.
Hope it helps.
class My_Extend_Rest extends WP_REST_Controller {
public function __construct() {
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}//end __construct
public function register_routes() {
$version = '1';
$namespace = 'my-fancy-namespace/v' . $version;
$base = 'my-route-base';
// so, site.com/wp-json/my-fancy-namespace/v2/my-route-base/
register_rest_route( $namespace, '/'. $base, array(
array(
'methods' => 'GET',
'callback' => array( $this, 'my_get_callback' ),
'permission_callback' => array( $this, 'key_permissions_check' ),
),
array(
'methods' => 'POST',
'callback' => array( $this, 'my_post_callback' ),
'permission_callback' => array( $this, 'key_permissions_check' ),
),)
);
$base2 = 'my-second-base';
// so, site.com/wp-json/my-fancy-namespace/v2/my-second-base/
register_rest_route( $namespace, '/'. $base2, array(
array(
'methods' => 'GET',
'callback' => array( $this, 'my_get_callback_two' ),
'permission_callback' => array( $this, 'key_permissions_check' ),
),
array(
'methods' => 'POST',
'callback' => array( $this, 'my_post_callback_two' ),
'permission_callback' => array( $this, 'key_permissions_check' ),
),)
);
}//register_routes
public function key_permissions_check() {
//do permissions check stuff
}
public function my_get_callback( WP_REST_Request $request ) {
//do stuff with $request
//see the methods mentioned in the comment
}//end
}//end class

Related

Notice: register_rest_route was called incorrectly. REST API routes must be registered on the rest_api_init action error in Wordpress theme

I have a problem with an old theme that was developed by our website developer who is no longer available to contact. We are unable to update to the latest version of Wordpress, due to the following error:
Notice: register_rest_route was called incorrectly. REST API routes must be registered on the rest_api_init action
Looking in our theme functions.php file, I think it's this part that's causing the problem:
/**
* Register menu routes for WP API v2.
*
* #since 1.2.0
*/
public function __construct() {
register_rest_route( self::get_plugin_namespace(), '/menus', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menus' ),
)
) );
register_rest_route( self::get_plugin_namespace(), '/menus/(?P<id>\d+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menu' ),
'args' => array(
'context' => array(
'default' => 'view',
),
),
)
) );
register_rest_route( self::get_plugin_namespace(), '/menu-locations', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menu_locations' ),
)
) );
register_rest_route( self::get_plugin_namespace(), '/menu-locations/(?P<location>[a-zA-Z0-9_-]+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menu_location' ),
)
) );
}
I've tried adding 'permission_callback' => '__return_true', but this doesn't seem to work.
Any advice would be appreciated.
OK, I think I've fixed this by changing the code, using this link as guidance:
https://github.com/unfulvio/wp-api-menus/blob/master/includes/wp-api-menus-v2.php

Is there any way to get related posts API in WordPress?

I need to create an API that will render a related post by category filter. I have written the code in my functions.php file but I did not get how can I pass a post id to the arguments?
function related_posts_endpoint( $request_data ) {
$uposts = get_posts(
array(
'post_type' => 'post',
'category__in' => wp_get_post_categories(183),
'posts_per_page' => 5,
'post__not_in' => array(183),
) );
return $uposts;
}
add_action( 'rest_api_init', function () {
register_rest_route( 'sections/v1', '/post/related/', array(
'methods' => 'GET',
'callback' => 'related_posts_endpoint'
) );
} );
I need to pass the id from my current API call. So, I need to pass that id to the related API arguments that I have currently passed as static (180)
Image of Current post API from which I need to render a related API
You can add to your rest route a parameter called post_id, and then access the id from the request_data array.
function related_posts_endpoint( $request_data ) {
$post_id = $request_data['post_id'];
$uposts = get_posts(
array(
'post_type' => 'post',
'category__in' => wp_get_post_categories($post_id),
'posts_per_page' => 5,
'post__not_in' => array($post_id),
)
);
return $uposts;
}
add_action( 'rest_api_init', function () {
register_rest_route( 'sections/v1', '/post/related/(?P<post_id>[\d]+)', array(
'methods' => 'GET',
'callback' => 'related_posts_endpoint'
));
});
You can add the id to the end of your URL call /post/related/183.
Your can get the post id like normal get request. ?key=value and use its ad $request['key'] so Your code should be like this.
function related_posts_endpoint( $request_data ) {
$uposts = get_posts(
array(
'post_type' => 'post',
'category__in' => wp_get_post_categories(183),
'posts_per_page' => 5,
'post__not_in' => array($request_data['post_id']),//your requested post id
)
);
return $uposts;
}
add_action( 'rest_api_init', function () {
register_rest_route( 'sections/v1', '/post/related/', array(
'methods' => 'GET',
'callback' => 'related_posts_endpoint'
));
});
Now your api url should be like this /post/related?post_id=183
try this then let me know the result.

Access to all content with specific post type (Wordpress)

I had a question about Wordpress + rest api,
I use register_rest_route for adding new end-point for my collection, and I also created a plugin named as 'article', and the type of this post type also is 'article'.
Now I wanna access all these post types in my new end-point with GET like this :
function my_awesome_func( $post_id ) {
$x = get_post_type_object( 'article' );
return $x[$post_id];
}
add_action( 'rest_api_init', function () {
register_rest_route( 'Articles/v2', '/author/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'my_awesome_func',
) );
} );
I know you can't write $x[$post_id]. I wrote it to say that I wanna access to specific article id. what should I do?
thanks.
I solve this problem finally, I post it, it may be useful for others.
add_action( 'rest_api_init', function () {
register_rest_route( 'wp/v2/Articles', '/author/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'my_awesome_func',
) );
} );
function my_awesome_func( $data ) {
$args = array(
'post_type' => 'article',
'p' => $data['id'],
);
$query = new WP_Query( $args );
return $query->post;
}

Wp Rest Api Custom End point

Im trying to add a custom end point to my wp-rest api the latest version. I have this already but the one with the slug param at the end does not work.. Does any one know why.. would be great if anyone could help..
register_rest_route( 'wp/v2', '/guestmix', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_guestmixes' )
),
'schema' => array( $this, 'get_public_item_schema' )
) );
register_rest_route( 'wp/v2', '/guestmix/(?P<slug>\d+)', array(
'methods' => 'GET',
'callback' => 'get_guestmix'
) );
i guess it because you used d metacharacter for regex (?P<slug>\d+) that's mean for digit, please try use S instead.
The code should look like this
register_rest_route( 'wp/v2', '/guestmix/(?P<slug>\S+)', array(
'methods' => 'GET',
'callback' => 'get_guestmix'
) );
this is cheat sheet for reference http://www.phpliveregex.com/
The above answer works for me, though I implemented the regular expression slightly differently, following a 2019 gist, that covers different url/slug-structure scenarios.
register_rest_route( 'wp/v2', '/guestmix/(?P<slug>[a-zA-Z0-9-]+)', array(
'methods' => 'GET',
'callback' => 'get_guestmix'
) );
Hope this helps

WordPress custom post type permalink structure with custom field value

I am trying to modify the URL structure of my custom post type 'project'.
I would like the URL structure to be as follows:
http://localhost/project/%location%/project-name
%location% is a custom field value associated with that post.
So if I had a post called 'test' with the custom field value of 'seattle', the URL would look like this:
http://localhost/project/seattle/test
I have semi completed this with the following:
function test_query_vars( $query_vars ) {
$query_vars[] = 'location';
return $query_vars;
}
add_filter( 'query_vars', 'test_query_vars' );
function test_init() {
$wp_rewrite->add_rewrite_tag( '%project%', '([^/]+)', 'project=' );
$wp_rewrite->add_rewrite_tag( '%location%', '([^/]+)', 'location=' );
$wp_rewrite->add_permastruct( 'project', 'project/%location%/%project%', false );
// Register post type
register_post_type( 'project',
array(
'labels' => $labels,
'public' => true,
'rewrite' => false,
'has_archive' => true,
'menu_position' => NULL,
'supports' => array ( 'title', 'editor', 'thumbnail', 'page-attributes', 'excerpt', 'comments', 'author' ),
'yarpp_support' => true,
)
);
}
add_action( 'init', 'test_init' );
There are a few problems with this:
The location custom field in the URL can be anything. If I go to http://localhost/project/atlanta/test and the location custom field is actually 'seattle', it will still bring up the desired post. It should be a 404 not found since the 'test' post has the custom field 'location' value set to 'seattle'.
If I go to http://localhost/project/seattle, it will bring up the Blog, but really it should bring up my projects that have the custom field value set to 'seattle'.
The archive for this post type is now having a 404, e.g. http://localhost/project/ should be displaying all projects.
I have tried modifying the query using the following but it is still not working:
function test_parse_query( $query ) {
if ( 'project' == $query->query_vars['post_type'] ) {
$query->set('meta_query', array(
array(
'key' => 'project_location',
'value' => $query->query_vars['location']
)
));
}
return $query;
}
add_filter( 'parse_query', 'test_parse_query' );
Any help would be appreciated :)

Resources