Accueil

Référence développeur · WordPress

Websource Builder pour WordPress — référence développeur

Blocs, shortcodes, modèle de données, API PHP, routes REST, hooks et variables CSS de Websource Builder.

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

Guide utilisateur

Cette extension existe aussi pour : PrestaShop

Vue d'ensemble

  • Espace de noms Websource\Builder, classes dans src/ (chargeur PSR-4 maison, pas de Composer). Fichier principal websource-builder.php : constantes WEBSOURCE_BUILDER_VERSION, WEBSOURCE_BUILDER_DIR, WEBSOURCE_BUILDER_URL, fonctions websource_builder() et websource_builder_render_composition().
  • Un seul catalogue de blocs (Block\BlockRegistry) alimente trois façades : blocs Gutenberg websource/<type> (rendu serveur, block.json dans blocks/<type>/), shortcodes [wsb_<type>], et le modèle JSON {type, data, style} utilisé par l'API PHP, l'export et le connecteur Websource MCP. C'est le même modèle que le module PrestaShop Websource Builder 1.13.
  • Type de contenu wsb_composition (« Compositions Websource », non public, show_in_rest), métadonnées _wsb_placements (liste d'emplacements), _wsb_lang, _wsb_pending_content (brouillon en attente d'une composition publiée).
  • Options : wsb_product_layout (disposition de la fiche produit), wsb_contact_page, wsb_placement_index (index des emplacements, reconstruit à chaque enregistrement).
  • Aucune table, aucun JavaScript public. CSS : assets/css/base.css + une feuille par bloc, chargées seulement si le bloc est présent (Assets::typesIn() analyse le contenu et les compositions retenues avant l'en-tête).
ClasseRôle
Plugin, Api, AssetsDémarrage, API publique, feuilles de style.
Block\*Catalogue, champs (Field), apparence (Appearance), validation (BlockSanitizer), couleurs (ColorValue), layouts (Layout\LayoutCatalog), types (Block\Type\*Block).
Gutenberg\*Enregistrement des blocs et données de l'éditeur (Blocks), shortcodes, gabarits (Patterns), conversion JSON ↔ contenu Gutenberg (Serializer).
Composition\*Type de contenu (PostType), catalogue des emplacements (Placements), affichage par hooks (Display).
Render\*Rendu (BlockRenderer, Html), icônes SVG (Icons), jetons (TokenResolver), contexte (RenderContext).
Product\*Dispositions de la fiche produit WooCommerce.
Seo\JsonLdFAQPage (fusionnée, une par page), VideoObject, ItemList.
ThemePackage\PackageExport / import JSON, section builder du paquet de thème.
Rest\Routes, Admin\Admin, I18n\TranslatorRoutes REST, écrans, traduction des libellés de catalogue.

Blocs

Nom Gutenberg websource/<type>, shortcode [wsb_<type>]. Tous ont l'attribut appearance (objet : apparence + style avancé) et className. Les attributs portent le nom du champ ; les noms réservés par Gutenberg (style, align, layout…) sont préfixés wsb_ (wsb_style pour le bouton, wsb_align pour l'appel à l'action).

TypeChamps (data)
herotitle, subtitle, button_label, button_url, image, height (m, l)
headingtitle, subtitle, level (h2, h3)
textcontent (HTML riche ; dans l'éditeur, blocs imbriqués)
imagesrc, alt, caption, link
buttonlabel, url, style (solid, outline)
spacersize (s, m, l), line (booléen)
featurescolumns (2–4), items[] : icon, title, text
cardscolumns (2–4), items[] : image, title, text, link
splitimage, side (left, right), title, text (riche), button_label, button_url
ctavariant (gradient, brand, split, floating, dark, minimal, icon, image), title, text, button_label, button_url, button2_label, button2_url, align (auto, left, center, right), size (s, m, l), icon, accent (blue, green, orange, pink, purple, red, black ou vide), accent_color (#rrggbb), image
faqitems[] : question, answer
testimonialscolumns (1–3), items[] : quote, author, role, photo, rating (1–5), date
statsitems[] : value, label
videourl (YouTube ou Vimeo), title, description, upload_date (AAAA-MM-JJ), thumbnail
announcementtext, link
productstitle, category (identifiant product_cat, 0 = nouveautés), limit (1–12), columns (2–4). WooCommerce requis.
htmlcode (HTML filtré par wp_kses_post)
pagecontenttitle, lead, content (riche ; blocs imbriqués dans l'éditeur)
columnsgap (s, m, l, none), valign (top, center, bottom, stretch), cols[] : w (1–6), blocks[] (modèle JSON) ; dans l'éditeur, blocs enfants websource/column (attribut w)

Apparence (style, commune à tous les blocs) :

CléValeursRôle
bgnone, soft, surface, brand, darkFond.
pads, m, lEspace autour.
widthcontainer, wide, fullDans le cadre, fond pleine largeur, bord à bord.
alignleft, centerAlignement du texte.
Style avancéc_bg, c_bg2, g_angle, c_text, c_accent, c_overlay, c_btn_bg, c_btn_text, c_btn_hover, c_card, b_style, b_width, b_color, b_radius, shadow, sh_color, p_top|right|bottom|left, m_top|right|bottom|left, f_family, f_size, f_weightCouleurs (#rrggbb, #rrggbbaa, rgb()/rgba()), tailles en px, listes fermées. Une valeur invalide est retirée.
layoutclé d'un layout du type (LayoutCatalog)Layout appliqué ; les clés de style qu'il fixe sont écrites dans style.

Icônes (icon) : icon:<nom> parmi truck, bag, chat, home, hand, rocket, sparkles, bolt, heart, shield, phone, tag, list, alert, return, star, bell, megaphone, mountain, quote, leaf, pin, cart, fire, thumb, link, check, lock… (Render\Icons::PATHS), ou un emoji, un court texte, une adresse d'image.

Jetons dans les textes et liens (Render\TokenResolver) : {price:N}, {link:home}, {link:contact}, {link:shop}, {link:cart}, {link:account}, {link:page:ID} (alias {link:cms:ID}), {link:post:ID}, {link:product:ID}, {link:category:ID}. Les identifiants sont traduits par Polylang / WPML.

Balisage produit : <section class="wsb-block wsb-b-<type> wsb-bg-<bg> wsb-pad-<pad> wsb-w-<width> wsb-al-<align> [wsb-l-<layout>]">, contenu dans .wsb-inner. Une composition est enveloppée dans <div class="wsb-composition wsb-at-<position>" data-wsb-composition="ID">.

Shortcodes

[wsb_hero title="Bienvenue" subtitle="…" button_label="Voir" button_url="{link:shop}" image="https://…/photo.jpg" height="l" style_bg="dark" style_pad="l"]
[wsb_features columns="3" style_bg="soft"]
  [wsb_item icon="icon:truck" title="Livraison rapide" text="Sous 48 h."]
  [wsb_item icon="icon:shield" title="Paiement sécurisé" text="3D Secure."]
[/wsb_features]
[wsb_text]<p>Texte riche : <strong>le contenu du shortcode</strong>.</p>[/wsb_text]
[wsb_columns gap="l" valign="center"][wsb_column w="2"]…[/wsb_column][wsb_column w="1"]…[/wsb_column][/wsb_columns]
[wsb_composition id="12"]
  • Un attribut par champ ; style_<clé> pour l'apparence et le style avancé ; class ajoute une classe CSS.
  • Listes (features, cards, faq, testimonials, stats) : un [wsb_item …] par élément, attributs = sous-champs.
  • Texte riche (text, split, pagecontent) : le contenu du shortcode remplace le champ riche.
  • [wsb_composition id="N"] affiche une composition publiée (vide sinon).

Modèle JSON

[
  {"type": "hero", "data": {"title": "Bienvenue", "button_url": "{link:shop}"}, "style": {"bg": "dark", "pad": "l"}},
  {"type": "columns", "data": {"cols": [
    {"w": 2, "blocks": [{"type": "heading", "data": {"title": "Colonne A"}}]},
    {"w": 1, "blocks": [{"type": "button", "data": {"label": "Voir", "style": "outline"}}]}
  ]}},
  {"type": "gutenberg", "data": {"ref": "a3f9…"}}
]
  • Un champ absent prend sa valeur par défaut ; une valeur hors liste revient à la valeur par défaut ; les types inconnus sont retirés ; 80 blocs au plus ; un seul niveau de colonnes.
  • gutenberg : un bloc natif de l'éditeur présent dans la composition, référencé par une empreinte ref. Serializer le conserve tel quel ; l'API refuse une référence inconnue (aucun bloc natif ne peut être créé par ce modèle).
  • Gutenberg\Serializer::toContent() / fromContent() convertissent dans les deux sens avec le contenu Gutenberg sérialisé.

API PHP

websource_builder() renvoie Websource\Builder\Api :

MéthodeRôle
version(): stringVersion de l'extension.
registry(): BlockRegistry, describeBlocks(): arrayCatalogue ; description par type : type, name, shortcode, label, description, category, icon, fields, defaults, layouts.
styleFields(): array, advancedStyleGroups(): arrayChamps d'apparence et groupes du style avancé.
sanitizeBlocks($blocks): arrayValide une liste de blocs (modèle JSON).
renderBlocks(array $blocks): stringHTML public d'une liste de blocs.
describePlacements(): arraypages (clé => libellé), positions (key, label, pages), targetable.
sanitizePlacement($placement): ?arrayEmplacement validé (page, position, object_id, hook, priority, native) ou null.
languages(): arrayCodes des langues du site (Polylang, WPML, sinon la locale).
listCompositions(): arrayCompositions hors corbeille : id, name, lang, status, is_published, has_changes, placements, date_upd, edit_url, shortcode.
findComposition(int $id): ?arrayIdem + blocks_live, blocks_draft.
createComposition(string $name, string $lang, array $placement, array $blocks): intCrée un brouillon ; 0 en cas d'échec.
saveDraft(int $id, string $name, array $blocks): boolRemplace le brouillon. Composition publiée : écrit _wsb_pending_content, la version en ligne ne change pas.
publish(int $id): boolPublie (le brouillon en attente devient le contenu).
setActive(int $id, bool $active): boolMet en ligne / hors ligne (statut draft), sans rien supprimer.
pendingContent(int $id): string, discardPending(int $id): boolBrouillon en attente.

websource_builder_render_composition(int $id): string : HTML d'une composition publiée.

Déclarer un bloc externe (il devient bloc Gutenberg, shortcode et type du connecteur MCP) :

add_action('websource_builder_register_blocks', function (Websource\Builder\Block\BlockRegistry $registry) {
    $registry->add(new Mon_Bloc()); // implémente Websource\Builder\Block\BlockInterface
});
add_filter('websource_builder_block_styles', fn(array $styles) => $styles + ['mon_bloc' => plugins_url('mon-bloc.css', __FILE__)]);

BlockInterface : getType(), getLabel(), getDescription(), getCategory(), getIcon(), getFields() (tableau de Block\Field::text(), textarea(), richText(), url(), image(), icon(), color(), select(), number(), toggle(), category(), repeater()), getDefaults(), render(array $data, RenderContext $context). Étendre Block\AbstractBlock fournit l'essentiel ; InnerContentBlock (innerField()) déclare un champ riche édité par blocs imbriqués.

Routes REST

Espace websource-builder/v1. Authentification WordPress (cookie + nonce X-WP-Nonce, ou mot de passe d'application).

MéthodeCheminDroitRôle
GET/blocksedit_pages{ "blocks": [...], "style": [...], "advanced_style": [...] }
GET/placementsedit_pages{ "pages": {...}, "positions": [...], "targetable": [...], "languages": [...] }
GET/compositions/{id}/pendingedit_post{ "content": "<!-- wp:websource/hero … -->" } (chaîne vide sans brouillon)
DELETE/compositions/{id}/pendingedit_post{ "deleted": true }
GET/exportmanage_optionsPaquet JSON (voir Export / import).
POST/importmanage_optionsCorps { "package": {...}, "mode": "merge"|"replace", "dry_run": false } ; réponse = rapport.

Les compositions elles-mêmes passent par la route native wp/v2/websource-compositions (métas _wsb_placements, _wsb_lang exposées en REST).

curl -u admin:xxxx-xxxx-xxxx-xxxx https://exemple.fr/wp-json/websource-builder/v1/placements
{
  "pages": {"all": "Toutes les pages du site", "home": "Page d'accueil", "product": "Fiches produit", "cms": "Pages de contenu (CMS)"},
  "positions": [{"key": "top", "label": "Tout en haut, sous l'en-tête (pleine largeur)", "pages": null},
                {"key": "product_info", "label": "Dans la fiche produit, sous le bouton d'achat", "pages": ["product"]}],
  "targetable": ["cms", "post", "product", "category"],
  "languages": ["fr"]
}

Emplacements

Un emplacement : { "page": "product", "position": "product_info", "object_id": 0, "hook": "", "priority": 10, "native": "" } (12 au plus par composition).

Pages : all, home, shop, category, product, cms, post, blog, login, registration, password, account, orders, cart, checkout, contact, search, notfound. object_id est accepté pour cms (page), post, product, category (product_cat).

PositionPagesHooks écoutés (thème Websource, WooCommerce, repli)
toptouteswebsource_wrapper_top ; woocommerce_before_main_content (5) ; thème à blocs : après l'en-tête (render_block_core/template-part) ; sinon loop_start
before_contenttouteswebsource_content_top ; woocommerce_before_single_product / woocommerce_before_shop_loop (5) ; the_content (20) sur un contenu seul ; loop_start
after_contenttouteswebsource_content_bottom ; woocommerce_after_single_product / woocommerce_after_shop_loop (50) ; the_content ; loop_end
homehome, allwebsource_home (section de l'accueil du thème Websource), sinon comme after_content
bottomtouteswebsource_wrapper_bottom ; woocommerce_after_main_content (50) ; thème à blocs : avant le pied de page ; sinon get_footer
footertouteswebsource_footer ; sinon wp_footer (1)
cms_pagecms, postthe_content ; native = hidden, above, below
category_topcategory, shopwoocommerce_archive_description (15)
product_infoproductwoocommerce_single_product_summary (35) ; zone « Réassurance » d'une disposition de fiche produit
product_footerproductwoocommerce_after_single_product_summary (25)
after_login_formloginwoocommerce_login_form_end (20)
registration_top, registration_bottomregistration, loginwoocommerce_register_form_start (5), woocommerce_register_form_end (20)
account_blockaccountwoocommerce_account_dashboard (20)
cart_topcartwoocommerce_before_cart (5)
checkout_topcheckoutwoocommerce_before_checkout_form (5)
customtoutesle hook donné dans hook (^[A-Za-z_][A-Za-z0-9_\/.:-]{2,80}$), à la priorité priority

Les thèmes à blocs sont pris en charge via render_block_core/template-part, render_block_core/query et render_block_woocommerce/product-collection.

Hooks

FiltreParamètresRôle
websource_builder_blocksBlockInterface[]Autre façon de déclarer des blocs externes.
websource_builder_block_stylesarray type => URLFeuille de style d'un bloc externe.
websource_builder_templatesarray définitionsGabarits (clé => label, description, icon, placement, blocks).
websource_builder_current_pagesstring[]Clés de page de la requête en cours.
websource_builder_composition_htmlstring $html, int $id, string $positionHTML d'une composition avant affichage.
websource_builder_is_editingboolContexte éditeur (aperçus).
websource_builder_linkstring $url, string $kind, int $idAdresse résolue d'un jeton {link:…}.
websource_builder_contact_pageint $pageIdPage de contact.
websource_builder_price_amount, websource_builder_format_pricefloat ; string $text, float $amountJeton {price:N}.
websource_builder_products_queryarray $args, int $categoryIdArguments de wc_get_products() du bloc Produits.
websource_builder_show_pricesbool, WC_ProductPrix dans le bloc Produits.
websource_builder_page_urlstringURL de la page dans le JSON-LD.
websource_builder_product_layoutarray $layoutDisposition de la fiche produit après lecture (preset, details_mode, zones, blocks).
websource_builder_apply_product_layoutboolDésactive l'application de la disposition.
websource_theme_export, websource_theme_importvoir ci-dessousSection builder du paquet de thème (Websource Theme Config).
ActionParamètresRôle
websource_builder_register_blocksBlockRegistry $registryDéclarer des blocs externes.
websource_builder_attach_positionstring $position, callable $echo, array $placementBrancher une position sur un hook supplémentaire (add_action('mon_hook', $echo)).

Le thème Websource expose aussi websource_theme_product_layout : la disposition enregistrée ici y est injectée (Product\ProductLayouts::forTheme()).

Export / import

GET /export, bouton Exporter les compositions, ou ThemePackage\Package::export() :

{
  "format": "websource-builder",
  "version": 1,
  "generator": "websource-builder/1.0.0 (wordpress)",
  "sections": {
    "builder": [
      {"key": "wsb-bandeau", "title": "Bandeau de promotion", "status": "publish", "lang": "",
       "placements": [{"page": "all", "position": "top", "hook": "", "priority": 10, "native": ""}],
       "content": "<!-- wp:websource/announcement {\"link\":\"{link:shop}\",\"appearance\":{\"bg\":\"brand\",\"pad\":\"s\",\"width\":\"wide\",\"align\":\"center\"}} /-->",
       "pending": ""}
    ],
    "builder_library": [{"key": "…", "title": "…", "content": "…"}],
    "product_layout": null
  }
}
  • key : clé stable de la composition (slug), utilisée pour la fusion. Un emplacement ciblant un contenu porte object_ref (slug) à la place de object_id ; les adresses du site dans les contenus sont réécrites à l'import. Les références introuvables sont listées dans missing et remplacées par l'accueil.
  • builder_library : sections réutilisables (wp_block) contenant des blocs Websource ; product_layout : disposition de la fiche produit (null si jamais enregistrée).
  • Package::import(array $package, string $mode = 'merge', bool $dryRun = false) renvoie dry_run, mode, created, updated, trashed, library, product_layout, missing, errors. Un paquet d'un format différent ou d'une version supérieure est refusé.
  • Le paquet complet du thème (Websource Theme Config) inclut les sections builder, builder_library et product_layout via websource_theme_export / websource_theme_import.

Variables CSS

Les feuilles de style lisent les variables du thème Websource avec repli :

Variable lueRepliUsage
--color-brand-600, --color-brand-50, --color-brand-on (alias --wst-brand…)couleur de lien du thème ou #0f766e, #eef7f6, #ffffffBoutons, fonds brand, soft, icônes.
--color-ink, --wst-muted#14282b, encre à 65 %Textes.
--color-line, --color-surface, --color-page#d9e6e4, #ffffffBordures, cartes, fond surface.
--radius-xl, --radius-2xl (--wst-radius)1rem, 1.5remBoutons, cartes.
--wst-card-shadownoneOmbre des cartes.
--font-sans, --font-headpile systèmePolices.
--container-page80remLargeur container / wide.

Variables posées par l'extension sur .wsb-block quand une valeur est fixée (apparence, layout ou style avancé) : --wsb-brand, --wsb-brand-soft, --wsb-ink, --wsb-line, --wsb-surface, --wsb-text, --wsb-overlay, --wsb-btn-bg, --wsb-btn-fg, --wsb-btn-hover, --wsb-card-bg, --wsb-r, --wsb-r2 (arrondis), --wsb-shadow, --wsb-font, --wsb-weight, --wsb-k (facteur de taille).

Données structurées

Seo\JsonLd imprime dans wp_footer : FAQPage (toutes les questions des blocs FAQ de la page, fusionnées en un seul nœud), VideoObject (bloc Vidéo avec titre, description, date, miniature), ItemList + Product / Offer (bloc Produits). Rien n'est imprimé dans l'éditeur ni sur une page sans ces blocs.

Multilingue

  • Composition : méta _wsb_lang (vide = toutes les langues) comparée à pll_current_language / wpml_current_language, sinon à la locale.
  • wpml-config.xml : type wsb_composition traduisible, métas copiées ou ignorées, champs texte des blocs déclarés pour l'éditeur de traduction avancé.
  • Jetons {link:…} : identifiants traduits par pll_get_post / wpml_object_id.

Désinstallation

uninstall.php supprime les compositions (wsb_composition, corbeille comprise, avec leurs métas) et les options wsb_placement_index, wsb_product_layout, wsb_contact_page. Les blocs présents dans les pages restent du contenu Gutenberg ordinaire (affichés comme des blocs inconnus, texte conservé).