{"id":21533137,"url":"https://github.com/jorisbertier/wordpress_extension","last_synced_at":"2026-05-17T17:40:47.366Z","repository":{"id":192232363,"uuid":"676959137","full_name":"jorisbertier/wordpress_extension","owner":"jorisbertier","description":null,"archived":false,"fork":false,"pushed_at":"2023-09-02T12:39:27.000Z","size":25637,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-17T19:46:59.927Z","etag":null,"topics":["php","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jorisbertier.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-10T12:09:19.000Z","updated_at":"2023-09-13T18:35:25.000Z","dependencies_parsed_at":"2023-09-03T15:42:26.092Z","dependency_job_id":null,"html_url":"https://github.com/jorisbertier/wordpress_extension","commit_stats":null,"previous_names":["jorisbertier/wordpress_extension"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jorisbertier/wordpress_extension","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisbertier%2Fwordpress_extension","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisbertier%2Fwordpress_extension/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisbertier%2Fwordpress_extension/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisbertier%2Fwordpress_extension/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jorisbertier","download_url":"https://codeload.github.com/jorisbertier/wordpress_extension/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorisbertier%2Fwordpress_extension/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267093915,"owners_count":24034957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","wordpress"],"created_at":"2024-11-24T02:23:55.468Z","updated_at":"2026-05-17T17:40:37.351Z","avatar_url":"https://github.com/jorisbertier.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wordpress\n\n## Mise en place du Virtual host\nQuand on utilise un serveur Apache (fourni avec Wamp / Xampp), il faut \nnormalement accéder à nos projets en passant par le localhost.\n\nAinsi, pour accéder au projet \"exemple\", il faut se rendre sur l'url :\n\u003e\u003e http://localhost/exemple\n\nPas toujours très pratique...\nL'idée du Virtual Host et de nous permettre d'accéder à notre projet \"exemple\" en se rendant simplement\nsur une url factice comme :\n\u003e\u003e http://exemple.local\n \nBeaucoup plus parlant et pratique si on a beaucoup de projets qui tournent sur notre serveur !\n\nPour arriver à cela, il faut éditer 2 fichiers\n1- Le fichier \"hosts\"\n- Sous Windows: C:\\Windows\\System32\\drivers\\etc\\hosts\n- Sous Linux: /etc/host\n\nA l'intérieur, vous trouverez normalement déjà quelques lignes.\n````\n127.0.0.1 localhost\n````\nCela signifie que l'on créé un \"alias\".\n127.0.0.1 est une IP \"placeholder\" qui pointe sur... votre propre machine.\nOn détermine ici que \"localhost\", c'est la même chose que 127.0.0.1.\n\nSi notre projet s'appelle \"exemple\", nous rajouterons ces lignes:\n````\n127.0.0.1 exemple.local\n````\nA présent, l'adresse exemple.local pointera également sur notre propre machine.\n\n2- httpd-vhosts.conf\n- Avec Wamp:\n\u003e\u003e C:\\wamp64\\bin\\apache\\apache\u003cvotre-version\u003e\\conf\\extra\\httpd-vhosts.conf\n- Avec Xampp:\n\u003e\u003e C:\\xampp\\apache\\conf\\extra\\httpd-vhosts.conf\n\nVous devriez déjà avoir quelque chose qui ressemble à ça:\n````\n# Virtual Hosts\n# Version WAMP\n\u003cVirtualHost *:80\u003e\n  ServerName localhost\n  ServerAlias localhost\n  DocumentRoot \"${INSTALL_DIR}/www\"\n  \u003cDirectory \"${INSTALL_DIR}/www/\"\u003e\n    Options +Indexes +Includes +FollowSymLinks +MultiViews\n    AllowOverride All\n    Require local\n  \u003c/Directory\u003e\n\u003c/VirtualHost\u003e\n\n# Version XAMPP\n\u003cVirtualHost *:80\u003e\n  ServerName localhost\n  ServerAlias localhost\n  DocumentRoot \"${INSTALL_DIR}/htdocs\"\n  \u003cDirectory \"${INSTALL_DIR}/htdocs/\"\u003e\n    Options +Indexes +Includes +FollowSymLinks +MultiViews\n    AllowOverride All\n    Require local\n  \u003c/Directory\u003e\n\u003c/VirtualHost\u003e\n````\nPour un projet qui s'appelle \"exemple\", ajoutez simplement ceci :\n````\n\u003cVirtualHost *:80\u003e\n  ServerName exemple.local\n  DocumentRoot \"${INSTALL_DIR}/www/exemple\" \u003c-- pour WAMP\n  DocumentRoot \"${INSTALL_DIR}/htdocs/exemple\" \u003c-- pour XAMPP\n\u003c/VirtualHost\u003e\n````\n\nTraduction: si une requête est faites sur localhost sur le port 80 (HTTP) et que\ncette requête contient \"exemple.local\", alors nous devons servir le contenu du dossier qui se trouve\nà l'emplacement indiqué \"/www/exemple\" (ou /htdocs/exemple sous xampp).\n\nRedémarrez votre WAMP/XAMPP et essayez d'aller sur \"http://exemple.local\" (précisez le http:// pour être sûr que votre navigateur ne vous redirige pas sur https).\n\n## Création de Thème\n\nCréer un nouveau dossier dans /wp-content/themes Puis rajouter:\n\n- index.php\n- style.css\n\nstyle.css devra contenir des méta données sur le thème.\n\n````css\n/*\nTheme Name: Le nom de mon thème\nVersion: 1.0\nRequires PHP: 8.0\nDescription: Votre description de super thème.\nTags: grid, custom-color, custom-background\nAuthor: Moi\nLicence: (GNU GPLv2 ou supérieure)\n */\n````\n\nSeul le nom du thème est obligatoire mais le reste peut être très utile si votre but est de partager ou de\ncommercialiser votre thème.\n\nPour que votre thème apparaisse avec une image dans la liste des thèmes installés dans le back office, vous pouvez\ninclure un fichier image qui devra s'appeler 'screenshot.png' à la racine de votre thème.\n\n### The Loop (la Boucle WP)\n[Documentation Officielle](https://developer.wordpress.org/themes/basics/the-loop/)\n\nLa boucle WP régie tout ou presque.\nElle s'exprime toujours de la manière suivante:\n\n````php\n\u003c?php\nif ( have_posts() ) :\n    while ( have_posts() ) : the_post();\n        // Display post content\n    endwhile;\nendif;\n?\u003e\n\n\u003c!-- Version courte (à éviter si vous n'êtes pas à l'aise avec ce format) --\u003e\n\u003c?php if (have_posts(): while(have_posts()): the_post(); ?\u003e\n    \u003c?-- Mon code --\u003e\n\u003c?php endwhile; endif; ?\u003e\n````\n\nOn voit que l'on vérifie si nous avons un ou plusieurs Posts (articles) et pour chacun\nd'entres eux, nous déclarons \"the_post()\".\n\nA partir de là, cela nous donne accès à une variable $post globale qui contient\ntout notre post ainsi que plusieurs fonctions qui servent à récupérer plus facilement un ou\n plusieurs informations contenu dans le Post.\n\n````php\n\u003c?php if ( have_posts() ) : ?\u003e\n    \u003c?php while ( have_posts() ) : the_post() ?\u003e\n        \u003ch1\u003e\u003c?php the_title() ?\u003e\u003c/h1\u003e\n        \u003csmall\u003eécrit par \u003c?php the_author() ?\u003e le \u003c?php the_time() ?\u003e\n        \u003cdiv\u003e\u003c?php the_content() ?\u003e\u003c/div\u003e\n        \u003c?php the_post_thumbnail('post-thumbnail', ['class' =\u003e 'apercu', 'alt' =\u003e 'Aperçu de mon article']); ?\u003e\n        \u003ca href=\"\u003c?php the_permalink() ?\u003e\"\u003e\u003c/a\u003e\n    \u003c?php endwhile ?\u003e\n\u003c?php endif ?\u003e;\n````\nRemarquez que nous n'avons que la structure HTML à définir, sutructure dans laquelle \nnous injectons les différentes parties de notre Post (titre, auteur, contenu...).\n\nVoici la liste des choses auquelles nous avons accès:\n\n\u003e\u003e next_post_link() – Lien vers le post suivant (chronologiquement)\n\u003e\u003e previous_post_link() – Lien vers le post précédent\n\u003e\u003e the_category() – La ou les catégories du post\n\u003e\u003e the_author() – L'auteur du post\n\u003e\u003e the_content() – Le contenu du post\n\u003e\u003e the_excerpt() – Un extrait du contenu du post\n\u003e\u003e the_ID() – L'ID du post\n\u003e\u003e the_meta() – Les métadonnées spécifiques à ce post\n\u003e\u003e the_permalink() - Retourne l'URL pour accéder au post\n\u003e\u003e the_shortlink() – Génère une balise a pointant sur le post, on peut passer en param le texte du lien\n\u003e\u003e the_tags() – Le ou les tags (étiquettes)\n\u003e\u003e the_title() – Titre du post\n\u003e\u003e the_time() – Date de publication du post\n\u003e\u003e the_post_thumbnail() - Image de mise en avant du post sous forme de balise \u003cimg/\u003e\n\u003e\u003e the_post_thumbnail_url() - Url de l'image de mise en avant\n\n### Template Hierarchy\n[Schéma de la hiérarchie des pages](https://developer.wordpress.org/files/2014/10/Screenshot-2019-01-23-00.20.04.png)\n\nVous remarquerez que même si l'on peut se déplacer sur le site (page home avec tous les posts, page de détail d'un post etc...) c'est toujours \nindex.php qui est appellé. Et pour cause, c'est notre seul fichier php !\n\nEn réalité, WP appelle automatiquement certains fichiers PHP et exécutent des requêtes SQL selon la route sur laquelle on se trouve.\nPar exemple:\n- route \"/\": \n    PHP: on appelle le fichier \"home.php\" si il existe ou \"index.php\"\n    SQL: on va chercher les X derniers posts\n- route \"/mon-article\"\n    PHP: on appelle le fichier \"single-post.php\", sinon \"single.php\", sinon \"index.php\"\n    SQL: on va chercher uniquement le post qui a le même nom que notre route (ici, \"mon-article\")\n\nJe vous invite à consulter le schéma de la hiérarchie des pages pour plus de détails.\n\n\u003e\u003e index.php - Sera toujours le fallback\n\n\u003e\u003e front-page.php\n\u003e\u003e home.php\nPage d'accueil\n\n\u003e\u003e single.php\nSera appellé quand on veut consulter un post particulier\n \n\u003e\u003e single-{post-type}.php\nPlus précis. Ne s'applique que si nos \"posts\" sont des \"posts\" (et non pas des custom post type)\nExemple : single-post.php\n\nOn peut être TRES (trop ?) précis :\n\u003e\u003e single-{post-type}-{slug}.php\nExemple : single-product-chaussette.php\nNe s'affichera que pour afficher le produit \"chaussette\".\n\narchive.php - Sera appellé quand on veut afficher la liste de tous nos posts\n\u003e\u003e archive-{post-type}.php\nPlus précis. Ne s'applique que si nos \"posts\" sont des \"posts\" (et non pas des custom post type) \nExemple: archive-product.php\nPage qui affiche la liste des posts de type \"products\"\n\n404.php - Page qui s'affichera quand on tombe sur une erreur 404 (pas inexistante)\n\nVous avez aussi les partials templates qui servent à être insérés dans d'autres pages:\nheader.php - Sera appelé par la fonction \"get_header()\"\nfooter.php - Sera appelé par la fonction \"get_footer()\"\n\n### Header et Footer\n\nPour automatiquement inclure le header et le footer de notre site, nous devons procéder comme ceci.\n\nindex.php\n\n````php\n\u003c?php get_header() ?\u003e\n    Mon contenu\n\u003c?php get_footer() ?\u003e\n````\n\nSi je veux personaliser mon header et mon footer je dois créer un fichier header.php et footer.php à la racine de mon\nthème.\n\nheader.php\n\n````php\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\"\u003e\n    \u003cmeta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\"\u003e\n    \u003c?php wp_head() ?\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\u003c!-- On ne referme pas le body ! --\u003e\n````\n\nfooter.php\n\n````php\n    \u003c?php wp_footer() ?\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n````\n\nRemarquez que l'on a inclus dans notre header \"wp_head()\" et dans notre footer \"wp_footer()\".\n\nwp_head permet de récupérérer automatiquement les métadonnées des pages WP (titre de la page, meta tags etc).\nwp_footer permet de faire apparaître le menu admin en haut de la page quand on est connecté.\n\n### La logique\nToute la logique de notre thème se trouvera dans un fichiers functions.php.\nCe fichiers sera chargé en amont du reste et nous permet d'injecter notre logique dans les rouages de Wordpress.\n\n\nActuellement, notre thème n'est pas très puissant et il lui manque des fonctionnalités basiques telles que les images de mises en avant (thumbnail) ou encore les titres de page en onglet.\n\nPour remédier à cela, nous pouvons passer des options.\n````php\nadd_theme_support('title-tag'); // Le titre de la page sera injecté grace à wp_head()\nadd_theme_support('post-thumbnails'); // Nous pouvons maintenant mettre des images thumbnails aux posts\n````\n[Liste des features activables](https://developer.wordpress.org/reference/functions/add_theme_support/)\n\n### Hooks : Actions et Filtres\n\n[Tuto sur l'utilisation des actions WP](https://www.youtube.com/watch?v=wiQMfaKcA9k\u0026list=PLjwdMgw5TTLWF1VV9TFWrsUTvWjtGS7Qt\u0026index=5\u0026ab_channel=Grafikart.fr)\n[Tuto sur l'utilisation des filtres WP](https://www.youtube.com/watch?v=oLP2T9DfnEk\u0026list=PLjwdMgw5TTLWF1VV9TFWrsUTvWjtGS7Qt\u0026index=7\u0026ab_channel=Grafikart.fr)\n\nSi ce n'est pas déjà fait, créez un ficher function.php qui regroupera l'ensemble des fonctions de notre thème. Avec les hooks, le\nbut est de se greffer à un évènement existant et de venir rajouter notre code.\n\n#### Actions\nUne action est un code que l'on exécute à un \"moment précis\" dans le cycle de vie de WP.\nUne action de retourne rien: elle se content de \"faire quelque chose\" (votre fonction) à \"un moment donné\" (défini par le hook indiqué).\n\n\u003e\u003e add_action('le-hook-wp', 'mafonction', priorité)\n\n````php\n\u003c?php\n\nfunction montheme_supports() {\n    add_theme_support('title-tag'); // On indique que notre thème supporte les title tag (nom de page dans l'onglet)\n}\n\nfunction montheme_register_assets() {\n    // Importation des assets CSS et JS\n    \n    // CSS\n    wp_register_style(\n        'bootstrap', // key\n        'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css' // src\n    ) // Permet d'enregister une feuille CSS (pas de l'utiliser)\n    \n    // JS\n    wp_register_script(\n        'bootstrap', // key \n        'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js', // src\n        ['popper'] // Dépendences \n    ) \n    wp_register_script('popper', 'https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js') \n    \n    // wp_deregister('jquery') // Si l'on veut supprimer un script particulier\n    \n    // On ajoute les assets dans notre header\n    wp_enqueue_style('bootstrap');\n    wp_enqueue_script('bootstrap');\n}\n\n// On lance ensuite nos actions qui vont se greffer sur des évents wp\nadd_action('after_setup_theme', 'montheme_supports');\nadd_action('wp_enqueue_scripts', 'montheme_register_assets');\n````\n\n#### Filtres\nLes filtres fonctionnent presque de la même façon.\nLa différence venat du fait qu'un filtre récupère une donnée (qui nous est envoyée par WP) et\nque notre fonction doit retourner quelque chose.\n\nVoyez ça comme un \"tuyau\" que l'on vient rajouter dans la machine WP: on veut qu'une donnée rentre dans\nnotre tuyau, et qu'une nouvelle donnée en ressorte.\n\n\u003e\u003e add_filter('le-hook-wp', 'mafonction', priorité)\n\n```php\n\nadd_filter('the_content', 'transform_the_content');\n\n// Quand on appelle la fonction\" \"the_content\", au lieu de retourner directement le contenu\n// le contenu passera d'abord dans cette fonction \"filtre\".\n// A la sortie, on voit que le contenu sera maintenant entouré de guillemets.\nfunction transform_the_content($content)\n{\n    // Mon code, ici j'ai accès au \"content\" des posts dans la variable $content\n    return '\"' . $content . '\"';\n}\n\n```\n\n### Menus\nIl faudra dire à notre thème de supporter les menus.\n````php\nadd_theme_support('menus');\nregister_nav_menu(\"header\", \"Menu de l'en-tête\")\n````\nA partir de là, on peut se rendre dans Apparence/menus dans la partie admin pour créer des menus.\nUne fois notre menu créé (on choisit bien l'emplacement \"header\" qui est le nom de notre menu) nous pouvons nous rendre dans header.php.\n\nheader.php\n```php\n\u003c?php wp_nav_menu([\n    'theme_location' =\u003e \"header\", // ID du menu\n    'container' =\u003e false, // Enlève la div autour du menu\n    'menu_class' =\u003e \"la-classe-du-menu\",\n])?\u003e\n```\n\nOn remarque que l'on a pu modifier la classe du menu, mais pas de ses éléments.\nEn grattant un peu dans WP, on découvre qu'il y existe un filtre pour cela !\nDans mon fonctions.php je peux donc venir modifier ce comportement.\n\n```php\nadd_filter(\"nav_menu_css_class\", \"change_nav_classes\");\nadd_filter(\"nav_menu_link_attributes\", \"change_nav_links\");\n\nfunction change_nav_classes($classes) {\n    // On récupère les classes de WP mais on injecte la notre !\n    $classes[] = \"ma-classe-pour-les-navitems\";\n    return $classes;\n}\n\nfunction change_nav_links($attr) {\n    // On récupère les classes de WP mais on injecte la notre !\n    $attr['class'] = \"ma-classe-pour-les-navlinks\";\n    return $attr;\n}\n\n```\n\n### Création d'un CustomPostType\n\nSous wordpress, presque tout est un \"Post\" (ou \"publication\"). Cependant, il arrive souvent que le post de base ne\nréponde pas à tous nos besoins. Il est donc possible de créer des CustomPostType qui sont un peu comme des Entities à la\ndifférence notable que, du point de vue de la base de données, tous nos types personalisés, en fin de compte, reste\ndes \"Post\".\n\n_Après avoir défini un CustomPostType ou une CustomTaxonomy il est IMPORTANT de se rendre dans le menu des Rêglages -\u003e\nPermaliens -\u003e Enregistrer les modifications afin de rafraîchir les liens de notre site et qu'ils prennents bien en\ncompte nos nouveaux éléments !_\n\n```php\n// Ici, on ajoute un nouveau type : le Héros\n\n// On se branche sur le hook \"init\" et on lance notre fonction\nadd_action('init', 'add_hero_post_type');\n\nfunction add_hero_post_type() {\n    // Nous demandons à créer un nouveau type: le \"Héros\"\n    // On commence par lui donner une clé unique (TRES IMPORTANT): \"hero\"\n    register_post_type('hero', [\n        'label' =\u003e 'Héros', // Le nom qui apparait un peu partout sur notre site\n        // On peut aussi fournir tout un tableau contenant les différentes appellation de notre PostType\n        // selon le contexte mais cela demande plus de travail\n        // 'labels' =\u003e [],\n        'description' =\u003e 'Un héros de RPG', // Description du post type\n        'public' =\u003e true, // Est-ce que les visiteurs ont le droit d'accéder aux pages relatives aux \"heros\"\n        'hierarchical' =\u003e false, // Est-ce que des héros peuvent être des \"enfants\" (des variations) de héros existants ?\n        'exclude_from_searrch' =\n        'show_in_admin_bar' =\u003e true,\n        'menu_icon' =\u003e 'dashicons-chart-pie', // L'icone qui apparait dans le menu du backoffice \n        'has_archive' =\u003e true, // Peut-on accéder à une page \"archive\" de ce type de post ?\n        'menu_position' =\u003e 4, // Permet de choisir l'emplacement de notre sous-menu dans le menu principale\n        'supports' =\u003e [ // On détermine ce que supporte notre custom post type\n            'title', // Il a un titre\n            'editor', // Il a un éditeur de texte\n            'thumbnail', // Il a une miniature\n        ],\n        'taxonomies' =\u003e [], // Liste des \"catégories\" disponibles pour ce Post Type\n        'show_in_rest' =\u003e true, // Accessible depuis API et permet d'avoir l'éditeur sous forme de bloc\n        // il existe d'autres options, consultez la documentation officielle !\n    ]);\n}\n\n```\n\nUne fois ce travail de définition effectué, notre nouveau PostType devient disponible depuis le menu principale.\n\nOn peut à présent créer et modifier nos \"Héros\" de la même façon que des Articles classiques.\n\n### Création de Taxonomie\n\nLes Taxonomies sont des \"catégories d'articles\" qui nous permettent de classer nos Post.\n\nDe base, on possède déjà les taxonomies \"catégorie\" et \"étiquette\". On note au passage que \"catégorie\" est hiérarchique:\non peut donc avoir des catégories et des sous catégories.\n\n```php\n\nadd_action('init', 'register_class_taxonomy');\n\nfunction register_class_taxonomy() {\n    register_taxonomy('class', 'hero', [\n        // Ici on passe nos options\n        'labels' =\u003e [\n            'name' =\u003e 'Classe',\n            'singular_name' =\u003e 'Classe',\n            'plural_name' =\u003e 'Classes',\n            'search_items' =\u003e 'Rechercher des classes',\n            'all_items' =\u003e 'Toutes les classes',\n            'edit_item' =\u003e 'Modifier la classe',\n            'update_item' =\u003e 'Mettre à jour la classe',\n            'add_new_item' =\u003e 'Ajouter une classe',\n            'new_item_name' =\u003e 'Nouvelle classe',\n            'menu_name' =\u003e 'Classes',\n        ],\n        'show_in_rest' =\u003e true, // Pour avoir accès à cette taxonomy depuis l'éditeur de Bloc\n        'hierarchical' =\u003e true, // Notre Classe peut avoir des \"sous-classe\" (sous-catégorie)\n        'public' =\u003e true, // Notre catégorie est-elle accéssible depuis le front ?\n        'show_admin_column' =\u003e true, // Est-ce que la taxonomy apparait dans les tableaux côté admin ?\n        'capabilities' =\u003e [ // Définir les permissions d'usage\n            'manage_terms' =\u003e 'manage_categories',\n            'edit_terms' =\u003e 'manage_categories',\n            'delete_terms' =\u003e 'manage_categories',\n            'assign_terms' =\u003e 'manage_categories',\n        ],\n        'rewrite' =\u003e 'slug', // Réécriture d'url via le slug de la taxonomy\n    ]);\n}\n```\n\nMais comment récupérer/afficher la liste des taxonomies de nos posts ?\nQuand vous êtes dans \"the_loop\", vous pouvez consulter la liste des \"terms\" avec la fonction \"get_terms\" et\nen lui passant un tableau de la liste des taxonomies que vous voulez voir (\"catégories\", \"étiquette\" etc...).\n\n\n```php\n\u003cul\u003e\n    \u003c?php foreach(get_terms(['gamme']) as $term): ?\u003e // On récupère uniquement les \"gammes\" (notre taxonomy custom)\n        \u003cli\u003e\n            \u003ca href=\"\u003c?= get_term_link($term) ?\u003e\"\u003e\n                \u003c?= $term-\u003ename?\u003e\n            \u003c/a\u003e\n        \u003c/li\u003e\n    \u003c?php endforeach ?\u003e\n\u003c/ul\u003e\n```\n\n\nQuelques liens utiles:\n[Documentation officielle pour l'ajout d'un post type](https://developer.wordpress.org/reference/functions/register_post_type/)\n[Documentation officielle pour l'ajout d'une taxonomie](https://developer.wordpress.org/reference/functions/register_taxonomy/)\n[Liste des icones WP](https://developer.wordpress.org/resource/dashicons/#buddicons-forums)\n\n### Extension ACF (Advanced Custom Fields)\nCette extension extrêment utile et populaire vous permet d'ajouter des champs à vos taxonomies et posts.\n\nVoyez un peu cela comme une façon de rajouter des propriétés à des Entities Symfony (en quelque sorte...).\n\nPar exemple, après avoir créé notre Custom Post Type \"Product\", on se rend compte que, contrairement à un Post\nclassique, un produit devrait avoir un prix. Il lui manque donc cette information.\n\nOn peut donc dire à ACF d'ajouter un nouveau champs \"prix\" qui s'appliquera quand:\n\u003e\u003e \"type de publication\" -- \"est égale à\" -- \"Produit\"\n\nA présent lors de la création/modification d'un produit, un champs supplémentaire apparaîtera en bas de page.\n\nProblème: comment récupérer cette information depuis un fichier php ?\nAvec la fonction \"get_field\" ! (ou \"the_field()\")\n\n```php\n\u003c?php if (have_posts): while (have_posts): the_post() ?\u003e\n    \u003c?php the_title() ?\u003e\n    \u003c?= get_field('price') ?\u003e // On récupère (et affiche) la valeur du champs \"price\" de notre post \"product\"\n\u003c?php endwhile; endif; ?\u003e\n```\n\n### Création d'Options\nLes options sont des données variables et manipulables depuis le backoffice et que l'on met à disposition dans l'intégralité\nde l'application.\n\nEn base de données, vous trouverez toutes vos options dans la tables wp-options.\n\nOn note que toutes les options ont une clé et une valeur:\nclé =\u003e valeur\n'siteurl' =\u003e monsite.fr\n\nPour créer des options, il nous faut tout d'abord créer le menu qui permettra de gérer ces options.\n\nPour ce faire, nous devons utiliser le hook \"admin_menu\".\n````php\n// Je me branche sur le hook \"admin_menu\" pour le modifier\nadd_action('admin_menu', 'ajout_menu_combat');\n\n// Je définis comment on accède à ma page d'options de puis le menu\nfunction ajout_menu_combat() {\n    add_options_page(\n        \"Titre de la page\",\n        \"Titre du menu\",\n        \"manage_options\", // Capabilities (les permissions)\n        \"slug_du_menu\",\n        'render_menu_combat' // Function d'affichage de la page\n    );\n}\n\n// Je définis le contenu de ma page d'options\nfunction render_menu_combat() {\n    echo \"Le contenu de ma page d'options !!\"\n}\n\n\n````\n\nOn va commencer par créer un formulaire sur notre page\n```php\n    function render_menu_combat()\n    {\n    // On peut fermer PHP ici pour écrire du HTML plus librement\n        ?\u003e\n        \u003ch1\u003eGestion de l'agence\u003c/h1\u003e\n\n        \u003cform action=\"options.php\" method=\"post\"\u003e\n            \u003c?php\n            // On prépare le formulaire et on le sécurise\n            settings_fields('combat_option');\n            \n            // On remplis notre formulaire avec les champs que l'on a défini\n            // pour nos options\n            do_settings_sections('combat_option');\n            \n            // On laisse WP générer le bouton de soumission\n            submit_button(); \n            ?\u003e\n        \u003c/form\u003e\n        \u003c?php\n    }\n```\n\nLe problème étant que les champs de formulaires que l'on injecte avec 'do_settings_sections()' n'existent pas !\n\nIl va donc falloir les créer !\n\n````php\n// On se branche sur \"admin_init\"\nadd_action('admin_init', 'register_combat_settings']);\n\nfunction register_combat_settings() \n{\n        register_setting(\n        'combat_options', // Nom de notre Groupe\n        'combat_starting_hp', // Le nom de l'option que l'on veut enregistrer\n        [\n            'default' =\u003e 100, // On peut passer une valeur par défaut\n        ]);\n        \n        \n        // Création d'une section du formulaire\n        add_settings_section(\n            'combat_options_section1', // Nom de la section\n            'Titre de la section', // Titre\n            function () { // Callback qui doit afficher quelque chose\n                echo 'Petit message de présentation de la section';\n            },\n            'combat_options' // nom du Group\n        );\n        \n        // Création d'un champs du formulaire\n        add_settings_field(\n            'combat_options_initialhp',\n            'Horaires d\\'ouverture',\n            function () {\n                ?\u003e\n                \u003ctextarea name=\"combat_initialhp\" cols=\"30\" rows=\"10\"\u003e\u003c?= get_option('combat_initialhp') ?\u003e\u003c/textarea\u003e\n                \u003c?php\n            },\n            'combat_options',\n            'combat_options_section1',\n        );\n}\n\n\n````\n\n### Shortcodes\n\nQuand on créé un thème ou un plugin, il peut être très pratique de se créer des shortcodes afin d'exposer certaines fonctions\nde notre programme.\n\n````php\n// On commence par créer une fonction qui retourne une vue HTML, ou du texte\nfunction dire_bonjour(): string {\n    return 'Bonjour !!';\n}\n\n// Il faut ensuite enregistrer cette fonction en tant que \"shortcode\"\nadd_shortcode('bonjour', 'dire_bonjour');\n\n// A présent, je peux l'invoquer depuis n'importe où dans mon code ou même depuis le contenu d'un Post\ndo_shortcode('[bonjour]');\n// Attention à ne pas oublier les crochets !\n\n\n// Si vous avez besoin de passer des paramètres c'est un peu plus délicat\nadd_shortcode('qqch', 'dire_quelquechose');\n\nfunction dire_quelquechose($atts): string\n{\n        $atts = shortcode_atts(\n        // On définie des valeurs par défault si besoin\n            [\n                'debut' =\u003e 'Coucou ',\n                'fin' =\u003e 'les petits amis !!'\n            ],\n            $atts,\n            'qqch' // nom du shortcode\n        );\n        return $debut . $fin;\n}\n// Usage\ndo_shortcode('[qqch debut=\"Hello \" fin=\"world!!\"]');\n// Résultat: \"Hello work!!\"\n\n\n````\n\n### POO et Wordpress\nPar propreté et afin de mieux organiser son code, je vous recommande chaudement d'installer composer et l'autoloader.\n\nL'idée et d'utiliser un fichier de point d'entrée (functions.php dans votre thème, ou le fichier qui porte le nom de votre plugin le cas échéant) et \nde simplement y importer les classes dont vous avez besoin qui contiennent les différents actions à effectuer.\n\nPar exemple :\n\n````php\nrequire 'vendor/autoload.php'; // On importe l'autoload \nuse Sanitizer\\Sanitizer; // On importe chaque classe dont on a besoin\n\nSanitizer::init(); // Nos classes ont chacune une méthode static qui permet d'initialiser leur logique interne\n\n//Sanitizer.php\nnamespace Sanitizer;\n\nclass Sanitizer\n{\n      \n    public static function init()\n    {\n        add_filter('sanitize_file_name', [self::class, 'sanitize_french_filename'], 10, 1);\n    }\n\n    public static function sanitize_french_filename(string $filename)\n    {\n         // Votre code\n    }\n}\n````\n\nCela permet d'avoir toutes les fonctions liés à une fonctionnalité précise dans le même fichier et de mieux s'y retrouver.\n\nDans le cas d'un thème ou d'un plugin ambitieux, c'est inestimable et cela rendra le code beaucoup plus simple à maintenir !\n\n## Création de plugin\n\n### A quoi servent les plugins WP ?\n\nLes plugins WordPress sont des extensions logicielles qui ajoutent des fonctionnalités supplémentaires à un site Web\ncréé avec WordPress. Ils permettent d'étendre les capacités de base de WordPress en ajoutant des fonctionnalités\nspécifiques, sans avoir besoin de modifier le code source du noyau WordPress lui-même. Voici une explication détaillée\nde l'utilité des plugins WordPress :\n\n1. **Personnalisation et fonctionnalités spécifiques** : Les plugins permettent de personnaliser votre site Web selon\n   vos besoins spécifiques. Par exemple, si vous souhaitez ajouter un formulaire de contact, un calendrier d'événements,\n   un système de réservation, des galeries d'images avancées ou une boutique en ligne, vous pouvez simplement installer\n   les plugins correspondants pour obtenir ces fonctionnalités sans écrire de code complexe.\n\n2. **Facilité d'utilisation** : La plupart des plugins WordPress sont conçus pour être faciles à installer, configurer\n   et utiliser. Vous n'avez pas besoin d'être un développeur expérimenté pour les utiliser. En quelques clics, vous\n   pouvez ajouter de nouvelles fonctionnalités à votre site Web sans devoir vous plonger dans le code.\n\n3. **Économie de temps et d'argent** : Les plugins sont souvent plus économiques que le développement personnalisé. Au\n   lieu de devoir embaucher un développeur pour créer une fonctionnalité spécifique à partir de zéro, vous pouvez\n   utiliser un plugin existant, qui est généralement moins cher et vous fait gagner du temps.\n\n4. **Mises à jour et support** : Les développeurs de plugins mettent généralement à jour leurs produits pour s'assurer\n   qu'ils restent compatibles avec les dernières versions de WordPress et qu'ils sont sécurisés. De plus, de nombreux\n   plugins sont accompagnés d'un support technique, ce qui peut être très utile si vous rencontrez des problèmes ou si\n   vous avez des questions.\n\n5. **Extensions pour les thèmes** : Les plugins peuvent ajouter des fonctionnalités avancées aux thèmes WordPress. Par\n   exemple, un plugin de mise en page vous permet de créer des mises en page complexes et personnalisées, ce qui est\n   souvent difficile à réaliser avec le thème seul.\n\n6. **SEO (Optimisation pour les moteurs de recherche)** : Certains plugins sont spécialement conçus pour améliorer le\n   référencement de votre site Web. Ils peuvent vous aider à optimiser vos pages pour les moteurs de recherche, créer\n   des sitemaps, gérer les balises méta, etc.\n\n7. **Sécurité** : Les plugins peuvent également améliorer la sécurité de votre site Web en ajoutant des fonctions de\n   protection contre les attaques potentielles, la détection des logiciels malveillants, le filtrage des spams et bien\n   plus encore.\n\n8. **Intégrations tierces** : Certains plugins permettent d'intégrer facilement des services tiers tels que les médias\n   sociaux, les plateformes de marketing par email, les services d'analyse, les systèmes de paiement, etc.\n\n9. **Communauté active** : La communauté WordPress est très active dans le développement de plugins. Vous pouvez trouver\n   des milliers de plugins gratuits et payants pour répondre à presque tous les besoins.\n\nCependant, il est essentiel de garder à l'esprit que l'utilisation de trop de plugins peut ralentir votre site Web et\ncréer des conflits entre eux. Il est donc recommandé d'utiliser uniquement les plugins nécessaires et de s'assurer\nqu'ils sont régulièrement mis à jour pour garantir la stabilité et la sécurité de votre site.\n\n### Plugins les plus populaires\n\n1. **Yoast SEO** : Ce plugin est l'un des plugins de référencement les plus utilisés. Il aide à optimiser le contenu de\n   votre site pour les moteurs de recherche en vous donnant des suggestions pour améliorer votre référencement, des\n   fonctionnalités de création de sitemaps XML, de gestion des balises méta, etc.\n\n2. **Akismet** : Ce plugin est un outil anti-spam qui protège votre site WordPress des commentaires indésirables et du\n   spam.\n\n3. **WooCommerce** : Il s'agit d'un plugin e-commerce populaire qui transforme votre site WordPress en une boutique en\n   ligne entièrement fonctionnelle. Il offre des fonctionnalités de gestion des produits, des paiements, des\n   expéditions, etc.\n\n4. **Contact Form 7** : Ce plugin permet de créer facilement des formulaires de contact personnalisables pour votre\n   site, sans nécessiter de connaissances en programmation.\n\n5. **Jetpack** : Jetpack est un plugin polyvalent qui offre des fonctionnalités de performance, de sécurité, de partage\n   social, de statistiques, de sauvegarde, etc.\n\n6. **Wordfence Security** : Il s'agit d'un plugin de sécurité complet qui protège votre site contre les attaques de\n   pirates, les logiciels malveillants, les tentatives de connexion frauduleuses, etc.\n\n7. **Elementor** : C'est un constructeur de pages glisser-déposer qui permet de créer des mises en page avancées et\n   personnalisées pour vos pages et articles WordPress.\n\n8. **UpdraftPlus** : Ce plugin de sauvegarde vous permet de sauvegarder facilement votre site WordPress et de restaurer\n   des sauvegardes en cas de besoin.\n\n9. **Smush** : Smush est un plugin d'optimisation d'images qui compresse automatiquement les images téléchargées pour\n   améliorer les performances du site sans compromettre la qualité visuelle.\n\n10. **MonsterInsights** : Ce plugin permet d'intégrer facilement Google Analytics sur votre site WordPress, vous offrant\n    ainsi des informations détaillées sur les visiteurs et le trafic de votre site.\n\n11. **Redirection** : Redirection est un gestionnaire de redirections qui vous permet de créer et de gérer facilement\n    des redirections 301 pour des pages qui ont été déplacées ou supprimées.\n\n12. **WP Super Cache** : Ce plugin améliore les performances de votre site en générant des fichiers HTML statiques à\n    partir de vos pages dynamiques, ce qui réduit le temps de chargement.\n\n13. **All in One SEO Pack** : Un autre plugin populaire pour l'optimisation des moteurs de recherche qui propose des\n    fonctionnalités similaires à Yoast SEO.\n\nCes plugins sont parmi les plus populaires, mais il en existe des milliers d'autres pour répondre à des besoins\nspécifiques. Lors du choix d'un plugin, assurez-vous de vérifier les avis, les évaluations et la compatibilité avec\nvotre version de WordPress pour vous assurer qu'ils répondent bien à vos besoins et qu'ils sont régulièrement mis à\njour.\n\n### Mise en place\n\n- Télécharger une base wordpress sur [le site officiel](https://wordpress.org/download/).\n- Créer une base de données sous Wamp qui servira à ce projet\n- Télécharger [le thème Understrap sur le github](https://github.com/understrap/understrap)\n- Inclure le thème dans /mon-projet/wp-content/themes/ et le définir depuis la partie admin\n- Créer un nouveau dossier dans /mon-projet/wp-content/plugins/\n- Dans ce dossier, créer un fichier php portant le même nom que le dossier (IMPORTANT), il servira de point d'entrée à\n  votre plugin.\n- Ce fichier devra commencer ainsi:\n\n```php\n\u003c?php\n/*\nPlugin Name: Nom du plugin\nPlugin URI: Lien vers la page du plugin (facultatif)\nDescription: Description du plugin\nVersion: 1.0.0\nAuthor: Votre nom\nAuthor URI: Votre site web (facultatif)\nLicense: (GNU GPLv2 ou supérieure)\n*/\n```\n\n- Pour Installer un plugin, vous pouvez l'inclure directement dans le dossier \"plugins\" ou bien le compresser au format\n  .zip et l'importer directement depuis la partie admin de votre WP.\n\n- Mettre en place l'autoloader (conseillé !)\n  -- faire un composer init dans le projet\n\n```bash\ncomposer init\n```\n\n-- modifier composer.json pour que le namespace de notre /src corresponde, de préférence, au nom de notre plugin (\nexemple)\n\n```json\n// composer.json\n{\n  \"name\": \"maxime/monsuperplugin\",\n  \"autoload\": {\n    \"psr-4\": {\n      \"MonSuperPlugin\\\\\": \"src/\"\n    }\n  },\n  \"authors\": [\n    {\n      \"name\": \"Maxime\",\n      \"email\": \"maxime@gmail.com\"\n    }\n  ],\n  \"require\": {}\n}\n```\n\n- Pour tester, vous pouvez créer une classe dans /src, par exemple la classe Test\n- Indiquez que la classe Test se trouve dans le namespace \"MonSuperPlugin\"\n\n```php\n\u003c?php\nnamespace MonSuperPlugin;\n\nclass Test\n{\n    // mon code\n}\n```\n\n- N'oubliez pas de mettre l'autoloader à jour\n\n```bash\ncomposer dump-autoload\n```\n\n- Dans votre fichier principal (celui qui porte le nom de votre plugin), ajoutez ceci\n\n```php\nrequire 'vendor/autoload.php';\nuse MonSuperPlugin\\Test;\n\n$test = new Test();\n```\n\n### Debug\n\nPlugin \"queryMonitor\" pour debbug\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjorisbertier%2Fwordpress_extension","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjorisbertier%2Fwordpress_extension","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjorisbertier%2Fwordpress_extension/lists"}