Vue d'ensemble
- Template de site
websource(templates/websource, média dansmedia/templates/site/websource), déclaréinheritable: les templates enfants sont pris en charge, toutes les ressources se résolvent d'abord dans l'enfant puis dans le parent. - Classes dans
src/, espace de nomsWebsource\Template, chargées parsrc/autoload.php(JLoader::registerNamespace, pas de Composer). - CSS : Tailwind v4 compilé en fichiers statiques.
theme.css(socle) est chargé partout, plus une seule feuillepages/<type>.cssselon le type de page. Aucun CSS n'est généré à l'exécution. - JavaScript sans jQuery :
theme.js(recherche mobile, menu push et filtres push, compteur du panier),product.js(détails de la fiche). - HikaShop est facultatif. Toutes les méthodes de
Websource\Template\Shoprépondent sans erreur quand il est absent. - Les feuilles de style du template sont placées après celles que les extensions ajoutent par
Document::addStyleSheet()(HikaShop le fait) : à spécificité égale, le template l'emporte.
Types de page
Websource\Template\Theme::pageType() renvoie l'un de : home, shop, product, cart, checkout, account, blog, post, page, search, 404. La valeur donne la classe wsx-page-<type> de <body> et la feuille de style chargée.
| Type | Pages |
|---|---|
home | Élément de menu par défaut du site. |
shop | Listes HikaShop : produits, catégories, marques. |
product | Fiche produit HikaShop. |
cart | Étape du tunnel HikaShop qui ne contient que le panier (et le code de réduction). |
checkout | Toute étape avec identification, adresse, livraison ou paiement ; page de fin. |
account | Espace client HikaShop, connexion, inscription et profil Joomla. |
blog, post, page | Listes d'articles, article, article ou contact lié directement à un élément de menu. |
search | Recherche (com_finder). |
404 | Page d'erreur (error.php). |
Positions de modules
24 positions : banner, topbar-left, topbar-right, header-search, header-actions, header-menu, drawer, wrapper-top, breadcrumbs, home, shop-sidebar, sidebar, product-reassurance, product-footer, cart-footer, wrapper-bottom, footer-before, footer-1, footer-2, footer-3, footer-after, debug, error-404, error-403.
Habillages de module (html/layouts/chromes) : websource (titre + contenu, sans cadre) et card (carte arrondie).
Dispositions de module livrées :
| Module | Disposition | Usage |
|---|---|---|
mod_menu | megamenu | Menu principal avec sous-menus en panneau (position header-menu). |
mod_menu | inline | Liens sur une ligne (barre du haut, pied de page). |
mod_menu | drawer | Menu push mobile ; appliquée automatiquement au module de header-menu. |
mod_hikashop_cart | websource | Lien panier avec compteur (position header-actions). |
mod_breadcrumbs, mod_finder, mod_login | default | Surcharges de la disposition par défaut. |
Variables CSS
Les variables sont déclarées sur :root dans theme.css. Les réglages du template et l'évènement onWebsourceTemplateTokens ajoutent une règle :root{…} en ligne qui ne contient que les valeurs modifiées.
| Variable | Valeur par défaut | Rôle |
|---|---|---|
--color-brand-50 … --color-brand-900 | #effaf8 … #05332f | Échelle de la couleur de marque. |
--color-brand, --color-brand-fill, --color-brand-on, --color-brand-text | #0f766e, #0f766e, #ffffff, #0b5f58 | Marque : couleur, fond plein, texte sur fond plein, texte sur fond clair. |
--color-secondary, --color-secondary-fill, --color-secondary-on, --color-secondary-text | #0b3a5c, #0b3a5c, #ffffff, #0b3a5c | Couleur secondaire. |
--color-accent, --color-accent-fill, --color-accent-on, --color-accent-text | #f5b83d, #f5b83d, #111827, #8a5a00 | Couleur d'accent. |
--color-accent-wst | #f0556b | Mise en avant : promotion, compteur du panier. |
--color-ink, --color-line, --color-page, --color-surface | #14282b, #d9e6e4, #ffffff, #ffffff | Texte, bordures, fond de page, fond des cartes. |
--color-footer, --color-footer-ink, --color-footer-muted, --color-footer-deep, --color-footer-line, --color-footer-hover | #14282b, #f1f5f4, #b9c6c4, #0d1b1d, #2b3f42, #f7c34c | Pied de page sombre. |
--container-page | 80rem | Largeur maximale du contenu. |
--radius-xl, --radius-2xl | 1rem, 1.5rem | Arrondi des champs et boutons, arrondi des cartes. |
--wst-card-shadow | none | Ombre des cartes. |
--wst-muted | color-mix(in srgb, var(--color-ink) 65%, transparent) | Texte secondaire. |
--font-sans, --font-head | pile système, var(--font-sans) | Polices du texte et des titres. |
Alias courts, à utiliser dans une extension avec une valeur de repli : --wst-brand, --wst-brand-light, --wst-brand-dark, --wst-brand-soft, --wst-brand-on, --wst-secondary, --wst-accent, --wst-highlight, --wst-ink, --wst-line, --wst-page, --wst-surface, --wst-footer, --wst-footer-ink, --wst-radius, --wst-radius-lg, --wst-font, --wst-font-head, --wst-container.
.mon-module { border: 1px solid var(--wst-line, #d9e6e4); border-radius: var(--wst-radius, 1rem); color: var(--wst-ink, #14282b); }
Évènements
Le template déclenche des évènements Joomla\Event\Event sur le répartiteur de l'application. Un plugin les écoute et modifie les arguments avec setArgument().
Un plugin doit implémenter Joomla\Event\SubscriberInterface. Avec un plugin à l'ancienne (méthodes on… sans SubscriberInterface), Joomla ne transmet l'évènement que si la méthode a un seul paramètre nommé $event et typé Joomla\Event\EventInterface ; sinon elle reçoit des copies des arguments et ne peut rien modifier.
namespace Acme\Plugin\System\Boutique\Extension;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\EventInterface;
use Joomla\Event\SubscriberInterface;
final class Boutique extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return ['onWebsourceTemplateTokens' => 'tokens', 'onWebsourceTemplateSettings' => 'settings'];
}
public function tokens(EventInterface $event): void
{
$tokens = $event->getArgument('tokens');
$tokens['--wst-brand'] = '#b45309'; // reconstruit toute l'échelle --color-brand-*
$tokens['--radius-xl'] = '.5rem';
$event->setArgument('tokens', $tokens);
}
public function settings(EventInterface $event): void
{
$settings = $event->getArgument('settings');
$settings['footer_style'] = 'light';
$event->setArgument('settings', $settings);
}
}
| Évènement | Arguments | Effet |
|---|---|---|
onWebsourceTemplateSettings | settings (tableau) | Réglages du style après lecture des paramètres. Clés à valeurs contrôlées : header_desktop (classic, centered, compact), header_mobile (icons_right, centered, stacked), mobile_nav (bottom, top), footer_style (dark, light), product_layout (classic, xl, showcase, minimal, sticky-buy, magazine), product_details (tabs, accordion, stacked), shop_sidebar (left, none), shop_columns (3, 4). Une valeur inconnue revient à la valeur par défaut. |
onWebsourceTemplateTokens | tokens (tableau variable → valeur), defaults | Variables CSS. Un alias --wst-* seul pilote sa variable canonique ; --wst-brand seul recalcule l'échelle de marque. Les noms et valeurs sont assainis. |
onWebsourceTemplatePageType | type | Type de page. |
onWebsourceTemplateProductLayout | layout (preset, details_mode, hidden), product | Disposition d'une fiche produit. hidden est la liste des blocs à masquer : title, flags, gallery, price, short_description, buy, reassurance, meta. |
onWebsourceTemplateProductFlags | flags (liste de type, label), product | Pastilles d'un produit (new, discount, out_of_stock). |
onWebsourceTemplateHomeSections | sections (categories, new_products) | Sections automatiques de l'accueil à afficher. |
onWebsourceTemplateTabbar | items (clé → url, icon, label, current) | Boutons de la barre du bas mobile. |
onWebsourceTemplateCopyright | text (HTML déjà échappé) | Ligne de copyright. |
onWebsourceTemplateRobots | robots | Contenu de la balise robots. |
onWebsourceTemplateCanonical | url | Adresse canonique. |
onWebsourceTemplateOpenGraph | og (propriété → contenu) | Balises Open Graph. |
onWebsourceTemplateBreadcrumb | links (liste de title, url) | Fil d'Ariane des données structurées. |
onWebsourceTemplateJsonLd | nodes (clé → nœud) | Nœuds JSON-LD : organization, website, webpage, breadcrumb, itemlist, article. Retirer une clé supprime le nœud. |
Fonctions publiques
Charger les classes depuis un module ou une surcharge :
require_once JPATH_THEMES . '/websource/src/autoload.php';
use Websource\Template\Shop;
use Websource\Template\Theme;
| Méthode | Retour |
|---|---|
Theme::pageType(): string | Type de la page courante. |
Theme::bodyClasses(string $extra = ''): string | Classes de <body>. |
Theme::icon(string $name, int $size = 24): string | Icône SVG en ligne : menu, search, account, cart, home, star, mail, close, filter, orders, downloads, address, payment, logout, dashboard, check, chevron, arrow-up, tag, wishlist. |
Theme::logo(bool $dark = false): string | Logo (image ou nom du site) lié à l'accueil. |
Theme::layout(string $name, array $data = []): string | Rend un layout html/layouts/websource/<name>.php (enfant d'abord). |
Theme::has(string $position): bool | La position contient au moins un module. |
Theme::position(string $position, string $style = 'websource'): string | Modules d'une position. |
Theme::positionWithLayout(string $position, string $layout, string $style = 'none'): string | Modules d'une position rendus avec une autre disposition. |
Theme::productFlags(object $row): array, Theme::flagsHtml(array $flags): string | Pastilles d'un produit HikaShop. |
Settings::get(string $key): string, Settings::all(): array | Réglages du style, évènement appliqué. |
Tokens::all(): array, Tokens::css(): string, Tokens::scale(string $name, string $hex): array | Variables CSS, règle :root{}, échelle de 50 à 900 depuis une couleur. |
Shop::enabled(): bool | HikaShop est installé et activé. |
Shop::cartCount(): int | Nombre d'articles du panier (0 sans HikaShop). |
Shop::cartUrl(), Shop::shopUrl(), Shop::accountUrl(), Shop::url(string $view, string $layout) | Adresses de la boutique, par l'élément de menu du site quand il existe. |
Shop::categories(int $limit = 8): array, Shop::products(int $limit = 8, string $order = 'created'): array | Catégories et produits pour les sections de l'accueil. |
Shop::checkoutStepIsCart(int $step, string $task = ''): bool | L'étape du tunnel ne contient que le panier. |
Seo::graph(HtmlDocument $doc): array, Seo::breadcrumb(): array | Nœuds JSON-LD et fil d'Ariane. |
Point d'entrée AJAX
Le template n'ajoute pas de route d'API. Il expose une méthode par com_ajax.
| Méthode | Chemin | Paramètres |
|---|---|---|
GET | index.php?option=com_ajax&template=websource&method=cart&format=json | Aucun. La session du visiteur identifie le panier. |
Exemple de requête :
curl -b cookies.txt 'https://exemple.test/index.php?option=com_ajax&template=websource&method=cart&format=json'
Exemple de réponse :
{"success":true,"message":null,"messages":null,"data":{"items_count":2}}
theme.js appelle cette adresse après les évènements HikaShop cart.updated, checkout.cart.updated, cart.empty et wishlist.updated, puis met à jour tous les éléments [data-wsx-cart-count]. L'adresse est fournie à la page par Joomla.getOptions('websource').cartUrl.
Attributs JavaScript
| Attribut | Effet |
|---|---|
data-wsx-drawer-open="<id>" | Ouvre le panneau push ou la colonne d'identifiant <id> (wsx-drawer, wsx-shop-sidebar). |
data-wsx-drawer-close | Ferme le panneau push ouvert. La touche Échap le ferme aussi. |
data-wsx-cart-count | Reçoit le nombre d'articles ; masqué à zéro. |
data-wsx-details, data-details-mode | Bloc des détails de la fiche : tabs, accordion ou stacked. |
Assets déclarés
joomla.asset.json déclare : template.websource.base (style), template.websource.page.<type> (un style par type de page), template.websource.offline, template.websource (script), template.websource.product (script), template.active, template.active.language, template.user, et le préréglage template.websource.
template.user charge css/user.css et js/user.js s'ils existent dans media/templates/site/websource (ou dans le template enfant). Le template ne livre pas ces fichiers.
En-tête SEO
Avec Balises de référencement sur Oui, Seo::head() écrit robots (noindex,follow sur la recherche, le panier, la commande et le compte), canonical, Open Graph et twitter:card. Une balise déjà présente dans le document n'est pas réécrite ; le canonical posé par HikaShop est repris. Sur une fiche produit, les liens rel="next" et rel="prev" ajoutés par les listes de modules sont retirés.
Avec Données structurées sur Oui, les nœuds sont écrits à la compilation du <head>. Quand le plugin schema.org de Joomla a déjà écrit son graphe pour la page (articles), le template n'ajoute que BreadcrumbList et ItemList. Le nœud Product vient de HikaShop.
Surcharges livrées
| Composant | Fichiers |
|---|---|
com_content | article/default, category/blog, category/blog_item, featured/default, featured/default_item |
com_contact | contact/default, contact/default_form |
com_users | login/default_login, registration/default, profile/default |
com_hikashop | product/listing_div, product/listing_img_title, product/show, product/show_default, category/listing_img_title, category/listing_title, checkout/end, user/cpanel |
| Layouts | websource/header, footer, drawer, tabbar, product_card, product_reviews, home/hero, home/sections |
Le panier, les étapes de commande, les listes de commandes et d'adresses gardent les vues d'origine de HikaShop : elles sont habillées par CSS (assets/src/hikashop-checkout.css, assets/src/pages/account.css).
Template enfant
Créer l'enfant depuis Système > Templates de site > Websource > Créer un template enfant. Un fichier placé dans templates/websource_<nom>/html/… remplace celui du parent ; Theme::layout() cherche d'abord dans l'enfant. Les réglages du style enfant sont indépendants.
Build CSS
nice npm install
nice npm run build # media/css/theme.css + media/css/pages/<type>.css
nice npm run watch
bash scripts/build-zip.sh # dist/tpl_websource-<version>.zip
scripts/pages.config.mjsassocie à chaque type de page ses sources (assets/src/…) et les gabarits analysés par Tailwind.- Ce qui se trouve déjà dans
theme.cssest retiré des fichiers de page. - Les CSS de composants sont hors
@layer: ils doivent l'emporter sur les CSS non stratifiés du cœur et de HikaShop. - Une classe utilitaire n'existe que si elle figure dans un gabarit analysé : relancer le build après tout ajout.