In diesem Blogpost geht es um einen Text, den Du auf der Startseite findest. Die Idee war, den Text täglich durch chatGPT zu aktualisieren und immer in leichtveränderter Form darzustellen. Also habe ich ein Plugin entwickelt, das chatGPT nutzt, um vorhandene Texte automatisch umzuschreiben und diese auf meiner Website einzubinden. In diesem Beitrag erkläre ich, wie mein Plugin funktioniert .
Die Idee hinter dem Plugin
Die Idee war es, ein Tool zu schaffen, das die Textgenerierung effizienter und kreativer gestaltet. Indem ich vorhandene Texte mit einer KI neu formulieren lasse, kann ich den Besuchern meiner Website regelmäßig frische Inhalte bieten, ohne jedes Mal neuen Text von Grund auf neu schreiben zu müssen. Das ganze soll allerdings nur einmal am Tag aktualisiert werden, damit der Text nicht bei jedem Aufruf neu generiert wird.
Plugin Ordnerstruktur
text-rewrite-plugin/
│
├── admin/
│ ├── menu.php
│ └── settings-page.php
│
├── cron/
│ └── cron-functions.php
│
├── includes/
│ ├── custom-post-types.php
│ ├── meta-boxes.php
│ └── shortcodes.php
│
├── index.php
└── text-rewrite-plugin.php
Lege die Ordner und die passenden Dateien an.
index.php
Kann man vermutlich ignorieren aber ist halt Standard.
<?php
// In the world of code, silence protects.
text-rewrite-plugin.php
Hier steht die Beschreibung für das Plugin und alle Dateien werden geladen.
<?php
/**
* Plugin Name: Text Rewrite Plugin
* Description: Ein Plugin, das Texte mittels KI umschreibt und über Shortcodes zugänglich macht.
* Version: 1.0
* Author: Alexander Thiele
* Author URI: https://www.linkedin.com/in/thielander/
* Text Domain: ai-text-rewrite
*/
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
require_once plugin_dir_path(__FILE__) . 'admin/menu.php';
require_once plugin_dir_path(__FILE__) . 'includes/custom-post-types.php';
require_once plugin_dir_path(__FILE__) . 'admin/settings-page.php';
require_once plugin_dir_path(__FILE__) . 'includes/meta-boxes.php';
require_once plugin_dir_path(__FILE__) . 'includes/shortcodes.php';
require_once plugin_dir_path(__FILE__) . 'cron/cron-functions.php';
admin/menu.php
Hier wird ein Menü Eintrag unter Einstellungen erstellt.
<?php
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
add_action('admin_menu', 'text_rewrite_add_admin_menu');
function text_rewrite_add_admin_menu() {
add_options_page(
'Text Rewrite Einstellungen', // Seiten Titel
'Text Rewrite', // Menü Titel
'manage_options', // Capability
'text-rewrite-settings', // Menü Slug
'text_rewrite_settings_page' // Funktion, die die Seite rendert
);
}
admin/settings-page.php
Diese Seite zeigt die Einstellungen an. Dort lässt sich einstellen, wie oft die Texte neu generiert werden sollen.
<?php
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
function text_rewrite_settings_page() {
?>
<div class="wrap">
<h1>Text Rewrite Einstellungen</h1>
<form method="post" action="options.php">
<?php
settings_fields('text_rewrite_settings');
do_settings_sections('text_rewrite_settings');
submit_button();
?>
</form>
</div>
<?php
}
add_action('admin_init', 'text_rewrite_settings_init');
function text_rewrite_settings_init() {
register_setting('text_rewrite_settings', 'text_rewrite_cron_frequency');
add_settings_section(
'text_rewrite_main_section', // Section ID
'Cron Einstellungen', // Titel
'text_rewrite_settings_section_callback', // Callback für Erklärungen
'text_rewrite_settings' // Seite, auf der die Section angezeigt wird
);
add_settings_field(
'text_rewrite_cron_frequency_field', // Feld ID
'Cron Häufigkeit', // Titel
'text_rewrite_cron_frequency_field_render', // Callback für das Feld
'text_rewrite_settings', // Seite
'text_rewrite_main_section' // Section
);
}
function text_rewrite_settings_section_callback() {
echo '<p>Wähle aus, wie oft der Cron-Job ausgeführt werden soll.</p>';
}
function text_rewrite_cron_frequency_field_render() {
$options = get_option('text_rewrite_cron_frequency');
?>
<select name="text_rewrite_cron_frequency">
<option value="daily" <?php selected($options, 'daily'); ?>>Täglich</option>
<option value="weekly" <?php selected($options, 'weekly'); ?>>Wöchentlich</option>
<option value="monthly" <?php selected($options, 'monthly'); ?>>Monatlich</option>
</select>
<?php
}
add_action('admin_enqueue_scripts', 'text_rewrite_admin_styles');
function text_rewrite_admin_styles($hook) {
if ('settings_page_text-rewrite-settings' !== $hook) {
return;
}
wp_enqueue_style('text-rewrite-admin-css', plugins_url('admin-style.css', __FILE__));
}
add_action('update_option_text_rewrite_cron_frequency', 'text_rewrite_update_cron_job', 10, 3);
function text_rewrite_update_cron_job($old_value, $value, $option) {
$timestamp = wp_next_scheduled('text_rewrite_cron_hook');
if ($timestamp) {
wp_unschedule_event($timestamp, 'text_rewrite_cron_hook');
}
wp_schedule_event(time(), $value, 'text_rewrite_cron_hook');
}
cron/cron-functions.php
Das ist die eigentliche Funktion, welche die Texte mittels chatGPT umschreibt und abspeichert. Hier ist es notwendig deinen eigenen API Key einzufügen, sonst funktioniert das ganze nicht.
PS: Im Code befinden sich noch einige Log Ausgaben, die waren zu Testzwecken und müssen nicht übernommen werden.
<?php
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
// Definiere API URL und Schlüssel
$api_url = 'https://api.openai.com/v1/chat/completions';
$api_key = 'OPENAPI KEY';
add_action('text_rewrite_cron_hook', 'text_rewrite_do_scheduled_task');
/**
* Führt die geplante Aufgabe aus, um Texte umzuschreiben.
*/
function text_rewrite_do_scheduled_task() {
global $wpdb;
error_log('Text rewrite task started.');
$posts = $wpdb->get_results("SELECT ID, post_content FROM {$wpdb->prefix}posts WHERE post_type = 'rewritten_text' AND post_status = 'publish'");
if (empty($posts)) {
error_log('No posts found for text rewriting.');
} else {
error_log(count($posts) . ' posts found for text rewriting.');
}
foreach ($posts as $post) {
error_log('Sending post ID ' . $post->ID . ' to GPT for rewriting.');
sendgpt($post->ID, $post->post_content);
}
error_log('Text rewrite task completed.');
}
/**
* Sendet Inhalt zu GPT-4o Mini und aktualisiert die Antwort in der Datenbank.
*
* @param int $post_id ID des Posts
* @param string $content Inhalt des Posts
*/
function sendgpt($post_id, $content) {
global $api_url, $api_key;
error_log('Preparing request for post ID ' . $post_id);
// Erstelle das Anfrage-Body-Array
$body = json_encode([
'model' => 'gpt-4o-mini',
'messages' => [
[
'role' => 'system',
'content' => [
[
'type' => 'text',
'text' => "Du bist mein Website Assistent, der mir vorhandene Texte etwas umschreibt. Bitte stelle sicher, dass die Antwort im JSON-Format vorliegt."
]
]
],
[
'role' => 'user',
'content' => [
[
'type' => 'text',
'text' => $content
]
]
]
],
'temperature' => 1,
'max_tokens' => 1000,
'top_p' => 1,
'frequency_penalty' => 0,
'presence_penalty' => 0,
'response_format' => [
'type' => 'json_object'
]
]);
error_log('Request body for post ID ' . $post_id . ': ' . $body);
$response = wp_remote_post($api_url, [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $api_key
],
'body' => $body,
'method' => 'POST',
'data_format' => 'body'
]);
// Überprüfen, ob die Antwort ein WP_Error ist
if (is_wp_error($response)) {
error_log('Error communicating with ChatGPT API for post ID ' . $post_id . ': ' . $response->get_error_message());
return;
}
// Überprüfen des HTTP-Statuscodes
$http_code = wp_remote_retrieve_response_code($response);
error_log('HTTP response code for post ID ' . $post_id . ': ' . $http_code);
if ($http_code != 200) {
error_log('Error in API response for post ID ' . $post_id . ': HTTP Status ' . $http_code);
error_log('API response body for post ID ' . $post_id . ': ' . wp_remote_retrieve_body($response));
return;
}
// Behandeln der Antwort
$response_body = json_decode(wp_remote_retrieve_body($response), true);
error_log('API response body for post ID ' . $post_id . ': ' . print_r($response_body, true));
if (!$response_body || isset($response_body['error'])) {
error_log('API response error for post ID ' . $post_id . ': ' . ($response_body['error']['message'] ?? 'Unknown error'));
return;
}
// Extrahiere den umgeschriebenen Text aus dem JSON-Objekt
$message_content = $response_body['choices'][0]['message']['content'] ?? null;
if ($message_content !== null) {
// Dekodiere den JSON-Inhalt aus dem 'content' Feld
$decoded_content = json_decode($message_content, true);
if ($decoded_content && isset($decoded_content['text'])) {
$rewritten_text = $decoded_content['text'];
error_log('Rewritten text for post ID ' . $post_id . ': ' . $rewritten_text);
// Entferne Punkte und Anführungszeichen am Anfang und Ende
$rewritten_text = ltrim($rewritten_text, ". ");
$rewritten_text = trim($rewritten_text, "\"'");
// Speichern nur, wenn der Text nicht null ist
update_post_meta($post_id, 'rewritten_text', sanitize_text_field($rewritten_text));
} else {
error_log('No rewritten text found in decoded content for post ID ' . $post_id);
}
} else {
error_log('No message content received for post ID ' . $post_id);
}
}
includes/custom-post-types.php
Einen eigenen Posttype registrieren um eigene Texte anzulegen.
Der Cron Abschnitt gehört da eigentlich nicht rein, aber das ignorieren wir mal :).
<?php
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
add_action('init', 'register_text_post_type');
function register_text_post_type() {
$args = array(
'public' => true,
'label' => 'Rewritten Texts',
'supports' => array('title', 'editor')
);
register_post_type('rewritten_text', $args);
}
/**
* Spalte hinzufügen
*/
add_filter('manage_rewritten_text_posts_columns', 'text_rewrite_add_shortcode_column');
function text_rewrite_add_shortcode_column($columns) {
$columns['shortcode'] = __('Shortcode', 'text-rewrite-plugin');
return $columns;
}
/**
* Was soll in der Spalte angezeigt werden
*/
add_action('manage_rewritten_text_posts_custom_column', 'text_rewrite_shortcode_column_content', 10, 2);
function text_rewrite_shortcode_column_content($column, $post_id) {
if ('shortcode' === $column) {
echo esc_html('[show_rewritten_text id="' . $post_id . '"]');
}
}
// Füge benutzerdefinierte Intervalle zum WordPress Cron hinzu
add_filter('cron_schedules', 'text_rewrite_add_custom_cron_intervals');
function text_rewrite_add_custom_cron_intervals($schedules) {
if (!isset($schedules['weekly'])) {
$schedules['weekly'] = [
'interval' => WEEK_IN_SECONDS,
'display' => 'Einmal wöchentlich'
];
}
if (!isset($schedules['monthly'])) {
$schedules['monthly'] = [
'interval' => MONTH_IN_SECONDS,
'display' => 'Einmal monatlich'
];
}
return $schedules;
}
includes/meta-boxes.php
Seite um den umgeschriebenen Text anzuzeigen.
<?php
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
add_action('add_meta_boxes', 'add_rewritten_text_metabox');
function add_rewritten_text_metabox() {
add_meta_box('rewritten_text_metabox', 'Umschriebener Text', 'rewritten_text_metabox_callback', 'rewritten_text', 'normal', 'high');
}
function rewritten_text_metabox_callback($post) {
$rewritten_text = get_post_meta($post->ID, 'rewritten_text', true);
echo '<textarea style="width:100%;" rows="10" name="rewritten_text">' . esc_textarea($rewritten_text) . '</textarea>';
}
add_action('save_post', 'save_rewritten_text_metabox_data');
function save_rewritten_text_metabox_data($post_id) {
if (isset($_POST['rewritten_text'])) {
update_post_meta($post_id, 'rewritten_text', sanitize_text_field($_POST['rewritten_text']));
}
}
includes/shortcodes.php
<?php
/**
* Exit if accessed directly.
*/
if (!defined('ABSPATH')) {
exit;
}
add_shortcode('show_rewritten_text', 'display_rewritten_text_shortcode');
function display_rewritten_text_shortcode($atts) {
$atts = shortcode_atts(array('id' => ''), $atts);
$rewritten_text = get_post_meta($atts['id'], 'rewritten_text', true);
// Entferne Anführungszeichen am Anfang und Ende
$rewritten_text = trim($rewritten_text, "\"'");
return esc_html($rewritten_text);
}
Benutzung
Und so funktioniert das ganze
Text erstellen
Ich klicke auf Rewritten Text und dann auf Neuen Beitrag erstellen, um einen Text anzulegen.
Im ersten Feld wird jetzt der Original Text eingetragen und gespeichert.
In dem zweiten Feld ( Umgeschriebener Text ), den Text von oben einfach kopieren und auch unten eintragen.
Warum den Text vorgeben?
Der Sinn und die Aussage soll möglichst gleich bleiben. Daher lege ich die Texte vorher fest und lasse sie nur umschreiben.
Cronjob
Der Cronjob sorgt jetzt dafür, das in dem eingestellten Intervall der Text von chatGPT neu generiert wird.
Texte in Website einbinden
In der Übersicht siehst Du für jeden Text einen Shortcode.
Der kann an beliebiger Stelle in der Website eingebunden werden, um den generierten Text anzuzeigen.
Auswirkungen auf Ranking?
Ich bin gespannt ob das SEO technisch irgendwelche Auswirkungen hat. Ich werde es beobachte. Aber ich kann mir vorstellen, das das Einfluss hat, weil erkannt wird, das der Inhalt regelmäßig geupdatet wird.