Ga naar inhoud

CMS, content & vertalingen

De webshop beheert statische content (sliders, banners, blogposts, tekstvariabelen) en meertalige vertalingen via een centrale cms_text-tabel. Alle vertaalbare teksten worden via de functie trans() opgezocht en via een Memcached-cache geserveerd.


Vertalingen

De cms_text-tabel

Database: atx_www — tabel cms_text

Kolom Type Toelichting
Varnaam string Sleutelnaam (bijv. mounting_travel_cost_hint)
Namespace string Namespace-pad (bijv. atx\articles) — samengestelde PK met Varnaam
Tekst_nl string Nederlandse tekst
Tekst_fr string Franse tekst
Tekst_en string Engelse tekst
Tekst_du string Duits — in de praktijk altijd ''
Waar string Context/locatieaanduiding — altijd ''
From string Broncodering — altijd 'utf-8'
To string Doelcodering — altijd 'html'. Als From != To, loopt de tekst door htmlentities() bij renderen.

Primaire sleutel: samengesteld (Varnaam, Namespace).

Namespace-overerving: Translator::loadTranslation() zoekt van meest specifiek naar minst specifiek: atx\articles\tyresatx\articlesatx''. De eerste treffer wordt gebruikt — dit maakt overschrijven op elk niveau mogelijk.


De trans()-functie

src/functions.php:567

function trans(
    string $key,
    ?string $ns = null,
    ?array $vars = null,
    ?string $lang = null,
    bool $nl2br = true,
    bool $htmlSafe = true
): ?string

Werking:

  1. Haalt de singleton Translator op uit ServiceRegistry.
  2. Injecteert standaardvariabelen: {APP_SITE_DOMAIN} / {site_domain} en {site_url}.
  3. Als $lang opgegeven is: tijdelijk taal wisselen, vertalen, daarna terugzetten.
  4. Retourneert $translator->translate() (HTML-escaping + optionele nl2br) of $translator->translateRaw() (ruwe tekst).
  5. Dezelfde functie is geregistreerd als Twig-functie (src/functions.php:620).

src/Atraxion/Translation/Translator.php — lees-engine:

  • Taalmap: nlgetTekst_nl, frgetTekst_fr, engetTekst_en, degetTekst_du.
  • Leest uitsluitend uit TranslationCache — nooit rechtstreeks uit de database.
  • Cache-miss → Translator::translate() retourneert nulltrans() geeft eveneens null terug (retourtype ?string, geen ?? '' coalescing — src/functions.php:591–599). In template-/echo-context is null niet zichtbaar, maar typed callers (bijv. if ($text !== null)) gedragen zich anders dan bij een lege string.

Vertaling-cache na migratie

Na het uitvoeren van een Doctrine-migratie die cms_text-rijen toevoegt, rendert trans() leeg totdat de cache handmatig is opgewarmd. Voer daarna altijd uit:

php cli.php cache:warmup

Een memcached-herstart alleen is niet voldoende — de DB-fallback moet ook gevuld zijn. Zie src/Atraxion/Translation/TranslationCache.php.

Niet gebruiken: de legacy $this->getText() via TranslatorService (_core/model/classes/atx/cms/TranslatorService.php).


Vertalingen toevoegen via migraties

Alle vertalingen worden toegevoegd als INSERT-statements in Doctrine-migraties. Pad: _core/config/doctrine/migrations/{YYYY}/{MM}/Version{YYYYMMDDHHmmss}.php.

Canoniek INSERT-patroon:

$this->addSql(
    'INSERT INTO cms_text (Varnaam, Namespace, Tekst_nl, Tekst_fr, Tekst_en, Tekst_du, Waar, `From`, `To`) '
    . 'VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)',
    [
        'mijn_sleutel',        // Varnaam
        'atx\\mijn\\ns',      // Namespace — ALTIJD als ? placeholder, nooit inline
        'Nederlandse tekst',
        'Texte français',
        'English text',
        '',                    // Tekst_du — altijd leeg
        '',                    // Waar — altijd leeg
        'utf-8',               // From
        'html',                // To
    ]
);

Canoniek DELETE-patroon (voor down()):

$this->addSql(
    'DELETE FROM cms_text WHERE Namespace = ? AND Varnaam = ?',
    ['atx\\mijn\\ns', 'mijn_sleutel']
);

Namespace inline in SQL

Plaats de atx\...-namespace nooit inline in de SQL-string. MySQL slokt de backslash op → 0 rijen gematcht, zonder foutmelding. Gebruik altijd ?-placeholders.


Vertalingen beheren in de admin

_admin/controller/classes/atx/cms/AdminTextController.php

  • getTexts — toont alle rijen gegroepeerd per namespace/sleutel.
  • editText — haalt één vertaalrij op voor alle talen.
  • save — schrijft via TextDAO::updateObject(), roept daarna automatisch CacheJanitor::cleanTranslation() aan. Dit herwarmt de translatie-cache onmiddellijk — alleen bij wijzigingen via de admin-interface. Na migraties is handmatige warmup via CLI nodig.

Cache-warmup

src/Atraxion/Translation/TranslationCache.php

Singleton backed by Memcached + DB-fallback (ResilientCacheAdapter).

warmUp() laadt alle cms_text-rijen via TextDAO::getObjects() en schrijft ze in de cache onder sleutel <namespace>_<varnaam>.

CLI-command:

php cli.php cache:warmup

src/Atraxion/Front/Command/CacheWarmupCommand.php — warmt naast vertalingen ook op: ConfigurationCache, LanguageCache, CustomerMarginCache, ArticlePopularCustomerCategoryDAO.

src/Atraxion/Cache/CacheJanitor.phpcleanTranslation() roept TranslationCache::getInstance()->warmUp() aan; clean() leegt ook opcache en gecompileerde JS/CSS.


Sliders

_core/model/classes/atx/pages/Slide.php — entiteitsklasse

Belangrijkste velden:

Veld Toelichting
Type link / page / url / video
Image / Extension Bestandsnaam + extensie (standaard jpg)
ImageAltNl/Fr/En Alt-tekst per taal
Order Prioriteit −2 tot +2; gelijke prioriteit = willekeurige volgorde
Klantnr / Klantcatcode Optioneel beperken tot één klant of klantcategorie
Category Alles, Banden, Velgen, Accessoires, …
Visibility 0 = alleen anoniem, 1 = alleen ingelogd, 2 = altijd
Active Aan/uit-schakelaar
onlyForMiniShops Alleen tonen op mini-shops
tags ManyToMany voor fijnmazige targeting

_core/model/classes/atx/pages/SlideRepository.phpfindAllSlidesByCriteria(array $criteria) filtert op actief, klant, categorie, channel, tags, zichtbaarheid en OE-corner.

Front controller: _core/controller/classes/atx/pages/SliderController.php — actie getSlider.

Admin: _admin/controller/classes/atx/pages/AdminSliderController.php

  • Acties: showDialog, showEditSlide, editSlide, editSlideOrder.
  • Afbeeldingen worden geüpload naar /images/slides/, geserveerd via APP_STATIC_URL.

Banners

Banners zijn geen aparte DB-tabel — het zijn cms_text-rijen:

Varnaam Toelichting
banner Hoofd-sitebanner
cart-banner Banner op de winkelwagenpagina

Beheer via AdminTextController (zie boven). Na opslaan wordt de cache automatisch herwarmd.


Blogposts

_core/model/classes/atx/cms/BlogPost.php — Doctrine-entiteit

  • Categorieën: news, tutorial, events, memory.
  • Meertalig via BlogPostTranslation (titel, slug, teaser, body per taal).
  • Bijlages via BlogPostMedia; auteur via Team; tags; actief/inactief; publicatiedatum.
  • Repository: _core/model/classes/atx/cms/BlogPostRepository.php.
  • Admin: _admin/controller/classes/atx/cms/AdminBlogPostsController.php.

Er bestaat ook een verouderde atx\articles\BlogPost — niet gebruiken.


CMS-pagina's en routing

Pagina-routing verloopt via _core/config/pages.xml (alle routes declaratief). Het Page-object (_core/model/classes/atx/cms/Page.php) is een routing-dispatch-object, geen database-entiteit. Statische pagina's worden verwerkt door _core/controller/classes/atx/pages/StaticPageController.php.