Diesmal war ich schneller: der neue Widget-Editor ist auch buggy

Ich habe mir gerade eine lokale Sicherungskopie dieses Blogs erstellt, weil ich damit mein Stichwort-Plugin testen möchte. Siehe hierzu übrigens folgende sehr informative Seite: bestehendes WordPress Blog…lokal kopieren (schon etwas älter, funkt aber)

Und, was soll ich sagen: ich wollte die Widgets anpassen, weil ein paar davon Fehlermeldungen geschmissen haben, und der Widget-Editor kam im neuen Gewand als Blockeditor und hat Kraut, Rüben und Fehler geliefert. Flugs das Plugin Classic Widget gesucht, gefunden und installiert, und schon läuft es wieder rund mit den Widgets. Oh Mann… ich liebe Gutenberg wirklich! 😉

Mal gucken, wie stabil der lokale Blog läuft, ich werde jetzt testen ob mein Stichwort Plugin tut was es soll. Es bleibt spannend!

Stichwortverzeichnis: so siehts aus (Screenshots)

Man nehme: den Shortcode [el_stichwort] und füge ihn in einer Seite deiner Wahl ein:

Das erzeugt zunächst aus der CSV-Datei ein Stichwortregister mit weiterführenden Links:

Screenshot Stichwortregister

Klick auf ein Stichwort öffnet eine Linkliste mit den zu diesem Stichwort gefundenen Rezepten:

Klick auf den Link öffnet das Rezept:

Screenshot Rezept

Eine runde Sache, und wenn ichs selber sage. Es ist noch ein bisschen Feinarbeit nötig, evtl. Sollte ich meine beiden Plugins zusammenfassen, aber das ist mir bei meiner mangelnden Fehlerbehandlung zu tricky. Eigentlich kam ich auf die Idee mit der Aufteilung in zwei Plugins daher, dass ich dank Gutenberg ständig Fehler bei der Shortcode-Ausführung hatte. Muss man sich mal vorstellen… das ist schon schwer buggy.

Ich lass es jetzt erstmal gut sein. Es war ein spannendes Projekt. Vielleicht mach ich noch die Positiv/Negativliste, wenns mich anspringt, aber jetzt ist erst mal Pause.

Jetzt aber: wir erstellen ein Stichwortverzeichnis mit Linkliste

Natürlich hab ich (design as you go) den PAP noch ein paar mal radikal geändert und das Konzept einige Male wieder über den Haufen geschmissen. Aber jetzt läuft zumindest eine Rohfassung, und die möchte ich euch nicht vorenthalten. Was bei mir wie immer fehlt ist eine Foolproof Fehlerbehandlung, da müsste man noch einiges tun. So wie es ist kann man das Ding keinesfalls in einer echten, life WordPress Installation verwenden, das wäre selbstmörderisch. Aber auf meinem lokalen Webserver ist es gut aufgehoben und kann als Ausgangsmaterial für ein vernünftiges Plugin dienen.

Die wichtigsten Punkte in meinem umgearbeiteten PAP im Überblick:

  • es gibt zwei Plugins. Eins erstellt die CSV-Datei mit den Stichworten aus den Titeln der Beiträge. Das zweite erzeugt eine Konfiguration für die Ausgabe (später mehr) und stellt einen Shortcode bereit, der das Stichwortverzeichnis an einer beliebigen Stelle (Seite) erzeugt.
  • Die CSV-Datei findet auf wundersame Weise ihren Weg in das Verzeichnis des zweiten Plugins. Das Plugin liest die Datei zeilenweise in ein Array ein und erzeugt daraus ein hübsch alfabetisch sortiertes Stichwortregister. Klick auf ein Stichwort öffnet eine Unterseite und gibt als Parameter das aktuelle Stichwort mit.
  • Damit eine Liste der gefundenen Beiträge zu einem Stichwort ausgegeben werden kann, ist die Ausgabe auf einer Unterseite zwingend notwendig. Dies ist eine ganz normale WordPress-Seite, die beim Anlegen der Plugin-Konfiguration neu erzeugt wird. Sie enthält nur einen Shortcode, der den beim Aufruf übergebenen Parameter stichwort übernimmt und daraus eine Liste der Beiträge zu diesem Stichwort erstellt. Die ID und der Permalink dieser Seite werden in der wp_options gespeichert. Diese Seite taucht auch ganz normal unter „Alle Seiten“ auf. Wenn man sie löscht – Pech. Da fehlt wieder die Fehlerbehandlung.
  • Vorläufig gibt es keine Möglichkeit, die Konfiguration des zweiten Plugins nachträglich zu ändern. Für Entwickler: man kann die Einträge in der wp_options manuell löschen, dann kann man die Konfiguration neu schreiben. Das sollte man aber nicht im laufenden Betrieb tun, Pfusch auf der Datenbank kann zu Serverabstürzen führen. Hier To Do.

So, genug ge-PAP-t. Jetzt wollen wir uns mal das Plugin ShortcodeStichwort näher ansehen.

Teil 1 die Konfiguration

Ich erzeuge zunächst einen Eintrag im Admin-Menü, wie gehabt:

//********************* Eintrag im Adminmenü erzeugen
  add_action('admin_menu', 'shortcodestichwort_plugin_setup_menu');
	
	function shortcodestichwort_plugin_setup_menu(){
    add_menu_page( 'ShortcodeStichwort', 'Shortcode Stichwort Konfiguration', 'manage_options', 'shortcodestichwort', 'shortcodestichwort_init' );
}

Dann gehts los: die Funktion shortcodestichwort_init fragt zuerst mal ab, ob eine Konfiguration bereits existiert, dazu hab ich einen Flag in der Options-Tabelle gesetzt:

function shortcodestichwort_init(){
	echo "<h2>Konfiguration für die Ausgabe Stichwortverzeichnis</h2>";
	
	//Prüfen, ob bereits eine Konfiguration gespeichert wurde
	$checkkonfig = get_option('stichwortkonfigexists');
	
	if ($checkkonfig == ""){
	echo "Noch keine Konfiguration gespeichert. Sie müssen einmal auf den Button Konfiguration speichern klicken. ";}

Der Button „Konfiguration speichern“ wird nur angezeigt, wenn noch keine Konfiguration vorhanden ist. Gleich mehr.

Wenn bereits eine KOnfiguration vorhanden ist, wird sie ausgelesen und angezeigt:

if ($checkkonfig == 'existiert'){
		echo "Konfiguration auslesen</br>";
		echo "Konfiguration: ".get_option('stichwortkonfigexists')."</br>";
		echo "Name der CSV-Datei: ".get_option('name_csvdatei')."</br>";
		echo "URL der Ausgabeseite: ".get_option('url_ausgabeseite')."</br>";
		echo "ID der Ausgabeseite: ".get_option('id_ausgabeseite')."</br>";
	}

Das Formular wird nur angezeigt, wenn noch keine Konfiguration vorhanden ist (To Do)…

//***************Begin Formular
//Formular und Button nur anzeigen, wenn Konfiguration noch nicht existiert
if ($checkkonfig == ""){
//Formular mit Buttons 
// Konfiguration speichern schreibt die Parameter in die wp_options

echo "<form action = '#' method = 'post'>";
	
	echo "<input type='submit' id='el_button2' name='ButtonKonfig' value='Konfiguration speichern'>";
	echo "</form>";
	
	if (isset($_POST['ButtonKonfig'])){
			
			return konfiguration_speichern();
		}
//*****************End Formular	
	
}

Die beim Klicken auf den Button aufgerufene Funktion konfiguration_speichern() macht Folgendes: Sie setzt den Flag stichwortkonfigexists und schreibt den Dateinamen der CSV-Datei in die wp_options. Dann wird die Ausgabeseite neu erstellt, sie kriegt gleich den Shortcode zur Erstellung der Linkliste mit. Dateiname und ID werden in der wp_options gespeichert.

function konfiguration_speichern(){
	echo "Ich speichere die Konfiguration";
	add_option('stichwortkonfigexists', 'existiert');
	add_option('name_csvdatei','stichwortliste.csv');
	
	
	//Hier wird die Ausgabeseite neu erstellt und gleich der Shortcode für die Unterseite mitgegeben
	
	$my_post = array(
          'post_title'    => 'Ausgabeseite für das Stichwortverzeichnis',
          'post_content'  => '[links_ausgeben]',
          'post_status'   => 'publish',
          'post_author'   => 1,
          'post_category' => array(1),
          'post_type'     => 'page'
          );

          // Insert the post into the database
          //wp_insert_post( $my_post );
		  $seite_erzeugen = wp_insert_post( $my_post );
		  
		  echo $seite_erzeugen;
		  echo get_permalink($seite_erzeugen);
		  $guid_seite = get_permalink($seite_erzeugen);
		  echo "Seite erzeugt";
		  //the_guid($my_post);
	
	//Ende Ausgabeseite neu erstellen
	
	//guid und ID in der Tabelle wp_options speichern
	add_option('url_ausgabeseite', $guid_seite);
	add_option ('id_ausgabeseite', $seite_erzeugen);
	
	
}

Das war Teil 1. Ich hol mir mal eine Tasse Tee, Kaffee hab ich heute schon genug gehabt 🙂

Teil 2: die Shortcodes

Ich muss meinen umgestrickten PAP nochmal korrigieren: ich erzeuge zwei Shortcodes. den ersten um das Stichwortregister anzuzeigen (Stichworte alfabetisch nach Buchstaben geordnet) und den zweiten um in der Unterseite die Linkliste anzuzeigen. Frisch ans Werk!

add_shortcode( 'el_stichwort', 'el_stichwort_handler_function' );

function el_stichwort_handler_function(){
	echo "<h2>Stichwortregister</h2>";

Jetzt wird die CSV-Datei zeilenweise eingelesen und auf ein Array gelegt. Die Funktion csv_einlesen schenke ich mir, das kann jeder selber komponieren. Hier ist noch eine Debug-Ausgabe mit der Größe des fertig eingelesenen Arrays drin.

//Variable für Liste bereitstellen
	$listenarray = array();	
	
	//csv-Datei einlesen
	$listenarray=csv_einlesen();
	
	echo "Sizeof listenarray :".sizeof($listenarray)."<br>";
	

Jetzt wirds spannend: ich steppe durch das Alphabet und gebe zu jedem Buchstaben die zugehörigen Stichwörter aus. Jedes Stichwort wird als Link formatiert, der die Unterseite (aus der wp_options) mit dem Parameter stichwort aufruft.

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

	//Durch alfabet durchsteppen
	foreach($alphas as $letter){
		
		
		echo "<h3>Buchstabe ".$letter."</h3></br>";
		
		//Nur einfügen, wenn mit dem richtigen Buchstaben anfängt
		foreach($listenarray as $einwort)
		{
			
			$hilf = substr($einwort,0,1);
			
			//***** Zeile mit a href und dem richtigen Pfad aufbauen ACHTUNG Absturzgefahr
			if ($hilf == $letter){
				
				//*****Ausgabeseite wert der Option holen und damit aufmachen
				$pfad_unterseite = get_option('url_ausgabeseite');
								
				//Link auf die Unterseite mit Übergabe des Stichworts als Parameter
				echo '<a href="', "".$pfad_unterseite."?stichwort=$einwort",' ",">', $einwort, '</a></br>';
			
			}
			
		}
		
		
	}//ende for each buchstabe

Schnieke Sache, nicht wahr? Fehlt nur noch der Code zur Erzeugung der Linkliste auf der Unterseite, den muss ich noch ein bisschen bereinigen, der Name der Tabelle Posts ist fest verdrahtet. Aber so funkt es. Ich gehe mit dem Stichwort zuerst ins Feld post_title und gebe die Treffer aus, dann gehe ich nochmal rein, in das Feld post_content (und nicht wie post_title) und gebe die ebenfalls aus. Thazzit!

//**********************Beginn Shortcode für die Ausgabe der Stichwortliste erzeugen To Do: Tabellenname iiiwpposts als Var generieren
add_shortcode( 'links_ausgeben', 'links_ausgeben_handler_function' );

function links_ausgeben_handler_function(){
	echo "<h2>Hier kommt die Linkliste:</h2>";
	
	$aktStichwort = $_GET['stichwort'];
	//echo $aktStichwort;

echo "<h3>".$aktStichwort."</h3>";
$neu=$aktStichwort;

global $wpdb;

//erst treffer aus dem Titel rausfischen
$alleposts = $wpdb->get_results("SELECT DISTINCT(post_title), guid from iii_wpposts where post_title like '%$neu%' and post_status = 'publish' and post_type = 'post'");

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

}


//dann treffer aus dem content ohne treffer aus dem title rausfischen(dubletten vermeiden)
$alleposts = $wpdb->get_results("SELECT DISTINCT(post_title), guid from iii_wpposts where post_title not like '%$neu%' and post_content like '%$neu%' and post_status = 'publish' and post_type = 'post'");

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

}
}//**********************Ende Shortcode für die Ausgabe der Stichwortliste erzeugen

Jetzt fehlen noch ein paar Screenshots, aber dafür gibts einen neuen Beitrag.

Danke, Gutenberg! Wenn Shortcodes nicht funzen…

… nehme man den Classic Editor. Nee, ohne Schmarrn, dem ist so. Ich hab gestern gedacht ich werde noch wahnsinnig, meine Shortcodes tun nicht das was sie sollen, ich krieg ständig diese bescheuerten JSON-Fehler. Permalinks neu erstellt, an- und abgemeldet, Webserver neu gestartet, half alles nix. Bis ich dann beim googlen auf den Hinweis gestossen bin, dass man auf den Classic Editor zurückswitchen soll, wenn diese Fehler auftreten.

Gesagt, getan. Und was soll ich sagen? Jetzt funken meine Shortcodes wieder. Das darf doch wohl nicht wahr sein! Ist natürlich verdammt ärgerlich. Und ich weiss nicht, ob ich bei meinen Life-Blogs wirklich auf den Classic Editor umstellen möchte, das muss ich mir noch schwer überlegen. Ist schon ein dicker Hund.

Stichwortverzeichnis: ich brauche einen neuen PAP

Tja, so kanns gehen. Meine Recherchen haben ergeben, das ich um eine eigens erstellte Ausgabeseite für das Stichwortverzeichnis nicht herumkomme. Mir schwebt da eine Lösung vor, dass ich den Plugin-Admin-Menüpunkt um eine Funktionalität erweitere: „Konfiguriere Ausgabeseite“. Da kann ich auf folgendes Snippet zurückgreifen:

$my_post = array(
          'post_title'    => 'hello',
          'post_content'  => 'This is my post.',
          'post_status'   => 'publish',
          'post_author'   => 1,
          'post_category' => array(1),
          'post_type'     => 'page'
          );

          // Insert the post into the database
          wp_insert_post( $my_post );

Dann müsste ich eigentlich die URL der neu erstellten Seite abgreifen können, und die wiederum könnte ich für die Erzeugung der Links verwenden. In die Seite muss natürlich noch ein Shortcode rein, der den übergebenen Parameter Stichwort auffängt und damit eine Liste der zu diesem Stichwort gefundenen Beiträge erstellt. Mit LInks aus der guid natürlich.

Halbwegs klar? Ich muss mir natürlich merken, wie meine Seite heißt und was sie für eine URL gekriegt hat, das erledige ich wahrscheinlich mit einem Eintrag in der wp_options. Da müsste ich sowieso ein paar Init-Werte reinschreiben, wie den CSV-Dateinamen, aber das ist nur so ein Randgedanke. Ich kann mir dann die Möglichkeit offenhalten, eine bereits existierende Ausgabeseite beizubehalten oder zu ersetzen, da muss ich mal gucken wie weit ich komme. Hach ja, morgen ist auch noch ein Tag. Es bleibt spannend.

Stichwortverzeichnis: der Shortcode

In WordPress einen Shortcode zu erzeugen ist recht einfach. Man fügt einfach folgenden Code ein:

//**********************Beginn Shortcode erzeugen
add_shortcode( 'shortcode_name', 'shortcode_handler_function' );

function shortcode_handler_function(){
	echo "Ich bin dein Shortcode";
	}

//***************End Shortcode erzeugen

Jetzt an beliebiger Stelle in einem Beitrag oder auf einer Seite das Kürzel [shortcode_name] einfügen und hoffen dass es funkt… ich hab da öfter eine JSON-Fehlermeldung, die sich durch ab- und wieder anmelden oder Plugin neu aktivieren beheben liess, aber nicht immer. WordPress kann auch sehr zickig sein wenn man versucht einen Shortcode umzubenennen, da gibts gern mal chaotische Fehlermeldungen. Sei’s drum.

Ich habe mich dafür entschieden ein eigenes Plugin für die Erzeugung des Shortcodes zu erstellen, dann hab ich den Code sauber getrennt und tu mir leichter mit dem Fehlerkorrigieren. Der Shortcode soll die CSV-Datei mit den Stichworten zeilenweise einlesen und in ein Array schreiben, daraus basteln wir dann das alfabetisch sortierte Stichwortverzeichnis mit den Links. Wie ich das mit der Unterseite löse weiß ich noch nicht, da heißts design as you go 🙂

Aber jetzt wollen wir mal.

Zuerst mal müssen wir unsere CSV-Datei einlesen und den Inhalt auf eine Array-Variable legen. Das geht zum Beispiel so:

//Variable für Liste bereitstellen
	$listenarray = array();	
	
	//csv-Datei einlesen
	$listenarray=csv_einlesen();

Die Funktion csv_einlesen sieht dann so aus:

function csv_einlesen(){
	
	//Verzeichnis ermitteln
	$dir = plugin_dir_path( __FILE__ );
	$aktVerzeichnis = $dir;
	
	//Der Name der CSV-Datei ist fest verdrahtet, das wäre nice to have anders
	$neuName = $aktVerzeichnis.'stichwortliste.csv';
	echo "Lese aus Datei ".$neuName."</br>";
	
	//Array anlegen
	$aktListe = array();
	
	
// Datei öffnen, $handle ist der Dateizeiger
$handle = fopen ($neuName,'r');
//Solange nicht EOF erreicht, 1000 ist die maximale Zeilenlänge
while (($csv_array = fgetcsv ($handle, 1000)) !== FALSE ) {

  foreach ($csv_array as $index) {
    //echo $index . '<br>';
	//Hier kommt der Knackpunkt: Neues Stichwort in Array schreiben
		  //***********************************
		  array_push($aktListe, $index);
		  //***********************************
  }
}

fclose($handle);

//Debug-Ausgabe
echo "Array eingelesen, Anzahl der Wörter: ".sizeof($aktListe)."</br>";


return $aktListe;	
	
}//Ende csv_einlesen

Das ist jetzt nicht weiter tragisch, der Witz ist dass das Array mit den eingelesenen Stichwörtern als Rückgabewert der Funktion dient. Damit können wir weiterarbeiten.

Als nächstes bauen wir ein schönes, alfabetisch geordnetes Stichwortverzeichnis auf, dazu brauchen wir zunächst mal ein Array mit allen Buchstaben des Alphabets. Durch das steppen wir durch und geben die Stichworte aus, wenn sie mit dem richtigen Buchstaben anfangen.

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

	//Durch alfabet durchsteppen
	foreach($alphas as $letter){
		
		
		echo "<h2>Buchstabe ".$letter."</h2></br>";
		
		//Nur einfügen, wenn mit dem richtigen Buchstaben anfängt
		foreach($listenarray as $einwort)
		{
			
			$hilf = substr($einwort,0,1);
			
			
			if ($hilf == $letter){
						
				echo $einwort."</br>";
//************************************************To Do: Link erzeugen
			}
			
		}
		
		
	}//ende for each buchstabe

Dann hörts aber auf. Ich suche noch nach einer eleganten Möglichkeit, die Liste als Links zu formatieren, die dann eine Unterseite aufmachen. Auf der Unterseite sollen natürlich alle Rezepte zum gewählten Stichwort angezeigt werden. Das funktioniert, solange ich eine statische Seite generiere und deren URL fest verdrahtet mitgebe, der Code für den Link sieht dann so aus:

echo '<a href="', "http://localhost:819/inselfisch-kochbuch/alle-eintraege-zu-stichwort/?stichwort=$einwort'",' ",">', $einwort, '</a></br>';	

Das ist jetzt aber nicht der Weisheit letzter Schluss, fest verdrahtete Dateinamen sind ganz, ganz schlechter Stil. Da muss ich mir was anderes einfallen lassen. Ich hab jetzt mal eine Anfrage im deutschen WordPress-Forum gestartet, mal schauen ob da was dabei rauskommt. Einstweilen: einen frischen Kaffee!

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! 😉

Stichwortverzeichnis: frisch gewagt in PHP und WordPress

Ich hab mich so über die unzuverlässige Asc()-Funktion in Access geärgert, jetzt hab ich mir die ganze Mechanik der Stichwort-Extraktion nochmal in PHP angetan, das funktioniert wesentlich zuverlässiger und erspart mir ausserdem den ständigen Datenimport/Export.

Praktisch gelöst wird die ganze Sache erst einmal über einen Shortcode, da musste ich jetzt schon nochmal überlegen wie das genau ging, ist lange her. Und wie ich so in $wpdb-Nostalgie schwelge, ist mir ein anderer Dreh eingefallen, wie ich die Stichwörterliste aus den Post-Titeln extrahieren kann, nämlich völlig dynamisch mithilfe von Arrays. Bei einigen Hundert Wörtern geht das noch sehr locker, da brauche ich mir wegen der Performance noch keine Gedanken zu machen…. dachte ich zuerst mal.

Nachdem mir aber ein paar mal hintereinander der lokale Webserver abgeraucht ist bei dem Versuch, eine dynamische Stichwortliste mit Links zu erzeugen, habe ich mich für eine Hybridlösung entschieden. Ich werde die Erzeugung der Quelldaten für das Stichwortverzeichnis doch über eine Tabelle abwickeln, das ist der erste Schritt. Dafür baue ich mir nach Erzeugung und Bereinigung des Arrays eine kleine MySQL-Abfrage, die die vorhandene Tabelle „quelle“ zuerst ausleert und dann neu befüllt. Das wäre natürlich nett, wenn man das über eine Art Benutzerführung abwickeln könnte, aber ich schau erstmal dass ich es überhaupt zum Laufen kriege. Dann kann ich meinen bereits vorhandenen Shortcode zur Erzeugung des Stichwortverzeichnisses aus der Tabelle quelle wiederverwenden, der ist nämlich schon fertig und funkt einwandfrei. Ich hab da so eine Idee, dass man die Datenbasis immer wieder mal neu erstellen können soll, wenn zum Beispiel viele Beiträge dazugekommen sind. Da es für die Erzeugung des Stichwortverzeichnisses aus einer statischen Tabelle keinerlei großartige PHP-Konstrukte braucht, sollte die Performance und Stabilität auch deutlich verbessert werden. Dann hab ich auch noch so eine Idee mit Positiv/Negativliste, mein Plugin könnte lernfähig werden, da gehts schon hübsch in Richtung AI. Morgen ist auch noch ein Tag…