Benutzerdefinierte Felder – im Beitrag anzeigen

Analog zu den Custom Fields in WordPress kann man auch in Joomla selbstdefinierte Felder zu den Artikeln anlegen. Ich bin da gleich mal reingerasselt, weil ich zu den Kochbüchern ein Feld „Unverbindliche Preisempfehlung“ haben wollte. Schauen sie mal unter Inhalte/Felder/Neu die Liste der Feldtypen an – da ist alles dabei, bloß keine Währung, der einzige verfügbare Zahlentyp ist Integer. Ein Datumsfeld sucht man auch erstmal, es versteckt sich hinter dem Feldtyp „Kalender“. Ansonsten stecken in den Feldtypen jede Menge Angaben, die ich für Spielerei halte, unter anderem auch ein Feldtyp „Farbe“, man sehe und staune:

rgb_feld

rgb_feld

Damit kann man sich im Frontend den RGB-Code der gewählten Farbe anzeigen lassen, wofür das auch immer gut sein soll.

Wenigstens kann man beim Anlegen der Felder angeben ob es sich um ein Pflichtfeld handelt, dann kriegt man beim Ausfüllen der Beiträge einen Hinweis, wenn was fehlt. Wo sich die Felder und die Feldinhalte wiederfinden lassen, dazu gibts einen:

Blick auf die Datenbank

Man kann auch noch Feldgruppen anlegen, aber das lassen wir mal aussen vor, sonst wirds zu kompliziert. Ich möchte jetzt einfach in einem Artikel den Wert eines benutzerdefinierten Feldes anzeigen, und zwar an beliebiger Stelle im Inhalt. Und – da bin ich ein bißchen eigen – ich möchte das auf relativ einfachen Weg in einem Sourcerer Codesnippet tun, ohne Overrides  und ohne eigens programmierte Module. Kann ja wohl nicht so schwer sein!

Dafür tun wir mal einen beherzten Griff in die Datenbank. Die relevanten Tabellen sind die #__contents, aus der brauchen wir die ID des Artikels, die Tabelle #__fields, aus der holen wir uns den Feldnamen und nach Belieben auch die Feld-ID, und schliesslich die #__fields_values, in der stecken schlussendlich die Werte der Felder. Ich habs mal kurz nach Access reingeschubst, da stellen sich die Beziehungen so dar:

fields_beziehungen

fields_beziehungen

Also, frisch auf, einen Join über alle drei Tabellen gebastelt, wichtig ist hier die item_id, die identifiziert unseren Artikel:

felder_join_alle_drei

felder_join_alle_drei

Der Select dazu sieht so aus und ist relativ straightforward:

SELECT Fields_values.field_id, Fields.name, Fields_values.item_id, Fields_values.value
FROM Fields INNER JOIN (Content INNER JOIN Fields_values ON Content.[id] = Fields_values.[item_id]) ON Fields.[id] = Fields_values.[field_id];

Wir wollen aber nur die Feldinhalte zum aktuellen Artikel ausgeben, ich nehm mal den mit der ID 22 und klemm noch eine Where-Klausel dran. Dann können wir uns auch den Join auf die #__contents noch sparen, die ID des Artikels ist ja erstmal fest.

SELECT Fields_values.field_id, Fields.name, Fields_values.item_id, Fields_values.value
FROM Fields INNER JOIN Fields_values ON Fields.[id] = Fields_values.[field_id]
WHERE (((Fields_values.item_id)=“22″));

Ergebnis wie erwartet:

felder_nur22

felder_nur22

Und jetzt kann man sich anhand der field_id oder dem field name ein benutzerdefiniertes Feld herauspicken, ich nehm mal den Namen:

SELECT Fields_values.field_id, Fields.name, Fields_values.item_id, Fields_values.value
FROM Fields INNER JOIN Fields_values ON Fields.[id] = Fields_values.[field_id]
WHERE (((Fields.name) Like „farbtest“) AND ((Fields_values.item_id)=“22„));

Schon haben wir den Datensatz mit dem richtigen Feldwert eingekreist:

felder_nurfarbtest

felder_nurfarbtest

Na bitte, geht doch!

Und wo kriegen wir jetzt die aktuelle Artikel-ID her?

Das ist eine berechtigte Frage, man kommt ihr aber mit folgender Konstruktion bei:

$article_id = JFactory::getApplication()->input->get('id');

Jetzt basteln wir uns wie gehabt ein neues Datenzugriffsobjekt in der Variablen $db, dazu muss man noch ein bisschen bei den doppelten und einfachen Hochkommata aufpassen und das Präfix #__ nicht vergessen, aber das sollte eigentlich problemlos klappen.:

$db = JFactory::getDBO();

$query = „SELECT #__fields_values.field_id, #__fields.name, #__fields_values.item_id, #__fields_values.value
FROM #__fields INNER JOIN #__fields_values ON #__fields.id = #__fields_values.field_id
WHERE (#__fields_values.item_id = „.$article_id.“ ) and (#__fields.name like ‚farbtest‚);“;

Die Variable $article_id schubsen wir in unsere Where-Klausel rein, den Namen des benutzerdefinierten Feldes auch, das kann man auch auf eine Variable legen, oder man verdrahtet es fest wie ich es getan habe. Das war schon der ganze Zauber!

Query zuweisen und ausführen:

$db->setQuery($query);
$result = $db->execute();

Objektliste laden, auch wenn wir nur 1 Zeile im result haben:

$results = $db->loadObjectList();

Ausgabe des Wertes aus dem Feld value mit foreach(), :

foreach ($results as $zeile) :
echo $zeile->value;
endforeach;

Das wars, da haben wir den Wert unseres benutzerdefinierten Feldes, und der kann an beliebiger Stelle im Artikel positioniert werden. Die anderen benutzerdefinierten Felder kann man natürlich auch mit dem Namen ansprechen, das geht ganz genau so wie hier vorgeführt.

Kleine Spielerei am Schluss: wenn wir schon einen RGB-Farbwert haben, möchten wir die Farbe auch sehen, ich mach mal ein Quadrat von 300 px Kantenlänge. Dann kommt in der foreach-Schleife noch eine Variablenzuweisung mit:

foreach ($results as $zeile) :
$aktuelle_farbe = $zeile->value;
echo $zeile->value.“<br>“;
endforeach;

Die verwenden wir jetzt in einer Div für das Farbquadrat:

echo „<div style=’background-color:“.$aktuelle_farbe.“; width: 300px; height: 300px;‘><h2>Aktuelle Farbe</h2></div>“;

farbquadrat

farbquadrat

Na siehste, haben wir doch noch eine Anwendung für den Feldtyp „Farbe“ gefunden!

Nachtrag

Ich bin gefragt worden, warum ich denn nicht ein alternatives Layout für die Anzeige der Felder angelegt habe und dann einfach dort an der richtigen Stelle mit:

<?php echo $this->item->jcfields[x]->value; ?>

das Feld mit der Nummer x einfüge. Ganz einfach: ich wollte den Feldinhalt innerhalb des Beitragstextes ausgeben, das ist der ganze Witz an der Sache. Das geht im Template nicht, da dort der Beitragstext als Ganzes mit <?php echo $this->item->text; ?> hereingeholt wird, und man keine Chance hat da innerhalb etwas zu positionieren. Ist der Sinn und Zweck der Übung jetzt etwas klarer?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.