J'ai une variable dans header.php, telle que:
$page_extra_title = get_post_meta($this_page->ID, "_theme_extra_title", true);
Une fois que je fais:
var_dump($page_extra_title);
Je NULL
sors toujours de header.php (var_dump fonctionne correctement dans header.php uniquement). J'ai collé la même variable partout où j'en ai besoin (page.php, post.php, footer.php etc.), mais c'est de la folie et rend tout presque impossible à maintenir.
Je me demande quelle est la meilleure façon de passer une variable dans tous les fichiers de mon thème? Je suppose que l'utilisation de functions.php avec "get_post_meta" pourrait ne pas être la meilleure idée? :)
global
-ce pas? Mais il est hors de question pour de bonnes raisons. De plus, vous devez aussi "appeler" lesglobal
variables, en utilisant le mot-clé pour les rendre disponibles. Selon le cas d'utilisation, les sessions peuvent être une solution. Sinon - comme mentionné - je pense qu'une fonction ou une classe pour faire le travail pour vous est la voie à suivre.Réponses:
Structures de données séparées de base
Pour faire circuler les données, vous utilisez normalement un modèle (c'est le "M" dans "MVC"). Regardons une interface très simple pour les données. Les interfaces sont juste utilisées comme "Recettes" pour nos blocs de construction:
Ci-dessus, ce que nous transmettons: un identifiant commun et un "label".
Affichage des données en combinant des pièces atomiques
Ensuite, nous avons besoin d'une vue qui négocie entre notre modèle et ... notre modèle.
Fondamentalement, cette interface dit
Enfin, nous devons implémenter ci-dessus et construire la vue réelle . Comme vous pouvez le voir, le constructeur dit que la chose obligatoire pour notre vue est un modèle et que nous pouvons le rendre. Pour faciliter le développement, nous vérifions même si le fichier de modèle est réellement présent afin que nous puissions faciliter la vie des autres développeurs (et la nôtre également) beaucoup plus et notons cela.
Dans une deuxième étape de la fonction de rendu, nous utilisons une fermeture pour créer le wrapper de modèle réel et
bindTo()
le modèle dans le modèle.Séparation de la vue et du rendu
Cela signifie que nous pouvons utiliser un modèle très simple comme le suivant
pour rendre notre contenu. En rassemblant les pièces, nous obtiendrions quelque chose autour des lignes suivantes (dans notre contrôleur, médiateur, etc.):
Qu'avons-nous gagné?
De cette façon, nous pouvons
Combiner OOP PHP avec l'API WP
Bien sûr , cela est à peine possible en utilisant la fonctionnalité de thématisation de base comme
get_header()
,get_footer()
, etc., non? Faux. Appelez simplement vos classes dans le modèle ou la partie de modèle que vous souhaitez. Rendez-le, transformez les données, faites ce que vous voulez. Si vous êtes vraiment sympa, vous n'avez qu'à ajouter votre propre groupe de filtres personnalisés et avoir un négociateur pour prendre soin de ce qui est rendu par quel contrôleur sur quelle route / chargement de modèle conditionnel.Conclusion?
Vous pouvez travailler avec des choses comme ci-dessus dans WP sans problème et vous en tenir à l'API de base et réutiliser le code et les données sans appeler un seul global ou gâcher et polluer l'espace de nom global.
la source
Il s'agit d'une approche alternative à la réponse @kaiser , que j'ai trouvée assez bien (+1 de moi) mais nécessite un travail supplémentaire pour être utilisé avec les fonctions de base de WP et elle est en soi peu intégrée à la hiérarchie des modèles.
L'approche que je veux partager est basée sur une seule classe (c'est une version allégée de quelque chose sur laquelle je travaille) qui prend en charge le rendu des données pour les modèles.
Il a quelques fonctionnalités (IMO) intéressantes:
$this
mot-clé: cela vous donne la possibilité d'éviter les notifications en production en cas de variables non définiesLa
Engine
classe(Disponible sous forme de Gist ici.)
Comment utiliser
La seule chose nécessaire est d'appeler la
Engine::init()
méthode, probablement en'template_redirect'
décrochant. Cela peut être fait par thèmefunctions.php
ou à partir d'un plugin.C'est tout.
Vos modèles existants fonctionneront comme prévu. Mais maintenant, vous avez la possibilité d'accéder aux données du modèle personnalisé.
Données de modèle personnalisé
Pour transmettre des données personnalisées aux modèles, il existe deux filtres:
'gm_template_data'
'gm_template_data_{$type}'
Le premier est déclenché pour tous les modèles, le second est spécifique au modèle, en fait, la partie dymamique
{$type}
est le nom de base du fichier de modèle sans extension de fichier.Par exemple, le filtre
'gm_template_data_single'
peut être utilisé pour transmettre des données ausingle.php
modèle.Les rappels attachés à ces hooks doivent renvoyer un tableau , où les clés sont les noms des variables.
Par exemple, vous pouvez transmettre des métadonnées en tant que données de modèle comme ceci:
Et puis, à l'intérieur du modèle, vous pouvez simplement utiliser:
Mode débogage
Lorsque les deux constantes
WP_DEBUG
etWP_DEBUG_DISPLAY
sont vraies, la classe fonctionne en mode débogage. Cela signifie que si une variable n'est pas définie, une exception est levée.Lorsque la classe n'est pas en mode débogage (probablement en production), l'accès à une variable non définie produira une chaîne vide.
Modèles de données
Une façon agréable et maintenable d'organiser vos données est d'utiliser des classes de modèles.
Il peut s'agir de classes très simples, qui renvoient des données à l'aide des mêmes filtres décrits ci-dessus. Il n'y a pas d'interface particulière à suivre, elles peuvent être organisées selon vos préférences.
Ci-dessous, il y a juste un exemple, mais vous êtes libre de le faire à votre manière.
La
__invoke()
méthode (qui s'exécute lorsqu'une classe est utilisée comme un rappel) renvoie une chaîne à utiliser pour la<title>
balise du modèle.Grâce au fait que le deuxième argument passé
'gm_template_data'
est le nom du modèle, la méthode renvoie un titre personnalisé pour la page d'accueil.Ayant le code ci-dessus, il est alors possible d'utiliser quelque chose comme
dans la
<head>
section de la page.Partiels
WordPress a des fonctions comme
get_header()
ouget_template_part()
qui peuvent être utilisées pour charger des partiels dans le modèle principal.Ces fonctions, comme toutes les autres fonctions WordPress, peuvent être utilisées dans les modèles lors de l'utilisation de la
Engine
classe.Le seul problème est qu'à l'intérieur des partiels chargés à l'aide des fonctions principales de WordPress, il n'est pas possible d'utiliser la fonctionnalité avancée d'obtenir des données de modèle personnalisé à l'aide
$this
.Pour cette raison, la
Engine
classe a une méthodepartial()
qui permet de charger un partiel (de manière entièrement compatible avec le thème enfant) et de pouvoir utiliser en partie les données du modèle personnalisé.L'utilisation est assez simple.
En supposant qu'il existe un fichier nommé
partials/content.php
dans le dossier thème (ou thème enfant), il peut être inclus en utilisant:À l'intérieur de ce partiel, il sera possible d'accéder à toutes les données du thème parent de la même manière.
Contrairement aux fonctions WordPress, la
Engine::partial()
méthode permet de transmettre des données spécifiques à des partiels, en passant simplement un tableau de données comme deuxième argument.Par défaut, les partiels ont accès aux données disponibles dans le thème parent et aux données explicites transmises.
Si une variable passée explicitement à partial a le même nom qu'une variable de thème parent, alors la variable explicitement passée gagne.
Cependant, il est également possible d'inclure un partiel en mode isolé , c'est-à-dire que le partiel n'a pas accès aux données du thème parent. Pour ce faire, passez simplement
true
le troisième argument àpartial()
:Conclusion
Même si elle est assez simple, la
Engine
classe est assez complète, mais peut certainement être encore améliorée. Par exemple, il n'y a aucun moyen de vérifier si une variable est définie ou non.Grâce à sa compatibilité à 100% avec les fonctionnalités de WordPress et la hiérarchie des modèles, vous pouvez l'intégrer sans problème avec du code existant et tiers.
Cependant, notez que ce n'est que partiellement testé, il est donc possible qu'il y ait des problèmes que je n'ai pas encore découverts.
Les cinq points sous "Qu'avons-nous gagné?" dans @kaiser réponse :
sont également valables pour ma classe.
la source
Réponse simple, ne passez pas de variables n'importe où car cela pue d'utiliser des variables globales, ce qui est mauvais.
D'après votre exemple, il semble que vous essayez de faire une optimisation précoce, encore un autre mal;)
Utilisez l'API wordpress pour obtenir des données qui sont stockées dans la base de données et n'essayez pas de déjouer et d'optimiser son utilisation car l'API fait plus que simplement récupérer des valeurs et elle active des filtres et des actions. En supprimant l'appel d'API, vous supprimez la capacité des autres développeurs à modifier le comportement de votre code sans le modifier.
la source
Bien que la réponse de Kaiser soit techniquement correcte, je doute que ce soit la meilleure réponse pour vous.
Si vous créez votre propre thème, je pense que c'est en effet le meilleur moyen de configurer une sorte de cadre à l'aide de classes (et peut-être aussi des espaces de noms et des interfaces, bien que cela puisse être un peu trop pour un thème WP).
D'un autre côté, si vous étendez / ajustez simplement un thème existant et n'avez besoin que de passer une ou quelques variables, je pense que vous devriez vous en tenir
global
. Parce queheader.php
est inclus dans une fonction, les variables que vous déclarez dans ce fichier sont utilisables uniquement dans ce fichier. Avecglobal
vous les rendez accessibles dans tout le projet WP:Dans
header.php
:Dans
single.php
(par exemple):la source
$wp_theme_vars_page_extra_title
ou$wp_theme_vars['page_extra_title']
par exemple. C'était juste une explication pour laquelle global fonctionnerait ici. OP a demandé un moyen de passer une variable dans tous les fichiers, en utilisantglobal
est un moyen de le faire.but it is really bad practice diving into the global scope
J'aimerais que quelqu'un le dise aux développeurs principaux de WP. Je ne comprends vraiment pas l'intérêt d'utiliser des espaces de noms, l'abstraction de données, des modèles de conception, des tests unitaires et d'autres meilleures pratiques / techniques de programmation dans le code écrit pour Wordpress lorsque le noyau Wordpress est jonché de mauvaises pratiques de codage comme les variables glabales (par exemple, les widgets code).Une solution simple consiste à écrire une fonction pour obtenir le titre supplémentaire. J'utilise une variable statique pour garder les appels de base de données à un seul. Mettez ceci dans votre functions.php.
En dehors de header.php, appelez la fonction pour obtenir la valeur:
la source