Accueil

Référence développeur · WordPress

Websource Listes de liens pour WordPress — référence développeur

Bloc, code court, widget, fonction PHP, emplacements, action AJAX d'administration, filtres, variables CSS, gabarit et format des données de Websource Link Lists.

Version 1.0.0 · WordPress 6.4+, WooCommerce 8+ (facultatif) · Mis à jour le 09/10/2026

Guide utilisateur

Cette extension existe aussi pour : PrestaShop

Vue d'ensemble

  • Espace de noms PHP : Websource\LinkLists (classes dans src/, PSR-4, chargeur dans websource-linklists.php, pas de Composer).
  • Préfixe des options, filtres et handles : wsx_linklists_. Classes CSS : wsll.
  • Stockage : options WordPress, aucune table. wsx_linklists_lists (listes publiées, chargée automatiquement), wsx_linklists_drafts (brouillons), wsx_linklists_seq (dernier numéro), wsx_linklists_rev (révision du cache), wsx_linklists_version.
  • Cache : un transient par liste et par langue, wsx_linklists_v_<révision>_<numéro>-<langue>, durée 1 heure. Vidé à chaque enregistrement et quand une page, un produit, un terme, les permaliens, le thème ou les pages WooCommerce changent.
  • Côté public : une feuille de style (assets/css/front.css, handle wsx-linklists), aucun JavaScript. La feuille n'est chargée que si une liste s'affiche sur la page.
  • Droit requis pour l'administration : edit_theme_options (filtre wsx_linklists_capability).
  • Aucune route REST propre. L'administration passe par une action admin-ajax.php protégée (voir « Action AJAX d'administration »).

Bloc

websource/link-list — rendu serveur, sans étape de build (blocks/link-list/block.json, blocks/link-list/editor.js).

AttributTypeDéfautRôle
liststring""Identifiant de la liste (informations) ou son numéro.
layoutstring""Présentation forcée pour ce bloc : columns, inline ou menu. Vide : celle de la liste.

Supports : align (wide, full), spacing.margin, spacing.padding, customClassName, plusieurs blocs par page.

<!-- wp:websource/link-list {"list":"informations","layout":"menu"} /-->

Le bloc ne rend rien sur le site si la liste est inconnue, masquée ou sans lien affichable. Dans l'éditeur, il affiche alors un message d'aide.

Code court

[websource_linklist list="informations"]
[websource_linklist id="1"]
AttributRôle
listIdentifiant lisible de la liste. Stable après un export puis un import.
idNuméro de la liste. Change si la liste est recréée par un import en remplacement.

Widget

Widget classique wsx_linklists (classe Websource\LinkLists\Widget\LinkListWidget, classe CSS widget_wsx_linklists). Réglages d'instance : title (facultatif) et list (identifiant). Disponible aussi comme widget hérité dans l'éditeur de widgets à blocs.

Fonction PHP

<?php
// Dans un fichier du thème : HTML d'une liste affichée sur le site, ou chaîne vide.
echo websource_linklist('informations'); // identifiant
echo websource_linklist(1);              // numéro

Accès aux services :

<?php
$plugin   = \Websource\LinkLists\Plugin::instance();
$html     = $plugin->renderer()->renderByRef('informations'); // comme websource_linklist()
$html     = $plugin->renderer()->renderList(1, 2);            // numéro, colonne du pied de page (0 à 4)
$all      = $plugin->lists()->all();                          // listes publiées, par numéro
$active   = $plugin->lists()->findActive();
$plugin->afterChange();                                       // vide le cache après une écriture directe

Emplacements

Un emplacement est une paire page + endroit. Son champ hook prend l'une de ces trois formes :

FormeExempleRendu
zone:<zone>zone:footerZone gérée par l'extension.
menu:<emplacement>menu:primaryÉléments <li class="menu-item wsll-menu-item"> ajoutés à la fin de cet emplacement de menu (filtre wp_nav_menu_items, thèmes classiques).
nom d'actionwoocommerce_after_single_product_summaryListe affichée sur cette action WordPress ou WooCommerce, dans <div class="wsll-zone wsll-zone--hook">. Sur loop_start et loop_end, seule la boucle principale est concernée.

Zones et points d'accroche :

Position (position)ZoneThème à blocsThème classiqueStorefront
topbar_left, topbar_righttopbarwp_body_open (5)wp_body_open (5)wp_body_open (5)
under_headerunder_headeraprès la partie de modèle headeraprès le premier </header> placé avant <main> ou <article> (tampon de sortie ouvert sur wp_body_open, fermé sur get_footer) ; à défaut, en haut de pagestorefront_before_content (5)
before_footerbefore_footeravant la partie de modèle footerget_footer (5)storefront_before_footer (10)
footer_col1 à footer_col4footerà l'intérieur de <footer>, en premierget_footer (10)storefront_footer (5)
after_footerafter_footeraprès la partie de modèle footerwp_footer (5)storefront_after_footer (10)
left_columnsidebar_top—dynamic_sidebar_beforedynamic_sidebar_before
right_columnsidebar_bottom—dynamic_sidebar_afterdynamic_sidebar_after
account_blockaccountdans le <nav> du compte WooCommerce, après son menuidemidem

Les zones de widgets dont l'identifiant contient footer, header, colophon ou bottom ne reçoivent pas les positions left_column et right_column (filtre wsx_linklists_sidebar_zone).

Clés de page (page) : all, home, shop, category, product, brand, cms (avec cms_id, 0 = toutes les pages), blog, search, login, password, account, cart, checkout, contact, notfound.

Les points d'accroche ne sont branchés que sur les pages où une liste affichée les utilise (Websource\LinkLists\Front\Placements::prepare(), action wp, priorité 20). Rien n'est branché en administration, en AJAX, en REST, dans les flux ni dans les contenus embarqués.

Action AJAX d'administration

L'extension ne déclare aucune route REST. L'écran Apparence > Listes de liens appelle une seule action.

  • Méthode et chemin : POST /wp-admin/admin-ajax.php
  • Paramètres communs : action=wsx_linklists, _ajax_nonce (nonce wsx_linklists_admin), do (opération).
  • Accès : utilisateur connecté disposant du droit edit_theme_options. Un visiteur anonyme reçoit la réponse 0 de WordPress (HTTP 400), un utilisateur sans le droit ou sans nonce valide reçoit HTTP 403.
doParamètresRéponse
createname, starter (blank ou footer){ "id": 6, "url": "…&edit=6" }
draftid, payload (JSON){ "preview": "<nav…>", "saved_at": "10:42" } — le site n'est pas modifié
saveid, payload (JSON){ "ok": true, "preview": "…", "saved_at": "10:42", "content": {…}, "dropped": 0 }
toggleid, active (0 ou 1){ "ok": true }
duplicateid{ "id": 7, "url": "…&edit=7" }
deleteid{ "ok": true }
searchq (nom ou UGS){ "results": [ { "id": 16, "name": "T-shirt Lagon" } ] } (15 au plus)

Exemple de requête :

curl -b cookies.txt https://exemple.fr/wp-admin/admin-ajax.php \
  -d action=wsx_linklists -d do=toggle -d id=1 -d active=0 -d _ajax_nonce=20c18e7621

Réponses d'erreur (JSON { "error": "…" }) : 400 action inconnue, 403 droit ou nonce refusé, 404 liste introuvable.

Le contenu reçu (payload) est toujours nettoyé par Websource\LinkLists\Admin\ListPayloadSanitizer : 60 liens et 20 emplacements au plus, sources et pages connues seulement, adresses passées par UrlSanitizer. dropped donne le nombre de liens refusés.

Format des données

Liste publiée (option wsx_linklists_lists)

{
  "id": 1,
  "identifier": "informations",
  "name": "Informations",
  "layout": "columns",
  "show_title": true,
  "active": true,
  "titles": { "fr": "Informations" },
  "links": [
    { "source": "page", "target_id": 0, "page_key": "contact", "url": "", "urls": [], "new_tab": false, "nofollow": false, "labels": [] },
    { "source": "custom", "target_id": 0, "page_key": "", "url": "https://www.websource.fr/", "urls": [], "new_tab": true, "nofollow": true, "labels": { "fr": "Websource" } }
  ],
  "placements": [
    { "page": "all", "position": "footer_col1", "cms_id": 0, "hook": "zone:footer" }
  ],
  "date_add": "2026-10-09 18:52:10",
  "date_upd": "2026-10-09 18:52:10"
}
Champ d'un lienRôle
sourcecustom (lien libre), cms (page WordPress), category (product_cat), brand (product_brand), product, page (page du site).
target_idIdentifiant de la page, du terme ou du produit pour cms, category, brand, product.
page_keyPour page : home, shop, blog, contact, sitemap, terms, privacy, stores, best-sales, new-products, prices-drop, manufacturers, authentication, my-account, history, cart.
url, urlsLien libre : adresse commune et adresses par code de langue.
labelsTexte affiché par code de langue. Vide : nom de la cible. Obligatoire pour un lien libre.
new_tab, nofollowtarget="_blank" + rel="noopener", rel="nofollow".

Adresses acceptées pour un lien libre (Websource\LinkLists\Link\UrlSanitizer) : http://, https://, chemin commençant par /, ancre #…, mailto:, tel:. Une adresse du type www.exemple.fr ou exemple.fr/page est complétée par https://. Tout le reste est refusé (javascript:, ftp:, espaces, guillemets, chevrons). 500 caractères au plus.

Un lien dont la cible n'existe plus ou n'est pas publiée reste enregistré mais n'est pas affiché.

Pages du site sans équivalent natif : contact, sitemap, terms, stores, prices-drop et manufacturers sont cherchées parmi les pages publiées, par slug (contact, plan-du-site, conditions-generales-de-vente, nos-magasins, promotions, marques et leurs variantes ; liste dans Websource\LinkLists\Link\SpecialPages::SLUGS). terms utilise d'abord la page des conditions générales de WooCommerce, privacy la page de politique de confidentialité de WordPress. best-sales et new-products mènent à la boutique triée (?orderby=popularity, ?orderby=date).

Vue d'une liste (filtre wsx_linklists_view, gabarit)

<?php
[
    'id' => 1,
    'identifier' => 'informations',
    'title' => 'Informations',
    'layout' => 'columns',        // columns, inline, menu
    'show_title' => true,
    'links' => [
        ['url' => 'https://exemple.fr/contact/', 'label' => 'Contact', 'target' => '', 'rel' => ''],
    ],
];

Paquet de thème

Section linklists, version 1, des filtres websource_theme_export et websource_theme_import de Websource Theme Config (classe Websource\LinkLists\ThemePackage\ThemePackage).

{
  "lists": [
    {
      "identifier": "informations",
      "name": "Informations",
      "layout": "columns",
      "show_title": true,
      "active": true,
      "titles": { "fr": "Informations" },
      "links": [
        { "source": "cms", "target": "cms:a-propos", "page_key": "", "url": "", "urls": [], "new_tab": false, "nofollow": false, "labels": [] },
        { "source": "product", "target": "product:WS-001", "page_key": "", "url": "", "urls": [], "new_tab": false, "nofollow": false, "labels": [] }
      ],
      "placements": [
        { "page": "cms", "position": "before_footer", "hook": "zone:before_footer", "cms": "cms:a-propos" }
      ]
    }
  ]
}
  • Clés stables des cibles : cms:<slug>, category:<slug>, brand:<slug>, product:<UGS> (ou product:<slug> sans UGS).
  • Contexte d'import : mode (replace par défaut, ou merge) et dry_run. replace supprime les listes du site puis crée celles du paquet (les numéros changent, les identifiants sont conservés). merge met à jour la liste de même identifiant et ajoute les autres.
  • Rapport renvoyé : { "action": "merge", "counts": { "create": 1, "update": 1, "delete": 0, "skip": 0 }, "messages": ["linklists : cible « cms:nexiste-pas » introuvable : lien ignoré."] }.
  • Une section de version supérieure à 1 lève une RuntimeException (rapportée en erreur par Websource Theme Config).
  • Les brouillons ne sont pas exportés. 60 listes au plus par import.
  • Paquets du module PrestaShop : les pages index, manufacturer, pagenotfound, my-account, authentication, order et product-list sont traduites en home, brand, notfound, account, login, checkout et category. Un hook libre displayXxx devient l'action wsx_linklists_displayxxx, à déclencher dans le thème avec do_action(). Sur un site à une seule langue, le premier texte du paquet est repris.

Filtres

FiltreParamètresRôle
wsx_linklists_viewarray $view, int $orderModifier une liste avant affichage (présentation, titre, liens).
wsx_linklists_templatestring $path, array $viewChemin du gabarit utilisé.
wsx_linklists_list_htmlstring $html, array $view, int $orderHTML final d'une liste (données structurées comprises).
wsx_linklists_zone_hooksarray $hooks, string $templateDéclarer les actions du thème pour les zones under_header, before_footer, footer, after_footer : [zone => [action, priorité]].
wsx_linklists_account_hookstring $hookAction de la zone du compte client (défaut woocommerce_after_account_navigation).
wsx_linklists_sidebar_zonebool $show, string $sidebar, string $zoneAutoriser ou non une zone de widgets pour les colonnes latérales.
wsx_linklists_suggested_hooksarray $hooksSuggestions du champ « Nom du hook » : [nom d'action => libellé].
wsx_linklists_current_pagestring $pageClé de la page affichée, pour un type de page propre au site.
wsx_linklists_special_page_idint $id, string $keyIdentifiant de la page WordPress d'une « page du site ».
wsx_linklists_special_pagearray\|null $result, string $key, string $languageFournir ou masquer une « page du site » : ['url' => …, 'label' => …] ou null.
wsx_linklists_capabilitystring $capabilityDroit requis pour gérer les listes.
wsx_linklists_woocommerce_activebool $activeForcer la présence ou l'absence de la boutique.

Exemple : déclarer les zones d'un thème classique.

<?php
add_filter('wsx_linklists_zone_hooks', function (array $hooks, string $template): array {
    if ($template === 'mon-theme') {
        $hooks['under_header'] = ['mon_theme_after_header', 10];
        $hooks['footer'] = ['mon_theme_footer_top', 10];
    }

    return $hooks;
}, 10, 2);

Exemple : forcer la présentation d'une liste.

<?php
add_filter('wsx_linklists_view', function (array $view): array {
    if ($view['identifier'] === 'informations') {
        $view['layout'] = 'inline';
    }

    return $view;
});

Gabarit et balisage

Gabarit : templates/list.php, surchargeable dans le thème (<thème>/websource-linklists/list.php). Variables : $wsll_list (la vue) et $wsll_order (colonne du pied de page, 0 à 4).

<nav class="wsll wsll--columns wsll--o1" data-wsll-list="informations" aria-label="Informations">
    <p class="wsll__title">Informations</p>
    <ul class="wsll__list">
        <li class="wsll__item"><a class="wsll__link" href="https://exemple.fr/contact/">Contact</a></li>
    </ul>
</nav>
ClasseRôle
wsll--columns, wsll--inline, wsll--menuPrésentation.
wsll--o1 à wsll--o4Ordre dans la grille du pied de page (order).
wsll-zone, wsll-zone--topbar, --under-header, --before-footer, --footer, --after-footer, --sidebar, --account, --hookConteneur d'une zone.
wsll-zone__side, wsll-zone__side--endCôtés de la barre du haut.
wsll-blockConteneur du bloc.
wsll-menu-itemÉlément ajouté à la fin d'un menu du thème.

Données structurées : après chaque liste affichée, une balise <script type="application/ld+json"> de type SiteNavigationElement (@graph, nom et adresse absolue de chaque lien http(s)). Une même liste affichée deux fois sur une page n'est décrite qu'une fois. Rien dans l'aperçu de l'administration ni dans l'éditeur de blocs.

Variables CSS

La feuille de style lit les variables du thème Websource et prévoit une valeur de repli pour tout autre thème.

VariableRepliUtilisation
--wst-ink, puis --color-ink#14282bTexte et titre.
--wst-brand, puis --color-brand-600#0f766eSurvol, contour au clavier.
--wst-brand-soft, puis --color-brand-50#effaf8Fond au survol du menu vertical.
--wst-line, puis --color-line#d9e6e4Bordures des pastilles, du menu vertical, de la barre du haut.
--wst-surface, puis --color-surface#fffFond du menu vertical.
--wst-muted, puis --color-muted#5b6f72Message du bloc vide.
--wst-radius, puis --radius-xl1remArrondi du menu vertical.
--wst-card-shadownoneOmbre du menu vertical.
--wp--style--global--wide-size, puis --wst-container1200pxLargeur maximale des zones.

Multilingue

  • Les titres, les textes des liens et les adresses des liens libres sont enregistrés par code de langue (fr, en…). La langue courante est lue auprès de Polylang (pll_current_language) ou de WPML (wpml_current_language) ; à défaut, la langue du site.
  • Texte absent dans une langue : celui de la langue par défaut est repris.
  • Les pages, produits et termes sont remplacés par leur traduction (pll_get_post, pll_get_term, wpml_object_id).
  • Les titres et textes des listes publiées sont déclarés à Polylang (pll_register_string, groupe « Websource Link Lists ») et à WPML (wpml-config.xml, option wsx_linklists_lists).
  • Classe utilitaire : Websource\LinkLists\Languages (all(), codes(), defaultCode(), current(), isMultilingual(), translatePost(), translateTerm(), pick()).

Classes PHP utiles

ClasseRôle
PluginServices, code court, vidage du cache (afterChange()).
Repository\ListRepositoryLecture et écriture des listes et des brouillons.
Admin\ListPayloadSanitizerNettoyage d'un contenu de liste.
Link\LinkSources, Link\LinkResolver, Link\SpecialPages, Link\UrlSanitizerSources de liens, résolution en adresse et texte, pages du site, adresses libres.
Placement\PlacementCatalog, Placement\PageDetector, Placement\DispatcherPages et positions, détection de la page affichée, listes à afficher sur un point d'accroche.
Front\PlacementsBranchement des zones et des actions.
Render\Renderer, Render\ListViewBuilder, Render\ListViewProvider, Render\ListCache, Render\JsonLdBuilderRendu, vue, cache, données structurées.
Block\LinkListBlock, Widget\LinkListWidgetBloc et widget.
ThemePackage\ThemePackageExport et import du paquet de thème.

Désinstallation

uninstall.php supprime les options wsx_linklists_lists, wsx_linklists_drafts, wsx_linklists_seq, wsx_linklists_rev, wsx_linklists_version, widget_wsx_linklists et les transients wsx_linklists_*, sur chaque site d'un réseau multisite.