Die Daten der Datenbank im Frontend nutzen
Wir haben eine Datenbank, in der die Daten zur Komponente gespeichert werden. Der nächste Schritt ist, die dynamischen Inhalte im Frontend anzuzeigen. In diesem Teil zeige ich dir, wie du den Inhalt eines Elements per Menüpunkt im Frontend anzeigst. Hierzu erstellen wir ein eigenes Formularfeld.
Für Ungeduldige: Sieh dir den geänderten Programmcode in der Diff-Ansicht[^codeberg.org/astrid/j4examplecode/compare/t6b…t7] an und übernimm diese Änderungen in deine Entwicklungsversion.
Schritt für Schritt
Neue Dateien
administrator/components/com_foos/src/Field/Modal/FooField.php
Als erstes erstellen wir das Formularfeld, über welches es möglich ist, ein Foo-Element auszuwählen, beziehungsweise abzuwählen. Auf ein vorgefertigtes Feld können wir in diesem Fall nicht zugreifen. Im Wesentlichen implementieren wir die Methoden getInput
und getLabel
und wir legen Typ mit Modal_Foo
fest. Das der Name der Klasse mit dem Wort Field
beginnt und dass die Klasse im Verzeichnis Field
gespeichert wird ist nicht zwingend. Es kann aber hilfreich sein, weil es in Joomla-eigenen Erweiterung Standard ist.
Es ist möglich, das Feld so zu erweitern, dass ein Foo-Elemente über eine Schaltfläche angelegt wird. Dies habe ich in der aktuellen Version der Übersicht halber außen vor gelassen. Beispielcode bietet die Komponente
com_contact
in der Dateiadministrator/components/com_contact/ src/Field/Modal/ContactField.php
.
administrator/components/com_foos/src/Field/Modal/FooField.php
// https://codeberg.org/astrid/j4examplecode/raw/branch/t7/src/administrator/components/com_foos/src/Field/Modal/FooField.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace FooNamespace\Component\Foos\Administrator\Field\Modal;
\defined('JPATH_BASE') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
/**
* Supports a modal foo picker.
*
* @since __DEPLOY_VERSION__
*/
class FooField extends FormField
{
/**
* The form field type.
*
* @var string
* @since __DEPLOY_VERSION__
*/
protected $type = 'Modal_Foo';
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*
* @since __DEPLOY_VERSION__
*/
protected function getInput()
{
$allowClear = ((string) $this->element['clear'] != 'false');
$allowSelect = ((string) $this->element['select'] != 'false');
// The active foo id field.
$value = (int) $this->value > 0 ? (int) $this->value : '';
// Create the modal id.
$modalId = 'Foo_' . $this->id;
// Add the modal field script to the document head.
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
// Add the modal field script to the document head.
$wa->useScript('field.modal-fields');
// Script to proxy the select modal function to the modal-fields.js file.
if ($allowSelect) {
static $scriptSelect = null;
if (is_null($scriptSelect)) {
$scriptSelect = [];
}
if (!isset($scriptSelect[$this->id])) {
$wa->addInlineScript("
window.jSelectFoo_" . $this->id . " = function (id, title, object) {
window.processModalSelect('Foo', '" . $this->id . "', id, title, '', object);
}",
[],
['type' => 'module']
);
$scriptSelect[$this->id] = true;
}
}
// Setup variables for display.
$linkFoos = 'index.php?option=com_foos&view=foos&layout=modal&tmpl=component&'
. Session::getFormToken() . '=1';
$linkFoo = 'index.php?option=com_foos&view=foo&layout=modal&tmpl=component&'
. Session::getFormToken() . '=1';
$modalTitle = Text::_('COM_FOOS_CHANGE_FOO');
$urlSelect = $linkFoos . '&function=jSelectFoo_' . $this->id;
if ($value) {
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('name'))
->from($db->quoteName('#__foos_details'))
->where($db->quoteName('id') . ' = ' . (int) $value);
$db->setQuery($query);
try {
$title = $db->loadResult();
} catch (\RuntimeException $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
}
}
$title = empty($title) ? Text::_('COM_FOOS_SELECT_A_FOO') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
// The current foo display field.
$html = '';
if ($allowSelect || $allowNew || $allowEdit || $allowClear) {
$html .= '<span class="input-group">';
}
$html .= '<input class="form-control" id="' . $this->id . '_name" type="text" value="' . $title . '" readonly size="35">';
// Select foo button
if ($allowSelect) {
$html .= '<button'
. ' class="btn btn-primary hasTooltip' . ($value ? ' hidden' : '') . '"'
. ' id="' . $this->id . '_select"'
. ' data-bs-toggle="modal"'
. ' type="button"'
. ' data-bs-target="#ModalSelect' . $modalId . '"'
. ' title="' . HTMLHelper::tooltipText('COM_FOOS_CHANGE_FOO') . '">'
. '<span class="icon-file" aria-hidden="true"></span> ' . Text::_('JSELECT')
. '</button>';
}
// Clear foo button
if ($allowClear) {
$html .= '<button'
. ' class="btn btn-secondary' . ($value ? '' : ' hidden') . '"'
. ' id="' . $this->id . '_clear"'
. ' type="button"'
. ' onclick="window.processModalParent(\'' . $this->id . '\'); return false;">'
. '<span class="icon-remove" aria-hidden="true"></span>' . Text::_('JCLEAR')
. '</button>';
}
if ($allowSelect || $allowNew || $allowEdit || $allowClear) {
$html .= '</span>';
}
// Select foo modal
if ($allowSelect) {
$html .= HTMLHelper::_(
'bootstrap.renderModal',
'ModalSelect' . $modalId,
[
'title' => $modalTitle,
'url' => $urlSelect,
'height' => '400px',
'width' => '800px',
'bodyHeight' => 70,
'modalWidth' => 80,
'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">'
. Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</button>',
]
);
}
// Note: class='required' for client side validation.
$class = $this->required ? ' class="required modal-value"' : '';
$html .= '<input type="hidden" id="'
. $this->id . '_id"'
. $class . ' data-required="' . (int) $this->required
. '" name="' . $this->name
. '" data-text="'
. htmlspecialchars(Text::_('COM_FOOS_SELECT_A_FOO', true), ENT_COMPAT, 'UTF-8')
. '" value="' . $value . '">';
return $html;
}
/**
* Method to get the field label markup.
*
* @return string The field label markup.
*
* @since __DEPLOY_VERSION__
*/
protected function getLabel()
{
return str_replace($this->id, $this->id . '_name', parent::getLabel());
}
}
Der Programmcode für das Formularfeld ist an Bootstrap 5[^getbootstrap.com] angepasst. Dieses Framework wurde im Pull Request 32037[^github.com/joomla/joomla-cms/pull/32037] in Joomla 4 integriert.
Achte darauf, dass du die korrekten Namen verwendest. Falls später beim Testen nichts passiert, wenn du ein einzelnes Foo auswählst, liegt es meist an einem Tippfehler. Hintergrund: Es wird JavaScript ausgeführt. Du fügst dieses Skript an zwei Stellen hinzu. Zuerst erstellst du die Funktion jSelectFoo_...
mithilfe von Variablen.
...
if (!isset($scriptSelect[$this->id])) {
$wa->addInlineScript("
window.jSelectFoo_" . $this->id . " = function (id, title, object) {
window.processModalSelect('Foo', '" . $this->id . "', id, title, '', object);
}",
[],
['type' => 'module']
);
$scriptSelect[$this->id] = true;
}
...
Im Quelltext des Joomla Administrationsbereich wird der folgende Code hinzugefügt:
<script nonce="beispielID=">
function jSelectFoos_jform_request_id(id, title, object) { window.processModalSelect('Foo', 'jform_request_id', id, title, '', object);}
</script>
Etwas später rufst du die Funktion auf.
...
$urlSelect = $linkFoos . '&function=jSelectFoo_' . $this->id;
...
Der Name der Funktion muss an beiden Stellen gleich sein!
In einer früher Beispielcode-Version zum Feld
FooField
nutzen wir den Webasset Manager nicht. Die notwendigen Änderungen findest du hier[^github.com/joomla/joomla-cms/commit/04f844ad4a6d0432ec4b770bbb2a33243ded16d9].
administrator/components/com_foos/tmpl/foos/modal.php
Die Auswahl öffnen wir über das FooField in einem Modal-Fenster. Als Adresse haben wir im Feld $linkFoos = 'index.php?option=com_foos&view=foos&layout=modal&tmpl=component&'
eingefügt. Der nachfolgende Code zeigt dir das Template für dieses Modal-Fenster.
administrator/components/com_foos/tmpl/foos/modal.php
// https://codeberg.org/astrid/j4examplecode/raw/branch/t7/src/administrator/components/com_foos/tmpl/foos/modal.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
$app = Factory::getApplication();
$wa = $this->document->getWebAssetManager();
$wa->useScript('com_foos.admin-foos-modal');
$function = $app->input->getCmd('function', 'jSelectFoos');
$onclick = $this->escape($function);
?>
<div class="container-popup">
<form action="<?php echo Route::_('index.php?option=com_foos&view=foos&layout=modal&tmpl=component&function=' . $function . '&' . Session::getFormToken() . '=1'); ?>" method="post" name="adminForm" id="adminForm" class="form-inline">
<?php if (empty($this->items)) : ?>
<div class="alert alert-warning">
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table table-sm">
<thead>
<tr>
<th scope="col" style="width:10%" class="d-none d-md-table-cell">
</th>
<th scope="col" style="width:1%">
</th>
</tr>
</thead>
<tbody>
<?php
$iconStates = [
-2 => 'icon-trash',
0 => 'icon-unpublish',
1 => 'icon-publish',
2 => 'icon-archive',
];
?>
<?php foreach ($this->items as $i => $item) : ?>
<?php $lang = ''; ?>
<tr class="row<?php echo $i % 2; ?>">
<th scope="row">
<a class="select-link" href="javascript:void(0)" data-function="<?php echo $this->escape($onclick); ?>" data-id="<?php echo $item->id; ?>" data-title="<?php echo $this->escape($item->name); ?>">
<?php echo $this->escape($item->name); ?>
</a>
</th>
<td>
<?php echo (int) $item->id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="forcedLanguage" value="<?php echo $app->input->get('forcedLanguage', '', 'CMD'); ?>">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
</div>
Ein Modal[^de.wikipedia.org/wiki/dialog_(benutzeroberfl%c3%a4che)] ist ein Bereich, der sich im Vordergrund einer Webseite öffnet und deren Zustand ändert. Es ist erforderlich, diesen aktiv zu schließen. Modale Dialoge sperren den Rest der Anwendung solange der Dialog angezeigt wird. Ein Modal wird ebenfalls Dialog oder Lightbox genannt.
media/com_foos/joomla.asset.json
Wir nutzen den Webassetmanager. Dieses mal fügen wir ein eigenes Webasset mithilfe der Datei joomla.asset.json
hinzu. Falls du dieses nicht korrekt einbindest, wird dir folgender Fehler angezeigt, wenn du für den Menüpunkt ein Foo-Element auswählst: There is no "com_foos.admin-foos-modal" asset of a "script" type in the registry.
. Grund: Im Modal wird mit der Zeile $wa->useScript('com_foos.admin-foos-modal');
das Skript com_foos.admin-foos-modal
aufgerufen, welches aber vorher nicht richtig registriert wurde. Deshalb wird es nicht gefunden.
Wegen der neu hinzugekommenen Datei
joomla.asset.json
ist es erforderlich, dass wir die Erweiterung neu installieren. Andere Dateien haben wir bisher ohne eine neue Installation in Joomla verwendet. Mit der Dateijoomla.asset.json
funktioniert das nicht. Diese muss einmal bei einer Installation registriert werden. Im Weiteren können Änderungen in ihr vorgenommen werden. Diese werden ohne Neuinstallation erkannt.
Es ist nicht zwingend die Datei
/de] nutzen möchtest. In der Dokumentation findest du Möglichkeiten, Webassets nachträglich im Code zu registrieren.joomla.asset.json
anzulegen, wenn du den den Webassetmanager[^docs.joomla.org/j4.x
media/com_foos/joomla.asset.json
/* https://codeberg.org/astrid/j4examplecode/raw/branch/t7/src/media/com_foos/joomla.asset.json */
{
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
"name": "com_foos",
"version": "1.0.0",
"description": "Joomla CMS",
"license": "GPL-2.0-or-later",
"assets": [
{
"name": "com_foos.admin-foos-modal",
"type": "script",
"uri": "com_foos/admin-foos-modal.js",
"dependencies": ["core"],
"attributes": {
"defer": true
}
}
]
}
Wunderst du dich, dass ich anstelle von
com_foos/js/admin-foos-modal.js
com_foos/admin-foos-modal.js
alsuri
schreibe? Meiner Meinung nach ist dies ein verstecktes Geheimnis in Joomla.js
undcss
Datei, wenn der Pfad nicht absolut[^github.com/joomla/joomla-cms/blob/ddb844b450ec989f08f6a54c051ca52d57fa0789/ libraries/src/webasset/webassetitem.php#l349] ist, werden automatisch im Unterverzeichnisjs
, bzw.css
gesucht. Dies war bereits in Joomla 3.x[^docs.joomla.org/adding_javascript/de#external_javascript] der Fall. Im AufrufJHtml::_('script', 'com_example/example.js', array('relative' => true));
erwartet Joomla, dass sich die Dateiexample.js
untermedia/com_example/js/example.js
befindet. Du solltestjs
nicht in den Pfad in der Anweisung einschließen. Dieses Verhalten wird vom Web Asset Manager für Skripte und Stile standardmäßig implementiert. Möchtest du einen genaueren Blick darauf werfen? Du findest den Code dafür in der Dateilibraries/src/WebAsset/WebAssetItem.php
.
Für die Medienversion setzt der Web Asset Manager den Standardwert auto
. Das bedeutet, dass JHtml::_('script', 'com_example/example.js', array('version' => 'auto'));
standardmäßig aufgerufen wird. Was bedeutet das genau? Die Medienversion wird verwendet, um das erneute Laden von CSS- und JavaScript-Dateien zu steuern. Insbesondere wird die Medienversion bei einer Aktualisierung, Installation oder Deinstallation zurückgesetzt. Der Grund dafür ist, dass Browser CSS- und JS-Dateien im Cache speichern, so dass die folgende Situation eintreten kann
- Ein Benutzer greift auf eine Joomla-Website zu, und die CSS- und JS-Dateien werden im Browser des Benutzers gespeichert.
- Joomla wird aktualisiert, und während des Aktualisierungsprozesses ändert sich der Inhalt mehrerer CSS- und JS-Dateien. Die Dateinamen bleiben gleich.
- Der Benutzer greift auf die neu aktualisierte Seite zu, aber die neuen CSS- und JS-Dateien werden nicht neu geladen, weil der Browser des Benutzers stattdessen die zwischengespeicherten Versionen verwendet.
- Wenn
version' => 'auto
gesetzt ist, ist dassrc
-Attribut des<script>
-Tags nach der Aktualisierung anders, und der Browser lädt die neue Datei. Für die normale Arbeit mit einer Joomla-Website ist diese Einstellung nützlich. Bei der Entwicklung kann es vorkommen, dass du Web-Asset-Dateien öfters neu laden möchtest. Ich verwende beim Entwickeln den Debug-Modus, weil auf diese Weise bei jeder HTTP-Anfrage eine neue Medienversion erzwungen wird.
Was bedeutet das Attribut
"defer": true
? Skripte werden mitasync
asynchron oder parallel zu anderen Ressourcen geladen.defer
verspricht dem Browser, dass die Webseite nicht durch Anweisungen geändert wird. Weitere Informationen bei Mozilla.org[^developer.mozilla.org/en-us/docs/web/html/element/script].
Der Joomla Web Assets Manager verwaltet alle Assets in einer Joomla-Installation. Es ist nicht zwingend Skriptdateien oder Stylesheets über diesen Manager einzubinden. Alle Aufrufe von
HTMLHelper::_('stylesheet oder script ...)
funktionieren, aber diese Assets werden nach den Web Asset Manager Assets angefügt. Dies führt dazu, dass Styles überschrieben werden, die im Template gesetzt werden. So hat ein Benutzer nicht die Möglichkeit, mithilfe eineruser.css
einzuwirken. Es gibt weitere Vorteile: Wenn Abhängigkeiten korrekt gesetzt sind, treten keine Konflikte auf und notwendige Dateien werden von Joomla geladen. Eine Abhängigkeit haben wir beispielsweise in der Zeile"dependencies": ["core"],
gesetzt.
media/com_foos/js/admin-foos-modal.js
Es folgt der JavaScript Code, der bewirkt, dass beim Anlegen eines Menüpunktes ein Foo-Element auswählbar ist. Die Klasse select-link
, deren Elemente Hauptbestandteil der Datei sind, werden wir später im Feld der entsprechenden Schaltfläche zuordnen.
media/com_foos/js/admin-foos-modal.js
/* https://codeberg.org/astrid/j4examplecode/raw/branch/t7/src/media/com_foos/js/admin-foos-modal.js */
;(function () {
'use strict'
document.addEventListener('DOMContentLoaded', function () {
var elements = document.querySelectorAll('.select-link')
for (var i = 0, l = elements.length; l > i; i += 1) {
elements[i].addEventListener('click', function (event) {
event.preventDefault()
var functionName = event.target.getAttribute('data-function')
window.parent[functionName](
event.target.getAttribute('data-id'),
event.target.getAttribute('data-title'),
null,
null,
event.target.getAttribute('data-uri'),
event.target.getAttribute('data-language'),
null
)
if (window.parent.Joomla.Modal) {
window.parent.Joomla.Modal.getCurrent().close()
}
})
}
})
})()
Geänderte Dateien
administrator/components/com_foos/foos.xml
Wir haben eine neue JavaScript-Datei erstellt. Wir legen sie im Verzeichnis media\js
ab. Damit sie bei der Installation der Komponente kopiert wird, fügen wir den Ordner js
in den Abschnitt media
des Installationsmanifests ein.
administrator/components/com_foos/foos.xml
<folder>src</folder>
<folder>tmpl</folder>
</files>
+ <media folder="media/com_foos" destination="com_foos">
+ <folder>js</folder>
+ <filename>joomla.asset.json</filename>
+ </media>
<!-- Back-end files -->
<administration>
<!-- Menu entries -->
Lies im Vorwort warum du das
media
Verzeichnis idealerweise für Assets wie JavaScript-Dateien oder Stylesheets wählst.
components/com_foos/src/Model/FooModel.php
Wir geben keinen statischen Text mehr aus. Es wird ein Element aus der Datenbank angezeigt. Deshalb benennen wir die Methode getMsg
in getItem
um. Wir passen die Variablenbezeichnungen an und erstellen eine Datenbankabfrage.
Achte darauf, dass du den DocBlock anpasst. Das hört sich zu Beginn kleinlich und unwichtig an. In kleinen Erweiterungen ist es vielleicht noch nebensächlich. Später möchtest du aber vielleicht einmal eine Dokumentation anhand dieser Information automatisch erstellen. Dann bist du froh, wenn diese korrekt sind.
components/com_foos/src/Model/FooModel.php
class FooModel extends BaseDatabaseModel
{
/**
- * @var string message
+ * @var string item
*/
- protected $message;
+ protected $_item = null;
/**
- * Get the message
+ * Gets a foo
*
- * @return string The message to be displayed to the user
+ * @param integer $pk Id for the foo
+ *
+ * @return mixed Object or null
+ *
+ * @since __BUMP_VERSION__
*/
- public function getMsg()
+ public function getItem($pk = null)
{
$app = Factory::getApplication();
- $this->message = $app->input->get('show_text', "Hi");
+ $pk = $app->input->getInt('id');
+
+ if ($this->_item === null)
+ {
+ $this->_item = array();
+ }
+
+ if (!isset($this->_item[$pk]))
+ {
+ try
+ {
+ $db = $this->getDbo();
+ $query = $db->getQuery(true);
+
+ $query->select('*')
+ ->from($db->quoteName('#__foos_details', 'a'))
+ ->where('a.id = ' . (int) $pk);
+
+ $db->setQuery($query);
+ $data = $db->loadObject();
+
+ if (empty($data))
+ {
+ throw new \Exception(Text::_('COM_FOOS_ERROR_FOO_NOT_FOUND'), 404);
+ }
+
+ $this->_item[$pk] = $data;
+ }
+ catch (\Exception $e)
+ {
+ $this->setError($e);
+ $this->_item[$pk] = false;
+ }
+ }
- return $this->message;
+ return $this->_item[$pk];
}
}
Joomla unterstützt dich beim Erstellen der Datenbankabfragen. Wenn du die zur Verfügung stehenden Anweisungen[^docs.joomla.org/accessing_the_database_using_jdatabase/de] nutzt, dann kümmert sich Joomla um Sicherheit oder unterschiedliche Syntax in PostgreSQL und MySQL.
components/com_foos/src/View/Foo/HtmlView.php
In der View tauschen wir folgerichtig $this->msg = $this->get('Msg');
gegen $this->item = $this->get('Item');
aus.
components/com_foos/src/View/Foo/HtmlView.php
class HtmlView extends BaseHtmlView
{
+ /**
+ * The item object details
+ *
+ * @var \JObject
+ * @since __BUMP_VERSION__
+ */
+ protected $item;
+
/**
* Execute and display a template script.
*
*/
public function display($tpl = null)
{
- $this->msg = $this->get('Msg');
+ $this->item = $this->get('Item');
return parent::display($tpl);
}
components/com_foos/tmpl/foo/default.php
Die Anzeige des Namens passen wir im Template an. Hier greifen wir auf das Element item
und dessen Eigenschaft name
zu. Auf diese Art können wir in Zukunft weitere Eigenschaften flexibel und unkompliziert ergänzen.
components/com_foos/tmpl/foo/default.php
\defined('_JEXEC') or die;
?>
-Hello Foos: <?php echo $this->msg;
+<?php
+echo $this->item->name;
components/com_foos/tmpl/foo/default.xml
Wir erstellen einen Eintrag in der Datei default.xml
für das neue Formularfeld. So ermöglichen wir beim Menüpunkt die Auswahl eines Foo-Elementes. Erwähnenswert sind die Einträge addfieldprefix="FooNamespace\Component\Foos\Administrator\Field"
und type="modal_foo"
:
components/com_foos/tmpl/foo/default.xml
</layout>
<!-- Add fields to the request variables for the layout. -->
<fields name="request">
- <fieldset name="request">
+ <fieldset name="request"
+ addfieldprefix="FooNamespace\Component\Foos\Administrator\Field"
+ >
<field
- name="show_text"
- type="text"
- label="COM_FOOS_FIELD_TEXT_SHOW_LABEL"
- default="Hi"
+ name="id"
+ type="modal_foo"
+ label="COM_FOOS_SELECT_FOO_LABEL"
+ required="true"
+ select="true"
+ new="true"
+ edit="true"
+ clear="true"
/>
</fieldset>
</fields>
Teste deine Joomla-Komponente
-
Installiere deine Komponente in Joomla Version 4, um sie zu testen: Kopiere die Dateien im
administrator
Ordner in denadministrator
Ordner deiner Joomla 4 Installation. Kopiere die Dateien imcomponents
Ordner in dencomponents
Ordner deiner Joomla 4 Installation. Kopiere die Dateien immedia
Ordner in denmedia
Ordner deiner Joomla 4 Installation. Eine neue Installation ist erforderlich, um die Dateijoomla.asset.json
zu registrieren. -
Öffne den Menümanager, um einen Menüpunkt anzulegen. Klicke dazu auf
Menü
und dann aufAll Menu Items
.
Klicke danach auf die Schaltfläche New
und fülle alle notwendigen Felder aus. Den passenden Menu Item Typ
findest du über die Select
Schaltfläche. Überzeuge dich davon, dass du, anstelle des Textfeldes zur Eingabe eines statischen Textes ein Auswahlfeld siehst. Das Auswahlfeld enthält ebenfalls eine Schaltfläche Select
.
- Klicke auf das zweite
Select
und wähle ein Item aus. Stelle sicher, dass ein gewähltes Element mittelsClear
widerufbar ist.
-
Speichere den Menüpunkt.
-
Wechsele anschließend ins Frontend und überzeuge dich davon, dass der Menüpunkt korrekt angelegt ist. Dir wird der Name des Elements angezeigt, welches du im Administrationsbereich ausgewählt hattest.