Componenten in Joomla
Een Joomla-pagina bestaat uit veel kleine onderdelen die samenwerken, maar slechts één onderdeel maakt de hoofdinhoud. Dat onderdeel is de component.
Bijna alles wat je in de Joomla-backend beheert, is een component: artikelen, contacten, gebruikers, menu’s, de Media Manager en de algemene configuratie. Zodra je begrijpt hoe één component is opgebouwd, kun je bijna elke andere component lezen, overriden en uitbreiden, of die nu standaard met Joomla wordt meegeleverd of van een externe ontwikkelaar komt.
Van “wat maakt de body van de pagina” tot MVC, de servicecontainer, routing en het schrijven van je eigen component.
Dit artikel legt uit hoe Joomla-componenten echt werken. Het behandelt de basis voor website-eigenaren en redacteuren, de praktische structuur voor beheerders en de technische details voor ontwikkelaars. Je leert wat een component is, hoe die rond het MVC-patroon is opgebouwd, hoe die via een servicecontainer in Joomla wordt gekoppeld, hoe data en rechten worden opgeslagen, en hoe je een component op de juiste manier uitbreidt.
Het doel is simpel: je helpen Joomla-componenten goed genoeg te begrijpen om er met vertrouwen mee te werken.
1. De basis
1.1 Wat is een component?
Een component is de hoofdapplicatie die de body van een Joomla-pagina opbouwt. Zie het als een mini-applicatie die binnen Joomla draait. Het CMS is het besturingssysteem, componenten zijn de apps die erop draaien.
De belangrijkste regel om te onthouden is deze:
Een Joomla-pagina wordt opgebouwd uit veel extensies, maar precies één component maakt de hoofdinhoud.
1.2 De vijf extensietypes
Een component is één lid van een familie van vijf extensietypes. Als je de andere types kent, wordt het woord “component” pas echt duidelijk:
| Type | Rol | Per pagina | Prefix |
|---|---|---|---|
| Component | Hoofdinhoud / applicatie van de pagina | precies 1 | com_ |
| Module | Kleine blokken rondom de inhoud | veel | mod_ |
| Plugin | Event-gestuurd gedrag op de achtergrond | veel | plg_ |
| Template | Uiterlijk, stijl en paginalay-out | 1 site + 1 beheeromgeving | tpl_ |
| Taal | Vertalingen | 1 actief | - |
Componenten, modules en plugins worden vaak samen geleverd in één installeerbaar pakket (prefix pkg_).
1.3 De pagina als krant
Dit is een handig denkmodel. De template is het paginakader. Daarbinnen vult de component het hoofdgedeelte en staan de modules eromheen:
┌────────────────────────────────┐
│ TEMPLATE (het paginakader) │
│ ┌──────┐ ┌─────────┐ ┌──────┐ │
│ │MODULE│ │COMPONENT│ │MODULE│ │
│ │(menu)│ │ de hoofd│ │(login│ │
│ │ │ │ inhoud │ │ ) │ │
│ └──────┘ └─────────┘ └──────┘ │
│ ┌─────────────────────┐ │
│ │MODULE (footer) │ │
│ └─────────────────────┘ │
└────────────────────────────────┘
Als de pagina een krant was, dan is de component het hoofdartikel. De modules zijn de zijbalken, advertenties en footers eromheen.
1.4 De com_-naamgeving
Elke componentnaam begint met com_. De parameter option in de URL vertelt Joomla welke component moet worden uitgevoerd:
index.php?option=com_content&view=article&id=42
│ │ │
│ │ └─ welk item
│ └─ welk scherm (de "view")
└─ welke component
Deze ene regel is de sleutel tot het begrijpen van alle Joomla-routing en SEF-URL’s (zoekmachinevriendelijke URL’s).
1.5 Componenten die je elke dag gebruikt
Open de Administrator en kijk naar het menu. Bijna elk onderdeel is een component:
| Component | Doel |
|---|---|
com_content |
Artikelen en artikelcategorieën (de kern van het CMS) |
com_contact |
Contacten en contactformulieren |
com_banners |
Beheer van zelfgehoste banneradvertenties |
com_newsfeeds |
Verzamelen van RSS-feeds |
com_media |
De Media Manager |
com_users |
Accounts, groepen en toegangsniveaus |
com_menus |
Beheer van menu’s en menu-items |
com_modules |
Modulebeheer |
com_categories |
Gedeeld categoriebeheer |
com_fields |
Gedeelde aangepaste velden |
com_config |
Algemene configuratie |
com_installer |
Installeren en updaten van extensies |
Veel hiervan vormen de infrastructuur. Zo bestaan com_categories en com_fields vooral zodat andere componenten deze kunnen hergebruiken.
2. Website versus Administrator
2.1 Een component leeft in twee werelden
Een component heeft twee kanten: de front-end die bezoekers zien en de back-end waarin je alles beheert. Deze bevinden zich in twee verschillende mappen:
public_html/
├── components/ ← SITE (front-end, wat bezoekers zien)
│ └── com_content/
└── administrator/
└── components/ ← ADMIN (back-end, waar je beheert)
└── com_content/
- Het Site-gedeelte toont het artikel op de openbare website.
- Het Administrator-gedeelte bevat de artikelbewerker, overzichtslijsten en batchtools.
Een component kan beide kanten hebben, maar ook slechts één:
| Component | Site | Admin |
|---|---|---|
com_content |
Ja | Ja |
com_installer |
Nee | Ja (alleen beheeromgeving) |
com_ajax |
Ja | Ja (geen gebruikersinterface, maar een service-endpoint) |
2.2 De levenscyclus van een verzoek
Het helpt om te begrijpen wat er gebeurt bij iedere paginalading. De component beheert het middelste deel van deze keten:
Browserverzoek
│ index.php?option=com_content&view=article&id=42
▼
CMS-applicatie (bootstrap, sessie, plugins onAfterInitialise)
▼
Router → zet de SEF-URL om naar option / view / id
▼
Dispatcher → laadt de component (com_content)
▼
Controller → bepaalt welke taak wordt uitgevoerd
▼
Model → haalt artikel 42 op uit de database
▼
View + Layout → genereert de HTML
▼
Template verpakt alles, modules worden eromheen weergegeven → pagina naar browser
Let erop dat de component verantwoordelijk is voor de stappen van Dispatcher tot en met View. Alles daarvoor is Joomla die de routing verzorgt, alles daarna is de template die de pagina vormgeeft.
Naar boven3. Binnen een component: de MVC-structuur
3.1 De moderne mappenstructuur
Sinds Joomla 4 volgen componenten een duidelijke mappenstructuur met namespaces. Hieronder zie je de beheerkant van com_content in Joomla 4, 5 en 6:
administrator/components/com_content/
├── content.xml ← manifest (naam, versie, bestanden, installatie)
├── services/
│ └── provider.php ← registratie van DI-services (het startpunt)
├── src/ ← PHP-klassen met PSR-4 namespaces
│ ├── Controller/ ← bepaalt WAT er moet gebeuren
│ ├── Model/ ← communiceert met de DATABASE
│ ├── View/ ← bereidt gegevens voor uitvoer voor
│ ├── Table/ ← koppelt één database-record aan een object
│ ├── Field/ ← aangepaste formuliervelden
│ ├── Service/ ← routing, HTML-helpers, categorie-factory
│ ├── Helper/ ← gedeelde hulpfuncties
│ └── Extension/ ← de componentklasse zelf
├── tmpl/ ← de daadwerkelijke HTML-layouts (.php)
├── forms/ ← XML-formulierdefinities
├── sql/ ← SQL voor installatie, updates en verwijdering
└── language/ ← vertaalbestanden (.ini)
Een belangrijke wijziging om te onthouden: sinds Joomla 4 bestaat er geen controller.php-bestand meer als ingangspunt. Het startpunt is nu services/provider.php.
3.2 De drie MVC-rollen
MVC staat voor Model-View-Controller. Het is een patroon dat het werk opsplitst in drie duidelijke rollen.
Controller, de verkeersregelaar
- Leest het verzoek (bijvoorbeeld
task=article.save). - Roept het juiste model aan en geeft vervolgens door aan de juiste view.
- Bevat geen HTML en geen SQL.
Model, het brein
- Bevat de bedrijfslogica en database-toegang.
- Beantwoordt verzoeken zoals "geef artikel 42", "sla dit op", "publiceer deze ID's" of "bouw deze lijstquery".
View en Layout, het gezicht
- Het View-object verzamelt gegevens uit het Model.
- De Layout (een bestand in
tmpl/) genereert de uiteindelijke HTML.
Deze scheiding van verantwoordelijkheden maakt een component eenvoudiger te onderhouden, te overriden en te testen.
3.3 De Table-klasse
Tussen het Model en de database bevindt zich de Table-klasse. Een Table-object vertegenwoordigt één database-record. Dit staat bekend als het Active Record-patroon:
$table = $this->getTable(); // bijvoorbeeld ContentTable
$table->load($id); // SELECT * FROM #__content WHERE id = ?
$table->title = 'Nieuwe titel';
$table->store(); // INSERT / UPDATE
$table->delete($id);
Table-klassen verzorgen ook de publicatiestatus, sortering, check-in en check-out, en de JSON-kolom params die veel items gebruiken om hun instellingen op te slaan.
4. Het manifest en de database
4.1 Het installatiemanifest
Elke component meldt zichzelf bij Joomla aan via een XML-manifestbestand. Voor com_content is dat bestand content.xml:
<extension type="component" method="upgrade">
<name>com_content</name>
<version>6.0.0</version>
<namespace path="src">Joomla\Component\Content</namespace>
<files folder="site">...</files> <!-- front-endbestanden -->
<administration>
<files folder="admin">...</files> <!-- back-endbestanden -->
<menu>com_content</menu> <!-- menu-item in beheeromgeving -->
<submenu>...</submenu>
</administration>
<install><sql><file driver="mysql">sql/install.mysql.utf8.sql</file></sql></install>
<update><schemas><schemapath type="mysql">sql/updates/mysql</schemapath></schemas></update>
<uninstall><sql>...</sql></uninstall>
</extension>
Dit ene bestand regelt de installatie, update en verwijdering. Het vertelt Joomla welke bestanden moeten worden gekopieerd, welke SQL-opdrachten moeten worden uitgevoerd en welke PSR-4-namespace moet worden geregistreerd.
4.2 Waar componenten worden geregistreerd
Elke geïnstalleerde extensie, inclusief componenten, heeft één record in de tabel #__extensions:
| Kolom | Voor een component |
|---|---|
type |
component |
element |
com_content |
name |
com_content |
enabled |
1 of 0 |
params |
JSON, de opties van de component (rechten, standaardinstellingen enzovoort) |
De knop Opties rechtsboven in een component bewerkt de JSON-inhoud van params in deze rij. Er bestaat dus geen aparte configuratietabel.
4.3 Elke component heeft zijn eigen tabellen
Een component maakt meestal zijn eigen databasetabellen aan. Deze beginnen met #__, een tijdelijke aanduiding voor het tabelprefix van de website:
| Component | Kern-tabellen |
|---|---|
com_content |
#__content, #__content_frontpage, #__content_types |
com_contact |
#__contact_details |
com_banners |
#__banners, #__banner_clients, #__banner_tracks |
com_newsfeeds |
#__newsfeeds |
com_categories |
#__categories (gedeeld door veel componenten) |
com_fields |
#__fields, #__fields_values, #__fields_groups |
De aanduiding #__ wordt tijdens runtime vervangen door het daadwerkelijke prefix uit configuration.php (bijvoorbeeld jos_).
4.4 ACL en de assets-tabel
Componenten slaan hun rechten niet zelf op. Ze maken gebruik van Joomla's centrale Access Control List (ACL), die wordt ondersteund door één gedeelde tabel: #__assets.
#__assets (geneste structuur, vergelijkbaar met categorieën)
├── root.1 ← globale configuratie
│ └── com_content ← regels op componentniveau
│ └── #__content.42 ← regels voor een individueel artikel
- Elke component, en eventueel elk individueel item, kan een eigen asset-record hebben.
- Elke rij bevat een JSON-kolom
rulesdie vastlegt welke gebruikersgroepen bepaalde acties mogen uitvoeren of juist niet.
De standaardacties voor componenten zijn:
| Actie | Betekenis |
|---|---|
core.admin |
Componentopties en rechten beheren |
core.manage |
Toegang tot de beheerschermen |
core.create |
Nieuwe items aanmaken |
core.edit |
Alle items bewerken |
core.edit.own |
Alleen eigen items bewerken |
core.edit.state |
Publiceren, depubliceren of archiveren |
core.delete |
Items verwijderen |
Componenten controleren deze rechten via het gebruikersobject:
if (!$user->authorise('core.edit', 'com_content.article.42')) {
throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
Rechten worden geërfd binnen de asset-structuur: van globaal niveau naar component, vervolgens categorie en uiteindelijk item.
Naar boven5. Het ontwikkelaarsmodel
5.1 Het moderne startpunt: services/provider.php
Sinds Joomla 4 wordt een component gekoppeld aan een Dependency Injection (DI)-container in plaats van via hardgecodeerde includes. Dit is de grootste verandering ten opzichte van het klassieke Joomla. Het bestand services/provider.php registreert de benodigde factories en bouwt vervolgens het componentobject op:
return new class () implements ServiceProviderInterface {
public function register(Container $container): void
{
// Registreer de factories die de component nodig heeft:
$container->registerServiceProvider(new CategoryFactory('\\Joomla\\Component\\Content'));
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Content'));
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Content'));
$container->registerServiceProvider(new RouterFactory('\\Joomla\\Component\\Content'));
// Bouw het componentobject en injecteer afhankelijkheden:
$container->set(ComponentInterface::class, function (Container $container) {
$component = new ContentComponent($container->get(ComponentDispatcherFactoryInterface::class));
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
$component->setCategoryFactory($container->get(CategoryFactoryInterface::class));
$component->setRouterFactory($container->get(RouterFactoryInterface::class));
return $component;
});
}
};
Dit is een echt voorbeeld uit com_content, licht ingekort.
5.2 Oude manier versus nieuwe manier
Het verschil wordt het duidelijkst wanneer je beide stijlen naast elkaar zet.
Klassiek (Joomla 1.5 t/m 3):
require_once 'controller.php';
$controller = new ContentController(); // sterk gekoppeld, globale status
$controller->execute(JFactory::getApplication()->input->get('task'));
Modern (Joomla 4 t/m 6):
// De MVCFactory bouwt controllers, modellen en views voor je,
// inclusief database, input, gebruiker, dispatcher enzovoort.
$controller = $mvcFactory->createController('Article', 'Site', [], $app, $input);
Waarom de nieuwe aanpak beter is:
- PSR-4 autoloading met namespaces, geen handmatige
require-instructies. - Testbaar, afhankelijkheden worden geïnjecteerd in plaats van opgehaald uit globale status.
- Consistent, alle core-componenten zijn op dezelfde manier opgebouwd.
5.3 De Dispatcher
De Dispatcher is tijdens runtime de voordeur van een component. De ComponentDispatcherFactory maakt deze aan. Hij leest het verzoek, controleert de toegangsrechten en stuurt door naar de juiste controller en taak:
CMS App → ComponentInterface → Dispatcher → Controller → Model → View
De meeste componenten schrijven geen eigen dispatcher. Ze erven de standaard ComponentDispatcher. Alleen voor speciale bootstrap- of initialisatiebehoeften maak je een eigen implementatie.
5.4 Routing en SEF-URL's
De RouterFactory geeft een component zijn eigen Router. Deze zet interne query's om naar nette URL's en andersom:
?option=com_content&view=article&id=42&catid=9
(interne query)
⇄
/nieuws/9-evenementen/42-zomerfeest
(SEF-URL)
build()zet een query om naar URL-segmenten voor gegenereerde links.parse()zet URL-segmenten terug om naar een query voor binnenkomende verzoeken.
Goede routing zorgt ervoor dat URL's gebruiksvriendelijk zijn voor zowel bezoekers als zoekmachines.
5.5 Events: hoe plugins een component uitbreiden
Een component blijft los gekoppeld aan extensies die extra functionaliteit toevoegen door op belangrijke momenten events af te vuren. Plugins luisteren naar deze events. De component hoeft niet te weten welke plugins dat zijn:
// Binnen save() van het model dispatcht com_content events:
$this->getDispatcher()->dispatch('onContentBeforeSave', $event);
// ... schrijf naar de database ...
$this->getDispatcher()->dispatch('onContentAfterSave', $event);
Veelgebruikte content-events waarop plugins kunnen inhaken:
| Event | Wordt uitgevoerd wanneer |
|---|---|
onContentPrepare |
Voordat tekst wordt weergegeven (plugins kunnen deze aanpassen) |
onContentBeforeSave / onContentAfterSave |
Voor en na het opslaan van een item |
onContentBeforeDelete / onContentAfterDelete |
Voor en na het verwijderen van een item |
onContentChangeState |
Wanneer een item wordt gepubliceerd of gedepubliceerd |
Dit is een voorbeeld van losse koppeling. Een plugin kan gedrag toevoegen aan com_content, of aan je eigen component, zonder de broncode van die component aan te passen.
6. Gedeelde diensten
6.1 Componenten werken zelden alleen
Moderne componenten maken gebruik van CMS-brede diensten in plaats van alles zelf opnieuw uit te vinden. Dit houdt het systeem consistent en voorkomt veel dubbele code:
| Dienst | Component | Wat deze aan een component biedt |
|---|---|---|
| Categorieën | com_categories |
Eén gedeeld hiërarchisch categoriesysteem |
| Aangepaste velden | com_fields |
Extra velden toevoegen zonder code |
| Tags | com_tags |
Tags gebruiken over meerdere componenten heen |
| Workflow | com_workflow |
Redactionele fases (concept → review → gepubliceerd) |
| Associaties | com_associations |
Koppelingen tussen meertalige items |
6.2 Categorieën zijn een dienst, geen onderdeel van com_content
Dit is een belangrijk inzicht dat veel mensen verrast. Categorieën horen niet bij artikelen. Ze zijn een gedeelde dienst waar com_content gebruik van maakt:
// In services/provider.php meldt com_content zich aan voor het gedeelde categorisatiesysteem:
$container->registerServiceProvider(new CategoryFactory('\\Joomla\\Component\\Content'));
...
$component->setCategoryFactory($container->get(CategoryFactoryInterface::class));
- Eén tabel,
#__categories, wordt gebruikt voor artikelen, contacten, banners, nieuwsfeeds en meer. - Elke component registreert een CategoryFactory om hiervan gebruik te maken.
- Categorieën hebben hun eigen ACL, taalinstellingen en geneste hiërarchie (de kolommen
lftenrgt).
Naar bovenCategorieën horen niet bij artikelen. Het is een gedeelde dienst die artikelen, en veel andere componenten, simpelweg gebruiken.
7. Werken met componenten
7.1 Hoe je elke component kunt begrijpen
Als je een component wilt doorgronden, lees de bestanden dan in deze volgorde. Dit stappenplan werkt voor vrijwel elke core-component en de meeste extensies van derden:
- Het
*.xml-manifest: wat is het, welke versie heeft het, welke bestanden en tabellen gebruikt het? services/provider.php: het startpunt en de diensten die worden gebruikt.src/Controller/: welke taken zijn beschikbaar?src/Model/: waar komt de data vandaan?tmpl/: wat ziet de gebruiker uiteindelijk?
7.2 Een component op de juiste manier aanpassen
Bewerk nooit rechtstreeks bestanden van een core-component. Bij de volgende update worden ze overschreven en ben je je wijzigingen kwijt. Gebruik in plaats daarvan de juiste techniek voor wat je wilt aanpassen:
| Behoefte | Juiste techniek |
|---|---|
| Output of HTML aanpassen | Template override: templates/<tpl>/html/com_xxx/<view>/<layout>.php |
| Gedrag wijzigen of reageren op events | Plugin die luistert naar de events van de component |
| Extra gegevensvelden toevoegen | Aangepaste velden (com_fields) |
| Teksten wijzigen | Taaloverride via Systeem → Talen → Overrides |
Een template override is simpelweg een kopie van een layoutbestand op een speciale locatie:
Kopieer: components/com_content/tmpl/article/default.php
Naar: templates/mytemplate/html/com_content/article/default.php
7.3 Zelf een component bouwen: het minimum
Een eenvoudige werkende component heeft verrassend weinig nodig:
com_hello/
├── hello.xml ← manifest
├── services/provider.php ← registratie in de DI-container
├── src/
│ ├── Extension/HelloComponent.php
│ ├── Controller/DisplayController.php
│ ├── Model/HelloModel.php
│ └── View/Hello/HtmlView.php
└── tmpl/hello/default.php ← <h1>Hallo, JUG!</h1>
De stappen om dit werkend te krijgen zijn:
- Maak er een ZIP-bestand van en ga naar Extensies → Beheren → Installeren.
- Joomla leest het manifest, kopieert de bestanden, registreert de namespace en voert de installatiescripts uit.
- Ga naar
index.php?option=com_helloen je code wordt uitgevoerd.
Een praktische tip: begin met een kleine core-component, bijvoorbeeld com_wrapper, en hernoem die. Je leert de structuur sneller vanuit een werkend voorbeeld dan vanaf een leeg scherm.
7.4 Veelvoorkomende valkuilen
Dit zijn fouten die ontwikkelaars regelmatig maken bij het werken met componenten:
- De
<namespace>-declaratie vergeten in het manifest, wat leidt tot een foutmelding zoals "class not found". - De
<namespace>-declaratie wijzigen zonder/administrator/cache/autoload_psr4.phpte verversen. Verwijder dit bestand, Joomla maakt het automatisch opnieuw aan. - Core-bestanden rechtstreeks aanpassen, waardoor wijzigingen bij de volgende update verloren gaan. Gebruik overrides.
- Een module (een klein herbruikbaar blok) verwarren met een component (één hoofdapplicatie per pagina).
- Bedrijfslogica of SQL in een layout plaatsen in plaats van in het model.
- Categorieën, velden of tags opnieuw bouwen terwijl hiervoor al gedeelde diensten beschikbaar zijn.
8. Meer dan alleen de browser: API en prestaties
8.1 Web Services: de headless kant van een component
Sinds Joomla 4 kan een component naast webpagina's ook een REST API aanbieden. Dit werkt via een aparte API-applicatie (/api/index.php) en de Web Services-plugins:
/api/index.php/v1/content/articles ← lijst met artikelen (GET)
/api/index.php/v1/content/articles/42 ← één artikel (GET / PATCH / DELETE)
/api/index.php/v1/users ← gebruikers-endpoint
- Een component voegt een
src/Controller/Api*-klasse, eensrc/View/.../JsonapiViewen een mapapi/toe. - Deze functionaliteit wordt per component geactiveerd via de bijbehorende Web Services-plugin (bijvoorbeeld
plg_webservices_content). - Authenticatie gebeurt via een token (de Joomla Token-plugin) of via Basic Authentication.
Dit maakt headless Joomla mogelijk. Mobiele apps, single-page applicaties en externe integraties communiceren allemaal met dezelfde component.
8.2 Prestatie-overwegingen
Componenten veroorzaken meestal het grootste deel van de belasting op een website. Daarom vindt ook het grootste deel van de optimalisatie daar plaats:
| Onderwerp | Aanpak |
|---|---|
| Caching | Gebruik Joomla-cache (de Cache-API, view-caching, caching van onContentPrepare) voor dure query's |
| Query-ontwerp | Bouw query's met DatabaseQuery, selecteer alleen benodigde kolommen en gebruik paginering |
| Indexering | Zorg voor indexen op catid, state, language, access en sorteerkolommen |
| ACL-kosten | Toegangscontroles per item kosten tijd, cache autorisatieresultaten waar mogelijk |
| Lazy loading | Laad zware gegevens (gerelateerde items, velden) pas wanneer ze daadwerkelijk nodig zijn |
Op grote schaal kan één component miljoenen records, duizenden categorieën en omvangrijke ACL-structuren beheren. Ontwerp daarom vanaf het begin je modellen en database-indexen met schaalbaarheid in gedachten.
Naar boven9. Veelgemaakte fouten en valkuilen
9.1 Componenten verwarren met modules
Een component produceert de hoofdinhoud van een pagina. Een module is een klein blok dat daaromheen staat, en je kunt er meerdere op één pagina hebben. Als je merkt dat je "veel exemplaren van hetzelfde" op één pagina wilt tonen, heb je waarschijnlijk een module nodig en geen component.
9.2 Core-bestanden aanpassen
Bestanden aanpassen binnen components/com_content/ of de beheerversie daarvan lijkt misschien snel, maar Joomla overschrijft deze bestanden bij de volgende update. Gebruik altijd een template override, plugin, aangepast veld of taaloverride.
9.3 MVC-lagen door elkaar halen
De meest voorkomende programmeerfout is het plaatsen van databasequery's of bedrijfslogica in een layoutbestand binnen tmpl/. Houd SQL en logica in het Model, beslissingen in de Controller en alleen presentatiecode in de Layout. Hierdoor blijft de component testbaar en eenvoudig aanpasbaar.
9.4 Gedeelde diensten opnieuw uitvinden
Bouw niet zelf een categoriebeheerder, veldsysteem of tagsysteem. Joomla levert hiervoor al com_categories, com_fields en com_tags als gedeelde diensten. Door deze te gebruiken krijg je hiërarchieën, ACL, taalondersteuning en beheerfunctionaliteit gratis mee.
9.5 Details in het manifest vergeten
Een ontbrekende <namespace>-declaratie veroorzaakt fouten zoals "class not found". Een ontbrekende of onjuiste <files>- of <sql>-vermelding zorgt ervoor dat bestanden of tabellen niet worden geïnstalleerd. Het manifest is klein, maar iedere regel telt.
10. Best practices
Als je maar een paar dingen uit dit artikel onthoudt, laat het dan deze punten zijn:
- Precies één component produceert de hoofdinhoud van iedere pagina.
- Je herkent een component aan het prefix
com_en de URL-parameteroption=. - Lees een component in deze volgorde: manifest,
provider.php, Controller, Model en vervolgenstmpl/. - Pas nooit core-bestanden aan. Gebruik template overrides, plugins, aangepaste velden of taaloverrides.
- Houd SQL en logica in het Model, niet in de Layout.
- Hergebruik gedeelde diensten zoals Categorieën, Velden, Tags en Workflow in plaats van zelf iets te bouwen.
- Optimaliseer prestaties in het Model: cache zware query's en voeg de juiste database-indexen toe.
11. In het kort
HERKENNEN Zoek naar option=com_xxx in de URL
SITEBESTANDEN components/com_xxx/
ADMINBESTANDEN administrator/components/com_xxx/
STARTPUNT services/provider.php (NIET controller.php)
STRUCTUUR src/Controller, src/Model, src/View, src/Table, tmpl/
INSTALLATIEREGEL #__extensions (type=component, params=JSON-opties)
EIGEN TABELLEN #__content, #__contact_details, #__banners, ...
RECHTEN #__assets (JSON-regels, overerving in de boomstructuur)
OVERRIDE templates/{tpl}/html/com_xxx/{view}/{layout}.php
UITBREIDEN Plugin die luistert naar onContent*-events
REST API /api/index.php/v1/... (Web Services-plugin activeren)
GEDEELD Categorieën, Velden, Tags, Workflow, Associaties
Naar boven12. Samenvatting
In Joomla is een component veel meer dan alleen "de inhoud in het midden". Het is een complete mini-applicatie die vrijwel iedere laag van het systeem raakt:
- Structuur: gebouwd volgens het MVC-patroon, met een duidelijke mappenstructuur.
- Koppeling: verbonden met Joomla via een servicecontainer in
services/provider.php. - Data: beheert zijn eigen databasetabellen en registreert zichzelf in
#__extensions. - Beveiliging: maakt gebruik van de centrale ACL via de tabel
#__assets. - Uitbreidbaarheid: activeert events zodat plugins functionaliteit kunnen toevoegen zonder de broncode aan te passen.
- Integratie: gebruikt gedeelde diensten zoals Categorieën, Velden en Tags.
- Bereik: kan headless functioneren via de Web Services REST API.
De belangrijkste gedachte om mee te nemen is deze: leer de anatomie van één core-component begrijpen, en je kunt vrijwel alle andere componenten lezen, overriden en uitbreiden, of ze nu onderdeel zijn van Joomla zelf of afkomstig zijn van een externe ontwikkelaar.
Als je een maatwerkfunctionaliteit voor Joomla wilt bouwen, een component probeert te debuggen of overweegt je data via een API beschikbaar te maken, dan loont het om te begrijpen hoe componenten zijn opgebouwd. Ze vormen de basis van iedere Joomla-pagina.
Naar boven

Joomla en Linux specialist voor snelle, veilige en schaalbare websites.


