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.
Related
How can I post a post on WordPress through a post request without using the UI?
If possible I would also like to have guidance on how I can implement this with ACF fields.
You could create a child theme or a plugin to write your custom functionality.
You can handle AJAX requests with a specific action, and call wp_insert_post() to create posts.
Example to get you started:
add_action( 'wp_ajax_create_post', 'create_post_ajax_handler' );
/**
* Handle the create post ajax request
*/
function create_post_ajax_handler() {
// Get the post title from the ajax request
// You can get whatever you have passed here
// Also, perform any validations you might want
$post_title = $_POST['post_title'];
// Create the post
$post_id = wp_insert_post( array(
'post_title' => $post_title,
'post_status' => 'publish'
// you could also specify the 'post_type', 'meta_input' etc
), true );
// Error handling
if ( is_wp_error( $post_id ) ) {
// Send error response
wp_send_json_error( $post_id->get_error_message() );
}
// Send success response
wp_send_json_success( $post_id );
}
add_action( 'wp_enqueue_scripts', 'enqueue_ajax_script' );
/**
* Enqueue the ajax script
*/
function enqueue_ajax_script() {
// Enqueue your JavaScript file with 'jquery' as a dependency
wp_enqueue_script(
'ajax-script',
plugin_dir_url( __FILE__ ) . 'ajax-script.js',
array( 'jquery' )
);
// Expose the url to admin-ajax.php as `ajax_object.ajaxurl`
wp_localize_script(
'ajax-script',
'ajax_object',
array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) )
);
}
// Set the url as `ajax_object.ajaxurl` which is the url to admin-ajax.php
$.ajax(ajax_object.ajaxurl, {
method: 'POST',
data: {
// Your action should match the name of your 'wp_ajax_{action}' hook
action: 'create_post',
// Pass any data you want
post_title: 'Example post title'
}
})
.done((response) => {
// Do whatever you want with the response (in this example, this would be the post id)
console.log(response);
})
.fail((error) => {
// Handle the errors
console.error(error);
});
You might also want to look into Nonces, which help protect against Cross-Site Request Forgery (CSRF).
Disclaimer: I haven't tested this code, but I hope you get the idea.
Edit: Since you mentioned that you use Advanced Custom Fields:
$post_id = wp_insert_post( array(
'post_title' => $post_title,
'post_status' => 'publish',
// You can set ACF fields in the 'meta_input' array
'meta_input' => array(
'acf_custom_field_name' => 'an example value'
)
), true );
Edit #2: Please read more about AJAX in WordPress on the Codex.
Replying to your comment:
to which URL should I make the ajax request in order for it to trigger?
On the Codex, under AJAX in Plugins > Ajax on the Viewer-Facing Side
You might also use wp_localize_script() to make the URL available to your script, and generate it using this expression: admin_url( 'admin-ajax.php' )
how do I insert the action "wp_ajax_create_post" in my post request?
On the Codex, AJAX in Plugins > Ajax on the Administration Side
Notice how the 'action' key's value 'my_action', defined in our JavaScript above, matches the latter half of the action 'wp_ajax_my_action' in our AJAX handler below.
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.
I am creating a new wordpress plugins and I want to use the cronjob system from wordpress. But I get a little bit confused: Everytime the cronjob gets executed I want to run a special function. But the action will not be done. No post will be inserted.
The cronjob itselfs works correct. Maybe I do something wrong. (I manually tested the cron by opening the url wp-cron.php?immo_import_check_import_folders, and it shows me blank page. (Seems this is normal)
Code:
register_activation_hook(__FILE__, 'immo_import_activation');
register_deactivation_hook(__FILE__, 'immo_import_deactivation');
function immo_import_activation() {
wp_schedule_event( time(), 'minutely', 'immo_import_check_import_folders' );
add_action( 'immo_import_check_import_folders', 'immo_import_check_import_folders2' );
}
function immo_import_deactivation() {
wp_clear_scheduled_hook('immo_import_check_import_folders');
}
function immo_import_check_import_folders2() {
$my_post = array(
'post_title' => wp_strip_all_tags( 'Test' ),
'post_content' => 'test .......',
'post_status' => 'publish',
'post_author' => 1,
'post_category' => array( 8,39 )
);
wp_insert_post($my_post);
}
Move your add_action out of immo_import_activation function. If you need one time cron action, look into wp_schedule_single_event
I'm developing a social network with Buddypress, I created a RSS plugin to pull the RSS feed from the specified websites.
Everything is working, except when the RSS is posted to the activity stream. When I create the activity content to print a link, I set the link target to "_new" to open it in a new page.
Here's the code:
function wprss_add_to_activity_feed($item, $inserted_ID) {
$permalink = $item->get_permalink();
$title = $item->get_title();
$admin = get_user_by('login', 'admin');
# Generates the link
$activity_action = sprintf( __( '%s published a new RSS link: %s - ', 'buddypress'), bp_core_get_userlink( $admin->ID ), '' . attribute_escape( wprss_limit_rss_title_chars($title) ) . '');
/* Record this in activity streams */
bp_activity_add( array(
'user_id' => $admin->ID,
'item_id' => $inserted_ID,
'action' => $activity_action,
'component' => 'rss',
'primary_link' => $permalink,
'type' => 'activity_update',
'hide_sitewide' => false
));
}
It should come up with something like that:
Test
But it prints like that:
Test
Why is this happening?
The 'target' attribute is probably getting stripped by BuddyPress's implementation of the kses filters. You can whitelist the attribute as follows:
function se16329156_whitelist_target_in_activity_action( $allowedtags ) {
$allowedtags['a']['target'] = array();
return $allowedtags;
}
add_filter( 'bp_activity_allowed_tags', 'se16329156_whitelist_target_in_activity_action' );
This probably won't retroactively fix the issue for existing activity items - it's likely that they had the offending attribute stripped before being stored in the database. But it should help for future items.
These apis work perfectly.
http://domain.com/wp/api/get_tag_posts/?tag_slug=banana
http://domain.com/wp/api/get_category_posts/?category_slug=featured
Is there any way to join multiple tags or categories into a single request?
E.g.
http://domain.com/wp/api/get_category_posts/?category_slug=featured,news
or
http://domain.com/wp/api/get_category_posts/?category_slug=featured|news
I'm hoping to do what in SQL would be a "where category_name in ('featured','news')
You are after this
<?php $args = array(
'posts_per_page' => 10,
'category__not_in' => array(5,151)
);
query_posts($args);?>
This is what you need to do in PHP to obtain multiple posts from multiple categories. Now in case you are also looking for json or xml or any format it spits out. Put a new function in functions.php and register it with
add_action( 'wp_ajax_nopriv_getmyjson', 'myfunctionname' );
add_action( 'wp_ajax_getmyjson', 'myfunctionname' );
function myfunctionname()
{
Global $wpdb;
...
}
Call this in your theme or plugin and use action=getmyjson and url goes to admin_ajax with nonce set. After Global $wpdb you can use above function to bring all posts and then through them out as json object. Something like this
$response = json_encode( array(
'success' => true,
'message' => $ajaxmsg
'posts' => $mypostarray
)
);
// response output
header( "Content-Type: application/json" );
echo $response;
die(); //This would then make sure it is not getting anything else out of wordpress and sends only json out.
Once this is all done. You will have multiple posts out put in json format.
I needed to do the same thing and ended up using this plugin
Query Multiple Taxonomies. This plugin lets you do faceted search using multiple custom taxonomies. (author's description).
http://wordpress.org/extend/plugins/query-multiple-taxonomies/
It's got a handy sidebar widget also. Hope this helps!
Have you tried making the category_name an array? e.g.
<?php $args = array(
'posts_per_page' => 10,
'category_name' => array('featured', 'news')
);
query_posts($args);?>
Also, with the tag, I found this example:
<?php query_posts('cat=32&tag=hs1+hs1&showposts=10'); ?>
or
<?php query_posts(array(
'posts_per_page' => 10,
'category_name' => array('featured', 'news'),
'tag_slug__and'=>array('banana')
)); ?>