The following code will create a plugin that allows you to download random posts based on selected categories in an admin page.
3 CVS files will be generated and downloaded as a zip file.
The 3 files will format the post content for BlueSky (Max 300 characters), Twitter (Max 280 characters) and Facebook/LinkedIn (500+ characters)
Create a new folder for your plugin, e.g., random-posts-csv, and inside this folder, create a file named random-posts-csv.php.
<?php
/**
* Plugin Name: Random Posts CSV Export
* Description: Export random posts from selected categories to a CSV file.
* Version: 1.0
* Author: Your Name
*/
// Exit if accessed directly.
if (!defined('ABSPATH')) {
exit;
}
// Include the admin page.
include(plugin_dir_path(__FILE__) . 'admin-page.php');
// Include the CSV generation functionality.
include(plugin_dir_path(__FILE__) . 'generate-csv.php');
?>
Create a new file named admin-page.php in the same folder and add the following code:
<?php
// Add the admin menu item.
add_action('admin_menu', 'rpcse_add_admin_menu');
function rpcse_add_admin_menu() {
add_menu_page('Random Posts CSV Export', 'Random Posts CSV Export', 'manage_options', 'rpcse-admin-page', 'rpcse_admin_page');
}
// Display the admin page.
function rpcse_admin_page() {
?>
<div class="wrap">
<h1>Random Posts CSV Export</h1>
<form method="post" action="">
<label for="rpcse_num_posts">Number of posts to select:</label>
<select name="rpcse_num_posts" id="rpcse_num_posts">
<?php for ($i = 1; $i <= 10; $i++) : ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php endfor; ?>
</select>
<br><br>
<label for="rpcse_categories">Select Categories:</label><br>
<?php
$categories = get_categories();
foreach ($categories as $category) : ?>
<input type="checkbox" name="rpcse_categories[]" value="<?php echo $category->term_id; ?>"> <?php echo $category->name; ?><br>
<?php endforeach; ?>
<br>
<input type="submit" name="rpcse_generate_csv" value="Generate CSV" class="button button-primary">
</form>
</div>
<?php
}
?>
Create a new file named generate-csv.php in the same folder and add the following code:
<?php
// Hook into the admin_init action to handle form submission.
add_action('admin_init', 'rpcse_handle_form_submission');
function rpcse_handle_form_submission() {
if (isset($_POST['rpcse_generate_csv'])) {
$num_posts = intval($_POST['rpcse_num_posts']);
$categories = isset($_POST['rpcse_categories']) ? $_POST['rpcse_categories'] : [];
// Fetch random posts.
$args = [
'posts_per_page' => $num_posts,
'orderby' => 'rand',
'category__in' => $categories,
];
$posts = get_posts($args);
// Generate CSV content - defaults
$twitter_csv_content = "";
$fb_linked_csv_content = "";
$blue_mast_csv_content = "";
// Set Character Limits
$FBLength = 1000;
$TwitterLength = 280;
$MastadonLength = 500;
$BlueSkyLength = 300;
global $wpdb;
foreach ($posts as $post) {
// Set Defaults for error handling
$TwitterExcerpt = '';
$FullExcerpt = '';
$MastadonExcerpt = '';
$BlueSkyExcerpt = '';
$title = $post->post_title;
$tempexcerpt = trim($post->post_excerpt);
if(($tempexcerpt=='') || (is_null($tempexcerpt)) || (empty($tempexcerpt)))
{
$tempexcerpt = trim($post->post_content);
}
$excerpt = wp_strip_all_tags($tempexcerpt);
$url = get_permalink($post);
// Overwrite URL if we have a short URL
if (is_plugin_active('url-shortify/url-shortify.php'))
{
// Get the short URL slug from the custom table.
$table_name = $wpdb->prefix . 'kc_us_links'; // Replace with your actual table name if different.
$post_id = $post->ID;
$slug = $wpdb->get_var($wpdb->prepare(
"SELECT slug FROM $table_name WHERE cpt_id = %d AND status = 1",
$post_id
));
// If a short URL slug is found, replace the $url variable.
if (!empty($slug)) {
$url = site_url($slug); // Assuming the slug is appended to your site URL.
}
}
$image = get_the_post_thumbnail_url($post, 'full');
// Adjust excerpt length if combined_info exceeds 280 characters.
$TweetTitleLength = 19;
$PostTitleLength = strlen($title);
$URLLength = strlen($url);
$excerptLength = strlen($excerpt);
// Twitter
$availableTwitterLength = $TwitterLength-($TweetTitleLength+$PostTitleLength+$URLLength);
$availableTwitterLength = $availableTwitterLength - 3;
// Grab Twitter Content
if($excerptLength > $availableTwitterLength)
{
$TwitterExcerpt = mb_substr($excerpt, 0, $availableTwitterLength);
$TwitterExcerpt = trim($TwitterExcerpt).'...';
}
else
{
$TwitterExcerpt = $excerpt;
}
$combined_twitter_info = "From The Archives: $title\n\n$TwitterExcerpt\n\n$url";
// BlueSky
$availableBSLength = $BlueSkyLength-($TweetTitleLength+$PostTitleLength+$URLLength);
$availableBSLength = $availableBSLength - 3;
// Grab BlueSky/Mastadon Content
if($excerptLength > $availableBSLength)
{
$BlueSkyExcerpt = mb_substr($excerpt, 0, $availableBSLength);
$BlueSkyExcerpt = trim($BlueSkyExcerpt).'...';
}
else
{
$BlueSkyExcerpt = $excerpt;
}
$combined_bluesky_info = "From The Archives: $title\n\n$BlueSkyExcerpt\n\n$url";
// Facebook
$availableFBLength = $FBLength-($TweetTitleLength+$PostTitleLength+$URLLength);
$availableFBLength = $availableFBLength - 3;
// Grab Facebook/LinkedIn Content
if($excerptLength > $FBLength)
{
$FullExcerpt = mb_substr($excerpt, 0, $availableFBLength);
$FullExcerpt = trim($FullExcerpt).'...';
}
else
{
$FullExcerpt = $excerpt;
}
$combined_fb_info = "From The Archives: $title\n\n$FullExcerpt\n\n$url";
// Add the data to the CSV content.
$twitter_csv_content .= '"' . str_replace('"', '""', $combined_twitter_info) . '","' . $image . "\",,,\n";
$blue_mast_csv_content .= '"' . str_replace('"', '""', $combined_bluesky_info) . '","' . $image . "\",,,\n";
$fb_linked_csv_content .= '"' . str_replace('"', '""', $combined_fb_info) . '","' . $image . "\",,,\n";
}
$generatedTime = date("Y-m-d - H-i-s");
// Output Facebook/LinkedIn CSV file for download.
// Create temporary files for CSVs.
$twitter_csv_filename = tempnam(sys_get_temp_dir(), 'twitter_posts') . '.csv';
$blue_mast_csv_filename = tempnam(sys_get_temp_dir(), 'bluesky_posts') . '.csv';
$fb_linked_csv_filename = tempnam(sys_get_temp_dir(), 'facebook_posts') . '.csv';
file_put_contents($twitter_csv_filename, "\xEF\xBB\xBF" . $twitter_csv_content);
file_put_contents($blue_mast_csv_filename, "\xEF\xBB\xBF" . $blue_mast_csv_content);
file_put_contents($fb_linked_csv_filename, "\xEF\xBB\xBF" . $fb_linked_csv_content);
// Create a zip file containing the CSV files.
$zip = new ZipArchive();
$zip_filename = tempnam(sys_get_temp_dir(), 'csv_files') . '.zip';
if ($zip->open($zip_filename, ZipArchive::CREATE) !== TRUE) {
exit("Unable to create zip file");
}
$zip->addFile($twitter_csv_filename, 'twitter_posts-' . $generatedTime . '.csv');
$zip->addFile($blue_mast_csv_filename, 'bluesky_posts-' . $generatedTime . '.csv');
$zip->addFile($fb_linked_csv_filename, 'facebook_posts-' . $generatedTime . '.csv');
$zip->close();
// Output the zip file for download.
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=evergreen_posts-' . $generatedTime . '.zip');
header('Content-Length: ' . filesize($zip_filename));
readfile($zip_filename);
// Clean up the temporary files.
unlink($twitter_csv_filename);
unlink($blue_mast_csv_filename);
unlink($fb_linked_csv_filename);
unlink($zip_filename);
exit;
}
}
?>
Install and Activate the Plugin
– Zip the random-posts-csv folder.
– Go to the WordPress admin dashboard.
– Navigate to Plugins > Add New > Upload Plugin.
– Upload the zipped folder and activate the plugin.