Utiliser du code DRY pour afficher des blocs côté serveur (PHP) et client (JS)
Les blocs dynamiques (Gutenberg) sont des blocs qui construisent leur structure et leur contenu à la volée lorsque le bloc est rendu sur le front-end.
Le rendu d'un bloc dynamique sur le front-end (pour l'afficher dans l'éditeur WordPress) et côté serveur (pour générer le HTML de l'article de blog) récupère généralement ses données de deux façons différentes :
- En se connectant à l'API côté client (JavaScript)
- En appelant des fonctions WordPress côté serveur (PHP)
Avec Gato GraphQL et ses extensions, il est possible de rendre cette logique DRY, en ayant une unique source de vérité pour récupérer les données côté client et côté serveur. Voyons comment procéder.
Stocker les requêtes GraphQL dans des fichiers .gql
Pour se connecter au serveur GraphQL depuis le client, nous exécutons généralement la requête GraphQL intégrée dans le code JavaScript, comme ceci :
const response = await fetch(endpoint, {
body: JSON.stringify({
query: `
query {
posts {
id
title
author {
id
name
}
}
}
`
)
} );Nous pouvons alternativement stocker la requête GraphQL dans un fichier .gql (ou .graphql), et importer son contenu en utilisant le raw-loader de Webpack :
// File webpack.config.js
const config = require( '@wordpress/scripts/config/webpack.config' );
config.module.rules.push(
{
test: /\.(gql|graphql)$/i,
use: 'raw-loader',
},
);
module.exports = config;(Ce code fonctionne pour Webpack v4 ; pour v5, nous devons utiliser les Asset Modules à la place.)
Ensuite, nous plaçons la requête GraphQL dans un fichier .gql :
# File graphql-documents/fetch-posts-with-author.gql
query {
posts {
id
title
author {
id
name
}
}
}Enfin, dans le code du bloc, nous importons le fichier et passons son contenu à fetch :
import graphQLQuery from './graphql-documents/fetch-posts-with-author.gql';
// ...
const response = await fetch(endpoint, {
body: JSON.stringify({
query: graphQLQuery
)
} );Résoudre les fichiers .gql côté serveur
Le fichier GraphQL que nous avons créé ci-dessus sera notre unique source de vérité pour récupérer les données du bloc. Il satisfait déjà cela pour le côté client ; voyons maintenant comment le faire pour le côté serveur.
L'extension Internal GraphQL Server installe un serveur qui peut être invoqué dans notre application, en utilisant du code PHP.
le Internal GraphQL Server fournit les méthodes statiques suivantes, via la classe GraphQLServer :
executeQuery: exécute une requête GraphQLexecuteQueryInFile: exécute une requête GraphQL contenue dans un fichier (.gql)executePersistedQuery: exécute une requête GraphQL persistée (en fournissant son ID sous forme d'entier, ou son slug sous forme de chaîne) (l'extension Persisted Queries est requise)
La signature de executeQueryInFile ressemble à ceci :
namespace GatoGraphQL\InternalGraphQLServer;
class GraphQLServer {
/**
* Execute a GraphQL query contained in a (`.gql`) file
*/
public static function executeQueryInFile(
string $file,
array $variables = [],
?string $operationName = null
): Response {
// ...
}
}En invoquant executeQueryInFile en passant le fichier .gql créé précédemment, nous récupérons les données lors du rendu du bloc dynamique :
use GatoGraphQL\InternalGraphQLServer\GraphQLServer;
$block = [
'render_callback' => function(array $attributes, string $content): string {
// Provide the GraphQL query file
$file = __DIR__ . '/blocks/my-block/graphql-documents/fetch-posts-with-author.gql';
// Execute the query against the internal server
$response = GraphQLServer::executeQueryInFile($file);
// Get the content and decode it
$responseContent = json_decode($response->getContent(), true);
// Access the data and errors from the response
$data = $responseContent["data"] ?? [];
$errors = $responseContent["errors"] ?? [];
// Do something with the data
// $content = $this->useGraphQLData($content, $data, $errors);
// ...
return $content;
},
];
register_block_type("namespace/my-block", $block);Ainsi, un seul fichier .gql récupère les données pour alimenter les blocs côté client et côté serveur.