Joomla 4.x-Tutorial - Entwicklung von Erweiterungen - Kategorien im Backend einrichten

Ändere diesen Beitrag

Fast jede Website unterteilt ihre Inhalte in Kategorien. Joomla bietet dieses nützliche Feature ebenfalls. Der aktuelle Teil des Tutorials zeigt dir, wie du Kategorien idealerweise in eine Joomla Komponente integrierst. Erfinde das Rad nicht selbst neu. Nutze das, was Joomla dir bietet.

Kategorien sind eine Möglichkeit, Inhalte in Joomla! zu organisieren. Eine Kategorie enthält Beiträge und andere Kategorien. Ein Beitrag kann nur in einer Kategorie sein. Wenn eine Kategorie in einer anderen enthalten ist, ist sie eine Unterkategorie der Kategorie.

Für Ungeduldige

Sieh dir den geänderten Programmcode in der Diff-Ansichtgithub.com/astridx/boilerplate/compare/t11b...t12 an und übernimm diese Änderungen in deine Entwicklungsversion.

Schritt für Schritt

In der nachfolgenden Übersicht sind die neu hinzugekommenen Dateien mit einem Hintergrund versehen und die geänderten umrandet.

Übersicht über die in diesem Kapitel bearbeiteten Dateien

Neue Dateien

administrator/components/com_foos/ sql/updates/mysql/12.0.0.sql

Wir speichern die Daten in der Datenbank, die zur Einordnung eines Elementes in eine Kategorie notwendig sind. Im Falle einer Aktualisierung ist es deshalb wichtig, die Datenbank um eine Spalte zu erweitern.

administrator/components/com_foos/ sql/updates/mysql/12.0.0.sql

<!-- https://raw.githubusercontent.com/astridx/boilerplate/t12/src/administrator/components/com_foos/sql/updates/mysql/12.0.0.sql -->

ALTER TABLE `#__foos_details` ADD COLUMN  `catid` int(11) NOT NULL DEFAULT 0 AFTER `alias`;

ALTER TABLE `#__foos_details` ADD KEY `idx_catid` (`catid`);

Geänderte Dateien

administrator/components/com_foos/access.xml

Die Einträge in der access.xml sind notwendig, um Berechtigungen für die Kategorie zu setzen. Der nachfolgende Code bewirkt die Anzeige eines Tabulators zur Festlegung der Benutzerrechte pro Kategorie im Administrationsbereich.

administrator/components/com_foos/access.xml

 		<action name="core.edit" title="JACTION_EDIT" />
 		<action name="core.edit.state" title="JACTION_EDITSTATE" />
 		<action name="core.edit.own" title="JACTION_EDITOWN" />
		<action name="core.edit.value" title="JACTION_EDITVALUE" />
	</section>
	<section name="category">
		<action name="core.create" title="JACTION_CREATE" />
		<action name="core.delete" title="JACTION_DELETE" />
		<action name="core.edit" title="JACTION_EDIT" />
		<action name="core.edit.state" title="JACTION_EDITSTATE" />
		<action name="core.edit.own" title="JACTION_EDITOWN" />
 	</section>
 </access>

administrator/components/com_foos/ foos.xml

Der Eintrag <menu link="option=com_categories&amp;extension=com_foos" bewirkt, dass im Menu des Administrationsbereichs ein Menüpunkt zur Bearbeitung der Kategorie hinzugefügt wird.

administrator/components/com_foos/ foos.xml

 		<menu view="foos">COM_FOOS</menu>
 		<submenu>
 			<menu link="option=com_foos">COM_FOOS</menu>
			<menu link="option=com_categories&amp;extension=com_foos"
				view="categories" img="class:foos-cat" alt="Foos/Categories">JCATEGORY</menu>
 		</submenu>
 		<files folder="administrator/components/com_foos">
 			<filename>access.xml</filename>

administrator/components/com_foos/ forms/foo.xml

Das Formular, mit dem ein Foo-Item angelegt wird, ergänzen wir um ein Auswahlfeld mit passenden Kategorien. Wir nutzen hierzu das Joomla eigenes Feld categoryedit. Beachte die Zeile extension="com_foos". Diese bewirkt, dass ausschließlich Kategorien angezeigt werden, die zu deiner Komponente gehören.

administrator/components/com_foos/ forms/foo.xml

 			hint="JFIELD_ALIAS_PLACEHOLDER"
 		/>

		<field
			name="catid"
			type="categoryedit"
			label="JCATEGORY"
			extension="com_foos"
			addfieldprefix="Joomla\Component\Categories\Administrator\Field"
			required="true"
			default=""
		/>

 		<field
 			name="access"
 			type="accesslevel"

administrator/components/com_foos/ script.php

Damit zu Beginn schon eine Kategorie vorhanden ist, ergänzen wir das Skript, welches bei der Installation aufgerufen wird. Über die Methode install legen wir mithilfe der Datenbank bei einer Neuinstallation eine Kategorie mit dem Titel Uncategorised für die Komponente an.

Um bei der Kategorie einen Benutzer als Ersteller angeben zu können, fragen wir die ID des Administrator in der Methode getAdminId() ab.

administrator/components/com_foos/script.php

  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  */
 \defined('_JEXEC') or die;

use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
 use Joomla\CMS\Installer\InstallerAdapter;
 use Joomla\CMS\Language\Text;
 use Joomla\CMS\Log\Log;
use Joomla\CMS\Table\Table;

 /**
  * Script file of Foo Component

 	{
 		echo Text::_('COM_FOOS_INSTALLERSCRIPT_INSTALL');

		$db = Factory::getDbo();
		$alias   = ApplicationHelper::stringURLSafe('FooUncategorised');

		// Initialize a new category.
		$category = Table::getInstance('Category');

		$data = array(
			'extension' => 'com_foos',
			'title' => 'FooUncategorised',
			'alias' => $alias . '(en-GB)',
			'description' => '',
			'published' => 1,
			'access' => 1,
			'params' => '{"target":"","image":""}',
			'metadesc' => '',
			'metakey' => '',
			'metadata' => '{"page_title":"","author":"","robots":""}',
			'created_time' => Factory::getDate()->toSql(),
			'created_user_id' => (int) $this->getAdminId(),
			'language' => 'en-GB',
			'rules' => array(),
			'parent_id' => 1,
		);

		$category->setLocation(1, 'last-child');

		// Bind the data to the table
		if (!$category->bind($data))
		{
			return false;
		}

		// Check to make sure our data is valid.
		if (!$category->check())
		{
			return false;
		}

		// Store the category.
		if (!$category->store(true))
		{
			return false;
		}

 		return true;
 	}



 		return true;
 	}

	/**
	 * Retrieve the admin user id.
	 *
	 * @return  integer|boolean  One Administrator ID.
	 *
	 * @since   __BUMP_VERSION__
	 */
	private function getAdminId()
	{
		$db    = Factory::getDbo();
		$query = $db->getQuery(true);

		// Select the admin user ID
		$query
			->clear()
			->select($db->quoteName('u') . '.' . $db->quoteName('id'))
			->from($db->quoteName('#__users', 'u'))
			->join(
				'LEFT',
				$db->quoteName('#__user_usergroup_map', 'map')
				. ' ON ' . $db->quoteName('map') . '.' . $db->quoteName('user_id')
				. ' = ' . $db->quoteName('u') . '.' . $db->quoteName('id')
			)
			->join(
				'LEFT',
				$db->quoteName('#__usergroups', 'g')
				. ' ON ' . $db->quoteName('map') . '.' . $db->quoteName('group_id')
				. ' = ' . $db->quoteName('g') . '.' . $db->quoteName('id')
			)
			->where(
				$db->quoteName('g') . '.' . $db->quoteName('title')
				. ' = ' . $db->quote('Super Users')
			);

		$db->setQuery($query);
		$id = $db->loadResult();

		if (!$id || $id instanceof \Exception)
		{
			return false;
		}

		return $id;
	}
 }

administrator/components/com_foos/ services/provider.php

Im Service Provider registrieren wir die Schnittstelle CategoryFactoryInterface. Es ist nicht notwendig, CategoryFactoryInterface selbst zu erstellen. Wir nutzen die Joomla eigene Funktionen.

administrator/components/com_foos/ services/provider.php

 \defined('_JEXEC') or die;

use Joomla\CMS\Categories\CategoryFactoryInterface;
 use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
 use Joomla\CMS\Extension\ComponentInterface;
 use Joomla\CMS\Extension\Service\Provider\CategoryFactory;


 				$component->setRegistry($container->get(Registry::class));
 				$component->setMVCFactory($container->get(MVCFactoryInterface::class));
				$component->setCategoryFactory($container->get(CategoryFactoryInterface::class));

 				return $component;
 			}

administrator/components/com_foos/ sql/install.mysql.utf8.sql

Damit bei einer Neuinstallation die Tabellenspalte angelegt wird, in der die Kategorie eines Foo-Elements gespeichert wird, fügen wir in der SQL-Datei die bei der Installation aufgerufen wird, den erforderlichen SQL-Befehl hinzu.

administrator/components/com_foos/ sql/install.mysql.utf8.sql

 ALTER TABLE `#__foos_details` ADD COLUMN  `access` int(10) unsigned NOT NULL DEFAULT 0 AFTER `alias`;

 ALTER TABLE `#__foos_details` ADD KEY `idx_access` (`access`);

ALTER TABLE `#__foos_details` ADD COLUMN  `catid` int(11) NOT NULL DEFAULT 0 AFTER `alias`;

administrator/components/com_foos/ src/Extension/FoosComponent.php

Zusätzlich sind in der Komponentenklasse Implementierungen erforderlich, um die Joomla eigenen Funktionen zu verwenden.

administrator/components/com_foos/ src/Extension/FoosComponent.php

 use Joomla\CMS\HTML\HTMLRegistryAwareTrait;
 use FooNamespace\Component\Foos\Administrator\Service\HTML\AdministratorService;
 use Psr\Container\ContainerInterface;
use Joomla\CMS\Helper\ContentHelper;

 /**
  * Component class for com_foos

 	{
 		$this->getRegistry()->register('foosadministrator', new AdministratorService);
 	}

	/**
	 * Adds Count Items for Category Manager.
	 *
	 * @param   \stdClass[]  $items    The category objects
	 * @param   string       $section  The section
	 *
	 * @return  void
	 *
	 * @since   __BUMP_VERSION__
	 */
	public function countItems(array $items, string $section)
	{
		try
		{
			$config = (object) array(
				'related_tbl'   => $this->getTableNameForSection($section),
				'state_col'     => 'published',
				'group_col'     => 'catid',
				'relation_type' => 'category_or_group',
			);

			ContentHelper::countRelations($items, $config);
		}
		catch (\Exception $e)
		{
			// Ignore it
		}
	}

	/**
	 * Returns the table for the count items functions for the given section.
	 *
	 * @param   string  $section  The section
	 *
	 * @return  string|null
	 *
	 * @since   __BUMP_VERSION__
	 */
	protected function getTableNameForSection(string $section = null)
	{
		return ($section === 'category' ? 'categories' : 'foos_details');

	}
 }

administrator/components/com_foos/ src/Model/FoosModel.php

Im Model fügen wir bei der Datenbankabfrage die Tabelle hinzu, in der Joomla-Kategorien speichert. So werden im Administrationsbereich bei Auswahl einer Kategorie nur die zu dieser gehörenden Elemente angezeigt.

administrator/components/com_foos/ src/Model/FoosModel.php

 		// Select the required fields from the table.
 		$query->select(
			$db->quoteName(array('a.id', 'a.name', 'a.alias', 'a.access'))
			$db->quoteName(array('a.id', 'a.name', 'a.alias', 'a.access', 'a.catid'))
 		);

 		$query->from($db->quoteName('#__foos_details', 'a'));

 				$db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access')
 			);

		// Join over the categories.
		$query->select($db->quoteName('c.title', 'category_title'))
			->join(
				'LEFT',
				$db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid')
			);

 		return $query;
 	}
 }

administrator/components/com_foos/ tmpl/foo/edit.php

Das Formular zum Editieren eines Elements erhält die Anweisung, das Kategorie-Feld mithilfe der Angaben in der XML-Datei anzuzeigen.

administrator/components/com_foos/ tmpl/foo/edit.php

 	<?php echo $this->getForm()->renderField('name'); ?>
 	<?php echo $this->getForm()->renderField('alias'); ?>
 	<?php echo $this->getForm()->renderField('access'); ?>
	<?php echo $this->getForm()->renderField('catid'); ?>
 	<input type="hidden" name="task" value="">
 	<?php echo HTMLHelper::_('form.token'); ?>
 </form>

administrator/components/com_foos/ tmpl/foos/default.php

In der Übersichtstabelle der Ansicht im Backend fügen wir eine Spalte für die Anzeige der Kategorie hinzu.

administrator/components/com_foos/ tmpl/foos/default.php

		<a class="hasTooltip" href="<?php echo Route::_('index.php?option=com_foos&task=foo.edit&id=' . (int) $item->id); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape(addslashes($item->name)); ?>">
			<?php echo $editIcon; ?><?php echo $this->escape($item->name); ?></a>

		<div class="small">
			<?php echo Text::_('JCATEGORY') . ': ' . $this->escape($item->category_title); ?>
		</div>
	</th>
	<td class="small d-none d-md-table-cell">
		<?php echo $item->access_level; ?>

Die Kategorien helfen dir, im Frontend deine Daten strukturiert anzuzeigen. Die Frontend-Ansichten erstellen wir im weiteren Verlauf dieser Artikelserie.

Teste deine Joomla-Komponente

  1. Installiere deine Komponente in Joomla Version 4, um sie zu testen:

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

Installiere deine Komponente wie in Teil eins beschrieben, nachdem du alle Dateien kopiert hast. Joomla aktualisiert bei der Installation die Datenbank für dich.

  1. Öffne die Ansicht deiner Komponente im Administrationsbereich.
  2. In der Seitenleiste siehst du einen neuen Menüpunkt. Dieser bietet dir alles, was du zum Anlegen und Bearbeiten der Kategorien deiner Komponente benötigst.

Joomla Kategorie Menüpunkt

  1. Öffne als Nächstes ein Element. Überzeuge dich davon, dass es möglich ist, diesem eine Kategorie zuzuordnen.

Joomla Kategorie zuordnen

  1. Stelle sicher, dass die Foo-spezifischen Kategorien nicht in anderen Komponenten erscheinen, zum Beispiel in com_contact.
Ändere diesen Beitrag

Comments