How do I write personalized endpoints in Wordpress? - wordpress

I have personalized custom fields in Wordpress as well as additional things like "user_meta". I've even added some custom fields in the table to some post types.
Now I can call or write classic wordpress variables using wp-rest-api. But it cannot interfere with the private areas I add. There are different types of scenarios, prerequisites and different types that allow you to read / write to different fields, for example: "POST: https: //example.com/wp-json/wp/v2/posts? Title = .... & content = ... "function to add a new text.
Well my font was "fruits" though. Example: "POST: https: //example.com/wp-json/wp/v2/fruits? Title = .... & content = ...." How do I write a custom endpoint?

The simple and easy way to understand how to create a custom endpoint in WordPress rest api this website will be helpful: https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
Below example will help you more to understand about the basic of custom end points:
GET: https: //example.com/wp-json/wp/v2/hello/world
Define Action:
add_action( 'rest_api_init', function(){
register_rest_route( 'wp/v2/hello', 'world', array(
'methods' => 'GET',
'callback' => 'rest_hello_world'
));
});
Call back function Definition:
function rest_hello_world(){
return "Hello World";
}
In order to create a POST method call simply change the method parameter as a POST:
register_rest_route( 'wp/v2/hello', 'world', array(
'methods' => 'POST',
'callback' => 'rest_hello_world'
));
Hope it will help you to understand the basic fundamental for creating custom endpoints!
Cheers
Jenil

Related

Wordpress REST API cannot post comments

I am trying to post comments to my posts using the Wordpress JSON API but I keep getting an error.
Heres what I have done:
I have added the 'rest_allow_anonymous_comments' function
add_filter( 'rest_allow_anonymous_comments', '__return_true' );
Then went to the URL
https://example.com/wp-json/wp/v2/comments?post=192&author_email=mytestemail#gmail.com&author_name=TestName&content=ThisIsTestContent
But it just returns the error:
{"code":"rest_forbidden_param","message":"Query parameter not permitted: author_email","data":{"status":401}}
Does anyone know what I am doing wrong?
First of all, You have to create a endpoint for comment.
add_action('rest_api_init', function () {
register_rest_route( 'mycomment/v1', 'comment/(?P<post_id>\d+)',array(
'methods' => 'POST',
'callback' => 'post_comment'
));
});
Then the post_comment in callback will point it to another function to create another function for your logic. In this call back function, you can add your comment using wp_insert_comment().
function post_comment($request) {
// Your code here
}
Enjoy!

Get current user inside register_rest_route method

How to retrive wp_get_current_user() inside a register_rest_route callback (Wordpress site)?
I'm just trying to do a simple hello wp_get_current_user()->user_login on a php test page:
add_action('rest_api_init', 'helloTest');
function helloTest() {
register_rest_route('hello', 'hello/(?P<id>\d+)', array(
'methods' => WP_REST_SERVER::READABLE,
'callback' => 'showHello'
));
}
function showHello($someVariable) {
echo "Hello " . wp_get_current_user()->user_login . $someVariable;
}
But wp_get_current_user() is null and wp_get_current_user->ID is 0;
I dont want to authenticate the user again. I just want to retrieve his username. If he is not logged in, just show empty an empty string.
If I have to authenticate again, how to add a "nonce" to it? On internet I just have examples using javascript, but not directly on PHP methods.
Issues in your code
First off, you should understand properly how to add custom WP REST API endpoints:
An endpoint's namespace (the first parameter passed to register_rest_route()) should be in this format: your-plugin/v<version>. E.g. hello/v1 or hello-world/v1 and not just hello or hello-world.
$someVariable (the first parameter passed to your endpoint callback function) is not just any variable — it's an instance of the WP_REST_Request class — and shouldn't be echo-ed like what you did here:
function showHello($someVariable) {
echo "Hello " . wp_get_current_user()->user_login . $someVariable;
}
And normally, the $someVariable is better be changed to $request (i.e. rename it to "request").
And you should return a valid WP REST API response. For example, to return just the username:
return new WP_REST_Response( wp_get_current_user()->user_login, 200 );
And know your own API endpoint URL..
(based on your original namespace)
/wp-json/hello/hello/1 <- correct
/wp-json/hello/?John <- incorrect
because in your code, the parameter is a number and not string: (?P<id>\d+)
I hope those help you, and once again, do read the handbook for a more detailed guide.
The Corrected Code
add_action( 'rest_api_init', 'helloTest' );
function helloTest() {
register_rest_route( 'hello/v1', 'hello/(?P<id>\d+)', array(
'methods' => WP_REST_SERVER::READABLE,
'callback' => 'showHello'
) );
}
function showHello( $request ) {
return new WP_REST_Response( wp_get_current_user()->user_login, 200 );
}
Now about getting the user (from the API endpoint — showHello())
If I have to authenticate again, how to add a "nonce" to it?
Just because the user is logged-in/authenticated to the (WordPress) site, it doesn't mean the user is automatically logged-in to the WP REST API. So yes, you'd need to either provide a nonce along with your API request, or use one of the authentication plugins mentioned right here.
Now in most cases, GET (i.e. read-only) requests to the API do not need any authentication, but if you'd like to retrieve the data of the currently logged-in user on your site, then one way is via the _wpnonce data parameter (either POST data or in the query for GET requests).
Example for a GET request:
http://example.com/wp-json/wp/v2/posts?_wpnonce=<nonce>
So based on your comment and the corrected code (above):
Theres no "code" that make the request. Its is just an anchor that
calls my route: Hello
You can add the nonce as part of the URL query string like so: (the namespace is hello/v1 and the <id> is 1)
// Make request to /wp-json/hello/v1/hello/<id>
$nonce = wp_create_nonce( 'wp_rest' );
echo 'Hello';
So try that out along with the corrected code and let me know how it goes. :)
And once again, be sure to read the REST API authentication handbook.

Wordpress Rest API returns error

I'am developing a plugin for wordpress and have trouble with the Rest API.
On my test server it works without a problem. (v4.6.6)
On a different server (v4.4.10) the API returns this error message:
{"code":"rest_invalid_handler","message":"
Der Handler f\u00fcr die Route ist ung\u00fcltig","data":{"status":500}}%
The message is in german and means "The handler for the route is invalid." Don't understand why they translate the error messages for an API. Makes no sense for me. :)
The routes on the http://domain/wp-json are equal.
Maybe an problem with the different WP versions?
Definition of the route:
function __construct() {
add_action( 'rest_api_init', function(){
register_rest_route( 'test_namespace', 'ping', array(
'methods' => 'POST',
'callback' => array($this, 'ping_test'),
'permission_callback' => array($this, 'myhacks_permission_callback'),
) );
} );
}
Thanks for help.
I had the same issue. It seems that method ping_test cannot be private. If you change it to public, the error disappears.
Take a look at the WordPress core and you can see that the method passed as the callback aka ping_test must be callable.
So this error triggers only when that method doesn't exist (for example I just encountered it because of a typo) or if is not accessible(like a protected or private method)

Reason I would get 403 rest_forbidden accessing WP API taxonomies/name-of-taxonomy?

I'm trying to get a list of taxonomies using the WordPress REST API. Hitting /wp-json/wp/v2/taxonomies/post_tag works fine, but I also have a custom taxonomy called location and accessing /wp-json/wp/v2/taxonomies/location returns a 403 rest_forbidden error.
I can't figure out under what circumstances taxonomy REST access would be forbidden in this way. Any ideas?
You need to set show_in_rest to true when registering your taxonomy.
https://codex.wordpress.org/Function_Reference/register_taxonomy
If your custom taxonomy was created by a plugin and you need to alter it's behaviour try this post :
http://scottbolinger.com/custom-taxonomies-in-the-wp-api/
In short, you can add the code below to your functions file to enable show_in_rest for all custom taxonomies.
function prefix_add_taxonimies_to_api() {
$args = array(
'public' => true,
'_builtin' => false
);
$taxonomies = get_taxonomies($args, 'objects');
foreach($taxonomies as $taxonomy) {
$taxonomy->show_in_rest = true;
}
}
add_action('init', 'prefix_add_taxonimies_to_api', 30);
I hope this helps you.

Drupal 8, http request to server and append to the site

I have a Drupal 8 site and I need to make a http request to another server (for content) and append it into the page like footer. I can't do this after DOM is loaded because of SEO issues.
I'm familiar with WordPress and so easy to do it with WP. However, I'm confused about how to do this with .twig, Drupal 8. Any suggestions would be great. Thanks.
If you want the content to be part of the DOM when it is sent to the browser this is not something you want to do in Twig, you should have the content loaded earlier in the process.
You can create a module that defines custom block and place that block in the correct region of your theme.
The block plugin class requires you to write a build() method that returns a render array for your block. Within build() you can do whatever you need to acquire the content, including making an HTTP Request using Symfony's Guzzle client:
public function build() {
$url = 'https://www.example.com/remote/service';
$client = \Drupal::httpClient();
$request = $client->createRequest('GET', $url);
// Do whatever's needed to extract the data you need from the request...
$build = ['my_remote_block' => [
'#theme' => 'my_custom_theme_function',
'#attributes' => [
//An array of variables to pass to the theme
],
'#cache' => [
//Some appropriate cache settings
],
],
];
If you are getting HTML back from your request you could skip the custom theme function and return an array with '#type' => 'markup' and then a field for the markup. The rest of this example assumes you get data back and want to render it yourself.
In your module's .module file you can define the custom theme function (so you can use a twig file of your own design).
function my_module_theme($existing, $type, $theme, $path) {
return [
'my_custom_theme_function' => [
'variables'=> [
// defaults for variables used in this block.
],
],
];
}
Then finally you can create a twig file named my-custom-theme-function.html.twig to render the output.
Often these kinds of setups are quite slow (since the browser's request then triggers another HTTP request + processing time) so you should consider either caching the block as much as possible or using a technique like BigPipe (which is probably not an option for you based on your question but seemed worth pointing out).

Resources