1 Commits

5 changed files with 182 additions and 114 deletions

View File

@@ -9,7 +9,11 @@
} }
const promptField = document.getElementById('groq-ai-term-prompt'); const promptField = document.getElementById('groq-ai-term-prompt');
const outputField = document.getElementById('groq-ai-term-generated'); const outputTopField = document.getElementById('groq-ai-term-generated-top');
const outputBottomField = document.getElementById('groq-ai-term-generated-bottom');
const outputMetaTitleField = document.getElementById('groq-ai-term-generated-meta-title');
const outputMetaDescriptionField = document.getElementById('groq-ai-term-generated-meta-description');
const outputFocusKeywordsField = document.getElementById('groq-ai-term-generated-focus-keywords');
const rawField = document.getElementById('groq-ai-term-raw'); const rawField = document.getElementById('groq-ai-term-raw');
const statusField = document.getElementById('groq-ai-term-status'); const statusField = document.getElementById('groq-ai-term-status');
const applyButton = document.getElementById('groq-ai-term-apply'); const applyButton = document.getElementById('groq-ai-term-apply');
@@ -48,14 +52,27 @@
applyButton.addEventListener('click', () => { applyButton.addEventListener('click', () => {
const descriptionField = document.getElementById('description'); const descriptionField = document.getElementById('description');
const bottomDescriptionField = document.getElementById('groq-ai-term-bottom-description'); const bottomDescriptionField = document.getElementById('groq-ai-term-bottom-description');
if (!outputField) { const rankmathTitleField = document.getElementById('groq-ai-rankmath-title');
const rankmathDescriptionField = document.getElementById('groq-ai-rankmath-description');
const rankmathKeywordsField = document.getElementById('groq-ai-rankmath-keywords');
if (!outputTopField) {
return; return;
} }
if (bottomDescriptionField) { if (descriptionField) {
bottomDescriptionField.value = outputField.value || ''; descriptionField.value = outputTopField.value || '';
} else if (descriptionField) { }
descriptionField.value = outputField.value || ''; if (bottomDescriptionField && outputBottomField) {
bottomDescriptionField.value = outputBottomField.value || '';
}
if (rankmathTitleField && outputMetaTitleField) {
rankmathTitleField.value = outputMetaTitleField.value || '';
}
if (rankmathDescriptionField && outputMetaDescriptionField) {
rankmathDescriptionField.value = outputMetaDescriptionField.value || '';
}
if (rankmathKeywordsField && outputFocusKeywordsField) {
rankmathKeywordsField.value = outputFocusKeywordsField.value || '';
} }
setStatus('Tekst ingevuld. Vergeet niet op "Opslaan" te klikken.', 'success'); setStatus('Tekst ingevuld. Vergeet niet op "Opslaan" te klikken.', 'success');
@@ -76,9 +93,11 @@
rawField.textContent = ''; rawField.textContent = '';
} }
if (outputField) { if (outputTopField) outputTopField.value = '';
outputField.value = ''; if (outputBottomField) outputBottomField.value = '';
} if (outputMetaTitleField) outputMetaTitleField.value = '';
if (outputMetaDescriptionField) outputMetaDescriptionField.value = '';
if (outputFocusKeywordsField) outputFocusKeywordsField.value = '';
fetch(GroqAITermGenerator.ajaxUrl, { fetch(GroqAITermGenerator.ajaxUrl, {
method: 'POST', method: 'POST',
@@ -94,9 +113,25 @@
throw new Error(errorMessage); throw new Error(errorMessage);
} }
if (outputField) { if (outputTopField) {
const text = json.data && json.data.description ? json.data.description : ''; const top = json.data && (json.data.top_description || json.data.description) ? (json.data.top_description || json.data.description) : '';
outputField.value = String(text).trim(); outputTopField.value = String(top).trim();
}
if (outputBottomField) {
const bottom = json.data && json.data.bottom_description ? json.data.bottom_description : '';
outputBottomField.value = String(bottom).trim();
}
if (outputMetaTitleField) {
const metaTitle = json.data && json.data.meta_title ? json.data.meta_title : '';
outputMetaTitleField.value = String(metaTitle).trim();
}
if (outputMetaDescriptionField) {
const metaDescription = json.data && json.data.meta_description ? json.data.meta_description : '';
outputMetaDescriptionField.value = String(metaDescription).trim();
}
if (outputFocusKeywordsField) {
const keywords = json.data && json.data.focus_keywords ? json.data.focus_keywords : '';
outputFocusKeywordsField.value = String(keywords).trim();
} }
if (rawField) { if (rawField) {
rawField.textContent = (json.data && json.data.raw ? String(json.data.raw) : '').trim(); rawField.textContent = (json.data && json.data.raw ? String(json.data.raw) : '').trim();

View File

@@ -2,7 +2,7 @@
/** /**
* Plugin Name: SitiAI Product Teksten * Plugin Name: SitiAI Product Teksten
* Description: Genereer productteksten met diverse AI-aanbieders rechtstreeks vanuit WooCommerce. * Description: Genereer productteksten met diverse AI-aanbieders rechtstreeks vanuit WooCommerce.
* Version: 1.4.3 * Version: 1.4.4
* Author: SitiAI * Author: SitiAI
* Text Domain: siti-ai-product-content-generator * Text Domain: siti-ai-product-content-generator
* Domain Path: /languages * Domain Path: /languages

View File

@@ -321,9 +321,18 @@ class Groq_AI_Product_Text_Settings_Page {
$meta_prompt = get_term_meta( $term_id, 'groq_ai_term_custom_prompt', true ); $meta_prompt = get_term_meta( $term_id, 'groq_ai_term_custom_prompt', true );
$settings = $this->plugin->get_settings(); $settings = $this->plugin->get_settings();
$bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings ); $bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings );
$bottom_description = ''; $effective_bottom_meta_key = '' !== $bottom_meta_key ? $bottom_meta_key : 'groq_ai_term_bottom_description';
if ( '' !== $bottom_meta_key ) { $bottom_description = (string) get_term_meta( $term_id, $effective_bottom_meta_key, true );
$bottom_description = (string) get_term_meta( $term_id, $bottom_meta_key, true ); $rankmath_module_enabled = $this->plugin->is_module_enabled( 'rankmath', $settings );
$rankmath_active = $this->plugin->is_rankmath_active();
$rankmath_title = '';
$rankmath_description = '';
$rankmath_focus_keywords = '';
if ( $rankmath_module_enabled ) {
$rankmath_keys = $this->resolve_rankmath_term_meta_keys( $term, $settings );
$rankmath_title = (string) get_term_meta( $term_id, $rankmath_keys['title'], true );
$rankmath_description = (string) get_term_meta( $term_id, $rankmath_keys['description'], true );
$rankmath_focus_keywords = (string) get_term_meta( $term_id, $rankmath_keys['focus_keyword'], true );
} }
$default_prompt = (string) $meta_prompt; $default_prompt = (string) $meta_prompt;
if ( '' === trim( $default_prompt ) ) { if ( '' === trim( $default_prompt ) ) {
@@ -360,7 +369,6 @@ class Groq_AI_Product_Text_Settings_Page {
<p class="description"><?php esc_html_e( 'Dit is de standaard WordPress term-omschrijving (wordt o.a. gebruikt op categorie/merk paginas).', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></p> <p class="description"><?php esc_html_e( 'Dit is de standaard WordPress term-omschrijving (wordt o.a. gebruikt op categorie/merk paginas).', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></p>
</td> </td>
</tr> </tr>
<?php if ( '' !== $bottom_meta_key ) : ?>
<tr> <tr>
<th scope="row"><label for="groq-ai-term-bottom-description"><?php esc_html_e( 'Omschrijving (onderaan)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th> <th scope="row"><label for="groq-ai-term-bottom-description"><?php esc_html_e( 'Omschrijving (onderaan)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th>
<td> <td>
@@ -369,14 +377,16 @@ class Groq_AI_Product_Text_Settings_Page {
<?php <?php
printf( printf(
/* translators: %s: meta key */ /* translators: %s: meta key */
esc_html__( 'Dit veld wordt opgeslagen in term meta (%s) en wordt onderaan de pagina getoond via LiveBetter customfields.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), esc_html__( 'Deze tekst wordt opgeslagen in term meta (%s) en is bedoeld voor helemaal onderaan (LiveBetter customfields).', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
esc_html( $bottom_meta_key ) esc_html( $effective_bottom_meta_key )
); );
if ( '' === $bottom_meta_key ) {
echo ' ' . esc_html__( 'Let op: stel de juiste LiveBetter meta key in via de plugin-instelling of via de filter groq_ai_term_bottom_description_meta_key.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
}
?> ?>
</p> </p>
</td> </td>
</tr> </tr>
<?php endif; ?>
<tr> <tr>
<th scope="row"><label for="groq-ai-term-custom-prompt"><?php esc_html_e( 'Prompt (optioneel, per term)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th> <th scope="row"><label for="groq-ai-term-custom-prompt"><?php esc_html_e( 'Prompt (optioneel, per term)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th>
<td> <td>
@@ -384,6 +394,34 @@ class Groq_AI_Product_Text_Settings_Page {
<p class="description"><?php esc_html_e( 'Laat leeg om de standaard prompt te gebruiken. Deze prompt wordt gebruikt wanneer je op de knop "Genereer" klikt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></p> <p class="description"><?php esc_html_e( 'Laat leeg om de standaard prompt te gebruiken. Deze prompt wordt gebruikt wanneer je op de knop "Genereer" klikt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></p>
</td> </td>
</tr> </tr>
<?php if ( $rankmath_module_enabled ) : ?>
<?php if ( ! $rankmath_active ) : ?>
<tr>
<th scope="row"><?php esc_html_e( 'Rank Math', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></th>
<td>
<p class="description"><?php esc_html_e( 'Rank Math plugin lijkt niet actief. Velden zijn wel invulbaar en worden opgeslagen in term meta, maar Rank Math gebruikt ze pas na activatie.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></p>
</td>
</tr>
<?php endif; ?>
<tr>
<th scope="row"><label for="groq-ai-rankmath-title"><?php esc_html_e( 'Rank Math meta title', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th>
<td>
<textarea name="groq_ai_rankmath_meta_title" id="groq-ai-rankmath-title" rows="2" class="large-text"><?php echo esc_textarea( (string) $rankmath_title ); ?></textarea>
</td>
</tr>
<tr>
<th scope="row"><label for="groq-ai-rankmath-description"><?php esc_html_e( 'Rank Math meta description', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th>
<td>
<textarea name="groq_ai_rankmath_meta_description" id="groq-ai-rankmath-description" rows="3" class="large-text"><?php echo esc_textarea( (string) $rankmath_description ); ?></textarea>
</td>
</tr>
<tr>
<th scope="row"><label for="groq-ai-rankmath-keywords"><?php esc_html_e( 'Rank Math focus keywords', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></label></th>
<td>
<textarea name="groq_ai_rankmath_focus_keywords" id="groq-ai-rankmath-keywords" rows="2" class="large-text" placeholder="<?php esc_attr_e( 'bijv. luxe massage apparaat, wellness cadeau', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?>"><?php echo esc_textarea( (string) $rankmath_focus_keywords ); ?></textarea>
</td>
</tr>
<?php endif; ?>
</table> </table>
<?php submit_button( __( 'Opslaan', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ); ?> <?php submit_button( __( 'Opslaan', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ); ?>
</form> </form>
@@ -407,19 +445,21 @@ class Groq_AI_Product_Text_Settings_Page {
<textarea id="groq-ai-term-prompt" class="large-text" rows="5"><?php echo esc_textarea( $default_prompt ); ?></textarea> <textarea id="groq-ai-term-prompt" class="large-text" rows="5"><?php echo esc_textarea( $default_prompt ); ?></textarea>
<p> <p>
<button type="submit" class="button button-primary"><?php esc_html_e( 'Genereer', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></button> <button type="submit" class="button button-primary"><?php esc_html_e( 'Genereer', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></button>
<button type="button" class="button" id="groq-ai-term-apply"> <button type="button" class="button" id="groq-ai-term-apply"><?php esc_html_e( 'Zet in velden', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></button>
<?php
if ( '' !== $bottom_meta_key ) {
esc_html_e( 'Zet in onderaan-veld', GROQ_AI_PRODUCT_TEXT_DOMAIN );
} else {
esc_html_e( 'Zet in omschrijving', GROQ_AI_PRODUCT_TEXT_DOMAIN );
}
?>
</button>
</p> </p>
<div id="groq-ai-term-status" class="description" aria-live="polite"></div> <div id="groq-ai-term-status" class="description" aria-live="polite"></div>
<h3><?php esc_html_e( 'Gegenereerde tekst (omschrijving, 1 alinea)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3>
<textarea id="groq-ai-term-generated-top" class="large-text" rows="6"></textarea>
<h3><?php esc_html_e( 'Gegenereerde tekst (onderaan)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3> <h3><?php esc_html_e( 'Gegenereerde tekst (onderaan)', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3>
<textarea id="groq-ai-term-generated" class="large-text" rows="10"></textarea> <textarea id="groq-ai-term-generated-bottom" class="large-text" rows="10"></textarea>
<?php if ( $rankmath_module_enabled ) : ?>
<h3><?php esc_html_e( 'Gegenereerde Rank Math meta title', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3>
<textarea id="groq-ai-term-generated-meta-title" class="large-text" rows="2"></textarea>
<h3><?php esc_html_e( 'Gegenereerde Rank Math meta description', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3>
<textarea id="groq-ai-term-generated-meta-description" class="large-text" rows="3"></textarea>
<h3><?php esc_html_e( 'Gegenereerde Rank Math focus keywords', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3>
<textarea id="groq-ai-term-generated-focus-keywords" class="large-text" rows="2"></textarea>
<?php endif; ?>
<h3><?php esc_html_e( 'Ruwe JSON-output', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3> <h3><?php esc_html_e( 'Ruwe JSON-output', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h3>
<pre id="groq-ai-term-raw" style="background:#fff;border:1px solid #ddd;padding:12px;max-height:240px;overflow:auto;"></pre> <pre id="groq-ai-term-raw" style="background:#fff;border:1px solid #ddd;padding:12px;max-height:240px;overflow:auto;"></pre>
</form> </form>
@@ -438,6 +478,24 @@ class Groq_AI_Product_Text_Settings_Page {
return $key; return $key;
} }
private function resolve_rankmath_term_meta_keys( $term, $settings ) {
$keys = [
'title' => 'rank_math_title',
'description' => 'rank_math_description',
'focus_keyword' => 'rank_math_focus_keyword',
];
$keys = apply_filters( 'groq_ai_rankmath_term_meta_keys', $keys, $term, $settings );
if ( ! is_array( $keys ) ) {
$keys = [];
}
return [
'title' => isset( $keys['title'] ) ? sanitize_key( (string) $keys['title'] ) : 'rank_math_title',
'description' => isset( $keys['description'] ) ? sanitize_key( (string) $keys['description'] ) : 'rank_math_description',
'focus_keyword' => isset( $keys['focus_keyword'] ) ? sanitize_key( (string) $keys['focus_keyword'] ) : 'rank_math_focus_keyword',
];
}
public function handle_save_term_content() { public function handle_save_term_content() {
if ( ! current_user_can( 'manage_options' ) ) { if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'Geen toestemming.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ); wp_die( esc_html__( 'Geen toestemming.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
@@ -450,6 +508,9 @@ class Groq_AI_Product_Text_Settings_Page {
$description = isset( $_POST['description'] ) ? wp_kses_post( wp_unslash( $_POST['description'] ) ) : ''; $description = isset( $_POST['description'] ) ? wp_kses_post( wp_unslash( $_POST['description'] ) ) : '';
$bottom_description = isset( $_POST['groq_ai_term_bottom_description'] ) ? wp_kses_post( wp_unslash( $_POST['groq_ai_term_bottom_description'] ) ) : ''; $bottom_description = isset( $_POST['groq_ai_term_bottom_description'] ) ? wp_kses_post( wp_unslash( $_POST['groq_ai_term_bottom_description'] ) ) : '';
$custom_prompt = isset( $_POST['groq_ai_term_custom_prompt'] ) ? sanitize_textarea_field( wp_unslash( $_POST['groq_ai_term_custom_prompt'] ) ) : ''; $custom_prompt = isset( $_POST['groq_ai_term_custom_prompt'] ) ? sanitize_textarea_field( wp_unslash( $_POST['groq_ai_term_custom_prompt'] ) ) : '';
$rankmath_meta_title = isset( $_POST['groq_ai_rankmath_meta_title'] ) ? sanitize_text_field( wp_unslash( $_POST['groq_ai_rankmath_meta_title'] ) ) : '';
$rankmath_meta_description = isset( $_POST['groq_ai_rankmath_meta_description'] ) ? sanitize_text_field( wp_unslash( $_POST['groq_ai_rankmath_meta_description'] ) ) : '';
$rankmath_focus_keywords = isset( $_POST['groq_ai_rankmath_focus_keywords'] ) ? sanitize_text_field( wp_unslash( $_POST['groq_ai_rankmath_focus_keywords'] ) ) : '';
if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) || ! $term_id ) { if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) || ! $term_id ) {
wp_safe_redirect( $this->get_settings_page_url() ); wp_safe_redirect( $this->get_settings_page_url() );
@@ -470,8 +531,15 @@ class Groq_AI_Product_Text_Settings_Page {
$term = get_term( $term_id, $taxonomy ); $term = get_term( $term_id, $taxonomy );
if ( $term && ! is_wp_error( $term ) ) { if ( $term && ! is_wp_error( $term ) ) {
$bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings ); $bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings );
if ( '' !== $bottom_meta_key ) { $effective_bottom_meta_key = '' !== $bottom_meta_key ? $bottom_meta_key : 'groq_ai_term_bottom_description';
update_term_meta( $term_id, $bottom_meta_key, $bottom_description ); update_term_meta( $term_id, $effective_bottom_meta_key, $bottom_description );
$rankmath_module_enabled = $this->plugin->is_module_enabled( 'rankmath', $settings );
if ( $rankmath_module_enabled ) {
$rankmath_keys = $this->resolve_rankmath_term_meta_keys( $term, $settings );
update_term_meta( $term_id, $rankmath_keys['title'], $rankmath_meta_title );
update_term_meta( $term_id, $rankmath_keys['description'], $rankmath_meta_description );
update_term_meta( $term_id, $rankmath_keys['focus_keyword'], $rankmath_focus_keywords );
} }
} }
} }

View File

@@ -105,20 +105,14 @@ class Groq_AI_Ajax_Controller {
]; ];
} }
$default_bottom_key = isset( $settings['term_bottom_description_meta_key'] ) ? sanitize_key( (string) $settings['term_bottom_description_meta_key'] ) : '';
$bottom_meta_key = apply_filters( 'groq_ai_term_bottom_description_meta_key', $default_bottom_key, $term, $settings );
$bottom_meta_key = sanitize_key( (string) $bottom_meta_key );
$has_bottom_field = ( '' !== $bottom_meta_key );
$top_description = isset( $parsed['description'] ) ? (string) $parsed['description'] : '';
$bottom_description = isset( $parsed['bottom_description'] ) ? (string) $parsed['bottom_description'] : '';
$apply_text = $has_bottom_field ? ( '' !== $bottom_description ? $bottom_description : $top_description ) : $top_description;
wp_send_json_success( wp_send_json_success(
[ [
'top_description' => $top_description, 'top_description' => isset( $parsed['top_description'] ) ? $parsed['top_description'] : ( isset( $parsed['description'] ) ? $parsed['description'] : '' ),
'bottom_description' => $has_bottom_field ? $apply_text : $bottom_description, 'bottom_description' => isset( $parsed['bottom_description'] ) ? $parsed['bottom_description'] : '',
'description' => $apply_text, 'meta_title' => isset( $parsed['meta_title'] ) ? $parsed['meta_title'] : '',
'meta_description' => isset( $parsed['meta_description'] ) ? $parsed['meta_description'] : '',
'focus_keywords' => isset( $parsed['focus_keywords'] ) ? $parsed['focus_keywords'] : '',
'description' => isset( $parsed['description'] ) ? $parsed['description'] : ( isset( $parsed['top_description'] ) ? $parsed['top_description'] : '' ),
'raw' => $response_text, 'raw' => $response_text,
] ]
); );

View File

@@ -425,6 +425,7 @@ class Groq_AI_Prompt_Builder {
} }
$bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings ); $bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings );
$bottom_meta_key = '' !== $bottom_meta_key ? $bottom_meta_key : 'groq_ai_term_bottom_description';
if ( '' !== $bottom_meta_key && $term_id ) { if ( '' !== $bottom_meta_key && $term_id ) {
$bottom = (string) get_term_meta( $term_id, $bottom_meta_key, true ); $bottom = (string) get_term_meta( $term_id, $bottom_meta_key, true );
$bottom = trim( wp_strip_all_tags( $bottom ) ); $bottom = trim( wp_strip_all_tags( $bottom ) );
@@ -474,27 +475,18 @@ class Groq_AI_Prompt_Builder {
$title_pixels = $this->settings_manager->get_rankmath_meta_title_pixel_limit( $settings ); $title_pixels = $this->settings_manager->get_rankmath_meta_title_pixel_limit( $settings );
$desc_pixels = $this->settings_manager->get_rankmath_meta_description_pixel_limit( $settings ); $desc_pixels = $this->settings_manager->get_rankmath_meta_description_pixel_limit( $settings );
$bottom_meta_key = $this->resolve_term_bottom_description_meta_key( null, $settings ); $properties = [
$use_bottom_field = ( '' !== $bottom_meta_key ); 'top_description' => [
$properties = [];
$required = [];
if ( $use_bottom_field ) {
$properties['bottom_description'] = [
'type' => 'string', 'type' => 'string',
'description' => __( 'Uitgebreide HTML-omschrijving (helemaal onderaan) met paragrafen en eventueel lijstjes.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'description' => __( 'Korte HTML-omschrijving (1 alinea) voor de standaard WordPress term description. Exact één alinea in <p>-tags.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'minLength' => 20, 'minLength' => 20,
]; ],
$required[] = 'bottom_description'; 'bottom_description' => [
} else {
$properties['description'] = [
'type' => 'string', 'type' => 'string',
'description' => __( 'HTML-omschrijving (WordPress term description) met paragrafen en eventueel lijstjes.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'description' => __( 'Uitgebreide HTML-omschrijving (helemaal onderaan), 24 alineas, met paragrafen en eventueel lijstjes.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'minLength' => 20, 'minLength' => 20,
],
]; ];
$required[] = 'description';
}
if ( $rankmath_enabled ) { if ( $rankmath_enabled ) {
$properties['meta_title'] = [ $properties['meta_title'] = [
@@ -529,7 +521,7 @@ class Groq_AI_Prompt_Builder {
$schema = [ $schema = [
'type' => 'object', 'type' => 'object',
'properties' => $properties, 'properties' => $properties,
'required' => $required, 'required' => [ 'top_description', 'bottom_description' ],
'additionalProperties' => false, 'additionalProperties' => false,
]; ];
@@ -572,36 +564,24 @@ class Groq_AI_Prompt_Builder {
]; ];
} }
$bottom_meta_key = $this->resolve_term_bottom_description_meta_key( null, $settings );
$use_bottom_field = ( '' !== $bottom_meta_key );
$description = isset( $decoded['description'] ) ? trim( (string) $decoded['description'] ) : '';
$top = isset( $decoded['top_description'] ) ? trim( (string) $decoded['top_description'] ) : ''; $top = isset( $decoded['top_description'] ) ? trim( (string) $decoded['top_description'] ) : '';
$bottom = isset( $decoded['bottom_description'] ) ? trim( (string) $decoded['bottom_description'] ) : ''; $bottom = isset( $decoded['bottom_description'] ) ? trim( (string) $decoded['bottom_description'] ) : '';
// Backward compatibility: older prompts only returned `description`.
if ( $use_bottom_field ) { if ( '' === $top && isset( $decoded['description'] ) ) {
if ( '' === $bottom ) { $top = trim( (string) $decoded['description'] );
$bottom = '' !== $description ? $description : $top;
}
if ( '' === $bottom ) {
return new WP_Error( 'groq_ai_parse_error', __( 'De AI-respons bevatte geen bottom_description veld.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
}
} else {
if ( '' === $description ) {
$description = '' !== $top ? $top : $bottom;
}
if ( '' === $description ) {
return new WP_Error( 'groq_ai_parse_error', __( 'De AI-respons bevatte geen description veld.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
} }
if ( '' === $top && '' === $bottom ) {
return new WP_Error( 'groq_ai_parse_error', __( 'De AI-respons bevatte geen top_description/bottom_description velden.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
} }
$result = []; $result = [];
if ( $use_bottom_field ) { if ( '' !== $top ) {
$result['bottom_description'] = $bottom; $result['top_description'] = $top;
// For backwards compatibility with existing UI, keep `description` alias. // For backwards compatibility with existing UI, keep `description` alias.
$result['description'] = $bottom; $result['description'] = $top;
} else { }
$result['description'] = $description; if ( '' !== $bottom ) {
$result['bottom_description'] = $bottom;
} }
if ( isset( $decoded['meta_title'] ) ) { if ( isset( $decoded['meta_title'] ) ) {
@@ -628,15 +608,10 @@ class Groq_AI_Prompt_Builder {
} }
private function get_term_structured_response_instructions( $settings = null ) { private function get_term_structured_response_instructions( $settings = null ) {
$bottom_meta_key = $this->resolve_term_bottom_description_meta_key( null, $settings ); $schema_parts = [
$use_bottom_field = ( '' !== $bottom_meta_key ); '"top_description":"..."',
'"bottom_description":"..."',
$schema_parts = []; ];
if ( $use_bottom_field ) {
$schema_parts[] = '"bottom_description":"..."';
} else {
$schema_parts[] = '"description":"..."';
}
$rankmath_enabled = $this->settings_manager->is_module_enabled( 'rankmath', $settings ); $rankmath_enabled = $this->settings_manager->is_module_enabled( 'rankmath', $settings );
if ( $rankmath_enabled ) { if ( $rankmath_enabled ) {
@@ -652,13 +627,9 @@ class Groq_AI_Prompt_Builder {
$json_structure $json_structure
); );
if ( $use_bottom_field ) { $instruction .= ' ' . __( 'Zorg dat top_description en bottom_description geldige HTML bevatten. top_description moet exact één alinea zijn in <p>-tags. bottom_description moet 24 alineas bevatten.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
$instruction .= ' ' . __( 'Zorg dat bottom_description geldige HTML bevat. Dit is de tekst die helemaal onderaan de pagina komt.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
} else {
$instruction .= ' ' . __( 'Zorg dat description geldige HTML bevat.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
}
$instruction .= ' ' . __( 'Voeg geen extra tekst buiten het JSON-object toe.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); $instruction .= ' ' . __( 'Voeg geen extra tekst buiten het JSON-object toe.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
$instruction .= ' ' . __( 'Als in de context een sectie "Interne links" staat, verwerk dan 25 van deze links natuurlijk in de hoofdtekst als HTML-links (<a href="URL">Anker</a>).', GROQ_AI_PRODUCT_TEXT_DOMAIN ); $instruction .= ' ' . __( 'Als in de context een sectie "Interne links" staat, verwerk dan 25 van deze links natuurlijk in bottom_description als HTML-links (<a href="URL">Anker</a>).', GROQ_AI_PRODUCT_TEXT_DOMAIN );
return $instruction; return $instruction;
} }