Custom API Endpoint get data from category - wordpress

im pretty stuck.. Im trying to get all post data from a specific category ID, using Wordpress REST API. But it dosen't output the content, only the ID & Title.. Cant see what I am doing wrong..
Heres the code:
/* Register Route http://dev.mpblogg.se/wp-json/api/v1/feedposts/id */
add_action( 'rest_api_init', function () {
register_rest_route( 'api/v1', '/feedposts/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'getAllPostsfromCategory',
));
});
/* Get all posts from the specific Caetgory */
function getAllPostsfromCategory( $data ) {
$secret = '2lpMh5EHaEiavhMONpWD';
$qs = explode('&', $_SERVER['QUERY_STRING'])[0];
$qs = explode('=', $qs)[1];
if($qs != $secret){
return false;
}
$posts = get_posts( array(
'category' => $data['id'],
));
$returnArray = array();
foreach($posts as $post) {
array_push($returnArray, array(
'id' => $post->ID,
'title' => $post->post_title,
'content' => $post->post_content
));
}
// die();
if(empty($posts)){
return null;
}
return $returnArray;
}
The JSON output looks like this:
After changing to array_push($returnArray,$post); it looks like this:

Okay... here's a clue that I got from the array_push image that you shared. The last string of the JSON output reads:
"filer": "raw"
This means that the resultant value would be stored as a raw, unfiltered content of the post.
So, you can try adding apply_filters() to the extracted content and see if it helps you display the required content.
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
echo $content;
This is used to apply the content filters to raw unfiltered post content, which usually comes from the use of $post->post_content .

As usual the answer why it didnt work is so dumb. Im not using the the_content.. Im using a custom field from ACF called post_excerpt. So I just added:
'excerpt' => get_field('post_excerpt', $post->ID),
Now it works.. Sorry all, but thank's for all the help.

Related

ACF Dynamic select values not showing data

This question makes me crazy for almost 2 weeks. I know I am not expert in Wordpress, so I am seeking for help here.
I have create a href that when user click it will go to new page.
Add Class2
This href post the Post id. Url display:
[http://localhost/dev6/create-class/?post=289][1]
create-class page:
At create-class page,I am using GET method to display post id from url
$post = $_GET['post'];
I have acf form in create-class page for create new post. In this form, there have dynamic select field but the select field not display any data.
<?php acf_form(array(
'post_id' => 'new_post',
'field_groups' => array(150),
'post_title' => false,
'post_content' => false,
'new_post' => array(
'post_type' => 'classes',
'post_status' => 'publish',
),
'return' => '%post_url%',
'submit_value' => 'Submit',
//'updated_message' => 'Course Submit!',
)); ?>
in my function.php I create function for dynamic select:
function acf_load_t_first_name2_field_choices($field) {
global $post;
//$post = $_GET['post'];
// reset choices
$field['choices'] = array();
// get the textarea value from options page without any formatting
$choices = get_field('t_first_name',$post->ID);
// loop through array and add to field 'choices'
if( is_array($choices) ) {
foreach( $choices as $choice ) {
$field['choices'][ $choice ] = $choice;
}
}
// return the field
return $field;
}
add_filter('acf/load_field/name=t_first_name2', 'acf_load_t_first_name2_field_choices');
Is there something wrong with my code?
I don't believe this will work in your create-class template:
$post = $_GET['post'];
You will need to set something like this up in your functions.php file:
function custom_query_vars_filter($vars) {
$vars[] .= 'post';
return $vars;
}
add_filter( 'query_vars', 'custom_query_vars_filter' );
Then, in your create-class template you can get the variable from the URL like this:
$post = get_query_var('post');
See if that gets you going in the right direction.

Wordpress REST response shows taxonomy categories only with ID's

I'm using WP as a headless CMS with ACF en ACF-2-REST plugins. I've added categories to a post-type and when I make a GET call, it shows me all the information of a particular post including the categories, but only the ID's. If I want to match it, I have to do another call to Categories to get the information of that categories (name, parent etc).
How can I show that information instead of just the ID in a post call?
How the JSON looks now at the /activities call:
{
"id":111,
"date":"2020-01-18T15:39:27",
"date_gmt":"2020-01-18T15:39:27",
"guid":{"rendered":"https:\/\/url.be\/?post_type=activities&p=111"},
"modified":"2020-01-18T15:39:27",
"modified_gmt":"2020-01-18T15:39:27",
"slug":"walking-on-wood",
"status":"publish",
"type":"activities",
"link":"https:\/\/url.be\/activities\/walking-on-wood\/",
"title":{"rendered":"Walking on wood"},
"template":"",
"categories":[14,25,13,2,18,21,6,24],
"acf":{...}
}
What I want to show in the "categories" instead of just the numbers (from the categories call)
{
"id":3,
"count":1,
"description":"",
"link":"https:\/\/url.be\/category\/duration\/lower-than-30-min\/",
"name":"< 30 min.",
"slug":"lower-than-30-min",
"taxonomy":"category",
"parent":2,"meta":[],
"acf":[],
"_links":{"self":[{"href":"https:\/\/url.be\/wp-json\/wp\/v2\/categories\/3"}],
"collection":[{"href":"https:\/\/url.be\/wp-json\/wp\/v2\/categories"}],
"about":[{"href":"https:\/\/url.be\/wp-json\/wp\/v2\/taxonomies\/category"}],
"up":[{"embeddable":true,"href":"https:\/\/url.be\/wp-json\/wp\/v2\/categories\/2"}],
"wp:post_type":[{"href":"https:\/\/url.be\/wp-json\/wp\/v2\/posts?categories=3"},{"href":"https:\/\/url.be\/wp-json\/wp\/v2\/activities?categories=3"}],
"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}
}
Can't find any solution on the internet how I could manipulate the structure of that JSON with a custom function, would appreciate it a lot if someone point me to the right direction. Thanks!
As discussed in the comments section, a solution to this question is to use a custom endpoint method for the WP REST API and perform extra queries in there to get the data you need. This way, you can do all the data manipulation to get the perfect response, resulting in one REST call.
As taken from the official developer docs
Define an endpoint method and add some extra data
<?php
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'my_awesome_func', //note that this is the method it will fire
'args' => array(
'id' => array(
'validate_callback' => function($param, $request, $key) {
return is_numeric( $param );
}
),
),
) );
/**
* Grab latest post by an author along with its category!
*
* #param array $data Options for the function.
* #return array Post,
*/
function my_awesome_func( $data ) {
$posts = get_posts( array(
'author' => $data['id'],
) );
if(!empty($posts)) {
//Example of appending extra data
foreach($posts as $post) {
$category = wp_get_post_terms($post->ID, 'category');
$post['category'] = $category;
}
return $posts;
} else {
return new WP_Error( 'no_author', 'Invalid author', array( 'status' => 404 ) );
}
}

wordpress rest api v2 how to list taxonomy terms?

i am new to v2, i use v1 for long time, currently upgrade to v2, i try to get all the terms belong to specific custom taxonomy.
In v1 i can do this to get terms
/taxonomies/location_category/terms
but in v2 i try
/taxonomies/terms
it return json error "code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status"
:404}}
if just /taxonomies/location_category/ it didn't show anything terms belong to taxonomy.
i search the question on google for few hours didn't show any result, anyone can help please, thank you
end out to write the custom code here
add blow code to functions.php
class all_terms
{
public function __construct()
{
$version = '2';
$namespace = 'wp/v' . $version;
$base = 'all-terms';
register_rest_route($namespace, '/' . $base, array(
'methods' => 'GET',
'callback' => array($this, 'get_all_terms'),
));
}
public function get_all_terms($object)
{
$return = array();
// $return['categories'] = get_terms('category');
// $return['tags'] = get_terms('post_tag');
// Get taxonomies
$args = array(
'public' => true,
'_builtin' => false
);
$output = 'names'; // or objects
$operator = 'and'; // 'and' or 'or'
$taxonomies = get_taxonomies($args, $output, $operator);
foreach ($taxonomies as $key => $taxonomy_name) {
if($taxonomy_name = $_GET['term']){
$return = get_terms($taxonomy_name);
}
}
return new WP_REST_Response($return, 200);
}
}
add_action('rest_api_init', function () {
$all_terms = new all_terms;
});
and enter url http://youdomain.com/wp-json/wp/v2/all-terms?term=you_taxonomy
so term = you_taxonomy, will get terms belong to job_category.
Taxonomy terms are simply called this way:
https://yoursite.com/wp-json/wp/v2/the-taxonomy-slug
For instance, to answer your question:
https://yoursite.com/wp-json/wp/v2/location_category
From terminal:
curl -X GET -i http://www.example.com/wp-json/wp/v2/location_category
For custom taxonomies, be sure that you're setting the 'show_in_rest' argument to be true (default is false) in your register_taxonomy() call.
The register_taxonomy() call is also where you can set the 'rest_base' argument (default will be the taxonomy name, /location_category/ in your example).
TLDR
Use the flag show_in_rest when you register the taxonomy. That's all.
Details
List all available taxonomies
All default taxonomies are available via REST API. Use the following endpoint to get a list of all available taxonomies:
https://exmaple.org/wp-json/wp/v2/taxonomies
It will tell you the correct endpoint for each taxonomy in the wp:items tag, e.g.
..., "wp:items":[{"href":"https://example.com/wp-json/wp/v2/categories"}], ...
..., "wp:items":[{"href":"https://example.com/wp-json/wp/v2/tags"}], ...
Adding new taxonomies to the REST endpoint
In case your taxonomy is not listed in this taxonomy overview, you need to enable the REST endpoint when calling register_taxonomy. You can do this by adding the argument 'show_in_rest' => true:
<php
register_taxonomy( 'location_category', 'post', [
// ...
'show_in_rest' => true, // ← make sure you have this line in the taxonomy args!
] );
Note: If you do NOT use show_in_rest, then the taxonomy is not available in the Block Editor ("Gutenberg").
I strongly advise against creating custom REST endpoints to duplicate built-in logic.
I.e. don't do this or this
Seems some confusion for some devs even for me.
Correct URL is
https://example.com/wp-json/wp/v2/{your_taxonomy}
Not
https://example.com/wp-json/wp/v2/taxonomies/{your_taxonomy}
"/taxonomies" not required
The accepted answer mostly worked for me. This is what I got
<?php
// your_theme/functions.php
/**
* how to list all taxonomy terms
*/
class all_terms
{
public function __construct()
{
$version = '2';
$namespace = 'wp/v' . $version;
$base = 'all-terms';
register_rest_route($namespace, '/' . $base, array(
'methods' => 'GET',
'callback' => array($this, 'get_all_terms'),
));
}
public function get_all_terms($object)
{
$args = array(
'public' => true,
'_builtin' => false
);
$output = 'names'; // or objects
$operator = 'and'; // 'and' or 'or'
$taxonomies = get_taxonomies($args, $output, $operator);
foreach ($taxonomies as $key => $taxonomy_name) {
if ($taxonomy_name = $_GET['term']) {
$return[] = get_terms(array(
'taxonomy' => $taxonomy_name,
'hide_empty' => false,
));
}
}
return new WP_REST_Response($return, 200);
}
}
add_action( 'rest_api_init', get_all_terms);
?>
matches the docs more closely https://developer.wordpress.org/reference/functions/get_terms/
If anyone is reading this in the future, I ran into an issue where the default WP category was outputting a parent key of 0, 1, 2 etc for each term object, which is a problem in itself, but a bigger problem when custom taxonomies do not have this parent value on objects
To solve this amend the ticked example with this:
foreach ($taxonomies as $key => $taxonomy_name) {
if($taxonomy_name = $_GET['term']){
$return = get_terms( array(
'taxonomy' => $taxonomy_name,
'hide_empty' => false,
));
}
}

Wordpress shortcode name as an Attribute

I was wondering if possible to setup a shortcode and have the name of the shortcode also work as an attribute. How I have mine currently setup is like so
add_shortcode('tooltip', 'tooltip');
function tooltip( $atts $content = null) {
array(
'type' => '',
);
So when someone in wordpress uses the shortcode you type in
[tooltip type="fruit"]Item Name[/tooltip]
Although I was wondering is it possible to just use the name of the shortcode as a atts so I can short it a little bit and have it look like this
[tooltip="fruit"]Item Name[/tooltip]
So pretty much cut out the type attribute and use the name of the shortcode tooltip as an attribute instead.
Nope, what you're proposing isn't possible. It may be shorter but in my opinion it would be confusing so I don't see it ever being something that's made possible short of you building the functionality yourself.
You have to use first item in $atts array, ($atts[0]) when using shortcode tag as attribute.
Working example:
<?php
add_shortcode('tooltip', 'tooltip');
function tooltip(Array $atts = array(), $content = null, $tag = null) {
$args = shortcode_atts(array( 0 => null ), $atts);
$args['type'] = trim($args[0], '"=');
unset($args[0]);
extract($args);
// Your code starts here ...
$output = array(
'$type' => $type,
'$content' => $content
);
$output = '<pre>' . print_r($output, true) . '</pre>';
return $output;
}
Please replace everything after // Your code starts here ...
Executing example:
[tooltip="fruit"]Item Name[/tooltip]
will return:
<pre>Array
(
[$type] => fruit
[$content] => Item Name
)
</pre>

Output buffering in wordpress

I'm trying to create a plugin for wordpress that automatically posts data from an API.
I've put the code that generates the HTML in a class:
class Poster{
public function generateHTML($data){
ob_start();
/*
some html and php code
*/
$html = ob_get_contents();
ob_end_flush();
return $html;
}
}
The event is triggered on the admin_menu action:
add_action('admin_menu', function(){
/*
get data from API
*/
$poster = new Poster();
$html = $poster->generateHTML($data);
$post = array(
'post_title' => $title,
'post_content' => $html,
'post_type' => 'post',
'comment_status' => 'open',
'ping_status' => 'open',
'post_status' => 'publish'
);
wp_insert_post($post, $wp_error, true);
});
Is there something wrong with my code?
It works sometimes but most of the time it doesn't.
And by 'it works' I mean the html is returned from the method and then stored in the $html variable. But most of the time the html returned from the method is the only one that's being outputted and it outputs in the admin panel(the rest of the admin panel is not outputted only the contents generated from the method is outputted).
So is there anything wrong with how I approach this?
Is there an alternative that I can do to achieve the same result? Thanks in advance!
Put a error_log message to find out the path and when it does display only your text in admin then catch it from there. Difficult to guess but you need debugging with error log.

Resources