Archiv der Kategorie: Programmierung

Es geht voran mit dem Stichwortregister-Plugin: aus drei mach zwei

Ich hab mir heute nochmal die Erstellung von Admin-Menüs in WordPress zu Gemüte geführt, und beschlossen aus den drei Plugins zur Erstellung eines Stichwortregisters doch zwei zu machen.  Es sind ja auch getrennte Funktionalitäten, einmal wird die Stichwortliste als CSV aus der wp_posts erstellt, eine Ausgabeseite angelegt und in die wp_options eingetragen, und der Shortcode erzeugt, und zum zweiten wird die Negativliste gepflegt. Ausserdem bräuchte ich dann für die Negativliste eine Menütiefe von 3, und da wirds tricky, das kann WordPress nicht so ohne weiteres.

Man könnte die CSV-Datei, die Ausgabeseite und die Tabelle für die Negativliste auch bei Aktivierung des entsprechenden Plugins automatisch erzeugen, aber irgendwie ist es mir sympathischer, das manuell anzustossen. Muss man halt eine recht ausführliche Anleitung mitliefern, aber das krieg ich auch noch gebacken 😉

Jetzt erst mal weiter mit dem Plugin-Zusammenfassen. Läuft ganz gut, ich hab wohl recht sauber programmiert, Morgen mehr!

Update: Das war ja einfach. Ich habe ein schönes Tutorial bei Honar Systems für die Erstellung von WordPress Admin Pages mit Sub Pages gefunden, damit war die Hauptarbeit schon erledigt. Es gibt jetzt einen Menüeintrag „Stichwortregister“ mit zwei Untermenüs „Konfiguration“ und „CSV Datei“. Es gibt des weiteren einen eigenen Menüpunkt „Negativliste bearbeiten“. Hier mal nur ein kurzes Snippet für die Erzeugung der Menüs:

 function stichwortregister_admin_menu() {
add_menu_page(
__( 'Stichwortregister', 'de_DE' ),
__( 'Stichwortregister', 'de_DE' ),
'manage_options',
'stichwort-page',
'stichwortregister_admin_page_contents',
'dashicons-plugins-checked',
3
);
add_submenu_page( 'stichwort-page',
__( 'Stichwortregister', 'de_DE' ),
__( 'CSV-Datei', 'de_DE' ),
'manage_options',
'stichwort-page-sub-menu-csv',
'stichwortregister_sub_menu_admin_page_csv_contents');

add_submenu_page( 'stichwort-page',
__( 'Stichwortregister', 'de_DE' ),
__( 'Konfiguration', 'de_DE' ),
'manage_options',
'stichwort-page-sub-menu',
'stichwortregister_sub_menu_admin_page_contents');


}
add_action( 'admin_menu', 'stichwortregister_admin_menu' );

Die Funktionalitäten haben sich nicht geändert, ich hab sie nur ein bisschen anders einsortiert. Lief problemlos, ich hab da echt sauber gearbeitet. So, jetzt muss es aber gut sein. Zwei Plugins für ein Stichwortregister, damit leben wir einfach 😉

Perfektionisten würden jetzt noch die Stichwortliste in eine MySQL Tabelle packen, aber mir gefällt das mit dem CSV eigentlich ganz gut, vielleicht will man die Liste auch mal extern bearbeiten oder ergänzen. Ich lass es jetzt mal so.

Nachtrag: die Negativliste im praktischen Einsatz

Ich war noch die praktische Anwendung der Negativliste für das Stichwortverzeichnis schuldig, die liefere ich jetzt nach. Wir haben ja unsere Negativ-Wörter in der Tabelle negativliste stehen und können sie per Plugin pflegen.

Jetzt kommt ihr Einsatz: ich mach das an der Stelle, wo die Stichwortliste aus der CSV-Datei eingelesen und in ein Array weggeschrieben wird. Also, wir gehen in die Function csv_einlesen(). Und zwar an die Stelle, wo die CSV mit einer While not EOF-Schleife eingelesen wird. In jeder eingelesenen Zeile wird der Flag für die Negativliste erstmal auf 0 gesetzt. Dann geht man mit einem Select in die Tabelle negativliste und prüft, ob das aktuelle Wort enthalten ist, wenn ja wird der Flag auf 1 gesetzt. Dann geht man hin und schreibt das aktuelle Wort nur in das Array, wenn der Flag == 0 ist. Das wars!

$negativ_flag = 0;

//Solange nicht EOF erreicht, 1000 ist die maximale Zeilenlänge
while (($csv_array = fgetcsv ($handle, 1000)) !== FALSE ) {

foreach ($csv_array as $index) {

$negativ_flag = 0;
//mit Negativliste abgleichen
$db_item = $wpdb->get_results(
"SELECT * FROM negativliste WHERE wort LIKE '$index'");

if (count($db_item) > 0){
$negativ_flag=1;
}

//Nur ausgeben wenn das Wort nicht in der Negativliste enthalten ist
if ($negativ_flag == 0){
//Hier kommt der Knackpunkt: Neues Stichwort in Array schreiben
//***********************************
array_push($aktListe, $index);
//***********************************

} //Ende von if negativ_flag == false
}
}

Ich muss sagen, ich bin mit der Funktionalität sehr zufrieden, so kriegt man mit relativ wenig Aufwand doch recht saubere Stichwörter und kann die kleinen Füllwörtchen prima ausblenden. Mein Progrämmchen ist lernfähig, das grenzt schon ein bisschen an KI 🙂

Stichwortregister revisited: aus drei mach eins

Jetzt hab ich drei Plugins, um ein Stichwortregister zu erzeugen, das ist irgendwie nicht so zufriedenstellend, das könnte man sicher auch zusammenfassen.  Ich mach mal ein Brainstorming und schau was dabei rauskommt.

  • Bei Aktivierung des Plugins sollen ein paar Aufgaben erledigt werden: die Tabelle negativliste mit einigen (wenigen) Beispieldaten soll angelegt werden, einige Setup-Informationen sollen in die wp_options geschrieben werden. Das geht wahrscheinlich mit dem
    register_activation_hook( __FILE__, array( $this, 'example_activate' ) );
    
  • die Erstellung der CSV-Datei mit den Stichworten (aus dem Feld post_title erzeugt) soll manuell angestossen werden, damit man hier bessere Kontrolle hat.
  • Der Abgleich mit der Negativliste soll live bei Erstellung des Stichwortregisters erfolgen.
  • Fleißaufgabe: statt der CSV-Datei könnte man auch eine Custom Tabelle hernehmen, aber dabei ist mir der Webserver zu oft abgeraucht, da hab ich keine Lust drauf.

Das wird natürlich ein ewig langer Rattenschwanz, wenn man das alles in ein einziges Plugin packt, da müsste ich gucken ob man den Ablauf nicht besser straffen und verschlanken kann. Mal schauen ob mich die Arbeitswut noch packt… ich zweifle, die Rohfassung läuft ja ganz hübsch, das langt mir immer 😉

Update am Folgetag: Ich versuch mal meinen inneren Schweinehund zu überwinden und die drei Plugins doch zu einem Paket zusammenzufassen. Ich hab mir dazu mal eine lokale Kopie meines Praxis Dr. Inselfisch Blogs angelegt, auf der ich auf einer „leeren Wiesn“ entwickeln kann. Mal sehen wie weit ich komme.

Update drei Tage später: ich prokrastiniere. Mir ist das einfach zu fad, bereits funktionierende Code Snippets nochmal komplett neu zusammen zu fassen. Na, ich muss mal schauen. wahrscheinlich geh ich eh nochmal drüber, wenn ich das Stichwortverzeichnis auf einem Life-Blog einsetzen möchte. Erster Kandidat ist dieser hier 😉

Der Tabelleneditor für die Negativliste: die Screenshots

Die Negativliste bearbeiten geht nur auf der Admin-Seite, das hab ich mal so festgelegt. Ich habe einen neuen Admin Menüpunkt “ Negativliste bearbeiten“ angelegt, wenn man den aufruft sieht die Startseite so aus:

Negativliste-bearbeiten

Die bereits vorhandenen Worte werden tabellarisch angezeigt, Man kann sie Löschen, dann öffnet sich das Unterformular und man muss nochmal auf den Button „Löschen“ klicken:

Wort-loeschen

Erst dann wird der Delete aktiv:

 Wort-loeschen-OK

 

…oder man kann einen neuen Eintrag anlegen.

Wort-eintragen

Ein kleines, aber rundes Feature, finden sie nicht auch? 🙂

Was mich allerdings beim Entwickeln ein bisschen ausgebremst hat: die Routinen für den Insert und Create und Delete haben mir ein paar Mal den Webserver abgeschossen bis sie fehlerfrei durchgelaufen sind, da half nur ein kompletter Neustart von Apache, MySQL und Xampp. Das darf natürlich in einer „richtigen“ WordPress-Umgebung nicht passieren, da muss man noch Fehlerbehandlungsroutinen einbauen. ich hab da jetzt aber keine Lust mehr dazu.

So, was fehlt noch? Ach ja, die Negativliste wartet noch auf ihren Einsatz beim Aufbau des Stichwortregisters. Das überleg ich mir morgen, wo man da am Geschicktesten einhakt.

Stichwortverzeichnis Negativliste: wir basteln uns einen Tabelleneditor

Ich bin mir ziemlich sicher dass ich sowas in der Art schon mal gemacht habe, aber ich finde es nicht mehr. Na ja, das übt und ist eine hübsche kleine Fingerübung. Ich mach mal einen kurzen PAP:

  • Die Tabelle für die Negativliste wird beim Setup des Stichwort-Plugins mit angelegt und mit einigen wenigen Beispieleinträgen befüllt. Jedenfalls gehe ich davon aus, dass sie schon existiert.
  • Es gibt einen neuen Admin-Menüpunkt Negativliste bearbeiten. Hier wird die existierende Liste tabellarisch angezeigt.
  • Es gibt bei jedem Datensatz einen Button „Löschen“ (mit Rückfrage)
  • Es gibt unterhalb der Tabelle einen Button „Neues Wort eintragen“
  • Die Buttons machen jeweils eine Unterseite auf, auf der die gewählte Aktion nochmal bestätigt wird.

Das wars eigentlich schon. Dann wollen wir mal. Zuerst kommen die Einträge für das Admin-Menü:

add_action('admin_menu', 'negativliste_plugin_setup_menu');

function negativliste_plugin_setup_menu(){
add_menu_page( 'Negativliste', 'Negativliste bearbeiten', 'manage_options', 'negativliste', 'negativliste_init' );
add_submenu_page('Negativliste', 'Eintragen', 'Eintragen', 'manage_options', 'eintragen', 'eintragen_function');
add_submenu_page('Negativliste', 'Loeschen', 'Loeschen', 'manage_options', 'loeschen', 'loeschen_function');
}

Schauen wir uns als erstes mal die Funktion negativliste_init an. Zuerst wird gecheckt, ob die Tabelle negativliste schon vorhanden ist:

//Überprüfen ob Tabelle schon existiert
$table_exists = $wpdb->get_var( "SHOW TABLES LIKE 'negativliste'" ); 

if ($table_exists == "") {
echo "Tabelle negativliste existiert noch nicht";
... (hier kann die Tabelle neu erstellt werden)


Da muss ich nochmal ran, eigentlich sollte die Tabelle beim Initialisieren des Plugins Stichworttabelle mit angelegt werden. Hier nur mal Interessehalber der Code zum Erstellen:

//Begin function tabelle_erzeugen - legt die Tabelle negativliste mit einem Feld "wort" an
function tabelle_erzeugen(){

global $wpdb;

$charset_collate = $wpdb->get_charset_collate();

$sql = "CREATE TABLE negativliste (
wort text
) $charset_collate;";

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );

} //End function tabelle_erzeugen

Interessant wirds im Else-Zweig der Funktion, da  kommt die Datenbankabfrage und der Aufbau der Tabelle zur Anzeige. Ich schau erst mal nach, ob die Tabelle überhaupt Datensätze hat und baue die Tabelle nur auf, wenn es mehr als 0 Datensätze sind:

function tabelle_bearbeiten(){

global $wpdb;
//Datensätze zählen & Ausgabe Anzahl
$count_query = "select count(*) from negativliste";
$num = $wpdb->get_var($count_query);
echo $num."&nbsp Einträge gefunden</br>";

if ($count_query <> 0) {

$anzeige_query = $wpdb->get_results("SELECT wort FROM negativliste ORDER BY wort");
...

So wird der Tabellenhead zusammengebaut:

echo "<table border='1' cellpadding='5'>
<tr>
<th>Wort</th>
<th>delete</th>
</tr>";

Danach steppe ich durch alle gefundenen Datensätze durch und baue ein Formular mit einem Löschen-Button zusammen. Der Button ruft die Unterseite loeschen auf und gibt als Parameter das aktuelle Wort mit.

echo "<form method='post'>";
foreach ($anzeige_query as $dsatz) {
echo "<tr>";
$id = $dsatz->wort;

echo "<td>" . $dsatz->wort . "</td>";
echo "</td>" .
"<td><input type='submit' name='löschen' formaction='admin.php?page=loeschen&aktuell=".$id."' value='löschen'></td>" .

"</tr>";
}// ende von foreach dsatz

Jetzt kommt nur noch ein Link zur der Seite auf der man einen neuen Datensatz eintragen kann, dann wars das auch schon:

echo "<p><input type='submit' name='eintragen' formaction='admin.php?page=eintragen' value='Neues Wort eintragen'></p></form> ";

Jetzt fehlen noch die Funktionen zum Eintragen eines neuen Datensatzes und zum Löschen des gewählten Datensatzes. Zuerst die zum Eintragen:

Zuerst wird ein kleines Formular aufgebaut: es gibt ein Textfeld, in das man das neue Wort eintragen kann, und einen Button zum Speichern. Wenn auf diesen Button geklickt wird, wird der Insert aufgerufen und kriegt das Wort als Parameter mit.

if (isset($_POST['neuesWortEintragen'])){
			$aktWort = $_POST["wort"];
			echo "Neues Wort ".$aktWort." wird eingetragen";
			
	// Insert-Anweisung erstellen
    $check = $wpdb->insert( 'negativliste', array( 'wort' => ''.$aktWort.'' ) );

    if($check) {
        echo "Ein neuer Datensatz erfolgreich hinzugefügt";
    }
	} // ende von isset 

Dann kommt noch ein Link zurück zum Hauptformular, und das wars.

 

echo "</form>";

echo "<a href='admin.php?page=negativliste'>Zurück zur Übersicht</a>";

Das Formular zum Löschen eines Datensatzes sieht ganz ähnlich aus, das Textfeld ist allerdings schreibgeschützt, es dient nur zur Anzeige des als Parameter übergebenen Worts.

function loeschen_function(){

global $wpdb;

$aktWort = $_GET['aktuell'];
echo $aktWort." wird gelöscht";

echo "<h2><Löschen</h2>";

echo "<form action='admin.php?page=loeschen&aktuell='".$aktWort."' method='post'>";
echo "<p><input name='wort' type='text' value = '$aktWort' readonly></p>";
echo "<p><input type='submit' name='WortLoeschen' value='Wort löschen'></p>";
...

Wenn auf den Button „Wort Löschen“ geklickt wird, triggert der Delete-Befehl:

if (isset($_POST['WortLoeschen'])){
$aktWort = $_POST["wort"];
echo "Wort ".$aktWort." wird gelöscht</br>";

// Delete-Anweisung erstellen
$check=$wpdb->query("DELETE FROM negativliste WHERE wort = '$aktWort'");

if($check) {
echo "Ein Datensatz erfolgreich gelöscht";
}
echo "</form>";

Auch hier kommt noch der Link zurück zur Übersicht, und das wars.  Jetzt fehlen noch ein paar Screenshots, aber dafür gibts einen neuen Beitrag.

Stichwortverzeichnis: die Negativ-Liste

Was soll die können? Nun, ganz einfach. Man soll da Wörter eintragen können, die in dieser Schreibweise nicht im Stichwortregister auftauchen sollen.

Hintergrund: die Stichwortliste wird ja programmgesteuert erzeugt und nimmt prinzipiell alle Wörter auf, die großgeschrieben sind. Die werden dann noch von etlichen Sonderzeichen bereinigt, aber es kann natürlich nicht geprüft werden, ob es sich wirklich um Substantive handelt oder ob nur ein Wort am Satzanfang großgeschrieben wurde.  Da rutschen dann schon mal Wörter durch wie Es, Da, Was, Das, So… klar was ich meine? Sind halt keine sinnvollen Stichwörter. Ich hab in der Access-Version mal versuchsweise alle Wörter ausgeblendet, die weniger als 3 Buchstaben haben, aber so ganz das Gelbe vom Ei ist das auch nicht. Auf dem Programmierblog hier würde dann z.B. alle rausfallen was SQL oder PHP oder AI  heißt – nicht gut!

Woher soll mein Plugin aber wissen, welche Wörter es ausblenden soll? Eben! Hier kommt die Negativliste ins Spiel. Ich versuche es mal mit einer Tabelle, obwohl ein CSV sicher auch sinnvoll wäre, das könnte man auch extern bearbeiten. Wie auch immer, es muss ein Admin-Menüpunkt her „Negativliste bearbeiten“. Und die Liste muss an geeigneter Stelle überprüft werden, das mach ich am besten an der Stelle, wo das CSV mit den Stichwörtern in ein Array eingelesen wird. Wenn ein Wort in der Negativliste gefunden wird, soll es nicht ins Array aufgenommen werden. Sollte so oder ähnlich funken, ich fang mal an und berichte später.

Inhaltsverzeichnis revisited: wg PHP 8 und sauber als Shortcode

Ich hab mir schon vor Jahren ein Inhaltsverzeichnis für meine WordPress-Webseiten gebastelt, das hatte ich damals mit PHP Code for Posts realisiert. Jetzt bei der Umstellung auf PHP 8 fällt es auf die Nase, ich musste es also eh noch mal überarbeiten. Es war ein relativ kleines Problem: ich hab in den Funktionsaufrufen für die Ausgabe pro Buchstabe keine Hochkommata für den Parameter dringehabt, das sah so aus:

BuchstabenAusgabe(A);

PHP 8 hätte es aber gern so:

BuchstabenAusgabe("A");

Bei der Gelegenheit hab ich es gleich in einen Shortcode gepackt und den Aufruf der Ausgabe mit einem Array gelöst, und weils so schön geklappt hat gehen wir es hier mal im Galopp nochmal durch.

Als Erstes kommt der Plugin-Header und die Definition des Shortcodes:

/*
Plugin Name: Inhaltsverzeichnis
Plugin URI: http://localhost/zum-schwarzen-pinguin/wp-content/plugins/inhaltsverzeichnis
Description: Erzeugt einen Shortcode [el_inhaltsverzeichnis] , der ein Inhaltsverzeichnis aller veröffentlichten Beiträge aus der Tabelle posts erstellt
Version: 3.0
Author: Evi Leu
Author URI: http://www.evileu.de
*/
add_shortcode( 'el_inhaltsverzeichnis', 'el_inhaltsverzeichnis_handler_function' );
function el_inhaltsverzeichnis_handler_function(){
echo "<h2>Inhaltsverzeichnis</h2>";...

Dann rufe ich die Funktion zur buchstabenweisen Ausgabe mit Hilfe eines Arrays für das Alfabet auf:

//Array mit Alfabet erzeugen
$alphas = range('A', 'Z');

//Durch alfabet durchsteppen
foreach($alphas as $letter){
//Alle Beiträge zu einem Buchstaben ausgeben
BuchstabenAusgabe("$letter");
}

Mit dem Buchstaben gehe ich in die Tabelle posts und hole mir die passenden Einträge heraus. Daraus wird eine Liste mit Links erzeugt, das geht schön mit der guid.

function BuchstabenAusgabe($aktBuchstabe){
global $wpdb;

//Beginn Originalcode
$table_name = $wpdb->prefix . 'posts';

//Datensätze zählen & Ausgabe Anzahl

$count_query = "select count(*) from $table_name where post_status='publish' and post_type = 'post' and post_title like '$aktBuchstabe%'";
$num = $wpdb->get_var($count_query);

//Ausgabe nur wenn auch Datensätze vorhanden sind
if ($num>0) { 
echo "<h2>$aktBuchstabe:&nbsp".$num."&nbsp Beiträge</h2>";

//Alle Datensätze vom Typ post und published ausgeben

$alleposts = $wpdb->get_results( "SELECT post_title, 
post_status, post_type,
guid FROM $table_name
where post_status='publish' and post_type = 'post' and post_title like '$aktBuchstabe%'
order by post_title");

foreach ( $alleposts as $einpost ) 
{ 
echo '<a href="', $einpost->guid, '/",">', $einpost->post_title, '</a></br>';

}

} //Ende if Anzahl grösser Null
//Ende Originalcode
}//ende function BuchstabenAusgabe

Das wars schon, Shortcode an beliebiger Stelle einsetzen und schwupps hat man ein schönes Inhaltsverzeichnis.

Intermezzo: warum ich so eine schlechte Programmiererin bin

Ich programmiere schon seit über 40 Jahren, und das meistens hauptberuflich. Ich habe in meinem Leben schon -zig Projekte kommen, gehen und sterben sehen und schon die tollsten Abenteuer erlebt. Aber eins hab ich noch nie gemocht: Fehlerbehandlungsroutinen (grusel)

Natürlich macht es Sinn, nach dem Versuch sich mit einer externen Datenbank zu verbinden abzuchecken, ob die Verbindung OK ist. Es macht Sinn zu überprüfen, ob eine weggeschriebene Datei existiert und den erhofften Inhalt hat. Es macht Sinn bei Lösch- und Aktualisierungsoperationen einen doppelten Boden einzubauen (..wollen Sie wirklich? Ja/Nein)

D’accord? Tscha, aber ich machs nicht. Seit ich im Ruhestand bin und eigentlich nur noch zum Vergnügen programmiere, erst recht nicht. Schließlich kann ich meistens mit auftretenden Fehlermeldungen etwas anfangen und korrigiere dann meinen Sourcecode entsprechend. Das kann ich mir deshalb erlauben, weil meine Projekte meistens Standalone-Routinen sind, zum Beispiel WordPress-Plugins oder VBA-Module. Mein Code ist selten länger als zwei, drei DIN A 4 Seiten und somit noch recht überschaubar, das geht schon. Guter Programmierstil ist es nicht, schon gar nicht wenn man in grösseren Projekten arbeitet – tu ich aber nicht (mehr).

Ich werde aber den Teufel tun und meine schlechten Programme in echt einsetzen, etwa auf meinen Live-Blogs (Inselfisch.Kochbuch, dieser Blog zum schwarzen Pinguin). Nee, die laufen auf meinem lokalen Xampp-Webserver auf den Test-Installationen oder in einer Access-Datenbank oder einer Exceltabelle, und ich lerne viel dabei. Und sei es, daß ein Programm so instabil läuft, daß es für den Livebetrieb gänzlich ungeeignet ist. That’s life. Mir macht Programmieren trotzdem Spaß! 🙂

Und wer bei mir was abkupfern möchte, kann das gerne tun, muss aber dann seine eigenen Fehlerbehandlungsroutinen einbauen. Ohne gehts im Echtbetrieb nun mal nicht.

Darf ich vorstellen: Stichwort Plugin Teil 1, CSV-Datei erzeugen

Da ich die ganze Mechanik schon mal programmiert habe, in Access mit Visual Basic, hab ich mir relativ leicht getan es auch in PHP zu lösen. Was gar nicht schön war: bei komplexeren Datenbankoperationen ist mir x-mal der Webserver abgeraucht. Deswegen hab ich dann die Notbremse gezogen und bin auf eine CSV-Datei ausgewichen. Nicht die schlechteste Lösung, was Stabilität und Performance angeht.

Was hab ich gemacht? Ich geh da mal im Schnelldurchlauf durch, haben wir alles schon mal so oder in ähnlicher Form gehabt. Trotzdem, das eine oder andere ist vielleicht gut zu wissen.

Also,, zunächst wird ein Plugin mit einem Eintrag für das Admin-Menü erstellt. Dazu legt man eine Datei an, die folgendermassen aussieht:

/*
Plugin Name: Stichworttabelle
Description: Erzeugt eine neue Stichworttabelle aus den Titeln der Beiträge (post_title)
Author: Evi Leu
Version: 0.1
*/
    add_action('admin_menu', 'stichworttabelle_plugin_setup_menu');
	
	function stichworttabelle_plugin_setup_menu(){
    add_menu_page( 'Stichworttabelle', 'Stichworttabelle Plugin', 'manage_options', 'stichworttabelle', 'stichworttabelle_init' );
}
 
function stichworttabelle_init(){... HIER GEHTS MIT DER MAIN FUNCTION LOS

Diese Datei kommt in ein eigenes Unterverzeichnis „Stichworttabelle“ im Plugin-Verzeichnis deiner WP-Installation und heißt Stichworttabelle.php. Sie kann jetzt in der Liste der installierten Plugins aktiviert werden. Sie tut zunächst mal nichts ausser einen Eintrag im Admin-Menü zu erzeugen, der heißt „Stichworttabelle Plugin“ und ist erstmal noch eine leere Seite.

Die Menüseite wird in der Funktion function stichworttabelle_init() mit Leben gefüllt, erst kommt ein bisschen Infotex, dann wird der Name der Datenbank ermittelt und ausgegeben:

echo "<h1>Stichworttabelle neu erstellen</h1>";
	echo "Das Plugin hat zwei Funktionalitäten: </br></br>
	1. Diesen Admin-Menüpunkt Stichworttabelle Plugin, in dem die Stichworttabelle neu aufgebaut werden kann.</br>
	Aus Performancegründe und wegen der Runtime-Stabilität wurde die Stichwortbasis in eine externe CSV-Datei ausgelagert. Diese wird neu erstellt, falls sie nicht schon vorhanden ist. Falls sie schon vorhanden sein sollte, wird sie überschrieben. Man kann die Datei beliebig oft neu erzeugen, z.B. wenn es grössere Mengen neuer Beiträge gibt.</br></br>
	
	2. einen Shortcode [stichwortverzeichnis]. der an beliebiger Stelle in einem Beitrag oder einer Seite eingesetzt werden kann und dort ein Stichwortverzeichnis erzeugt.</br></br>";
	global $wpdb;
	
	//Datenbankname ermitteln
	$mydatabase=$wpdb->dbname;
	echo "Sie arbeiten auf der Datenbank: ".$mydatabase."</br>";
	echo "Stichworte werden aus den Titeln ihrer Beiträge erzeugt</br>";

Dann kommt ein kleines Formular, das aus genau einem Button besteht:

//***************Begin Formular
//Formular mit Button
//"
// Stichwortliste Datei neu erzeugen startet die array-Erzeugung fuellen und befüllt die Datei stichwortliste.csv wieder

echo "<form action = '#' method = 'post'>";
	
	echo "<input type='submit' id='el_button2' name='ButtonFuellen' value='Stichwortliste Datei neu erzeugen'>";
	echo "</form>";
	
	if (isset($_POST['ButtonFuellen'])){
			
			return tabelle_fuellen();
		}
//*****************End Formular

Wenn auf den Knopf gedrückt wird, wird die Funktion tabelle_fuellen aufgerufen. Jetzt wirds interessant:

function tabelle_fuellen(){
	
	$neuesArray=array_erzeugen();
	erzeuge_csv($neuesArray);
}

Die Variable $neuesArray wird mit Hilfe der Funktion array_erzeugen() befüllt. Diese erstellt eine Stichwortliste aus den Titeln aller Beiträge in der Tabelle wp_posts, dazu gleich mehr.

Dann wird die Funktion erzeuge_csv aufgerufen, sie kriegt als Parameter unser Array mit und schreibt die Einträge zeilenweise in eine Datei.

Frischauf, wir sehen uns die Funktion array_erzeugen() mal näher an. Der erste Teil mit den nötigen MySQL-Abfragen sieht so aus:

global $wpdb;

//Beginn Originalcode
$table_name = $wpdb->prefix.'posts';

	//Datensätze zählen & Ausgabe Anzahl
	$count_query = "select count(*) from $table_name where post_status='publish' and post_type = 'post'";
	$num = $wpdb->get_var($count_query);
	echo $num."&nbsp Beiträge gefunden</br>";
	
//******************

//Alle Datensätze vom Typ post und published ausgeben
$alleposts = $wpdb->get_results( "SELECT * FROM ".$table_name."
								where post_status='publish' and post_type = 'post' order by post_title");


Das übliche Spiel wenn man die veröffentlichten Beiträge ausgeben will, man braucht in der Where-Klausel die Bedingung post_status=’publish‘ and post_type = ‚post‘. Und zugegeben, man könnte statt select * auch select post_title verwenden, das fällt mir erst jetzt auf.

Jetzt stecken alle veröffentlichten Beiträge als Array in der Variablen $alleposts. Durch dieses Array steppe ich jetzt mit foreach durch und nehme mir die einzelnen Einträge vor, die werden mit Hilfe der Funktion explode() am Leerzeichen gesplittet, mit preg_replace() von Sonderzeichen bereinigt und mit ctype_upper auf Groß/Kleinschreibung überprüft, ich nehme nur die groß geschriebenen Einträge. Das ist willkürlich festgelegt, produziert aber eine sehr brauchbare Stichwortliste. Schließlich wird der gefundene Eintrag mit array_push() in die Variable $stichwortliste weggeschrieben.

$stichwortliste = array(); 
//Durch alle gefundenen Datensätze durchsteppen
$zaehler = 0;
foreach ( $alleposts as $einpost ) 
{ 
  //ersten gefundenen Titel in array aufsplitten
  $liste = explode(" ", $einpost->post_title);
  
  //Durch das Array durchsteppen
   foreach ($liste as $einwort)
  {
	  //Prüfen, ob Wort groß geschrieben ist
	  $wortanfang = substr($einwort,0,1);
	  
	  //Sonderzeichen entfernen (nach Bedarf editieren)
	  $einwort = preg_replace('/[0-9\@\.\;\" "\(\)\:\?\!\,]+/', '', $einwort);
	  
	  //nur ausgeben wenn Groß geschrieben
	  if (ctype_upper($wortanfang)){
		 
		  $zaehler = $zaehler+1;
		  
		  //Hier kommt der Knackpunkt: Neues Stichwort in Array schreiben
		  //***********************************
		  array_push($stichwortliste, $einwort);
		  //***********************************
	  }// ende von ctype_upper
  }// ende von liste as einwort

  
}//ende von alleposts as einpost und array befüllen

Es folgt noch ein bisschen Kosmetik, und ganz am Ende gibt unsere Funktion das gebrauchsfertige Array zurück:

//Dubletten entfernen
$stichwortliste= array_unique($stichwortliste);

//Array sortieren
sort($stichwortliste);

//Ausgabe Anzahlen erzeugter Stichwörter
echo "Anzahl Stichwörter in den Rohdaten: ".$zaehler."</br>";
echo "Grösse des sortierten und Dubletten-bereinigten Arrays: ".count($stichwortliste)."</br>";
echo "<h2>Erzeuge neue Stichwortliste aus der Tabelle: ".$table_name."</h2>";

return $stichwortliste;
}// ende array erzeugen_function

Noch alle mit mir beieinander? Fehlt noch was? Ach ja, die Erzeugung der CSV-Datei mit Hilfe der Funktion erzeuge_csv(), damit halte ich mich jetzt nicht lange auf, die ist einigermassen selbsterklärend:

function erzeuge_csv($liste){
	
	global $wpdb;
	
	echo "Ich erzeuge jetzt ein csv: ";
	
	//***************
	// Verzeichis des aktuellen Plugins ermitteln
	$dir = plugin_dir_path( __FILE__ );
	$aktVerzeichnis = $dir;
	//Dateiname fest verdrahtet	
	$fileName = $aktVerzeichnis.'stichwortliste.csv';
	echo $fileName."</br>";
	
if(file_exists($fileName)){
	echo "Die alte Datei wird überschrieben</br>";
	}
    
	//Gnadenlos überschreiben, der Parameter 'w' ersetzt den alten Dateiinhalt
	
    $csvFile = fopen($fileName,'w');
    $head = ["Wort"];
    fputcsv($csvFile,$head);

// Variable mit den Listeneinträgen befüllen
foreach ($liste as $einwort){
$data = [
    ["$einwort"],
    
];

//Durch alle data-Einträge durchsteppen und in Datei schreiben

foreach($data as $row){
    fputcsv($csvFile,$row);
}
}
fclose($csvFile);

 //Debug-Ausgabe aller Stichworte
$anzahl = sizeof($liste);
echo "<h2>Testausgabe: ".$anzahl." Stichwörter erzeugt</h2>";

foreach ($liste as $stichwort){
	
	echo $stichwort."</br>";
	
}
		
}// Ende function erzeuge csv
//*****************************************

Falls die Datei nicht existiert, wird sie neu angelegt. Falls sie schon existiert, wird der Inhalt überschrieben. So das wars. Jetzt einen Kaffee und sacken lassen. Und dann Hurra auf zu neuen Ufern, jetzt kommt der Teil mit dem Shortcode. Aber dazu gibts einen neuen Beitrag.

Da knarzt es im Gebälk: ich brauche einen PAP für mein Stichwortverzeichnis

Also, ich hab ja jetzt schon ein paar Tage Gehirnschmalz in das Stichwortverzeichnis investiert, und stelle fest dass die Sache schon hübsch komplex wird. Vor allem muss ich mir Gedanken machen, wer was wann macht (machen darf) und was wohin gehört. Ich mach mal ein Brainstorming:

  • es soll ein WordPress-Plugin (PHP) werden, ich möchte ohne Datenimport/Export in MYSQL arbeiten
  • Auf der WordPress-Adminseite soll es einen neuen Menüpunkt geben: „Stichworttabelle neu erstellen“ . Hier soll erst eine Sicherung der alten Stichworttabelle (falls vorhanden) angelegt werden, dann die Tabelle quelle erst geleert und dann mit der aktuell aus der Tabelle wp_posts (Feld wp_title) neu erstellten Stichwortliste neu befüllt werden.
  • Es soll ein Shortcode mitgeliefert werden [Stichwortverzeichnis], der an beliebiger Stelle auf einer Seite oder in einem Beitrag eingefügt werden kann und der da ein komplettes Stichwortverzeichnis (mit Unterseite) generiert.
  • Es soll eine Positiv- und Negativliste geben, für Wörter die auf jeden Fall/auf keinen Fall im Stichwortverzeichnis auftauchen sollen (nice to have)

Ich seh schon, ich muss mich erst mal wieder mit dem good old WordPress auseinandersetzen, das ist verdammt lang her dass ich was mit Plugins und Admin-Menüs gemacht habe. OK, ich geh mal googlen… bis dann!

Update am Montagmittag: nachdem mir der Webserver noch einige Male unter lautem Jubel abgerauscht ist, schmeisse ich den PAP nochmal über den Haufen. Anscheinend sind die vielen PHP-gesteuerten MySQL-Kommandos zuviel für das gute alte WordPress. Ich machs jetzt ganz anders, ich lege die Stichwörter in eine CSV-Datei. Die sollte man eigentlich gefahrlos wieder auslesen können – ich bin da recht vorsichtig geworden.

Update am Montagabend: Das mit dem CSV war der Schlüssel zum Erfolg, jetzt läuft die ganze Chose stabil. Die Erzeugung einer Stichwortdatei aus den Beitragstiteln der wp_posts läuft einwandfrei, und dauert nicht mal lang. Morgen bastel ich dann den Shortcode, der eben jene CSV-Datei wieder ausliest und das Stichwortverzeichnis an beliebiger Stelle in einem Beitrag oder auf einer Seite aufbaut. Mal sehen ob das ohne grössere Unfälle funkt. Hach, Programmieren ist so eine kurzweilige Sache! 😉