Archiv der Kategorie: HTML

Noch’n Nachschlag: Formular mit Gedächtnis (reines PHP)

Formular soll sich Eingaben merken

Kennen sie das auch: man hat ein Online-Formular ausgefüllt und auf den „Abschicken“-Button geklickt, und alle Benutzereingaben verschwinden, man hat wieder ein leeres Formular vor sich. Passiert heutzutage gottseidank nicht mehr so oft, aber wenn dann ist es oft verdammt ärgerlich, wenn man nicht das gewünschte Ergebnis erzielt hat und das Formular nochmal von vorn ausfüllen muß. Unser Freizeitsportpartner-Suchformular vom Turnverein Weiß-Blau leidet noch unter dieser Kinderkrankheit, und die wollen wir ihm abgewöhnen. Kurz zur Erinnerung, das Formular sieht so aus:

suchformular

suchformular

Selektive Vorbelegung

Jetzt möchte ich gerne, daß nach dem Klick auf „Abschicken“ die vom Benutzer gesetzten Häkchen in den Checkboxen erhalten bleiben. Bislang sah der Code für eine Checkbox so aus:

echo „<input type=’checkbox‘ name=’turnen‘ value=’ja‘>Turnen<br>“;

Den brechen wir jetzt ein bißchen auf, und wir fragen ab ob denn der Wert für die Checkbox nicht schon mal gesetzt wurde, das sieht dann so aus:

echo „<input type=’checkbox‘ name=’turnen‘ value=’ja'“;
            if ($_POST[‚turnen‘] == ‚ja‘){
            echo „checked=’checked'“;
            }
        echo „>Turnen<br>“;

Das $_POST[‚turnen‘] enthält den aktuellen Wert des Feldes, der ist leer, wenn die Checkbox vor dem Drücken des Abschicken-Buttons leer war, und er enthält ein „ja“, wenn die Checkbox angekreuzt war. Das checken wir mit dem IF ab, und mit dem „checked=’checked'“ setzen wir im ja-Fall das Häckchen.

That’s it! Das machen wir für alle anderen Checkboxen analog, und schon haben wir ein Formular mit Gedächtnis.

Dropdownfeld mit Gedächtnis

Für die, die’s ganz perfekt haben wollen, hier noch die Vorbelegung für das Dropdown-Feld:

/*Begin select*/
echo „Auswahl Fitneß: &nbsp“;
echo „<select name=’meine_auswahl‘>“;

echo „<option“;
if ($_POST[‚meine_auswahl‘] == ‚egal‘){
    echo “ selected“;
}
echo „>egal</option>“;

echo „<option“;
if ($_POST[‚meine_auswahl‘] == ‚Anfänger‘){
    echo “ selected“;
}
echo „>Anfänger</option>“;

echo „<option“;
if ($_POST[‚meine_auswahl‘] == ‚Freizeitsportler‘){
    echo “ selected“;
}
echo „>Freizeitsportler</option>“;

echo „<option“;
if ($_POST[‚meine_auswahl‘] == ‚Profi‘){
    echo “ selected“;
}
echo „>Profi</option></select><br>“;
/*End Select*/

Das können sie sich jetzt aber selber zusammenreimen, der Mechanismus ist genau so wie bei der Checkbox, nur halt für jede Option extra. Zugegeben, es ist ein bißchen Aufwand, aber in Sachen Benutzerfreundlichkeit der Mühe wert.

Mein Freund, der Shortcode – auch auf Knopfdruck mit Button

Warum ich Shortcodes so nützlich finde

Ganz einfach, weil sie die volle Funktionalität von PHP mit all den vielfältigen Möglichkeiten von WordPress vereinen. Ich glaube, daß Shortcodes eins der meistunterschätzten programmiertechnischen Werkzeuge von WordPress sind. Alle Welt schreit immer nach Plugins, aber die sind nicht immer der Weisheit letzter Schluß. Gerade wenn man Ausgaben und Ereignisse auf der für den Benutzer sichtbaren Oberfläche einer Webseite steuern will, sind Shortcodes ein mächtiges Werkzeug und nahezu universell einsetzbar. Sie erlauben durch das wpdb-Objekt vollen Datenbankzugriff (übrigens auf jede beliebige Datenbank, für die man den Connect hat), sie erlauben einem das Einsetzen von Formularen mit all den ausgefuchsten Feinheiten von PHP, sie erlauben die Abfrage der Eigenschaften und die Manipulation nahezu aller WordPress-Objekte, und vieles mehr. Kurz gesagt, sie sind das geniale Universal-Schweizermesser wenn man WordPress programmiererisch zuleibe rücken möchte. Jetzt aber genug der Lobeshymne, heute Abend hab ich noch ein nettes Zuckerl:

Shortcodes auf Knopfdruck mit Buttons

Manchmal wäre es ganz nett, wenn ein Shortcode auf einer Seite oder in einem Beitrag nicht sofort beim Aufruf loslegen würde, besonders dann nicht, wenn man mehrere Shortcodes im selben Objekt einsetzen möchte, das wird schnell unübersichtlich. Dann wäre es ganz nützlich, wenn man erst einmal auf ein entsprechend beschriftetes Knöpfchen drücken könnte, und der Shortcode erst dann ausgeführt wird. Das ist nicht schwer zu realisieren, und die Lösung ist (wie könnte es anders sein) selbst ein Shortcode.

Formular für den Button

Um einen klickbaren Button zu erhalten, lege ich ein kleines Formular an, das nichts ausser einem submit-Button enthält, das sieht so aus:

echo ‚<form method=“post“>‘;
echo ‚<input type=“submit“ name = „senden“ value=“Shortcode abrufen“/>‘;
echo „</form>“;

Was passieren soll, wenn auf den Button geklickt wird, wird wie üblich mit ISSET bestimmt, und hier kommt auch gleich der Witz an der ganzen Sache:

if (isset($_POST[’senden‘]))
{
    //Hier Shortcode einsetzen, wichtig: einfache Hochkommas
    $inhalt = „[form id=’26‘ title=’Anmeldung‘]“;
    echo do_shortcode($inhalt);
}

Die Variable $inhalt wird einfach mit dem String des aufzurufenden Shortcodes belegt, und das kann wirklich ein x-beliebiger Shortcode sein, ob selbst definiert, oder der Shortcode eines Contact-Form-7-Formulars, oder ein MetaSlider-Shortcode oder was einem sonst gerade einfällt. Wichtig ist nur, dass man die doppelten Anführungszeichen in den Shortcode-Parametern durch einfache Hochkommas ersetzt. Mehr ist nicht dran, so sieht das Ganze am Stück aus:
function button_shortcode(){
   
//Begin Formular
echo ‚<form method=“post“>‘;
echo ‚<input type=“submit“ name = „senden“ value=“Shortcode abrufen“/>‘.“<br>“;
echo „</form>“;
// End Formular

if (isset($_POST[’senden‘]))
{
    //Hier Shortcode einsetzen, wichtig: einfache Hochkommas
    $inhalt = „[form id=’26‘ title=’Anmeldung‘]“;
    echo do_shortcode($inhalt);
}
   
}
add_shortcode(‚button‘, ‚button_shortcode‘);

An der gewünschten Stelle im Beitrag oder auf einer Seite den Shortcode [button] einsetzen, und voila, sie haben ihren Shortcode auf Knopfdruck!

Mitgliederverzeichnis mit Adressdaten

Wir basteln uns ein Mitgliederverzeichnis

Damit wir von unserer tabellarischen Ausgabe zu einem vernünftigen Mitgliederverzeichnis komplett mit Fotos kommen, ist ein wenig Handarbeit angesagt, wie immer, wenn man es in WordPress mit einzelnen Beiträgen zu tun hat. Aber keine Bange, wir machen nur das absolute Minimum. Jetzt knüpfen wir uns die neuen Mitglieder der Reihe nach vor und legen uns zu jedem Mitglieds-Datensatz einen eigenen Beitrag an.

Dazu folgende Vorüberlegungen:

  1. Wenn wir den Beitrag einfach mit Vorname und Name des Mitglieds betiteln, kann es zu Konflikten kommen, schließlich können wir mehr als einen „Peter Müller“ oder „Stefan Huber“ in unserer Mitgliederliste haben. Also stellen wir dem Namen einfach die automatisch vergebene id aus der Tabelle mitglieder_stamm voran, dann haben wir Eindeutigkeit. Und weil unsere Mitglieder untereinander per Du sind, verzichten wir auf den Nachnamen und sparen uns Tipparbeit. Unser erster Beitrag erhält also den Titel „1 Ferdinand“, der zweite wird „2 Marius“ heißen, der dritte „3 Ivonne“ usw., einfach der Reihe nach durch.
  2. Das Paßfoto laden wir als Beitragsbild hoch (rechts unten im Beitragseditor bei „Beitragsbild festlegen“), dann haben wir für spätere Ausgaben Zugriff über darauf. Auch das haben wir schon mal gemacht, mit wp_get_attachment_url(get_post_thumbnail_id(post_ID))
  3. Wir legen 1 benutzerdefiniertes Feld an, das heißt „mitglied_id“ und erhält als Inhalt (na was wohl?) unsere eindeutige id.
mitglied_id

mitglied_id

4. Wenn wir den Beitrag für ein neues Mitglied vollständig angelegt haben, könnten wir das Feld „status“ in der Tabelle mitglieder_stamm von „neuzugang“ auf „aktiv“ stellen – jaja ich hörs schon, das sollte man programmgesteuert mit einem Update machen, aber wir operieren hier gerade mal auf einer Handvoll Testdaten, da reicht der manuelle Eintrag. Soll ja auch nur beispielhaft zeigen, daß der Bearbeitungsstand eines Mitgliederdatensatzes durch den Status mitprotokolliert werden kann.

Das wars schon! Den Rest holen wir uns aus der Datenbank, aber ich hol mir mal einen frischen Kaffee während sie die Beiträge anlegen 🙂

Vorüberlegung: was wollen wir im Mitgliederverzeichnis alles ausgeben?

Na, alles! Die kompletten Adressdaten, die sportlichen Präferenzen, das Paßfoto, den ganzen Summs möchten wir im Mitgliederverzeichnis sehen, ohne auch nur ein einziges weiteres Datenfeld manuell eingeben zu müssen. Uns reicht das benutzerdefinierte Feld mitglied_id, darüber verknüpfen wir uns die ganze Tabelle mitglieder_stamm und basteln uns die gewünschte Ausgabe.

Wie sieht es jetzt aus?

Das ist leider sehr abhängig vom Theme und läßt sich nicht so global sagen. Aber wenn sie jetzt auf ihre Beitragsseite gehen, müßten eigentlich die Beitragsbilder(Paßfotos) und die eingegebenen Beitragstitel (1 Ferdinand, 2 Marius…) aufgelistet werden. Manche Themes geben allerdings die Thumbnails (Beitragsbilder) in der Übersicht gar nicht mit aus. Wenn wir jetzt auf einen Beitragstitel klicken, sehen wir – nichts. Völlig korrekt, wir haben ja auch keinerlei Beitragstext eingegeben. Und unser benutzerdefiniertes Feld mitglied_id sehen wir auch nicht, weil es noch nicht in das Template mit eingebunden ist. Also, an die Arbeit. Wenn sie genau nachvollziehen wollen, an welcher Stelle welche Anpassungen wie greifen, wäre es sinnvoll, wenn sie das selbe Theme wie ich verwenden, es ist ein Child-Theme von Twentyfourteen.

Unsere Anpassungen an der single.php

Für die Darstellung der einzelnen Beiträge wird die single.php verwendet, und die nehmen wir uns jetzt vor. Machen sie eine Kopie der Originaldatei, legen sie sie in ihrem Child-Theme-Ordner ab und öffnen sie sie in einem Editor. Unsere Anpassungen erfolgen innerhalb des Loops, unmittelbar vor der Previous/next post navigation, hier im Screenshot wirds deutlich:

innerhalb_des_loops

innerhalb_des_loops

Geben sie hier mal zum Testen nur die einzige Echo-Zeile ein und schauen sie sich einen Beitrag an, da darf nichts stehen ausser dem Text des echo.

Wie kriegen wir jetzt unsere Stammdaten hier rein?

Über eine Verknüpfung mit der Tabelle mitglieder_stamm über das benutzerdefinierte  Feld mitglied_id. Wir geben als allererstes mal nur die mitglied_id aus, das machen wir so:

echo "<h2>Mitgliederdaten</h2>";
                    $akt_mitglied_id = get_post_meta($post->ID, 'mitglied_id', true);
                    echo "Aktuelle Mitglied ID:&nbsp".$akt_mitglied_id."<br>";

Der Witz steckt natürlich in der Funktion get_post_meta, die holt uns zur aktuellen WordPress-ID des Beitrags den Wert des benutzerdefinierten Feldes mit dem Namen „mitglied_id“. Das „true“ bewirkt, daß ein einzelner String ausgegeben wird, mehr brauchen wir nicht.

Jetzt müssen wir noch angeben, aus welcher Tabelle wir die Daten holen wollen, dazu lege ich den Tabellennamen wieder auf eine Konstante, damit man ihn später leicht auswechseln kann, und gönne mir noch eine Debug-Ausgabe.

/*****Haupttabelle Name als Konstante definieren*******/
                    define("MAINTABLE","mitglieder_stamm");                    
                    echo "Aktuelle Tabelle =&nbsp".MAINTABLE."<br>";

Und jetzt haben wir schon alles, was wir für unseren Select brauchen! Der sieht so aus:

$alleposts = $wpdb->get_results( "SELECT * from ".MAINTABLE."
 WHERE id = '".$akt_mitglied_id."'");

Und schon haben wir den richtigen Datensatz anhand der Mitglieds-id herausgefischt! Die Ausgabe der einzelnen Felder erfolgt dann wie gehabt wieder mit einer Foreach-Schleife, ich gebe hier mal beispielhaft nur ein paar Felder aus:

foreach ( $alleposts as $einpost ) {             
                            
                            echo $einpost->vorname."<br>";
                            echo $einpost->nachname."<br>";
                            echo $einpost->ort."<br>";
                            echo $einpost->strassehausnummer."<br>";
                    }

Das Ergebnis

…ist noch nicht besonders hübsch formatiert, aber es zeigt das Prinzip:

maja_daten

maja_daten

Am schönsten sähe es natürlich aus, wenn man die Stammdaten tabellarisch ausgibt, aber das kann sich jeder selber einrichten wie er es möchte. Jedenfalls haben wir übere unsere Verknüpfung mit der mitglied_id Zugriff auf alle Datenfelder der Tabelle mitglieder_stamm, und das war ja genau das, um was es ging. So simpel ist die Lösung mit einer eigenen Tabelle für die Mitgliederdaten!

Klarer Vorteil gegenüber den benutzerdefinierten Feldern

Ausser der mitglied_id muß im Beitrag nichts per Hand eingegeben werden, das erspart einem einen Haufen (fehlerträchtiger) Handarbeit. Stellen sie sich nur mal vor, sie müßten jetzt zu allen Mitgliedern die vollständigen Adressdaten händisch in Custom Fields erfassen – also nee, echt nicht. Das haben wir eleganter gelöst. Und wenn es mal Änderungen an den Benutzerdaten geben sollte, auch die können wir in unser eigenen Tabelle mitglieder_stamm einpflegen, wir müssen dazu nicht den entsprechenden Beitrag bearbeiten. Auch das ist ein weiterer Vorteil, der nicht zu unterschätzen ist. Man kann sich auch mit PHP einen kleinen Mitgliederdaten-Editor basteln, vielleicht mach ich das später mal, das führt jetzt wirklich zu weit. Und jetzt viel Vergnügen beim individuellen Einbinden und Formatieren ihrer Felder!

Turnverein die erste Liste: Mitglieder-Adressen

Ausgabe Adressenliste

Alle alten Programmierer lieben Listen, und wir können uns aus unseren schönen Stammdaten schon eine erste Ausgabe bauen: Namen, Adressen und Telefonnummern nämlich, da brauchen wir gar nichts weiter dazu als unser gutes altes Arbeitspferd PHP Code for Posts. Unsere eigene Tabelle mitglieder_stamm kann nämlich vom $wpdb-Objekt genau so angesprochen werden wie die WordPress-eigenen Tabellen, liegt ja in der selben Datenbank.

Tabelle als Konstante definieren

Da wir ja ganz am Ende wieder auf unsere Originaltabelle savecontactform7_1 switchen wollen, lege ich den Namen der aktuellen Tabelle auf eine Konstante und gebe den Tabellennamen im Kopf mit aus, damit wir wissen wo wir arbeiten.

/*****Haupttabelle Name als Konstante definieren*******/
 define("MAINTABLE","mitglieder_stamm");

echo "<h2>Mitglieder Adressenliste</h2>";

echo "Aktuelle Tabelle =&nbsp".MAINTABLE."<br>";

Der Select ist dann ganz simpel:

global $wpdb;
        $alleposts = $wpdb->get_results( "SELECT * from ".MAINTABLE."");

Ausgabe als Tabelle

Wie gewohnt mit einer Foreach-Schleife, das haben wir schon oft genug gemacht, da spare ich mir jetzt nähere Kommentare:

foreach_adressen

foreach_adressen

Das reicht schon, wir bekommen jetzt alle eingegebenen Testdaten tabellarisch angezeigt.

adressenliste

adressenliste

Das war jetzt zu einfach, nicht wahr? Bitte sehr, wir erweitern unsere Möglichkeiten jetzt gleich kräftig, aber dazu gibts einen neuen Beitrag.

Der Turnverein Weiß-Blau: jede Menge Spaß mit eigenen Tabellen

Über den TV Weiß-Blau

Der kleine fiktive  Vorort-Turnverein im Münchner Norden möchte WordPress für seinen Webauftritt verwenden. Die informativen Seiten (Über den TV-Weiß-Blau, Vereinsangebot) sind schnell angelegt. Dann kommt noch ein Registrierungsformular für neue Mitglieder dazu, das machen wir mit Contact Form 7 und nutzen gleich noch Save Contact Form 7 um die Daten den prospektiven Mitglieder direkt in der MySQL-Datenbank zu speichern. Save Contact Form 7 erzeugt zu jedem neuen abgeschickten Formular eine fortlaufende ID, die wird unsere Mitgliedsnummer.

Unser besonderer Service: finden sie ihren individuellen Freizeitsport-Partner!

Und weil wir mit dem Registrierungsformular so schöne Daten abfragen (Beispiel kommt noch) möchten wir als besonders „Zuckerl“ für unsere Mitglieder einen super Service anbieten: man kann nach geeigneten Sportpartnern suchen! Wer hat am Abend oder am Wochenende Zeit, wer ist in meiner Leistungsgruppe oder Größenklasse, wer hat Interesse an Basketball oder Tennis – das wird der ganz besondere Service für den Verein und hebt unser Angebot von der Konkurrenz ab.

Das Datenmodell in WordPress und Contact Form 7

… ist denkbar einfach. Wir legen für jedes Vereinsmitglied einen Beitrag an, da kommt noch ein Paßfoto mit dazu, und das wars auch schon. Alle anderen relevanten Daten bekommen wir aus unserem Registrierungsformular. Das haben wir mit Contact Form 7 schnell erstellt. Im ersten Teil werden die persönlichen Daten und die Adresse abgefragt:

anmeldeformular_adressdaten

Nichts weiter ungewöhnliches, interessanter wirds da schon im zweiten Teil, da werden Infos zu den sportlichen Aktivitäten abgefragt:

fitness_sportarten

fitness_sportarten

Der Größenbereich erlaubt die Auswahl „unter 170“, „170-180“ und „über 180“. Bei „Fitneß“ kann man Anfänger, Freizeitsportler oder Profi auswählen, die anderen Formularfelder sind eigentlich selbsterklärend. Warum habe ich bei „Verfügbarkeit“ und „Sportarten“ Radiobuttons mit ja/nein gewählt, und keine Optionsgruppen? Weil die Daten so schöner auszuwerten sind, das wird man später noch sehen.

Woher kommen nun die Daten?

Alle diese wertvollen Daten erhalten wir einfach dadurch, daß Anmeldeformulare ausgefüllt und abgeschickt werden. Wenn sich jemand persönlich vor Ort oder auf traditionell schriftlichem Weg im Verein anmeldet, werden die persönlichen Daten halt auch einfach über das Kontaktformular erfaßt, ist ja egal wer die eingibt. Jedenfalls haben wir so schnell einen kleinen Stammdaten-Pool beieinander, mit dem wir arbeiten können.

Kleine Anmerkung zur tabellarischen Darstellung in CF7

Wie bringt man CF7 dazu, eine Gruppe mit Radiobuttons vernünftig formatiert darzustellen? Bin ich gefragt worden, gebe ich gern Auskunft. Man packt sie in eine Tabelle, das sieht dann im Entwurf so aus:

cf7_tabellen

cf7_tabellen

Das aber nur als kleiner Layout-Tipp am Rande. Im nächsten Artikel geht es weiter mit unseren Mitgliederdaten.

 

Was wir mit Bildern können, können wir mit Posts schon lange!

Alle veröffentlichten Beiträge

Es wird wieder Zeit für ein bißchen Spaß auf der Datenbank! Wir gehen wieder zurück zu unserer zentralen Tabelle wp_posts und picken uns diesmal alle veröffentlichten Beiträge heraus. Das haben wir schonmal gemacht, bei der Ausgabe der Beitragsbilder ganz am Anfang, wissen sie noch? Der Select ist supersimpel:

SELECT * from wp_posts where post_status = ‚publish‘ and post_type = ‚post‘

Die könnten wir jetzt einfach mal alle ausgeben so wie sie daherkommen, nämlich einfach nacheinander aufsteigend Datum. Das sähe dann aber der Beitragsseite (nur mit umgekehrter Sortierung) verdammt ähnlich und hätte weiter keinen Närwert, deshalb geben wir die Beiträge jetzt erst mal gekürzt und in Divs gepackt als Übersicht aus. Unser foreach für diesen Zweck ist auch denkbar einfach, ich gebe fürs erste nur den Titel und den Inhalt aus:

foreach ( $alleposts as $einpost ) 
            { 
            echo "<div class = 'post_ausgabe'>";
                echo "<h1>".$einpost->post_title."</h1>";
                echo $einpost->post_content."</br>";
            echo "</div>";    
            }

Ich habe mir eine neue Klasse von Div, die post_ausgabe definiert, weil ich die Formatierung etwas anders als bei der Bilderausgabe gestalten möchte. Der CSS-Eintrag sieht so aus:

.post_ausgabe{
    
    float:left;
    height: 300px;
    width: 30%;
    overflow: hidden;
    border: 1px solid blue;
    margin: 2px;
    padding:2px;    
    
}

Wichtig ist der overflow: hidden; damit die Sache leserlich bleibt. Und die Ausgabe? Ich nehme mal wieder das Inselfisch-Kochbuch, da sind richtig schön viele Beiträge drin, und das sieht jetzt erstmal so aus:

post_ausgabe

post_ausgabe

Zugegeben, das könnte hübscher sein, aber darum kümmern wir uns später. Falls sie sich wundern, daß hier überrall „Einleitung“ als Untertitel steht: das ist völlig korrekt so, weil bei mir (fast) jedes Rezept mit einer Einleitung beginnt. Erinnern sie sich? Da war was mit der Textstrukturierung wegen der Barrierefreiheit. Deswegen kommt als erster Text im post_content das Wörtchen „Einleitung“, als h2-Überschrift formatiert. Die Ausgabe ist also völlig richtig.

Link auf den Beitrag

Jetzt fehlt natürlich der Link auf den Beitrag, den holen wir uns wieder mal mit get_permalink(ID) und machen einen a href auf die Überschrift daraus. Der foreach folgt sogleich:

foreach ( $alleposts as $einpost ) 
            { 
            $akt_link = get_permalink($einpost->ID);
            
            echo "<div class = 'post_ausgabe'>";
                echo "<a href = '".$akt_link."'><h1>".$einpost->post_title."</h1></a>";
                echo $einpost->post_content."</br>";
            echo "</div>";    
            
            }

Jetzt sitzen die Links auf den Überschriften, wo sie hingehören.

alle_posts_mit_links

alle_posts_mit_links

Wieder das Spiel mit dem Limit und der Zufallszahl

Man kann natürlich auch hier die Anzahl der auszugebenden Beiträge limitieren, und mit Rand() eine zufällige Auswahl der Beiträge erzeugen, und man kann den ganzen Shortcode natürlich auch wieder ins Text-Widget packen und z.B. in die Seitenleiste verschieben, da kann jeder selber damit spielen.

Was noch nicht schön ist

Der abgeschnittene Text stört mich, und der -zigfache Text Einleitung. Da letzteres aber sozusagen mein Privatvergnügen ist, gibts dafür einen neuen Beitrag.

 

 

 

Nützlicher Helfer: der Shortcode

Verlieren sie auch allmählich den Überblick bei den ganzen PHP-Code-Snippets? Mir gehts immer so, wenn sich mehr als ein Dutzend Snippets in PHP Code for Posts angesammelt habe, muß ich aufräumen. Dann überlege ich mir, welche echt nur zum Testen da waren, und welche Funktionalitäten ich wirklich weiterverwenden möchte. Aus letzteren baue ich mir dann Shortcodes mit aussagekräftigen Namen, und bunkere sie in meiner Archiv-Bibliothek.

Was ist ein Shortcode?

Kennen wir doch schon!

shortcode

shortcode

Das ist das Kürzel, das an dieser Stelle den PHP-Code von Snippet Nr. 7 ausführt. Kann an beliebiger Stelle in einen Beitrag oder auf einer Seite eingesetzt werden. Sogar in das Text-Widget kann der Shortcode eingesetzt werden (wo es Sinn macht), und führt auch hier z.B. in der Sidebar seine Funktion aus.

Wie baue ich einen Shortcode?

Das ist keine schwierige Sache. Zu einem Shortcode gehören essentiell zwei Dinge:

  1. ein Kürzel
  2. eine PHP-Funktion

Das wars schon. Es gibt auch Shortcodes mit Parameter und umschließende Shortcodes, aber wir wollen es mal bei der minimalistischen Version belassen. Kürzel und zugehörige Funktion kommen in die functions.php ihres Child-Themes, das sieht im einfachsten Fall so aus:

hallo_evi_shortcode

hallo_evi_shortcode

Zuerst kommt die Funktion, die tut hier im Beispiel nichts weiter als einen Text mit echo ausgeben. Dann definiert man das Kürzel mit add_shortcode und gibt ihm den Funktionsnamen mit. Das wars schon. Jetzt an beliebiger Stelle einsetzen, z.B. in einen neuen Beitrag, einfach das Kürzel in eckigen Klammern, und voilá die Ausgabe (hier im Inselfisch-Kochbuch), brav als h1 formatiert:

mhs_ausgabe

mhs_ausgabe

Nahezu unbegrenzte Möglichkeiten

So eine Shortcode-Funktion kann aber noch viel mehr als nur echo-Ausgaben! Sie können zum Beispiel den gesamten Code für die Bilderausgabe in die Funktion packen, oder das Inhaltsverzeichnis, oder was immer sie wollen. Jeder valide PHP-Code ist möglich!

Wichtig ist nur, daß sie wirklich auf der functions.php ihres Child-Themes arbeiten, sonst sind beim nächsten Theme-Update unter Umständen ihre gesammelten Shortcodes futsch! Dabei sind die doch so vielseitig verwendbar – mehr dazu im nächsten Beitrag.

 

 

Kommt auf den Wunschzettel: eine eigene Bildertabelle für WordPress

Der Attachment-Kuddelmuddel in der wp_posts

Wie wir gesehen haben, war es ein ganz schöner Aufwand, alle relevanten Informationen für die Ausgabe aller Bilder zusammenzutragen. Ich habe an anderer Stelle schon angemeckert, daß es aus aus Sicht eines alten Datenbankers nicht OK ist, so unterschiedliche Entitäten wie Posts und Attachments in der selben Tabelle, nämlich der wp_posts, zu verwalten. Ich laß jetzt mal die anderen Attachment-Typen (ZIP, Wav, Doc…) weg und werfe nur einen gezielten Blick auf die Bilder. Das ist auch semantisch sinnvoll, weil Bilder eine ganz spezielle Art von MIME-Types darstellen. Korrekterweise muß man sagen, daß wir hier von Inline-Bildern sprechen, die vom Browser im Dokument innerhalb des Textflusses direkt dargestellt werden. Externe Bilder wären dann die, die erst geladen werden wenn man auf einen Link oder ein Vorschaubild klickt, aber ich schweife ein bißchen ab. Wer mehr wissen will: ein interessanter Artikel zu dem Thema ist hier bei der Uni Passau zu finden.

Begnügen wir uns mit den ganz normalen Bildern auf Seiten und in Beiträgen, und ich geh mal lieber direkt ran an meine Wunschtabelle.

Die neue Bilder-Tabelle: ein Vorschlag

Wie könnte das jetzt aussehen, wenn man die Bilder aus der wp_posts auslagert und eine eigene Tabelle für sie anlegt? Ganz einfach so:

neue_bildertabelle

neue_bildertabelle

Feldliste der neuen Tabelle

Ich geh mal die Felder der Reihe nach durch:

  1. bild_id: AutoIncrement, die eindeutige Identifikationsnummer des Datensatzes.
  2. beitrag_ix: der Fremdschlüssel für die ID des zugehörigen Beitrags, das „ix“ steht für „id extern“
  3. bild_url: der vollständige Pfad zur Bilddatei
  4. bild_titel: selbsterklärend
  5. bild_beschriftung: selbsterklärend
  6. bild_alt_text: selbsterklärend
  7. bild_beschreibung: selbsterklärend

Wo sind denn all die anderen Felder geblieben?

Brauchen wir nicht mehr.

  • Der post_type attachment ist überflüssig, weil wir hier in der neuen Tabelle nur noch Attachments verwalten.
  • Der post_mime_type image/ ist überflüssig, weil wir nur noch Bilder verwalten.
  • Es ist sogar überflüssig, nach MIME-Type jpeg oder andere Bildformate zu unterscheiden, weil im img src-Tag auch png, gif, ico usw, zulässig sind, genaueres zu den zulässigen Bildtypen steht im Codex.
  • Der post_status ist überflüssig, aber der hat uns ohnehin für die Bildausgabe nicht die Bohne interessiert.
  • die Verknüpfung auf die wp_postmeta ist überflüssig, weil wir hier für den alt-Text das eigene Feld bild_alt_text haben

Alles klar soweit?

Das neue SQL Statement

Wie lautet also das neue SQL für die Ausgabe aller Bilder? Gehen wir mal davon aus, daß die Tabelle schlicht wp_bilder heissen soll. Dann schreibt sich das so:

Select * from wp_bilder;

Das wars.

Und das möchte ich jetzt erstmal etwas einwirken und sacken lassen.

Barrierefreiheit für den Hausgebrauch: Strukturierung

Ich stehe beim großen Thema Barrierefreiheit zugegeben erst am Anfang, da gibt es noch viel zu lernen. Aber ich hatte tatkräftige Hilfe von der Stiftung Pfennigparade, die erfahrenen Programmierer dort haben mir viele wertvolle Tipps gegeben, so daß ich mein Inselfisch-Kochbuch zumindest barrierearm und auch für Menschen mit Handicap gut zugänglich gestalten konnte. Das war für mich ein großer persönlicher Erfolg, und ich freue mich über stetig wachsende Besucherzahlen. Es war aber auch ein Haufen Arbeit, und ich möchte hier einige Tipps geben, die es anderen WordPress-Entwicklern und auch privaten Anwendern vielleicht leichter machen, barrierearme Webseiten zu erstellen.

Von Anfang an gut strukturieren: HTML Bascis

Die allermeiste Heidenarbeit war es, die Beiträge in meinem Kochbuch im nachhinein durchzustrukturieren und sinnvoll zu formatieren. Ich habe über 200 Rezepte manuell anfassen müssen, weil ich sie im Lauf der Jahre einfach so als Fließtexte erfasst hatte und keine vernünftige Dokumentstruktur drin hatte. Dabei ist es eigentlich ganz einfach: längere Textpassagen sind mit Zwischenüberschriften zu untergliedern, und diese sind in HTML ganz schlicht als h1, h2, h3… h6 auszuzeichnen. Wobei ich mehr als h3 noch nie gebraucht habe, für die meisten Zwecke reichen zwei Überschriften-Ebenen vollkommen aus. Der Fließtext dazwischen wird sinnvollerweise als Absatz (<p>) formatiert. Für Aufzählungen nimmt man ein <ul>, für nummerierte Listen ein <ol>. Reinstes HTML-Basic! All diese Strukturierungselemente stehen im visuellen Editor einwandfrei zur Verfügung, nur benutzen muß man sie auch!

Anwendungsbeispiel Kochrezept

Ich zeige zuerst einmal, wie man es nicht macht. Dieser Rezepttext wurde einfach so heruntergeschrieben und mag jedem einigermassen erfahrenen Hobbykoch etwas sagen, aber er ist grottenschlecht im Sinne der Barrierefreiheit weil gar nicht strukturiert. Das geht schon damit los, daß die eigentliche Überschrift mit im Fließtext klemmt und nur fett hervorgehoben wurde. Auch der Rest des Rezepts ist schlicht gar nicht strukturiert, das wird einfach so heruntergeplaudert und man kann schlecht erkennen, wo es jetzt um die Zutaten und wo es um die Zubereitung geht, und was da sonst noch stehen mag.

Das unstrukturierte Rezept


Curry-Bananen-Dip zum Fondue, oder auch zu Gegrilltem. Man braucht dafür eine richtig reife Banane, am Besten schon ein paar Tage vorher kaufen und reifen lassen, bis sie schön weich ist und cremig wird. Banane mit Limettensaft mit einer Gabel fein zermusen, Salz und soviel Currypulver darangeben daß es deutlich scharf, aber noch angenehm schmeckt. Sofort servieren, oder den Dip mit zusätzlich etwas Limettensaft beträufeln, er verfärbt sich sonst braun. Nach einem guten, würzigen aber nicht penetranten Currypulver muß man ein wenig suchen, die aus dem Supermarkt sind meistens nicht so überragend. Wenn man kein anderes kriegt, eher weniger Currypulver verwenden und die nötige Schärfe mit ein paar Tropfen Tabasco oder etwas Sambal Oelek herbeizaubern.


Da muß Struktur rein! Ein Kochrezept besteht ja bei mir meistens aus 4 Komponenten:

  1. einer Einleitung, in der ich ein paar nette Worte über Herkunft und Besonderheiten des Rezeptes erzähle,
  2. einer Zutatenliste,
  3. der eigentlichen Zubereitung
  4. und dann noch ein oder mehrere Tipps zum Rezept.

Ja dunnerlittchen, da sind mir vielleicht die Schuppen aus den Haaren gefallen, als mir der nette Herr Programmierer von der Pfennigparade erklärte, daß das als Strukturierung vollständig ausreichte, ich müßte es nur auch in HTML umsetzen!

Und das geht so: Zwischenüberschriften rein und mit Überschrift 2 formatieren, Überschrift 1 ist schon vergeben, die hat in WordPress der Beitragstitel. Zutaten und Zubereitung klar trennen, die Tipps einzeln ans Ende setzen. Das sieht dann so aus:

Das gut strukturierte Rezept:


Curry-Bananen-Dip

Einleitung

Zum Fondue, oder auch zu Gegrilltem. Man braucht dafür eine richtig reife Banane, am Besten schon ein paar Tage vorher kaufen und reifen lassen, bis sie schön weich ist und cremig wird.

Zutaten

1 reife Banane, Saft 1 Limette, wenig Salz, 1-2 Teel. gutes Currypulver.

Zubereitung

Banane mit dem Limettensaft mit einer Gabel fein zermusen, Salz und soviel Currypulver darangeben daß es deutlich scharf, aber noch angenehm schmeckt. Sofort servieren, oder den Dip mit zusätzlich etwas Limettensaft beträufeln, er verfärbt sich sonst braun.

Tipp:

Nach einem guten, würzigen aber nicht penetranten Currypulver muß man ein wenig suchen, die aus dem Supermarkt sind meistens nicht so überragend. Wenn man kein anderes kriegt, eher weniger Currypulver verwenden und die nötige Schärfe mit ein paar Tropfen Tabasco oder etwas Sambal Oelek herbeizaubern.


Fazit

Da staunste, was? Die Strukturierung im Sinne der Barrierefreieheit hat das Rezept wesentlich übersichtlicher gemacht und auch für „normale“ Besucher besser zu lesen. Das ist übrigens ein angenehmer Nebeneffekt bei der Gestaltung im Sinne der Accessibility, wie das auf neudeutsch heißt: es tut der Lesbarkeit und der Verständlichkeit der meisten Texte gut, wenn man auf eine saubere Strukturierung achtet.

Aber trotzdem, 200 Rezepte nachträglich strukturieren, das mach ich nicht nochmal, das war eine Mordsarbeit. Jetzt schau ich halt, daß ich die Rezepte gleich von Anfang an richtig strukturiere und formatiere, und gut ists.

Bildausgabe: noch ein paar Spielereien

Das selbe nochmal mit Vorschaubildern

Also gut, meine Bildausgabe sah zugegeben nicht besonders ordentlich aus, weil die Bildformate im Inselfisch-Kochbuch so höllisch unterschiedlich sind. Dann nehmen wir halt in Gottes Namen mal die quadratischen Vorschaubilder. Und die Beschriftungen und Beschreibungen lassen wir ganz weg, weil da eh nichts Gescheits drinsteht. So besser?

join_mit_thumbnails

join_mit_thumbnails

Was hab ich gemacht? Mir das quadratische Vorschaubild mit der Funktion wp_get_attachment_thumb_url($att_id)
geholt. Davor muß man allerdings den Select erweitern und sich noch die ID des Bild-Datensatzes für die Funktion mit dazunehmen, ich hab das mal so gemacht:

SELECT wp_posts.ID as ‚BildID‘,…

Der Rest des Select bleibt absolut gleich. Die foreach-Schleife sieht jetzt so aus:

bild_ausgabe_thumb

bild_ausgabe_thumb

Die echos für die jetzt überflüssigen Felder sind rausgeflogen, und in den img src-Tag kommt jetzt eben die URL des Thumbnails und nicht die des Originalbildes. Ausserdem habe ich die width-Angabe rausgenommen, weil die Thumbnails in meinem Theme eh bloß 150x150px groß sind.

Jetzt noch ein paar Anpassungen in der style.css, die height für evisdiv auf auto gesetzt, das Orange im Background rausgenommen und den border radius rausgeschmissen. Jetzt kann echt keiner mehr meckern:

inner_join_ergebnis_style

inner_join_ergebnis_style

Es sieht jetzt wirklich auf den ersten Blick ordentlicher aus, aber die abgeschnittenen Bilder finde ich nach wie vor nicht schön. Na ja, wer’s mag…