I’ve been stuck on a complex problem for several days and I haven’t found anything to unblock it.
- I’ve created a wordpress plugin, called keywordize, that allows me to modify keywords from about 400 texts sorted by years. I use Mistral AI for that.
- I call the plugin within a wordpress page with a shortcode [keywordize]
- Here is the
keywordize.php file :
function keywordize_enqueue_scripts()
{
wp_enqueue_style('keywordize-style', plugin_dir_url(__FILE__) . 'style.css');
wp_enqueue_script('keywordize-script', plugin_dir_url(__FILE__) . 'script.js', array('jquery'), null, true);
// Get data from DB
global $wpdb;
$r_sujets = "SELECT * FROM Sujet ORDER BY AnneeS DESC;";
$q_sujets = $wpdb -> get_results($r_sujets, ARRAY_A);
$php_vars = array(
'sujets' => $q_sujets,
'pluginDir' => plugin_dir_url(__FILE__),
);
wp_localize_script('keywordize-script', 'php_vars', $php_vars );
}
add_action('wp_enqueue_scripts', 'keywordize_enqueue_scripts');
function keywordize_shortcode()
{
ob_start(); ?>
<div id="keywordize">
<div id="timeout-wrapper">
Timeout : <input id="timeout" type="text"/>
</div>
<div id="years-select-wrapper">
Sélection :
<select id="years-select">
<option value=""></option>
</select>
</div>
<div id="submit-wrapper">
<button id="submit">Submit</button>
</div>
<div id="years-select-wrapper"></div>
<div id="subjects-by-year-wrapper"></div>
<div id="submit-subjects-by-year"></div>
</div>
<div id="update"><?php
include_once('update.php');
?></div>
<?php
return ob_get_clean();
}
add_shortcode('keywordize', 'keywordize_shortcode');
- This php file loads a js file
script.js. This file takes the result of my php request, calls Mistral AI on each text to get keywords from the text, then add lines to the page:
jQuery(document).ready(function ($) {
// get variables from keywordize.php
const sujets = php_vars.sujets;
const pluginDir = php_vars.pluginDir;
console.log("sujets", sujets);
const tempAnnees = sujets.map(sujet => sujet.AnneeS);
const annees = [...new Set(tempAnnees)];
console.log("annees", annees);
$("#timeout").val(1000);
annees.forEach(function (annee) {
$("#years-select").append('<option value="' + annee + '">' + annee + '</option>');
});
$("#submit").on('click', function () {
if ($(this).text() == "Reset") {
$("#timeout").val(1000);
$("#years-select").val("");
$(this).text("Submit");
} else {
$(this).text("Reset");
const annee = $("#years-select").val();
const timeout = $("#timeout").val();
$("#subjects-by-year-wrapper").text("");
const sujetsParAnnee = sujets.filter(function (sujet) {
return sujet.AnneeS == annee;
});
console.log("sujetsParAnnee", sujetsParAnnee);
$("#subjects-by-year-wrapper").append("<br/><h3>" + sujetsParAnnee.length + " sujets pour l'année " + annee + "</h3>");
getKeywords(sujetsParAnnee, timeout, function () {
console.log("FINISHED");
});
}
});
function getOptions(resume) {
return options = {
method: 'POST',
headers: {
'Authorization': 'Bearer API_KEY',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
"model": "mistral-large-2407",
"messages": [
{
"role": "user",
"content": "Donne moi 4 mots-clés issus de ce texte : " + resume
}
]
}),
}
}
function modifyKeywords(submitSubject, idS, keywordsArray) {
console.log("let's replace keywords of subject " + idS);
}
async function getKeywords(sujets, timeout, callback) {
const url = "https://api.mistral.ai/v1/chat/completions";
const nbSujets = sujets.length;
const delay = (ms = timeout) => new Promise(r => setTimeout(r, ms));
let i = 1;
for (let sujet of sujets) {
// Construction des lignes d'accueil de la réponse
const subjectLineWrapper = document.createElement("div");
const formWrapper = document.createElement("div");
formWrapper.setAttribute("class", "form");
const form = document.createElement("form");
form.setAttribute("action", "javascript:;");
const subjectWrapper = document.createElement("div");
subjectWrapper.setAttribute("class", "subject");
const subject = document.createElement("div");
try {
const resume = sujet.TitreS + "." + sujet.DescriptionS;
const response = await fetch(url, getOptions(resume));
if (!response.ok) {
throw new Error('Response status: ' + response.status);
}
const json = await response.json();
const keywords = json.choices[0].message.content;
// console.log(keywords);
// REGEX sur réponse IA keywords
const keywordsArray = [];
const regex = /^[0-9]+. (.*(?:n(?![0-9]+.).*)*)/gm;
// const regex = new RegExp('^[0-9]+\. (.*(?:\n(?![0-9]+\.).*)*)', 'gm')
let match;
while ((match = regex.exec(keywords)) !== null) {
keywordsArray.push(match[1].replaceAll("*", ""));
}
// console.log("keyword array = ", keywordsArray);
// Mise en forme et ajout texte des lignes de réponse
if (i % 2 == 0) subjectLineWrapper.setAttribute("class", "subject-line subject-line-gray");
else subjectLineWrapper.setAttribute("class", "subject-line subject-line-white");
const button = document.createElement("input");
button.setAttribute("type", "submit");
button.setAttribute("value", "Replace keywords");
form.appendChild(button);
formWrapper.appendChild(form);
form.addEventListener('submit', function (event) {
modifyKeywords(event.submitter.value, sujet.IdS, keywordsArray);
});
subject.innerHTML += "(" + i + "/" + nbSujets + ") "
+ sujet.Theme1 + " / "
+ sujet.Theme2 + " / "
+ sujet.Theme3 + " / "
+ sujet.Theme4 + " / "
+ " => " + keywordsArray;
subjectLineWrapper.appendChild(subjectWrapper);
subjectLineWrapper.appendChild(formWrapper);
} catch (error) {
subject.setAttribute("class", "subject-red");
subject.innerHTML += "(" + i + "/" + nbSujets + ") " + sujet.TitreS + " > " + error.message;
subjectLineWrapper.setAttribute("class", "subject-line subject-line-red");
subjectLineWrapper.appendChild(subjectWrapper);
// console.error(error.message);
}
subjectWrapper.appendChild(subject);
document.getElementById("subjects-by-year-wrapper").appendChild(subjectLineWrapper);
await delay();
i++;
};
callback();
}
});
- Everything works perfectly, and I get this result:

- My problem is now this one : how to treat each line, so update each subject (I want it one by one to avoid errors), by clicking each button one by one ? I put here the research I’ve made so far :
function modifyKeywords(submitSubject, idS, keywordsArray) {
console.log("let's replace keywords of subject " + idS);
$.ajax({
url: pluginDir + "update.php",
type: "POST",
data: {
"submitSubject": submitSubject,
"idS": idS,
"keywordsArray": keywordsArray,
},
error: function (xhr, status, error) {
console.log("Error: " + error);
},
success: function (result, status, xhr) {
console.log("Success: " + result);
}
});
}
- So with AJAX, I send some variables to another php file, called
update.php :
$submitSubject = $_POST['submitSubject'];
$idS = $_POST['idS'];
$keywordsArray = $_POST['keywordsArray'];
if (isset($idS))
echo "idS = " . $idS . "<br/>";
- But I’m stuck here because when I click a button, I obtain only a console output, which is my AJAX success.
Success: idS = 585<br/>
- Or if I modify
update.php with $r_subject = "SELECT * FROM Sujet WHERE IdS = $idS;";echo "request = " . $r_subject . "<br>";:
Success: request = SELECT * FROM Sujet WHERE IdS = 586;<br>
- Then I have another error when I execute the request, but it will be another question soon on SO 🙂
So what I want to be able to do is to interact with update.php when I click a button. How to display something in my php file update.php without refreshing ? How my php file knows that some modifications have been made by javascript on itself ? I’m lost 🙂
Many thanks