2024-08-22
This commit is contained in:
parent
d9e6ad1667
commit
5045ef25dc
598 changed files with 6310 additions and 5620 deletions
|
|
@ -583,28 +583,28 @@ ul.avec-puce-cercle a {
|
|||
.informations-produit__conteneur > section + section {
|
||||
border-top: 1px solid var(--couleur-noir);
|
||||
}
|
||||
.informations-produit .details-produit {
|
||||
.informations-produit .onglets-details-produit {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
grid-template-rows: 1fr min-content;
|
||||
padding: initial;
|
||||
}
|
||||
.informations-produit .details-produit > section {
|
||||
.informations-produit .onglets-details-produit > section {
|
||||
grid-column: span 3;
|
||||
padding: 1rem;
|
||||
font-weight: 350;
|
||||
}
|
||||
.informations-produit .details-produit > section[hidden] {
|
||||
.informations-produit .onglets-details-produit > section[hidden] {
|
||||
display: none;
|
||||
}
|
||||
.informations-produit .details-produit > section ul {
|
||||
.informations-produit .onglets-details-produit > section ul {
|
||||
list-style: disc;
|
||||
list-style-position: inside;
|
||||
}
|
||||
.informations-produit .details-produit > section > * + * {
|
||||
.informations-produit .onglets-details-produit > section > * + * {
|
||||
margin-top: 1lh;
|
||||
}
|
||||
.informations-produit .details-produit > ul {
|
||||
.informations-produit .onglets-details-produit > ul {
|
||||
display: grid;
|
||||
grid-column: span 3;
|
||||
grid-row: 2;
|
||||
|
|
@ -613,10 +613,10 @@ ul.avec-puce-cercle a {
|
|||
text-transform: lowercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.informations-produit .details-produit > ul li {
|
||||
.informations-produit .onglets-details-produit > ul li {
|
||||
width: 100%;
|
||||
}
|
||||
.informations-produit .details-produit > ul li a {
|
||||
.informations-produit .onglets-details-produit > ul li a {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -625,13 +625,13 @@ ul.avec-puce-cercle a {
|
|||
border-right: 1px solid var(--couleur-noir);
|
||||
border-left: 1px solid var(--couleur-noir);
|
||||
}
|
||||
.informations-produit .details-produit > ul li a:first-of-type {
|
||||
.informations-produit .onglets-details-produit > ul li a:first-of-type {
|
||||
border-left: initial;
|
||||
}
|
||||
.informations-produit .details-produit > ul li a:last-of-type {
|
||||
.informations-produit .onglets-details-produit > ul li a:last-of-type {
|
||||
border-left: initial;
|
||||
}
|
||||
.informations-produit .details-produit > ul li a[aria-selected=true] {
|
||||
.informations-produit .onglets-details-produit > ul li a[aria-selected=true] {
|
||||
border-top-color: transparent;
|
||||
}
|
||||
.informations-produit .selecteur-produit {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -9,6 +9,9 @@
|
|||
"file": "scripts-page-produit.js",
|
||||
"name": "scripts-page-produit",
|
||||
"src": "web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts",
|
||||
"isEntry": true
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
// # sourceMappingURL=dom.js.map
|
||||
const l=t=>r=>{const e=Array.from(t.querySelectorAll(r));if(!e||e.length===0)throw new Error(`La requête "${r}" n'a débouché sur aucun Élément.`);return e};export{l as s};
|
||||
//# sourceMappingURL=dom.js.map
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"dom.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
{"version":3,"file":"dom.js","sources":["../../src/scripts/lib/dom.ts"],"sourcesContent":["export const safeQuerySelector = (parent: Document | Element) => (query: string) => {\n const element: Element | null = parent.querySelector(query);\n if (!element) throw new Error(`La requête \"${query}\" n'a débouché sur aucun Élément.`);\n return element;\n};\n\nexport const safeQuerySelectorAll = (parent: Document | Element) => (query: string) => {\n const elements: Element[] = Array.from(parent.querySelectorAll(query));\n if (!elements || elements.length === 0) throw new Error(`La requête \"${query}\" n'a débouché sur aucun Élément.`);\n return elements;\n};\n\nexport const estDansLaVue = (element: Element) => {\n const rect: DOMRect = element.getBoundingClientRect();\n\n return (\n rect.top >= 0\n && rect.left >= 0\n && rect.top <= (window.innerHeight || document.documentElement.clientHeight)\n && rect.right <= (window.innerWidth || document.documentElement.clientWidth)\n );\n};\n"],"names":["safeQuerySelectorAll","parent","query","elements"],"mappings":"AAMO,MAAMA,EAAwBC,GAAgCC,GAAkB,CACrF,MAAMC,EAAsB,MAAM,KAAKF,EAAO,iBAAiBC,CAAK,CAAC,EACjE,GAAA,CAACC,GAAYA,EAAS,SAAW,QAAS,IAAI,MAAM,eAAeD,CAAK,mCAAmC,EACxG,OAAAC,CACT"}
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
document.addEventListener("DOMContentLoaded",()=>{});
|
||||
|
||||
//# sourceMappingURL=scripts-page-produit.js.map
|
||||
import{s as a}from"./dom.js";const c=o=>{o.forEach(t=>{t[0].setAttribute("aria-selected","false"),t[1].setAttribute("hidden","true")})},d=()=>{const o=a(document)("a[role='tab']"),t=a(document)("section[role='tabpanel']"),r=new Map;o.forEach((e,s)=>{const n=e.getAttribute("id"),i=t[s];if(!n)throw new Error("Le lien ne dispose pas d'ID !");if(!i)throw new Error("Le lien ne dispose pas de section correspondante !");r.set(n,[e,i])}),Array.from(r.values()).forEach(e=>{e[0].addEventListener("click",s=>{s.preventDefault();const n=e[0].getAttribute("aria-selected")==="true";c(Array.from(r.values())),!n&&(e[0].setAttribute("aria-selected","true"),e[1].removeAttribute("hidden"))})}),console.debug(r)};document.addEventListener("DOMContentLoaded",()=>{d()});
|
||||
//# sourceMappingURL=scripts-page-produit.js.map
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["../../src/scripts/scripts-page-produit.ts"],"names":[],"mappings":"AA8BA,SAAS,gBAAgB,CAAC,mBAAoB,KAE9C","file":"scripts-page-produit.js","sourcesContent":["// Scripts pour la Page Produit\n\nconst CLASSE_POSITION_FIXE: string = \"position-fixe\";\nconst CLASSE_INFORMATIONS_PRODUIT = \"informations-produit\";\nconst CLASSE_PRODUITS_SIMILAIRES = \"produits-similaires\";\n\n/* Fonctions utilitaires */\n\n// const creeObservateurIntersection = (element: Element, options: IntersectionObserverInit, classe = \"anime\") => {\n// const observateur = new IntersectionObserver(entrees => {\n// for (const entree of entrees) {\n// const cible = entree.target;\n\n// /* Enclenchement de l'animation */\n// if (entree.isIntersecting || estDansLaVue(cible)) {\n// cible.classList.add(classe);\n// return;\n// }\n\n// /* Empêche que le cycle ne se répète */\n// if (cible.classList.contains(classe)) {\n// observateur.unobserve(cible);\n// }\n// }\n// }, options || {});\n\n// observateur.observe(element);\n// return observateur;\n// };\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n // gereBoiteInformationsProduit();\n});\n"]}
|
||||
{"version":3,"file":"scripts-page-produit.js","sources":["../../src/scripts/scripts-page-produit.ts"],"sourcesContent":["// Scripts pour la Page Produit\n\nimport { safeQuerySelectorAll } from \"./lib/dom.js\";\n\ntype EnsembleLienContenu = [Element, Element];\n\nconst fermeToutesSections = (ensembleLiensContenus: EnsembleLienContenu[]) => {\n ensembleLiensContenus.forEach((ensemble) => {\n ensemble[0].setAttribute(\"aria-selected\", \"false\");\n ensemble[1].setAttribute(\"hidden\", \"true\");\n });\n};\n\nconst gereBoiteInformationsProduit = () => {\n const liensOnglets: Element[] = safeQuerySelectorAll(document)(\"a[role='tab']\");\n const sectionsContenus: Element[] = safeQuerySelectorAll(document)(\"section[role='tabpanel']\");\n const onglets = new Map<string, EnsembleLienContenu>();\n\n /* Créé la Map avec les ensembles Lien-Contenu */\n liensOnglets.forEach((lien, index) => {\n const idOnglet: string | null = lien.getAttribute(\"id\");\n const sectionCorrespondante: Element | undefined = sectionsContenus[index];\n\n if (!idOnglet) throw new Error(\"Le lien ne dispose pas d'ID !\");\n if (!sectionCorrespondante) throw new Error(\"Le lien ne dispose pas de section correspondante !\");\n\n onglets.set(idOnglet, [lien, sectionCorrespondante]);\n });\n\n // TODO: Déplacer dans la première itération ?\n Array.from(onglets.values()).forEach((v) => {\n /* Ajout d'un Écouteur d'Événement sur le lien */\n v[0].addEventListener(\"click\", (e) => {\n /* Empêche la pollution de l'historique de navigation */\n e.preventDefault();\n\n /* Sauvegarde l'état d'ouverture de la section avant de toutes les fermer */\n const estAncienOngletCourant: boolean = v[0].getAttribute(\"aria-selected\") === \"true\";\n fermeToutesSections(Array.from(onglets.values()));\n\n /* Ne fais rien de plus si l'onglet sélectionné était le courant */\n if (estAncienOngletCourant) return;\n\n /* Ouvre le nouvel onglet sélectionné */\n v[0].setAttribute(\"aria-selected\", \"true\");\n v[1].removeAttribute(\"hidden\");\n });\n });\n\n console.debug(onglets);\n};\n\n/* Fonctions utilitaires */\n\n// const creeObservateurIntersection = (element: Element, options: IntersectionObserverInit, classe = \"anime\") => {\n// const observateur = new IntersectionObserver(entrees => {\n// for (const entree of entrees) {\n// const cible = entree.target;\n\n// /* Enclenchement de l'animation */\n// if (entree.isIntersecting || estDansLaVue(cible)) {\n// cible.classList.add(classe);\n// return;\n// }\n\n// /* Empêche que le cycle ne se répète */\n// if (cible.classList.contains(classe)) {\n// observateur.unobserve(cible);\n// }\n// }\n// }, options || {});\n\n// observateur.observe(element);\n// return observateur;\n// };\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n gereBoiteInformationsProduit();\n});\n"],"names":["safeQuerySelectorAll","fermeToutesSections","ensembleLiensContenus","ensemble","gereBoiteInformationsProduit","liensOnglets","sectionsContenus","onglets","lien","index","idOnglet","sectionCorrespondante","v","e","estAncienOngletCourant"],"mappings":"AAMA,OAAA,KAAAA,MAAA,WAAA,MAAMC,EAAuBC,GAAiD,CACtDA,EAAA,QAASC,GAAa,CAC1CA,EAAS,CAAC,EAAE,aAAa,gBAAiB,OAAO,EACjDA,EAAS,CAAC,EAAE,aAAa,SAAU,MAAM,CAAA,CAC1C,CACH,EAEMC,EAA+B,IAAM,CACzC,MAAMC,EAA0BL,EAAqB,QAAQ,EAAE,eAAe,EACxEM,EAA8BN,EAAqB,QAAQ,EAAE,0BAA0B,EACvFO,MAAc,IAGPF,EAAA,QAAQ,CAACG,EAAMC,IAAU,CAC9B,MAAAC,EAA0BF,EAAK,aAAa,IAAI,EAChDG,EAA6CL,EAAiBG,CAAK,EAEzE,GAAI,CAACC,EAAgB,MAAA,IAAI,MAAM,+BAA+B,EAC9D,GAAI,CAACC,EAA6B,MAAA,IAAI,MAAM,oDAAoD,EAEhGJ,EAAQ,IAAIG,EAAU,CAACF,EAAMG,CAAqB,CAAC,CAAA,CACpD,EAGD,MAAM,KAAKJ,EAAQ,OAAQ,CAAA,EAAE,QAASK,GAAM,CAE1CA,EAAE,CAAC,EAAE,iBAAiB,QAAUC,GAAM,CAEpCA,EAAE,eAAe,EAGjB,MAAMC,EAAkCF,EAAE,CAAC,EAAE,aAAa,eAAe,IAAM,OAC/EX,EAAoB,MAAM,KAAKM,EAAQ,OAAA,CAAQ,CAAC,EAG5C,CAAAO,IAGJF,EAAE,CAAC,EAAE,aAAa,gBAAiB,MAAM,EACvCA,EAAA,CAAC,EAAE,gBAAgB,QAAQ,EAAA,CAC9B,CAAA,CACF,EAED,QAAQ,MAAML,CAAO,CACvB,EA0BA,SAAS,iBAAiB,mBAAoB,IAAM,CACrBH,GAC/B,CAAC"}
|
||||
34
web/app/themes/haiku-atelier-2024/assets/vendor/controle-personnalise-tinymce.js
vendored
Normal file
34
web/app/themes/haiku-atelier-2024/assets/vendor/controle-personnalise-tinymce.js
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
jQuery(document).ready(function($) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* TinyMCE Custom Control
|
||||
*
|
||||
* @author Anthony Hortin <http://maddisondesigns.com>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.html
|
||||
* @link https://github.com/maddisondesigns
|
||||
*/
|
||||
|
||||
$(".customize-control-tinymce-editor").each(function() {
|
||||
// Get the toolbar strings that were passed from the PHP Class
|
||||
var tinyMCEToolbar1String = _wpCustomizeSettings.controls[$(this).attr("id")].skyrockettinymcetoolbar1;
|
||||
var tinyMCEToolbar2String = _wpCustomizeSettings.controls[$(this).attr("id")].skyrockettinymcetoolbar2;
|
||||
var tinyMCEMediaButtons = _wpCustomizeSettings.controls[$(this).attr("id")].skyrocketmediabuttons;
|
||||
|
||||
wp.editor.initialize($(this).attr("id"), {
|
||||
tinymce: {
|
||||
wpautop: true,
|
||||
toolbar1: tinyMCEToolbar1String,
|
||||
toolbar2: tinyMCEToolbar2String,
|
||||
},
|
||||
quicktags: true,
|
||||
mediaButtons: tinyMCEMediaButtons,
|
||||
});
|
||||
});
|
||||
$(document).on("tinymce-editor-init", function(event, editor) {
|
||||
editor.on("change", function(e) {
|
||||
tinyMCE.triggerSave();
|
||||
$("#" + editor.id).trigger("change");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -8,6 +8,7 @@ use Timber\Timber;
|
|||
|
||||
// Récupère les dépendances Composer
|
||||
require_once __DIR__ . "../../../../../vendor/autoload.php";
|
||||
require_once __DIR__ . "/src/inc/ControlesPersonnalises.php";
|
||||
|
||||
require_once __DIR__ . "/src/StarterSite.php";
|
||||
require_once __DIR__ . "/src/inc/Fonctionnalites.php";
|
||||
|
|
@ -41,7 +42,7 @@ new StarterSite();
|
|||
*/
|
||||
|
||||
// Personnalisation du thème
|
||||
function enregistre_personnalisation_theme($wp_customize) {
|
||||
function enregistre_personnalisations_theme($wp_customize) {
|
||||
// Section « Réseaux sociaux »
|
||||
$wp_customize->add_section("liens_reseaux_sociaux", [
|
||||
"title" => __("Liens des réseaux sociaux"),
|
||||
|
|
@ -80,8 +81,52 @@ function enregistre_personnalisation_theme($wp_customize) {
|
|||
"section" => "liens_reseaux_sociaux",
|
||||
"label" => __("Profil Pinterest"),
|
||||
]);
|
||||
|
||||
// Section « Descriptions Produits »
|
||||
$wp_customize->add_section("descriptions_produits", [
|
||||
"title" => __("Textes des descriptions Produits"),
|
||||
"description" => __("Textes des descriptions apparaissant sur les pages Produit."),
|
||||
]);
|
||||
|
||||
$wp_customize->add_setting("texte_conditions_livraison", [
|
||||
"capability" => "edit_theme_options",
|
||||
"default" => "",
|
||||
"sanitize_callback" => "wp_kses_post",
|
||||
"transport" => "postMessage",
|
||||
"type" => "theme_mod",
|
||||
]);
|
||||
$wp_customize->add_control(
|
||||
new Controle_Personnalise_TinyMCE($wp_customize, "texte_conditions_livraison", [
|
||||
"label" => __("Conditions de livraison"),
|
||||
"description" => __("Descriptif des conditions de livraison."),
|
||||
"section" => "descriptions_produits",
|
||||
"input_attrs" => [
|
||||
"toolbar1" => "bold italic bullist numlist alignleft aligncenter alignright link",
|
||||
"mediaButtons" => true,
|
||||
],
|
||||
]),
|
||||
);
|
||||
|
||||
$wp_customize->add_setting("texte_entretien_produit", [
|
||||
"capability" => "edit_theme_options",
|
||||
"default" => "",
|
||||
"sanitize_callback" => "wp_kses_post",
|
||||
"transport" => "postMessage",
|
||||
"type" => "theme_mod",
|
||||
]);
|
||||
$wp_customize->add_control(
|
||||
new Controle_Personnalise_TinyMCE($wp_customize, "texte_entretien_produit", [
|
||||
"label" => __("Entretien du Produit"),
|
||||
"description" => __("Descriptif des bonnes pratiques pour l'entretien du Produit."),
|
||||
"section" => "descriptions_produits",
|
||||
"input_attrs" => [
|
||||
"toolbar1" => "bold italic bullist numlist alignleft aligncenter alignright link",
|
||||
"mediaButtons" => true,
|
||||
],
|
||||
]),
|
||||
);
|
||||
}
|
||||
add_action("customize_register", "enregistre_personnalisation_theme");
|
||||
add_action("customize_register", "enregistre_personnalisations_theme");
|
||||
|
||||
/**
|
||||
* WooCommerce
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ $produits_collection = array_map(
|
|||
$contexte["produit"] = $produit;
|
||||
$contexte["produits_collection"] = $produits_collection;
|
||||
|
||||
/* echo "<pre>";
|
||||
print_r($produit);
|
||||
echo "</pre>"; */
|
||||
|
||||
/**
|
||||
* Charge les Scripts nécessaires pour la page Produit.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use Timber\Site;
|
|||
|
||||
class StarterSite extends Site {
|
||||
public function __construct() {
|
||||
add_action("after_setup_theme", [$this, "definis_fonctionnalites_theme"]);
|
||||
add_action("after_setup_theme", [$this, "defini_fonctionnalites_theme"]);
|
||||
add_action("after_setup_theme", [$this, "charge_traductions_theme"]);
|
||||
|
||||
add_action("timber/context", [$this, "ajoute_au_contexte_twig"]);
|
||||
|
|
@ -17,11 +17,15 @@ class StarterSite extends Site {
|
|||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int,mixed> $context
|
||||
* @return array<int,mixed>
|
||||
*/
|
||||
public function ajoute_au_contexte_twig(array $context): array {
|
||||
$context["site"] = $this;
|
||||
$personnalisations_theme = get_theme_mods();
|
||||
|
||||
// Récupère les liens des réseaux sociaux définis dans la personnalisation du thème
|
||||
$personnalisations_theme = get_theme_mods();
|
||||
$liens_reseaux_sociaux = [];
|
||||
$liens_reseaux_sociaux["facebook"] = [
|
||||
"nom" => "Facebook",
|
||||
|
|
@ -37,6 +41,13 @@ class StarterSite extends Site {
|
|||
];
|
||||
$context["liens_reseaux_sociaux"] = $liens_reseaux_sociaux;
|
||||
|
||||
// Récupère les textes apparaissant sur les pages Produits
|
||||
$descriptions_produits = [
|
||||
"texte_conditions_livraison" => wpautop($personnalisations_theme["texte_conditions_livraison"]) ?? "",
|
||||
"texte_entretien_produit" => wpautop($personnalisations_theme["texte_entretien_produit"]) ?? "",
|
||||
];
|
||||
$context["descriptions_produits"] = $descriptions_produits;
|
||||
|
||||
// Logo personnalisée
|
||||
$logo_personnalisee_id = get_theme_mod("custom_logo");
|
||||
$logo_personnalisee = wp_get_attachment_image_src($logo_personnalisee_id, "full");
|
||||
|
|
@ -95,7 +106,7 @@ class StarterSite extends Site {
|
|||
return $context;
|
||||
}
|
||||
|
||||
public function definis_fonctionnalites_theme(): void {
|
||||
public function defini_fonctionnalites_theme(): void {
|
||||
// Laisse WordPress gérer le titre de la page
|
||||
add_theme_support("title-tag");
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
/**
|
||||
* Enregistre et rend disponible des types de contrôles personnalisés.
|
||||
*
|
||||
* Pour l'instant, il s'agit d'un éditeur TinyMCE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
function enregistre_controle_personnalise_tinymce(): void {
|
||||
/**
|
||||
* TinyMCE Custom Control
|
||||
*
|
||||
* @author Anthony Hortin <http://maddisondesigns.com>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.html
|
||||
* @link https://github.com/maddisondesigns
|
||||
*/
|
||||
class Controle_Personnalise_TinyMCE extends WP_Customize_Control {
|
||||
/**
|
||||
* The type of control being rendered
|
||||
*/
|
||||
public $type = "editeur_tinymce";
|
||||
|
||||
/**
|
||||
* Enqueue our scripts and styles
|
||||
*/
|
||||
public function enqueue(): void {
|
||||
wp_enqueue_script(
|
||||
handle: "controle-personnalise-tinymce",
|
||||
src: get_template_directory_uri() . "/assets/vendor/controle-personnalise-tinymce.js",
|
||||
deps: ["jquery"],
|
||||
ver: "1.3",
|
||||
args: true,
|
||||
);
|
||||
wp_enqueue_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass our TinyMCE toolbar string to JavaScript
|
||||
*/
|
||||
public function to_json(): void {
|
||||
parent::to_json();
|
||||
|
||||
$this->json["skyrockettinymcetoolbar1"] = isset($this->input_attrs["toolbar1"])
|
||||
? esc_attr($this->input_attrs["toolbar1"])
|
||||
: "bold italic bullist numlist alignleft aligncenter alignright link";
|
||||
|
||||
$this->json["skyrockettinymcetoolbar2"] = isset($this->input_attrs["toolbar2"])
|
||||
? esc_attr($this->input_attrs["toolbar2"])
|
||||
: "";
|
||||
$this->json["skyrocketmediabuttons"] =
|
||||
isset($this->input_attrs["mediaButtons"]) && $this->input_attrs["mediaButtons"] === true ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the control in the customizer
|
||||
*/
|
||||
public function render_content() {
|
||||
?>
|
||||
<div class="tinymce-control">
|
||||
<span class="customize-control-title"><?php echo esc_html($this->label); ?></span>
|
||||
<?php if (!empty($this->description)) { ?>
|
||||
<span class="customize-control-description"><?php echo esc_html($this->description); ?></span>
|
||||
<?php } ?>
|
||||
<textarea id="<?php echo esc_attr(
|
||||
$this->id,
|
||||
); ?>" class="customize-control-tinymce-editor" <?php $this->link(); ?>><?php echo esc_html(
|
||||
$this->value(),
|
||||
); ?></textarea>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action("customize_register", "enregistre_controle_personnalise_tinymce");
|
||||
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
/* Page Shop */
|
||||
|
||||
/**
|
||||
* Récupère les informations utilisées pour la grille des Produits et les retourne sous forme de
|
||||
* tableau associatif.
|
||||
* Récupère les informations utilisées pour la grille des Produits et les retourne sous forme
|
||||
* de tableau associatif.
|
||||
*/
|
||||
function recupere_informations_produit_shop($produit) {
|
||||
return [
|
||||
|
|
@ -36,6 +38,8 @@ function recupere_informations_produit_shop($produit) {
|
|||
];
|
||||
}
|
||||
|
||||
/* Page Produit */
|
||||
|
||||
/**
|
||||
* Retourne un tableau associatif des informations affichées sur la page Produit depuis les
|
||||
* données brutes d'un Produit.
|
||||
|
|
@ -45,9 +49,15 @@ function recupere_informations_produit_shop($produit) {
|
|||
*/
|
||||
function recupere_informations_produit_page_produit($donnees_produit): mixed {
|
||||
return [
|
||||
/* Slug de la Collection */
|
||||
"collection" => get_the_terms($donnees_produit->get_id(), "collection")[0]->slug,
|
||||
/* Détails (Description) du Produit */
|
||||
"details" => wpautop($donnees_produit->get_description()),
|
||||
/* Identifiant du Produit */
|
||||
"id" => $donnees_produit->get_id(),
|
||||
/* Nom affiché du Produit */
|
||||
"nom" => $donnees_produit->get_name(),
|
||||
/* Prix affiché du Produit */
|
||||
"prix" => $donnees_produit->get_price(),
|
||||
"photos_colonne_gauche" => array_map(
|
||||
$callback = "genere_balise_img",
|
||||
|
|
@ -69,7 +79,9 @@ function recupere_informations_produit_page_produit($donnees_produit): mixed {
|
|||
false,
|
||||
["loading" => false],
|
||||
),
|
||||
/* Slug du Produit */
|
||||
"slug" => $donnees_produit->get_slug(),
|
||||
/* URL du Produit */
|
||||
"url" => $donnees_produit->get_permalink(),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.details-produit {
|
||||
.onglets-details-produit {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
grid-template-rows: 1fr min-content;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ export const safeQuerySelector = (parent: Document | Element) => (query: string)
|
|||
return element;
|
||||
};
|
||||
|
||||
export const safeQuerySelectorAll = (parent: Document | Element) => (query: string) => {
|
||||
const elements: Element[] = Array.from(parent.querySelectorAll(query));
|
||||
if (!elements || elements.length === 0) throw new Error(`La requête "${query}" n'a débouché sur aucun Élément.`);
|
||||
return elements;
|
||||
};
|
||||
|
||||
export const estDansLaVue = (element: Element) => {
|
||||
const rect: DOMRect = element.getBoundingClientRect();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,54 @@
|
|||
// Scripts pour la Page Produit
|
||||
|
||||
const CLASSE_POSITION_FIXE: string = "position-fixe";
|
||||
const CLASSE_INFORMATIONS_PRODUIT = "informations-produit";
|
||||
const CLASSE_PRODUITS_SIMILAIRES = "produits-similaires";
|
||||
import { safeQuerySelectorAll } from "./lib/dom.js";
|
||||
|
||||
type EnsembleLienContenu = [Element, Element];
|
||||
|
||||
const fermeToutesSections = (ensembleLiensContenus: EnsembleLienContenu[]) => {
|
||||
ensembleLiensContenus.forEach((ensemble) => {
|
||||
ensemble[0].setAttribute("aria-selected", "false");
|
||||
ensemble[1].setAttribute("hidden", "true");
|
||||
});
|
||||
};
|
||||
|
||||
const gereBoiteInformationsProduit = () => {
|
||||
const liensOnglets: Element[] = safeQuerySelectorAll(document)("a[role='tab']");
|
||||
const sectionsContenus: Element[] = safeQuerySelectorAll(document)("section[role='tabpanel']");
|
||||
const onglets = new Map<string, EnsembleLienContenu>();
|
||||
|
||||
/* Créé la Map avec les ensembles Lien-Contenu */
|
||||
liensOnglets.forEach((lien, index) => {
|
||||
const idOnglet: string | null = lien.getAttribute("id");
|
||||
const sectionCorrespondante: Element | undefined = sectionsContenus[index];
|
||||
|
||||
if (!idOnglet) throw new Error("Le lien ne dispose pas d'ID !");
|
||||
if (!sectionCorrespondante) throw new Error("Le lien ne dispose pas de section correspondante !");
|
||||
|
||||
onglets.set(idOnglet, [lien, sectionCorrespondante]);
|
||||
});
|
||||
|
||||
// TODO: Déplacer dans la première itération ?
|
||||
Array.from(onglets.values()).forEach((v) => {
|
||||
/* Ajout d'un Écouteur d'Événement sur le lien */
|
||||
v[0].addEventListener("click", (e) => {
|
||||
/* Empêche la pollution de l'historique de navigation */
|
||||
e.preventDefault();
|
||||
|
||||
/* Sauvegarde l'état d'ouverture de la section avant de toutes les fermer */
|
||||
const estAncienOngletCourant: boolean = v[0].getAttribute("aria-selected") === "true";
|
||||
fermeToutesSections(Array.from(onglets.values()));
|
||||
|
||||
/* Ne fais rien de plus si l'onglet sélectionné était le courant */
|
||||
if (estAncienOngletCourant) return;
|
||||
|
||||
/* Ouvre le nouvel onglet sélectionné */
|
||||
v[0].setAttribute("aria-selected", "true");
|
||||
v[1].removeAttribute("hidden");
|
||||
});
|
||||
});
|
||||
|
||||
console.debug(onglets);
|
||||
};
|
||||
|
||||
/* Fonctions utilitaires */
|
||||
|
||||
|
|
@ -29,5 +75,5 @@ const CLASSE_PRODUITS_SIMILAIRES = "produits-similaires";
|
|||
// };
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// gereBoiteInformationsProduit();
|
||||
gereBoiteInformationsProduit();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,53 +2,32 @@
|
|||
|
||||
<aside aria-label="Product's details, size and quantity selection" class="informations-produit">
|
||||
<div class="informations-produit__conteneur">
|
||||
<section class="details-produit">
|
||||
<section role="tabpanel" id="section1" aria-labelledby="tab1" hidden>
|
||||
<p>A statement piece quite playful with 3 rings moving along.</p>
|
||||
<ul>
|
||||
<li>band height 8mm</li>
|
||||
<li>ringos from 5 to 1 mm diameter</li>
|
||||
<li>handmade in Belgium</li>
|
||||
</ul>
|
||||
|
||||
<p>Find some to choose your ring size here.</p>
|
||||
<section class="onglets-details-produit">
|
||||
{# Contenus #}
|
||||
<section role="tabpanel" id="details-produit" aria-labelledby="label-details-produit" hidden>
|
||||
{{ produit.details }}
|
||||
</section>
|
||||
|
||||
<section role="tabpanel" id="section2" aria-labelledby="tab2" hidden>
|
||||
<p>
|
||||
Products can be shipped up to two weeks after the order has been placed, depending on stock. However, we
|
||||
strive to prepare your order for the quickest delivery possible.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Belgium and France: free shipping.</li>
|
||||
<li>Worldwide: free shipping on orders above 150€.</li>
|
||||
</ul>
|
||||
|
||||
<p>For return inquiries, please contact us within 14 days after the item's reception.</p>
|
||||
<section role="tabpanel" id="conditions-livraison" aria-labelledby="label-conditions-livraison" hidden>
|
||||
{{ descriptions_produits.texte_conditions_livraison }}
|
||||
</section>
|
||||
|
||||
<section role="tabpanel" id="section3" aria-labelledby="tab3" hidden>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Totam id a iusto voluptatem rem dolores hic incidunt
|
||||
provident illo unde accusamus, itaque ipsa optio pariatur ullam qui porro mollitia vel?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Totam id a iusto voluptatem rem dolores hic incidunt
|
||||
provident illo unde accusamus, itaque ipsa optio pariatur ullam qui porro mollitia vel?
|
||||
</p>
|
||||
<section role="tabpanel" id="entretien-produit" aria-labelledby="label-entretien-produit" hidden>
|
||||
{{ descriptions_produits.texte_entretien_produit }}
|
||||
</section>
|
||||
|
||||
{# Onglets #}
|
||||
<ul role="tablist">
|
||||
<li role="presentation">
|
||||
<a role="tab" href="#section1" id="tab1" aria-selected="false">Details</a>
|
||||
<a role="tab" href="#details-produit" id="label-details-produit" aria-selected="false">Details</a>
|
||||
</li>
|
||||
|
||||
<li role="presentation">
|
||||
<a role="tab" href="#section2" id="tab2" aria-selected="false">Shipping</a>
|
||||
<a role="tab" href="#conditions-livraison" id="label-conditions-livraison" aria-selected="false">Shipping</a>
|
||||
</li>
|
||||
|
||||
<li role="presentation">
|
||||
<a role="tab" href="#section3" id="tab3" aria-selected="false">Care</a>
|
||||
<a role="tab" href="#entretien-produit" id="label-entretien-produit" aria-selected="false">Care</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
|
@ -67,7 +46,7 @@
|
|||
id="selecteur-variation"
|
||||
name="variations"
|
||||
>
|
||||
<option value="" disabled selected>--</option>
|
||||
<option disabled selected value="">--</option>
|
||||
<option value="50">50</option>
|
||||
<option value="52">52</option>
|
||||
<option value="54">54</option>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue