Heim > Artikel > Backend-Entwicklung > Erstellen eines benutzerdefinierten Formularfeldtyps in Joomla anhand des Modal Select-Beispiels
Verwendung des ModalSelect-Formularfeldtyps in Joomla 5, um das Finden des richtigen Produkts aus Tausenden zu vereinfachen, indem bei der Entwicklung einer Erweiterung in einem modalen Fenster nach Kategorie, Hersteller und Suche gefiltert wird.
Bei der Arbeit mit Kunden gibt es Aufgaben auf verschiedenen Ebenen: Jemand braucht eine einfache Website mit 5-6 Seiten. Jemand benötigt einen großen Warenkatalog oder einen Online-Shop mit Integrationen in Drittsysteme über die REST-API. Jemand anderes benötigt nicht standardmäßige Funktionen, für die es keine gängigen Lösungen gibt.
Joomla eignet sich gut für die Entwicklung und ermöglicht die Erstellung leicht zu wartenden Codes. Wenn die Anforderung dem CMS-Kern folgt, gibt es für alle diese Fälle eine Antwort.
Um ein großes Projekt abzuschließen, müssen wir es in kleinere Aufgaben aufteilen, und ich möchte in diesem Artikel über die Lösung einer dieser Aufgaben sprechen.
Kunden haben bereits einen Produktkatalog auf einer der beliebten Komponenten des Online-Shops für Joomla (JoomShopping) erstellt. Sie können die Parameter des Produkts auswählen, es in den Warenkorb legen und einen Kauf tätigen. Alles ist wie immer. Jetzt müssen Sie jedoch die Möglichkeit hinzufügen, ein grafisches Layout für Produkte zu erstellen. Ihr Produkt ist beispielsweise eine Tasse oder ein T-Shirt. Und vor dem Kauf können Sie zum Produktdesigner gehen, Ihr Logo oder Foto hochladen, einen Text schreiben und dieses Layout wird der Bestellung im Online-Shop beigefügt. Nach der Bezahlung geht das Layout direkt in die Produktion, wo das Bild und der Text auf deine Tasse aufgebracht und an die Adresse verschickt werden.
Da die Implementierung dieser Funktionalität recht zeitaufwändig ist, wird sie als separate Produktdesigner-Komponente erstellt. Und es werden bereits Plugins für Datenanbieter erstellt, die es Ihnen ermöglichen, mit der einen oder anderen E-Commerce-Komponente zu arbeiten.
Eine der kleinen, angewandten Aufgaben besteht darin, Verbindungen zwischen den Waren der Online-Shop-Komponente und den Waren in der Produktdesigner-Komponente herzustellen. Dies sollte für Content-Manager, die in Zukunft an den Inhalten arbeiten, bequem und intuitiv sein. Daher reicht es nicht aus, nur ein Textfeld zu erstellen, in dem die ID-Nummer des gewünschten Produkts angegeben wird. Möglicherweise gibt es in einem Online-Shop nur ein paar Dutzend Produkte, und dann ist die Auswahl eines Produkts für die Kommunikation nicht sehr schwierig. Bei Tausenden von Produkten ist die Funktionalität zum Suchen und Filtern von Produkten nach Parametern wichtig. Wenn Sie die Produktliste nach Kategorie oder Hersteller filtern oder unter Hunderten anderen nach Namen suchen können, wird Ihre Arbeit viel schneller und einfacher.
Sehen Sie sich das Video an
Dieses Feld ähnelt sehr der Arbeit der Editor-Button-Plugins (Gruppe editors-xtd), bei denen die Daten zur Auswahl im modalen Fenster angezeigt werden: ein Link zum Artikel, ein Kurzcode für das Modul usw.
Im Joomla-Administratorbereich gibt es verschiedene Felder, die mit Daten aus anderen Komponenten gefüllt werden müssen: Geben Sie den Artikel, den Menüpunkt, den Kontakt, das Produkt usw. an. Normalerweise sind solche Felder als Dropdown-Liste mit Auswahloptionen konzipiert , können sie als Eingabetyp="Text" mit einer Datenliste gestaltet werden, es gibt aber auch praktische Felder, die eine Liste der gewünschten Entitäten anzeigen, mit Filterung, Suche und Paginierung. Als Datenquelle können nicht nur Quellen innerhalb der Site (verschiedene Komponenten, Plugins) fungieren, sondern auch über die REST-API verfügbare Dienste von Drittanbietern: CRM, Lieferdienste, externe Datenbanken, andere Joomla-Sites usw.
Wir alle haben diese Felder in Aktion gesehen, als wir einen Artikel in einem Menüpunkt wie „Artikel – Einzelner Artikel“, „Kontakte – Einzelner Kontakt“ oder beim Erstellen eines Alias des Menüpunkts – „Systemlinks – Menü“ – ausgewählt haben Artikelalias". Erinnern wir uns jedoch daran, wie sie aussehen.
Ein modales Artikelauswahlfenster.
Ein modales Einzelkontaktauswahlfenster.
Schauen wir uns diese Felder genauer an – was genau sie Ihnen ermöglichen. Irgendwo tief im Inneren verstehen wir, dass die Hauptaufgabe dieses Feldes darin besteht, die ID der ausgewählten Entität abzurufen und diese ID in ein Textfeld einzufügen. Aber auf dem Bildschirm sehen wir etwas anderes – statt einer ID-Nummer sehen wir den Titel des Artikels oder Kontakts. Es ist schön und praktisch. Sie müssen sich den Namen des Artikels mit der ID 1452704 nicht merken. Außerdem zeigt das Video deutlich, dass die Schaltfläche „Löschen“ angezeigt wird, wenn das Feld bereits einen Wert enthält. Dadurch wird der Wert des Felds zurückgesetzt und Sie können erneut auf die Schaltfläche „Auswählen“ klicken.
In manchen Fällen haben wir die Möglichkeit einen ausgewählten Entitätstyp zu erstellen – Artikel, Kontakt usw.direkt beim Erstellen eines Menüpunkts. Diese Schaltfläche funktioniert unter Berücksichtigung der ACL – Trennung der Zugriffsrechte in Joomla.
Stellen Sie sich vor, Sie erstellen eine Website und erstellen eine „Kontakte“-Seite. Wenn Sie nicht viele Unternehmenszweige mit einer komplexen Struktur haben, dann ist dies nur der übliche Joomla-Artikel in der Kategorie „Nicht kategorisiert“. Und es verfügt bereits über alle Kontakte in Form von Text oder Variablen. In der Antike musste man zuerst den Artikel erstellen und dann zu den Menüpunkten gehen und einen Menüpunkt dafür erstellen. Das müssen Sie jetzt nicht tun.
Und wenn das Feld bereits einen Wert hat, ist es in manchen Fällen möglich, die ausgewählte Entität (Artikel, Menüpunkt usw.) direkt beim Erstellen eines Menüpunkts zu bearbeiten.
Mithilfe des Auswahlfelds im modalen Fenster können wir also:
Das ist es, was ich vor Augen habe. Aber in den Tiefen von Joomla gibt es auch einen merkwürdigen urlCheckin-Parameter, der es Ihnen ermöglicht, den ausgewählten Wert an die im Feld angegebene URL zu senden. Es ist erwähnenswert, dass sich diese Funktionalität in Joomla seit geraumer Zeit schrittweise weiterentwickelt. Ein separater universeller Feldtyp, der für Ihre Bedürfnisse verwendet werden kann, erschien jedoch nur in Joomla 5. Dies ist nicht einmal in Joomla 4 der Fall.
Zuvor hieß dieser Konstruktor JForm. Ich gehe davon aus, dass nicht alle meine Leser über ein solches Entwicklungstool wie eine IDE – Entwicklungsumgebung – a la PHP Storm oder VS Code verfügen, daher werde ich versuchen, zusätzliche Richtlinien für die Navigation in der Codebasis zu geben.
In Joomla ist die Logik von der Ansicht (der eigentlichen HTML-Ausgabe) getrennt, daher werden wir sie an mehreren Stellen gleichzeitig untersuchen.
Logic ist die Form-Klasse. In Joomla 5 befinden sich die Form-Klassendateien in libraries/src/Form. Wir untersuchen diese Dateien, um die Logik selbst zu verstehen, was mit den Daten passiert und wie man damit arbeitet.
Kurz gesagt, der Formularkonstruktor empfängt XML mit einer Beschreibung der Felder. liest Daten (Feldtyp, benutzerdefinierte Feldklasse aus dem Attribut addfieldprefix, falls vorhanden usw.), lädt die erforderliche Feldklasse mit FormHelper. Wenn das Feld einige Regeln zum Filtern der Ausgabedaten enthält – die FormRule-Klasse wird verwendet – denken Sie an die Joomla-Felder vom Typ Dateiliste, in denen Sie Filterparameter angeben und beispielsweise nur PHP- oder nur CSS-Dateien auswählen können.
Joomla Form-Feldklassendateien befinden sich in libraries/src/Form/Field. Es gibt, gelinde gesagt, viele davon. Dies ist das Baumaterial des Admin-Panels und manchmal auch des Frontends.
Klassendateien beschreiben Klasseneigenschaften wie $type, $layout und andere, die für den Betrieb notwendig sind. Die meisten Felder verfügen über Methoden getInput() – gibt tatsächlich die HTML-Ausgabe des Felds zurück, getLayoutData() – verarbeitet Daten für das Feld vor, bevor es an den Renderer gesendet wird, getLabel() – arbeitet mit der Feldbezeichnung usw.
Wir erinnern uns, dass die Feldklassen die übergeordnete FormField-Klasse erben. In der Klassendatei libraries/src/Form/FormField.php werden die möglichen Attribute des Feldes beschrieben, die in der Beschreibung in XML verwendet werden können. Sie haben eine kurze Beschreibung, was es ist und warum.
Untergeordnete Klassen (Erben) haben die Möglichkeit, mit den Methoden der übergeordneten Klasse zu arbeiten und diese bei Bedarf zu überschreiben.
Jede Feldklasse verfügt über eine HTML-Ausgabe. Im klassischen MVC funktioniert die Ansicht sofort mit der Datenausgabe, aber in Joomla gibt es eine zusätzliche Ebene – Layout, mit der Sie Layouts überschreiben können – eine der wichtigsten Funktionen dieses CMS. Die Kernlayouts sind wird voraussichtlich im Layouts-Ordner im Stammverzeichnis der Site liegen. Sie übergeben ein Array von $displayData mit allen von der Methode getLayoutData() empfangenen Daten. Wir geben in der Klasseneigenschaft $layout an, welches Ausgabelayout verwendet werden soll.
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
Diese Art der Aufnahme kommt recht häufig vor. In Joomla ist Layout ein durch Punkte getrennter Pfad zur Layout-Datei aus dem Layout-Ordner im Stammverzeichnis der Site. Das heißt, der Eintrag $layout = 'joomla.form.field.email' bedeutet das Beim Rendern des Feldes werden Layouts verwendet layouts/joomla/form/field/email.php.
<?php use Joomla\CMS\Layout\LayoutHelper; $displayData = [ 'src' => $this->item->image, 'alt' => $this->item->name, ]; echo LayoutHelper::render( 'joomla.html.image', $displayData );
In ähnlicher Weise wird in diesem Beispiel das Layout layouts/joomla/html/image.php verwendet. Einige Layouts können im Ordner html der Site-Vorlagen und im Admin-Bereich überschrieben werden.
Wenn wir dementsprechend genau sehen möchten, welche Daten am Ende in das Layout gelangen und wie diese angezeigt werden, gehen Sie in die Layoutdatei und schauen Sie nach.
Jetzt kehren wir zur Hauptaufgabe des Artikels zurück.
Beispiele sind für uns wichtig, um sie zu studieren (Joomla 5.0.1 zum Zeitpunkt des Schreibens dieses Artikels):
Das modale Einzelkontakt-Auswahlfeld von com_contacts zum Zeitpunkt des Schreibens dieses Artikels wurde noch nicht in einen universellen Feldtyp eins konvertiert und liegt nur (in Joomla 5.0.2, als dieser Artikel geschrieben wurde) Administrator /components/com_contact/src/Field/Modal/ContactField.php. Es erbt FormField direkt, nicht ModalSelectField.
Der Aktionsalgorithmus zum Hinzufügen eines eigenen Felds ist wie folgt:
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
Damit alles, was in PHP passiert, klar ist, müssen Sie sich zunächst das Layout der Feldausgabe ansehen. Es befindet sich in der Datei layouts/joomla/form/field/modal-select.php. Tatsächlich werden 2 Eingabefelder ausgegeben – eines sichtbar, das andere unsichtbar. Der Titel des ausgewählten Artikels, Kontakts oder Produkts wird in Form eines Platzhalters – dem Parameter $valueTitle – in das sichtbare Feld eingetragen. Und der zweite ist seine ID – $value. Wenn wir noch nichts ausgewählt haben, sollte im Feld ein Satz wie „Artikel auswählen“ oder „Produkt auswählen“ stehen. Dies ist eine Sprachkonstante, die wir in das Hint-Attribut im XML-Feld oder in die setup()-Methode der Feldklasse einfügen.
Alle für das Ausgabelayout verfügbaren Parameter (d. h. diejenigen, die programmgesteuert oder in einer XML-Datei verwendet werden können):
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
Die Feldklasse befindet sich, wie Sie vielleicht erraten haben, in meinem Plugin. Der Weg dorthin plugins/wtproductbuilder/providerjoomshopping/src/Field/ProductlistField.php. Ich habe das einzelne modale Artikelauswahlfeld als Grundlage genommen und es an meine Bedürfnisse angepasst – Auswahl eines Produkts aus dem JoomShopping-Onlineshop. Wir erweitern die übergeordnete ModalSelectField-Klasse um unsere eigene Klasse.
Zu meinen Aufgaben gehört nur die Produktauswahl, Bearbeitung und Erstellung nicht, daher geht es im Text des Artikels nur um die Produktauswahl. Die PHP-Klasse ist klein, ich werde sie vollständig wiedergeben und kommentieren.
<?php use Joomla\CMS\Layout\LayoutHelper; $displayData = [ 'src' => $this->item->image, 'alt' => $this->item->name, ]; echo LayoutHelper::render( 'joomla.html.image', $displayData );
Separat wurde die Methode getValueTitle() eingeführt, die den Namen der ausgewählten Entität (Produktname, Artikeltitel usw.) anzeigt, wenn diese bereits ausgewählt und gespeichert wurde. Das heißt, wir haben den Menüpunkt bearbeitet, wir berühren das Feld nicht, aber wir möchten, dass der Titel des Artikels/Produktnamens für die Menschen verständlich ist und nicht nur eine ID. Diese Methode zeigt den gewünschten Titel an.
<field type="productlist" name="product_id" addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field" label="Field label" hint="Field placeholder" />
In einigen Feldern, in denen komplexere Funktionen erforderlich sind – mehrsprachige Assoziationen usw. – gibt es andere Methoden in der Feldklasse, die die grundlegenden Methoden der FormField-Klasse überschreiben:
In unserem Fall besteht kein solcher Bedarf, daher verwenden wir sie nicht.
Wenn Sie auf die Schaltfläche „Auswählen“ klicken, öffnet sich ein modales Bootstrap-Fenster, in dem sich eine Liste der Produkte im
In meinem Plugin gibt die Methode onAjaxProviderjoomshopping() die HTML-Ausgabe der Produktliste zurück. Dort durchlaufen wir mit ihnen das Array, nehmen das Bild, den Namen und die Ausgabe auf. Der Code ist im Allgemeinen umfangreich, daher werde ich die wichtigsten Fragmente veröffentlichen.
Vereinfachtes Schleifencodebeispiel:
<?php extract($displayData); /** * Layout variables * ----------------- * @var string $autocomplete Autocomplete attribute for the field. * @var boolean $autofocus Is autofocus enabled? * @var string $class Classes for the input. * @var string $description Description of the field. * @var boolean $disabled Is this field disabled? * @var string $group Group the field belongs to. <fields> section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var string $dataAttribute Miscellaneous data attributes preprocessed for HTML output * @var array $dataAttributes Miscellaneous data attribute for eg, data-* * @var string $valueTitle * @var array $canDo * @var string[] $urls * @var string[] $modalTitles * @var string[] $buttonIcons */
Zweite. Der Link-Tag-Code muss Datenattribute mit den von uns benötigten Daten enthalten. Wir haben dieses Fragment im Beispielcode des Warenausgangszyklus gesehen.
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
Jetzt beginnen wir mit der Arbeit mit JavaScript. Während des Schreibens des Artikels sind Nuancen aufgetaucht, die es uns ermöglichen, über alte und neue Arbeitsweisen zu sprechen.
Wir erinnern uns, dass wir im Laufe der Arbeit die folgenden js-Skripte verbunden haben
Beginnen wir mit unserem eigenen Javascript. Hier erhalten wir mithilfe der Select-Link-Klasse alle Selektoren und hängen den Listener des Klickereignisses an sie.
<?php use Joomla\CMS\Layout\LayoutHelper; $displayData = [ 'src' => $this->item->image, 'alt' => $this->item->name, ]; echo LayoutHelper::render( 'joomla.html.image', $displayData );
Wenn mit ID und Titel alles intuitiv ist, dann ist es mit dem Datenobjekt und der PostMessage für diejenigen, die es gewohnt sind, mit Joomla zu arbeiten, möglicherweise nicht offensichtlich.
Zuvor wurde in Joomla 2.5, 3.x und sogar in 4.x der folgende Ansatz verwendet: Im Layout der Feldausgabe haben wir ein Inline-Skript verwendet, um eine Handler-Funktion an das Fenster zu hängen, und von < ;iframe> Wir haben es als window.parent[functionName] bezeichnet. Schauen Sie sich diesen Code an
<field type="productlist" name="product_id" addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field" label="Field label" hint="Field placeholder" />
In diesem Formular wurde der Funktionsname im Datenfunktionsattribut jedes Links in der Liste der Artikel/Kontakte/Menüelemente angegeben. Und die Funktion selbst wurde inline platziert, wobei ihr Name manchmal mit einer zusätzlichen ID vereinheitlicht wurde. Beispiel: "jSelectArticle_".$this->id.
Die jSelectArticle()-Funktion oder eine ähnliche Funktion (wir hätten jSelectProduct()) ist ein Wrapper für die Standardfunktion „processModalSelect()“ aus der Datei modal-fields.min.js . Es ruft wiederum die Funktion „processModalParent()“ auf und schließt das modale Fenster nach der Ausführung.
Damit diese Funktion funktioniert, musste sie eine Reihe von Parametern angeben: den Typ der Entität (Artikel, Kontakt usw.), das Präfix des Felds (das sich in der Praxis als ID des HTML-Feldselektors herausstellte) und die tatsächliche ID und Titel – die Parameter, die wir benötigen usw.
In einer Funktion wurde alles für alle Gelegenheiten gesammelt. Dort wurden die Daten in unserem Bereich platziert.
Jetzt, in Joomla 5, wird diese Datei jedoch nicht mehr benötigt. Wenn wir das Standardlayout der Feldausgabe verwenden, ist das Asset „Modal-Content-Select-Field“ damit verbunden und funktioniert auf eine neue Art und Weise.
Jetzt stellt das Joomla 5-Frontend auf die Verwendung von JavaScript postMessages um. Da noch nicht alle alten Erweiterungen bereit sind, auf neue Schienen umzusteigen, wurde das Flag JoomlaExpectingPostMessage implementiert, mit dem Sie veraltete Methoden zum Aufrufen von Ereignissen unterscheiden können. Es hat einen indirekten Zusammenhang mit der beschriebenen Arbeitsweise, kann aber für jemanden nützlich sein. Dieses Flag wird nach dem vollständigen Übergang zu postMessages entfernt.
Jetzt brauchen wir also keine zusätzlichen Attribute von Links mit dem Namen der aufgerufenen Funktionen. Stattdessen verwenden wir den postMessage-Mechanismus. Dazu müssen wir im Datenobjekt den Parameter messageType gleich joomla:content-select angeben. Warum? Aus Sicht von JavaScript sieht die Arbeit in Joomla wie folgt aus:
Beim Studium des Joomla-Kerncodes und der Suche nach einer Lösung bin ich natürlich auf die Funktionen jSelectArticle() und dergleichen gestoßen. Dann stieß ich auf postMessage und beschloss, meinem MessageType einen langen, eindeutigen Namen zu geben. Damit es funktioniert, habe ich meine eigene Verarbeitung geschrieben und die (wie sich herausstellte, veraltete) Funktion „processModalSelect()“ aufgerufen. Und ich wurde mit der Tatsache konfrontiert, dass sich das modale Fenster überhaupt nicht schließen wollte, obwohl die Daten korrekt in die Felder eingefügt wurden. Weitere Suchvorgänge führten zunächst zum richtigen Ereignistyp und dann zur Entfernung unnötiger Skripte und zur Vereinfachung des gesamten Codes.
Joomla stellt dem Entwickler einen umfangreichen Satz an Tools zur Verfügung, mit denen er Daten aus Drittquellen bearbeiten und abrufen und in Ihrem Code verwenden kann. Die Arbeit mit JForm-Feldern ist für einen Entwickler wichtig, wenn er eigene Erweiterungen erstellt, insbesondere wenn eine Aufgabe gelöst werden muss, die über den typischen Rahmen hinausgeht. Natürlich ist ein solches modales Fenster und die Auswahl der Daten darin ein eher Sonderfall, aber auf diese Weise können Sie sowohl beliebige andere JForm-Felder überschreiben als auch eigene Typen mit Ihrer eigenen UX-Logik erstellen.
Das obige ist der detaillierte Inhalt vonErstellen eines benutzerdefinierten Formularfeldtyps in Joomla anhand des Modal Select-Beispiels. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!