Dateien nach „d2s-askki“ hochladen
This commit is contained in:
parent
866e4070e6
commit
b3e51f24a2
2 changed files with 716 additions and 0 deletions
646
d2s-askki/d2s-askki.php
Normal file
646
d2s-askki/d2s-askki.php
Normal file
|
|
@ -0,0 +1,646 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: Donau2Space – KI-Erklärbuttons (ChatGPT, Grok, Perplexity)
|
||||||
|
* Description: Buttons unter Content oder per Shortcode. Admin-Einstellungen: Prompt, Hint-Text, Kategorie-Ausschluss, Einfügemodus, Post Types (inkl. Seiten), Styling (CSS-Variablen).
|
||||||
|
* Version: 1.4.1
|
||||||
|
* Author: Donau2Space
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
define('D2S_KI_OPT_PROMPT', 'd2s_ki_prompt_prefix');
|
||||||
|
define('D2S_KI_OPT_HINT', 'd2s_ki_hint_text');
|
||||||
|
|
||||||
|
define('D2S_KI_OPT_EXCL_CATS', 'd2s_ki_excluded_category_ids');
|
||||||
|
define('D2S_KI_OPT_MODE', 'd2s_ki_insertion_mode'); // auto | shortcode | both
|
||||||
|
define('D2S_KI_OPT_POST_TYPES', 'd2s_ki_post_types'); // array of allowed post types
|
||||||
|
define('D2S_KI_OPT_STYLE', 'd2s_ki_style'); // associative array
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Defaults
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
function d2s_ki_default_prompt_prefix(): string {
|
||||||
|
return 'Kannst du mir den Blogartikel ganz einfach erklären und die wichtigsten Punkte auflisten?';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_default_hint_text(): string {
|
||||||
|
return 'Wenn du beim Lesen denkst „Worum geht’s hier eigentlich genau?“ – dann lass dir’s von der KI in einfachen Worten erklären.';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_default_mode(): string {
|
||||||
|
return 'auto'; // auto | shortcode | both
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_default_post_types(): array {
|
||||||
|
return ['post']; // user can add 'page' in admin
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_default_style(): array {
|
||||||
|
return [
|
||||||
|
'gpt_bg' => '#10a37f',
|
||||||
|
'gpt_fg' => '#ffffff',
|
||||||
|
'grok_bg' => '#000000',
|
||||||
|
'grok_fg' => '#ffffff',
|
||||||
|
'pplx_bg' => '#1557ff',
|
||||||
|
'pplx_fg' => '#ffffff',
|
||||||
|
|
||||||
|
'radius' => '999px',
|
||||||
|
'pad_y' => '0.65rem',
|
||||||
|
'pad_x' => '1rem',
|
||||||
|
'gap' => '0.5rem',
|
||||||
|
'shadow' => '0 6px 20px rgba(0,0,0,.12)',
|
||||||
|
'shadow_h' => '0 8px 26px rgba(0,0,0,.18)',
|
||||||
|
'scale_h' => '1.02',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Option getters
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
function d2s_ki_get_prompt_prefix(): string {
|
||||||
|
$v = get_option(D2S_KI_OPT_PROMPT, d2s_ki_default_prompt_prefix());
|
||||||
|
$v = is_string($v) ? trim(wp_strip_all_tags($v)) : '';
|
||||||
|
return $v !== '' ? $v : d2s_ki_default_prompt_prefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_get_hint_text(): string {
|
||||||
|
$v = get_option(D2S_KI_OPT_HINT, d2s_ki_default_hint_text());
|
||||||
|
$v = is_string($v) ? trim(wp_strip_all_tags($v)) : '';
|
||||||
|
return $v !== '' ? $v : d2s_ki_default_hint_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_get_excluded_cat_ids(): array {
|
||||||
|
$v = get_option(D2S_KI_OPT_EXCL_CATS, []);
|
||||||
|
if (!is_array($v)) return [];
|
||||||
|
return array_values(array_filter(array_map('intval', $v), fn($id) => $id > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_get_mode(): string {
|
||||||
|
$v = get_option(D2S_KI_OPT_MODE, d2s_ki_default_mode());
|
||||||
|
$allowed = ['auto','shortcode','both'];
|
||||||
|
return in_array($v, $allowed, true) ? $v : d2s_ki_default_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_get_post_types(): array {
|
||||||
|
$v = get_option(D2S_KI_OPT_POST_TYPES, d2s_ki_default_post_types());
|
||||||
|
if (!is_array($v)) $v = d2s_ki_default_post_types();
|
||||||
|
$v = array_values(array_filter(array_map('sanitize_key', $v)));
|
||||||
|
|
||||||
|
$existing = get_post_types(['public' => true], 'names');
|
||||||
|
$v = array_values(array_filter($v, fn($pt) => isset($existing[$pt])));
|
||||||
|
return $v ?: d2s_ki_default_post_types();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_get_style(): array {
|
||||||
|
$v = get_option(D2S_KI_OPT_STYLE, d2s_ki_default_style());
|
||||||
|
if (!is_array($v)) $v = [];
|
||||||
|
return array_merge(d2s_ki_default_style(), $v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Logic: Should display?
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
function d2s_ki_is_allowed_on_post(int $post_id, string $context = 'auto'): bool {
|
||||||
|
if (!$post_id) return false;
|
||||||
|
|
||||||
|
$pt = get_post_type($post_id);
|
||||||
|
if (!$pt) return false;
|
||||||
|
|
||||||
|
$allowed_pts = d2s_ki_get_post_types();
|
||||||
|
if (!in_array($pt, $allowed_pts, true)) return false;
|
||||||
|
|
||||||
|
if ($pt === 'post') {
|
||||||
|
$excluded = d2s_ki_get_excluded_cat_ids();
|
||||||
|
if ($excluded && has_category($excluded, $post_id)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = d2s_ki_get_mode();
|
||||||
|
if ($context === 'auto' && !in_array($mode, ['auto','both'], true)) return false;
|
||||||
|
if ($context === 'shortcode' && !in_array($mode, ['shortcode','both'], true)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Prompt + Providers
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt bauen:
|
||||||
|
* - Promptprefix
|
||||||
|
* - LEERZEILE
|
||||||
|
* - URL
|
||||||
|
*
|
||||||
|
* Vorteil: immer sauber getrennt (kein "…?https://")
|
||||||
|
*/
|
||||||
|
function d2s_ki_build_prompt(string $post_url): string {
|
||||||
|
$prefix = trim(d2s_ki_get_prompt_prefix());
|
||||||
|
|
||||||
|
// Falls jemand im Prefix am Ende ein Satzzeichen ohne Leerzeichen hat: egal, wir trennen fix.
|
||||||
|
// 2 Zeilen sind in Chat-UIs super lesbar.
|
||||||
|
return $prefix . "\n\n" . $post_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_providers(string $prompt): array {
|
||||||
|
$q = http_build_query(['q' => $prompt], '', '&', PHP_QUERY_RFC3986);
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'key' => 'chatgpt',
|
||||||
|
'name' => 'Mit ChatGPT erklären lassen',
|
||||||
|
'href' => 'https://chatgpt.com/?' . $q,
|
||||||
|
'title' => 'Öffnet ChatGPT mit vorbefüllter Nachricht',
|
||||||
|
'icon' => '💬',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => 'grok',
|
||||||
|
'name' => 'Mit Grok erklären lassen',
|
||||||
|
'href' => 'https://grok.com/?' . $q,
|
||||||
|
'title' => 'Öffnet Grok mit vorbefüllter Nachricht',
|
||||||
|
'icon' => '🧠',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => 'perplexity',
|
||||||
|
'name' => 'Mit Perplexity erklären lassen',
|
||||||
|
'href' => 'https://www.perplexity.ai/search?' . $q,
|
||||||
|
'title' => 'Öffnet Perplexity mit vorbefüllter Anfrage',
|
||||||
|
'icon' => '🔎',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Rendering
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
function d2s_ki_render_markup(int $post_id): string {
|
||||||
|
$post_url = get_permalink($post_id);
|
||||||
|
$prompt = d2s_ki_build_prompt($post_url);
|
||||||
|
$links = d2s_ki_providers($prompt);
|
||||||
|
$hint = d2s_ki_get_hint_text();
|
||||||
|
|
||||||
|
ob_start(); ?>
|
||||||
|
<div class="d2s-ki-buttons" aria-label="Erklär-Buttons">
|
||||||
|
<?php foreach ($links as $lnk): ?>
|
||||||
|
<a
|
||||||
|
href="<?php echo esc_url($lnk['href']); ?>"
|
||||||
|
class="d2s-ki-btn d2s-ki-<?php echo esc_attr($lnk['key']); ?>"
|
||||||
|
onclick="window.open('<?php echo esc_js($lnk['href']); ?>', '_blank', 'noopener,noreferrer'); return false;"
|
||||||
|
title="<?php echo esc_attr($lnk['title']); ?>"
|
||||||
|
aria-label="<?php echo esc_attr($lnk['title']); ?>"
|
||||||
|
>
|
||||||
|
<span class="d2s-ki-icon"><?php echo esc_html($lnk['icon']); ?></span>
|
||||||
|
<span class="d2s-ki-text"><?php echo esc_html($lnk['name']); ?></span>
|
||||||
|
</a>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
<?php if ($hint !== ''): ?>
|
||||||
|
<small class="d2s-ki-hint"><?php echo esc_html($hint); ?></small>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto insertion: under content
|
||||||
|
*/
|
||||||
|
function d2s_ki_render_buttons($content) {
|
||||||
|
if (!is_singular()) return $content;
|
||||||
|
|
||||||
|
$post_id = (int) get_queried_object_id();
|
||||||
|
if (!d2s_ki_is_allowed_on_post($post_id, 'auto')) return $content;
|
||||||
|
|
||||||
|
return $content . d2s_ki_render_markup($post_id);
|
||||||
|
}
|
||||||
|
add_filter('the_content', 'd2s_ki_render_buttons', 20);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcode: [d2s_ki_buttons]
|
||||||
|
*/
|
||||||
|
function d2s_ki_shortcode() {
|
||||||
|
if (!is_singular()) return '';
|
||||||
|
|
||||||
|
$post_id = (int) get_queried_object_id();
|
||||||
|
if (!d2s_ki_is_allowed_on_post($post_id, 'shortcode')) return '';
|
||||||
|
|
||||||
|
return d2s_ki_render_markup($post_id);
|
||||||
|
}
|
||||||
|
add_shortcode('d2s_ki_buttons', 'd2s_ki_shortcode');
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Assets: style.css + CSS vars
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
function d2s_ki_enqueue_assets() {
|
||||||
|
if (!is_singular()) return;
|
||||||
|
|
||||||
|
$post_id = (int) get_queried_object_id();
|
||||||
|
$pt = get_post_type($post_id);
|
||||||
|
$allowed_pts = d2s_ki_get_post_types();
|
||||||
|
if (!$pt || !in_array($pt, $allowed_pts, true)) return;
|
||||||
|
|
||||||
|
wp_enqueue_style(
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
plugin_dir_url(__FILE__) . 'assets/style.css',
|
||||||
|
[],
|
||||||
|
'1.4.1'
|
||||||
|
);
|
||||||
|
|
||||||
|
$s = d2s_ki_get_style();
|
||||||
|
|
||||||
|
$vars = [
|
||||||
|
'--d2s-gpt-bg' => $s['gpt_bg'],
|
||||||
|
'--d2s-gpt-fg' => $s['gpt_fg'],
|
||||||
|
'--d2s-grok-bg' => $s['grok_bg'],
|
||||||
|
'--d2s-grok-fg' => $s['grok_fg'],
|
||||||
|
'--d2s-pplx-bg' => $s['pplx_bg'],
|
||||||
|
'--d2s-pplx-fg' => $s['pplx_fg'],
|
||||||
|
'--d2s-radius' => $s['radius'],
|
||||||
|
'--d2s-pad-y' => $s['pad_y'],
|
||||||
|
'--d2s-pad-x' => $s['pad_x'],
|
||||||
|
'--d2s-gap' => $s['gap'],
|
||||||
|
'--d2s-shadow' => $s['shadow'],
|
||||||
|
'--d2s-shadow-h' => $s['shadow_h'],
|
||||||
|
'--d2s-scale-h' => $s['scale_h'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$css = ":root{\n";
|
||||||
|
foreach ($vars as $k => $v) {
|
||||||
|
if ($v === '' || $v === null) continue;
|
||||||
|
$css .= " {$k}: {$v};\n";
|
||||||
|
}
|
||||||
|
$css .= "}\n";
|
||||||
|
|
||||||
|
wp_add_inline_style('d2s-ki-buttons', $css);
|
||||||
|
}
|
||||||
|
add_action('wp_enqueue_scripts', 'd2s_ki_enqueue_assets');
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Admin Settings Page
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
function d2s_ki_admin_menu() {
|
||||||
|
add_options_page(
|
||||||
|
'D2S KI-Erklärbuttons',
|
||||||
|
'D2S KI-Erklärbuttons',
|
||||||
|
'manage_options',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_admin_page_render'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action('admin_menu', 'd2s_ki_admin_menu');
|
||||||
|
|
||||||
|
function d2s_ki_admin_init() {
|
||||||
|
|
||||||
|
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_PROMPT, [
|
||||||
|
'type' => 'string',
|
||||||
|
'sanitize_callback' => 'd2s_ki_sanitize_textline_required',
|
||||||
|
'default' => d2s_ki_default_prompt_prefix(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_HINT, [
|
||||||
|
'type' => 'string',
|
||||||
|
'sanitize_callback' => 'd2s_ki_sanitize_textline_required',
|
||||||
|
'default' => d2s_ki_default_hint_text(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_EXCL_CATS, [
|
||||||
|
'type' => 'array',
|
||||||
|
'sanitize_callback' => 'd2s_ki_sanitize_excluded_categories',
|
||||||
|
'default' => [],
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_MODE, [
|
||||||
|
'type' => 'string',
|
||||||
|
'sanitize_callback' => 'd2s_ki_sanitize_mode',
|
||||||
|
'default' => d2s_ki_default_mode(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_POST_TYPES, [
|
||||||
|
'type' => 'array',
|
||||||
|
'sanitize_callback' => 'd2s_ki_sanitize_post_types',
|
||||||
|
'default' => d2s_ki_default_post_types(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_STYLE, [
|
||||||
|
'type' => 'array',
|
||||||
|
'sanitize_callback' => 'd2s_ki_sanitize_style',
|
||||||
|
'default' => d2s_ki_default_style(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
add_settings_section(
|
||||||
|
'd2s_ki_main',
|
||||||
|
'Allgemein',
|
||||||
|
'__return_false',
|
||||||
|
'd2s-ki-buttons'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_prompt_prefix',
|
||||||
|
'Prompt-Text (Prefix)',
|
||||||
|
'd2s_ki_field_prompt_prefix',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_main'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_hint_text',
|
||||||
|
'Hint-Text unter den Buttons',
|
||||||
|
'd2s_ki_field_hint_text',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_main'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_mode',
|
||||||
|
'Einfüge-Modus',
|
||||||
|
'd2s_ki_field_mode',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_main'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_post_types',
|
||||||
|
'Anzeigen auf',
|
||||||
|
'd2s_ki_field_post_types',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_main'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_excluded_cats',
|
||||||
|
'Kategorien ausschließen (nur Posts)',
|
||||||
|
'd2s_ki_field_excluded_categories',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_main'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_section(
|
||||||
|
'd2s_ki_style',
|
||||||
|
'Styling',
|
||||||
|
'__return_false',
|
||||||
|
'd2s-ki-buttons'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_style_colors',
|
||||||
|
'Farben',
|
||||||
|
'd2s_ki_field_style_colors',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_style'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_style_layout',
|
||||||
|
'Layout',
|
||||||
|
'd2s_ki_field_style_layout',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_style'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'd2s_ki_style_fx',
|
||||||
|
'Effekte',
|
||||||
|
'd2s_ki_field_style_fx',
|
||||||
|
'd2s-ki-buttons',
|
||||||
|
'd2s_ki_style'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action('admin_init', 'd2s_ki_admin_init');
|
||||||
|
|
||||||
|
/* ===== Sanitizers ===== */
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_textline_required($v): string {
|
||||||
|
if (!is_string($v)) $v = '';
|
||||||
|
$v = trim(wp_strip_all_tags($v));
|
||||||
|
return $v !== '' ? $v : '—';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_excluded_categories($v): array {
|
||||||
|
if (!is_array($v)) return [];
|
||||||
|
return array_values(array_unique(array_filter(array_map('intval', $v), fn($id) => $id > 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_mode($v): string {
|
||||||
|
$allowed = ['auto','shortcode','both'];
|
||||||
|
return in_array($v, $allowed, true) ? $v : d2s_ki_default_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_post_types($v): array {
|
||||||
|
if (!is_array($v)) $v = [];
|
||||||
|
$v = array_values(array_filter(array_map('sanitize_key', $v)));
|
||||||
|
|
||||||
|
$existing = get_post_types(['public' => true], 'names');
|
||||||
|
$v = array_values(array_filter($v, fn($pt) => isset($existing[$pt])));
|
||||||
|
|
||||||
|
return $v ?: d2s_ki_default_post_types();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_hex_color_or_empty($v): string {
|
||||||
|
$v = is_string($v) ? trim($v) : '';
|
||||||
|
if ($v === '') return '';
|
||||||
|
$c = sanitize_hex_color($v);
|
||||||
|
return $c ? $c : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_css_len($v, string $fallback): string {
|
||||||
|
$v = is_string($v) ? trim($v) : '';
|
||||||
|
if ($v === '') return $fallback;
|
||||||
|
if (preg_match('/^[0-9.\s%a-zA-Z()+,-]+$/', $v)) return $v;
|
||||||
|
return $fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_css_value($v, string $fallback): string {
|
||||||
|
$v = is_string($v) ? trim($v) : '';
|
||||||
|
if ($v === '') return $fallback;
|
||||||
|
if (preg_match('/^[0-9.\s%a-zA-Z()+,\/-]+$/', $v)) return $v;
|
||||||
|
return $fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_sanitize_style($v): array {
|
||||||
|
$d = d2s_ki_default_style();
|
||||||
|
if (!is_array($v)) $v = [];
|
||||||
|
|
||||||
|
return [
|
||||||
|
'gpt_bg' => d2s_ki_sanitize_hex_color_or_empty($v['gpt_bg'] ?? $d['gpt_bg']) ?: $d['gpt_bg'],
|
||||||
|
'gpt_fg' => d2s_ki_sanitize_hex_color_or_empty($v['gpt_fg'] ?? $d['gpt_fg']) ?: $d['gpt_fg'],
|
||||||
|
'grok_bg' => d2s_ki_sanitize_hex_color_or_empty($v['grok_bg'] ?? $d['grok_bg']) ?: $d['grok_bg'],
|
||||||
|
'grok_fg' => d2s_ki_sanitize_hex_color_or_empty($v['grok_fg'] ?? $d['grok_fg']) ?: $d['grok_fg'],
|
||||||
|
'pplx_bg' => d2s_ki_sanitize_hex_color_or_empty($v['pplx_bg'] ?? $d['pplx_bg']) ?: $d['pplx_bg'],
|
||||||
|
'pplx_fg' => d2s_ki_sanitize_hex_color_or_empty($v['pplx_fg'] ?? $d['pplx_fg']) ?: $d['pplx_fg'],
|
||||||
|
|
||||||
|
'radius' => d2s_ki_sanitize_css_len($v['radius'] ?? '', $d['radius']),
|
||||||
|
'pad_y' => d2s_ki_sanitize_css_len($v['pad_y'] ?? '', $d['pad_y']),
|
||||||
|
'pad_x' => d2s_ki_sanitize_css_len($v['pad_x'] ?? '', $d['pad_x']),
|
||||||
|
'gap' => d2s_ki_sanitize_css_len($v['gap'] ?? '', $d['gap']),
|
||||||
|
|
||||||
|
'shadow' => d2s_ki_sanitize_css_value($v['shadow'] ?? '', $d['shadow']),
|
||||||
|
'shadow_h' => d2s_ki_sanitize_css_value($v['shadow_h'] ?? '', $d['shadow_h']),
|
||||||
|
'scale_h' => d2s_ki_sanitize_css_value($v['scale_h'] ?? '', $d['scale_h']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Admin Fields ===== */
|
||||||
|
|
||||||
|
function d2s_ki_field_prompt_prefix() {
|
||||||
|
$val = d2s_ki_get_prompt_prefix();
|
||||||
|
echo '<textarea name="'.esc_attr(D2S_KI_OPT_PROMPT).'" rows="3" style="width:100%;max-width:760px;">'.esc_textarea($val).'</textarea>';
|
||||||
|
echo '<p class="description">Wird an die KI übergeben. Die URL wird automatisch in einer neuen Zeile angehängt.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_hint_text() {
|
||||||
|
$val = d2s_ki_get_hint_text();
|
||||||
|
echo '<textarea name="'.esc_attr(D2S_KI_OPT_HINT).'" rows="2" style="width:100%;max-width:760px;">'.esc_textarea($val).'</textarea>';
|
||||||
|
echo '<p class="description">Text unter den Buttons. Leer lassen (oder „—“) um ihn praktisch auszublenden.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_mode() {
|
||||||
|
$mode = d2s_ki_get_mode();
|
||||||
|
$opts = [
|
||||||
|
'auto' => 'Automatisch unter Content einfügen',
|
||||||
|
'shortcode' => 'Nur per Shortcode (du platzierst es selbst)',
|
||||||
|
'both' => 'Beides (Auto + Shortcode)',
|
||||||
|
];
|
||||||
|
echo '<select name="'.esc_attr(D2S_KI_OPT_MODE).'" style="min-width:360px;">';
|
||||||
|
foreach ($opts as $k => $label) {
|
||||||
|
echo '<option value="'.esc_attr($k).'" '.selected($mode, $k, false).'>'.esc_html($label).'</option>';
|
||||||
|
}
|
||||||
|
echo '</select>';
|
||||||
|
echo '<p class="description">Shortcode: <code>[d2s_ki_buttons]</code></p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_post_types() {
|
||||||
|
$selected = d2s_ki_get_post_types();
|
||||||
|
$pts = get_post_types(['public' => true], 'objects');
|
||||||
|
|
||||||
|
echo '<div style="max-width:760px;padding:12px;border:1px solid #dcdcde;background:#fff;">';
|
||||||
|
foreach ($pts as $pt) {
|
||||||
|
if ($pt->name === 'attachment') continue;
|
||||||
|
$checked = in_array($pt->name, $selected, true) ? 'checked' : '';
|
||||||
|
echo '<label style="display:block;margin:6px 0;">';
|
||||||
|
echo '<input type="checkbox" name="'.esc_attr(D2S_KI_OPT_POST_TYPES).'[]" value="'.esc_attr($pt->name).'" '.$checked.'> ';
|
||||||
|
echo esc_html($pt->labels->singular_name) . ' <span style="opacity:.6;">(' . esc_html($pt->name) . ')</span>';
|
||||||
|
echo '</label>';
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
echo '<p class="description">Für Seiten: <strong>page</strong> aktivieren.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_excluded_categories() {
|
||||||
|
$selected = d2s_ki_get_excluded_cat_ids();
|
||||||
|
$cats = get_categories(['hide_empty' => false]);
|
||||||
|
|
||||||
|
if (!$cats) {
|
||||||
|
echo '<em>Keine Kategorien gefunden.</em>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<div style="max-width:760px;padding:12px;border:1px solid #dcdcde;background:#fff;">';
|
||||||
|
echo '<p class="description" style="margin-top:0;">Häkchen setzen = Buttons werden in dieser Kategorie <strong>nicht</strong> angezeigt (nur Posts).</p>';
|
||||||
|
|
||||||
|
foreach ($cats as $cat) {
|
||||||
|
$id = (int)$cat->term_id;
|
||||||
|
$checked = in_array($id, $selected, true) ? 'checked' : '';
|
||||||
|
echo '<label style="display:block;margin:6px 0;">';
|
||||||
|
echo '<input type="checkbox" name="'.esc_attr(D2S_KI_OPT_EXCL_CATS).'[]" value="'.esc_attr($id).'" '.$checked.'> ';
|
||||||
|
echo esc_html($cat->name) . ' <span style="opacity:.6;">(' . esc_html($cat->slug) . ')</span>';
|
||||||
|
echo '</label>';
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_style_colors() {
|
||||||
|
$s = d2s_ki_get_style();
|
||||||
|
$name = D2S_KI_OPT_STYLE;
|
||||||
|
|
||||||
|
echo '<table class="widefat striped" style="max-width:760px;"><tbody>';
|
||||||
|
|
||||||
|
$rows = [
|
||||||
|
['ChatGPT Hintergrund', "{$name}[gpt_bg]", $s['gpt_bg']],
|
||||||
|
['ChatGPT Text', "{$name}[gpt_fg]", $s['gpt_fg']],
|
||||||
|
['Grok Hintergrund', "{$name}[grok_bg]", $s['grok_bg']],
|
||||||
|
['Grok Text', "{$name}[grok_fg]", $s['grok_fg']],
|
||||||
|
['Perplexity Hintergrund', "{$name}[pplx_bg]", $s['pplx_bg']],
|
||||||
|
['Perplexity Text', "{$name}[pplx_fg]", $s['pplx_fg']],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($rows as [$label, $field, $val]) {
|
||||||
|
echo '<tr>';
|
||||||
|
echo '<th style="width:260px;">'.esc_html($label).'</th>';
|
||||||
|
echo '<td><input type="text" name="'.esc_attr($field).'" value="'.esc_attr($val).'" class="regular-text" placeholder="#rrggbb" /> ';
|
||||||
|
echo '<span style="display:inline-block;width:18px;height:18px;border:1px solid #ccc;vertical-align:middle;background:'.esc_attr($val).';"></span>';
|
||||||
|
echo '</td>';
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</tbody></table>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_style_layout() {
|
||||||
|
$s = d2s_ki_get_style();
|
||||||
|
$name = D2S_KI_OPT_STYLE;
|
||||||
|
|
||||||
|
echo '<table class="widefat striped" style="max-width:760px;"><tbody>';
|
||||||
|
|
||||||
|
$rows = [
|
||||||
|
['Border-Radius', "{$name}[radius]", $s['radius'], 'z.B. 999px / 14px'],
|
||||||
|
['Padding Y', "{$name}[pad_y]", $s['pad_y'], 'z.B. 0.65rem'],
|
||||||
|
['Padding X', "{$name}[pad_x]", $s['pad_x'], 'z.B. 1rem'],
|
||||||
|
['Gap', "{$name}[gap]", $s['gap'], 'z.B. 0.5rem'],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($rows as [$label, $field, $val, $hint]) {
|
||||||
|
echo '<tr>';
|
||||||
|
echo '<th style="width:260px;">'.esc_html($label).'</th>';
|
||||||
|
echo '<td><input type="text" name="'.esc_attr($field).'" value="'.esc_attr($val).'" class="regular-text" placeholder="'.esc_attr($hint).'" /></td>';
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</tbody></table>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_field_style_fx() {
|
||||||
|
$s = d2s_ki_get_style();
|
||||||
|
$name = D2S_KI_OPT_STYLE;
|
||||||
|
|
||||||
|
echo '<table class="widefat striped" style="max-width:760px;"><tbody>';
|
||||||
|
|
||||||
|
$rows = [
|
||||||
|
['Shadow', "{$name}[shadow]", $s['shadow'], 'z.B. 0 6px 20px rgba(0,0,0,.12)'],
|
||||||
|
['Shadow Hover', "{$name}[shadow_h]", $s['shadow_h'], 'z.B. 0 8px 26px rgba(0,0,0,.18)'],
|
||||||
|
['Scale Hover', "{$name}[scale_h]", $s['scale_h'], 'z.B. 1.02'],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($rows as [$label, $field, $val, $hint]) {
|
||||||
|
echo '<tr>';
|
||||||
|
echo '<th style="width:260px;">'.esc_html($label).'</th>';
|
||||||
|
echo '<td><input type="text" name="'.esc_attr($field).'" value="'.esc_attr($val).'" style="width:100%;max-width:520px;" placeholder="'.esc_attr($hint).'" /></td>';
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</tbody></table>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function d2s_ki_admin_page_render() {
|
||||||
|
if (!current_user_can('manage_options')) return;
|
||||||
|
|
||||||
|
echo '<div class="wrap">';
|
||||||
|
echo '<h1>D2S KI-Erklärbuttons</h1>';
|
||||||
|
echo '<form method="post" action="options.php">';
|
||||||
|
|
||||||
|
settings_fields('d2s_ki_buttons_settings');
|
||||||
|
do_settings_sections('d2s-ki-buttons');
|
||||||
|
submit_button('Speichern');
|
||||||
|
|
||||||
|
echo '</form>';
|
||||||
|
|
||||||
|
echo '<hr />';
|
||||||
|
echo '<h2>Info</h2>';
|
||||||
|
echo '<p><strong>Shortcode:</strong> <code>[d2s_ki_buttons]</code></p>';
|
||||||
|
echo '<p><strong>Prompt-Beispiel (Trennung):</strong><br><code>' . esc_html(d2s_ki_get_prompt_prefix()) . "\\n\\nhttps://example.com/dein-artikel/</code></p>";
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
70
d2s-askki/style.css
Normal file
70
d2s-askki/style.css
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* Donau2Space – KI-Erklärbuttons
|
||||||
|
Styling via CSS-Variablen (werden im Admin gesetzt) */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--d2s-gpt-bg: #10a37f;
|
||||||
|
--d2s-gpt-fg: #ffffff;
|
||||||
|
|
||||||
|
--d2s-grok-bg: #000000;
|
||||||
|
--d2s-grok-fg: #ffffff;
|
||||||
|
|
||||||
|
--d2s-pplx-bg: #1557ff;
|
||||||
|
--d2s-pplx-fg: #ffffff;
|
||||||
|
|
||||||
|
--d2s-radius: 999px;
|
||||||
|
--d2s-pad-y: 0.65rem;
|
||||||
|
--d2s-pad-x: 1rem;
|
||||||
|
--d2s-gap: 0.5rem;
|
||||||
|
|
||||||
|
--d2s-shadow: 0 6px 20px rgba(0,0,0,.12);
|
||||||
|
--d2s-shadow-h: 0 8px 26px rgba(0,0,0,.18);
|
||||||
|
--d2s-scale-h: 1.02;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2s-ki-buttons {
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--d2s-gap);
|
||||||
|
align-items: center;
|
||||||
|
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2s-ki-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.55rem;
|
||||||
|
padding: var(--d2s-pad-y) var(--d2s-pad-x);
|
||||||
|
border-radius: var(--d2s-radius);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 700;
|
||||||
|
box-shadow: var(--d2s-shadow);
|
||||||
|
transition: transform .12s ease, box-shadow .12s ease, opacity .12s ease;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2s-ki-btn:focus {
|
||||||
|
outline: 2px solid rgba(0,0,0,.25);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2s-ki-btn:hover {
|
||||||
|
transform: scale(var(--d2s-scale-h));
|
||||||
|
box-shadow: var(--d2s-shadow-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2s-ki-chatgpt { background: var(--d2s-gpt-bg); color: var(--d2s-gpt-fg); }
|
||||||
|
.d2s-ki-grok { background: var(--d2s-grok-bg); color: var(--d2s-grok-fg); }
|
||||||
|
.d2s-ki-perplexity { background: var(--d2s-pplx-bg); color: var(--d2s-pplx-fg); }
|
||||||
|
|
||||||
|
.d2s-ki-icon { font-size: 1.05em; }
|
||||||
|
.d2s-ki-text { white-space: nowrap; }
|
||||||
|
|
||||||
|
.d2s-ki-hint {
|
||||||
|
opacity: 0.7;
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.d2s-ki-hint { opacity: 0.85; }
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue