Manchmal ist es erforderlich, die Darstellung im Frontend unterschiedlich zu gestalten. Hierfür ist grundsätzlich das Template zuständig. Eine Komponente ist für die Ausgabe von Inhalten verantwortlich, nicht mehr und nicht weniger. Das Template sorgt für ein einheitliches Aussehen. Trotzdem gibt es Anwendungsfälle für unterschiedliche Layouts. Wie du diese für eine Ansicht einbaust, ist Thema des folgenden Artikels.

Für Ungeduldige: Sieh dir den geänderten Programmcode in der Diff-Ansicht[^codeberg.org/astrid/j4examplecode/compare/t19...t20] an und übernimm diese Änderungen in deine Entwicklungsversion.

Schritt für Schritt

Wir nutzen bereits Layouts. Das Empty-State-Layout (administrator/components/com_foos/tmpl/foos/emptystate.php)[^github.com/astridx/boilerplate/blob/t6b/src/administrator/components/com_foos/tmpl/foos/emptystate.php] ist ein Beispiel. In diesem Teil des Textes geht es darum, alle Schritte zur Integration eines Layouts zusammenhängend zu betrachten.

Neue Dateien

components/com_foos/tmpl/foo/withhead.php

components/com_foos/tmpl/foo/withhead.php

<?php
// https://codeberg.org/astrid/j4examplecode/raw/branch/t24/src/components/com_foos/tmpl/foo/withhead.php

\defined('_JEXEC') or die;

use Joomla\CMS\Language\Text;

echo "<hr>Hier kannst du einen Headertext anzeigen.<hr>";

if ($this->item->params->get('show_name')) {
	if ($this->params->get('show_foo_name_label')) {
		echo Text::_('COM_FOOS_NAME') . $this->item->name;
	} else {
		echo $this->item->name;
	}
}

echo $this->item->event->afterDisplayTitle;
echo $this->item->event->beforeDisplayContent;
echo $this->item->event->afterDisplayContent;

components/com_foos/tmpl/foo/withhead.xml

components/com_foos/tmpl/foo/withhead.xml

<!-- https://codeberg.org/astrid/j4examplecode/raw/branch/t24/src/components/com_foos/tmpl/foo/withhead.xml -->

<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_FOOS_FOO_VIEW_WITHHEAD_TITLE">
		<message>
			<![CDATA[COM_FOOS_FOO_VIEW_WITHHEAD_DESC]]>
		</message>
	</layout>
	<!-- Add fields to the request variables for the layout. -->
	<fields name="request">
		<fieldset name="request"
			addfieldprefix="FooNamespace\Component\Foos\Administrator\Field"
		>
			<field
				name="id"
				type="modal_foo"
				label="COM_FOOS_SELECT_FOO_LABEL"
				required="true"
				select="true"
				new="true"
				edit="true"
				clear="true"
			/>
		</fieldset>
	</fields>
</metadata>

components/com_foos/tmpl/foo/withheadandfoot.php

components/com_foos/tmpl/foo/withheadandfoot.php

// https://codeberg.org/astrid/j4examplecode/raw/branch/t24/src/components/com_foos/tmpl/foo/withheadandfoot.php

<?php

\defined('_JEXEC') or die;

use Joomla\CMS\Language\Text;

echo "<hr>Hier kannst du einen Headertext anzeigen.<hr>";

if ($this->item->params->get('show_name')) {
	if ($this->Params->get('show_foo_name_label')) {
		echo Text::_('COM_FOOS_NAME') . $this->item->name;
	} else {
		echo $this->item->name;
	}
}

echo "<hr>Hier kannst du eine Fußzeile anzeigen.<hr>";

echo $this->item->event->afterDisplayTitle;
echo $this->item->event->beforeDisplayContent;
echo $this->item->event->afterDisplayContent;

Geänderte Dateien

administrator/components/com_foos/forms/foo.xml

Im Formular des Elements ergänzen wir ein Feld zum Auswählen des Layouts.

administrator/components/com_foos/forms/foo.xml

 				<option value="0">JHIDE</option>
 				<option value="1">JSHOW</option>
 			</field>

			<field
				name="foos_layout"
				type="componentlayout"
				label="JFIELD_ALT_LAYOUT_LABEL"
				class="custom-select"
				extension="com_foos"
				view="foo"
				useglobal="true"
			/>
 		</fieldset>
 	</fields>
 </form>

components/com_foos/src/Model/FooModel.php

So etwas passiert beim Entwickeln. Im Grunde genommen müssten wir die Datei components/com_foos/src/Model/FooModel.php nicht ändern. In diesem Kapitel ist mir aufgefallen, dass ein use-Eintrag fehlt. Deshalb erfolgt doch eine Änderung.

components/com_foos/src/Model/FooModel.php

 use Joomla\CMS\Factory;
 use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Language\Text;

 /**
  * Foo model for the Joomla Foos component.

components/com_foos/src/View/Foo/HtmlView.php

Im Falle eines Menüpunktes finde ich es wichtig, dass dieser - beziehungsweise der Inhalt und das Design- immer einheitlich angezeigt werden. Deshalb fragen wir den aktiven Menüpunkt ab. Werden beispielsweise Elemente über eine Kategorie-Ansicht angezeigt, dann ist mithilfe dieser Information ein einheitliches Layout möglich. Wird der Content als einzelnes Element angezeigt kann auf ein anderes Layout zurückgegriffen werden.

components/com_foos/src/View/Foo/HtmlView.php

 		$temp->merge($itemparams);
 		$item->params = $temp;

		$active = Factory::getApplication()->getMenu()->getActive();

		// Override the layout only if this is not the active menu item
		// If it is the active menu item, then the view and item id will match
		if ((!$active) || ((strpos($active->link, 'view=foo') === false) || (strpos($active->link, '&id=' . (string) $this->item->id) === false)))
		{
			if (($layout = $item->params->get('foos_layout')))
			{
				$this->setLayout($layout);
			}
		}
		elseif (isset($active->query['layout']))
		{
			// We need to set the layout in case this is an alternative menu item (with an alternative layout)
			$this->setLayout($active->query['layout']);
		}

 		Factory::getApplication()->triggerEvent('onContentPrepare', array ('com_foos.foo', &$item));

 		// Store the events for later

Teste deine Joomla-Komponente

  1. Führe eine neue Installation durch. Deinstalliere hierzu deine bisherige Installation und kopiere alle Dateien erneut. In einem frisch installierten System ist die Erklärung der Layouts unkomplizierter.

Kopiere die Dateien im administrator Ordner in den administrator Ordner deiner Joomla 4 Installation.
Kopiere die Dateien im components Ordner in den components Ordner deiner Joomla 4 Installation.

Installiere deine Komponente wie in Teil eins beschrieben, nachdem du alle Dateien kopiert hast.

  1. Stelle bei einem Item ein spezielles Layout ein. Ich habe withhead bei dem Item mit der ID 2 gesetzt.

Joomla Layouts

  1. Sie dir die Ausgabe im Frontend an. Gibt dazu die URL JOOMLA4/?option=com_foos&id=2&view=foo in der Adresszeile des Browsers ein. Du siehst das ausgewählte Layout. Überzeuge dich davon, dass die Eingabe von JOOMLA4/?option=com_foos&id=1&view=foo das Standardlayout aufruft - sofern kein spezielles eingestellt ist.

  2. Dieses Layout ist ebenfalls per Menüpunkt ansteuerbar.

Joomla Layouts

Ein Item ohne XML-Datei ist nicht im Administrationsbereich auswählbar. Trotzdem sind solche Layouts sinnvoll! Im Programmcode ist es an jeder Stelle möglich, dieses zuzuweisen: $this->setLayout('withheadandfoot');

Da bei der Ansteuerung über einen Menüpunkt die Ansicht einheitlich erwartet wird, wird das im Menüitem eingestellte Layout bevorzugt.