Menggunakan kode DRY untuk merender blok di sisi server (PHP) dan klien (JS)
Blok dinamis (Gutenberg) adalah blok yang membangun struktur dan kontennya secara langsung ketika blok dirender di front-end.
Merender blok dinamis di front-end (untuk menampilkannya di editor WordPress) dan di sisi server (untuk menghasilkan HTML untuk posting blog) biasanya akan mengambil datanya dengan dua cara yang berbeda:
- Menghubungkan ke API di sisi klien (JavaScript)
- Memanggil fungsi WordPress di sisi server (PHP)
Dengan Gato GraphQL dan ekstensinya, dimungkinkan untuk membuat logika ini DRY, memiliki satu sumber kebenaran untuk mengambil data bagi sisi klien maupun server. Mari kita jelajahi cara melakukannya.
Menyimpan query GraphQL dalam file .gql
Untuk terhubung ke server GraphQL dari klien, kita biasanya mengeksekusi query GraphQL yang tertanam dalam kode JavaScript, seperti ini:
const response = await fetch(endpoint, {
body: JSON.stringify({
query: `
query {
posts {
id
title
author {
id
name
}
}
}
`
)
} );Kita dapat secara alternatif menyimpan query GraphQL dalam file .gql (atau .graphql), dan mengimpor isinya menggunakan raw-loader dari 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;(Kode ini bekerja untuk Webpack v4; untuk v5, kita harus menggunakan Asset Modules sebagai gantinya.)
Selanjutnya, kita menempatkan query GraphQL di dalam file .gql:
# File graphql-documents/fetch-posts-with-author.gql
query {
posts {
id
title
author {
id
name
}
}
}Terakhir, di dalam kode blok, kita mengimpor file tersebut dan meneruskan isinya ke fetch:
import graphQLQuery from './graphql-documents/fetch-posts-with-author.gql';
// ...
const response = await fetch(endpoint, {
body: JSON.stringify({
query: graphQLQuery
)
} );Menyelesaikan file .gql di sisi server
File GraphQL yang kita buat di atas akan menjadi satu sumber kebenaran kita untuk mengambil data bagi blok tersebut. Ini sudah memenuhi kebutuhan untuk sisi klien; sekarang mari kita lihat cara melakukannya untuk sisi server.
Ekstensi Internal GraphQL Server menginstal server yang dapat dipanggil di dalam aplikasi kita, menggunakan kode PHP.
Internal GraphQL Server menyediakan metode statis berikut, melalui kelas GraphQLServer:
executeQuery: Mengeksekusi sebuah query GraphQLexecuteQueryInFile: Mengeksekusi query GraphQL yang terdapat dalam file (.gql)executePersistedQuery: Mengeksekusi query GraphQL yang dipersistensikan (memberikan ID-nya sebagai int, atau slug sebagai string) (ekstensi Persisted Queries diperlukan)
Tanda tangan dari executeQueryInFile terlihat seperti ini:
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 {
// ...
}
}Dengan memanggil executeQueryInFile yang melewatkan file .gql yang dibuat sebelumnya, kita mengambil data saat merender blok dinamis:
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);Dengan cara ini, satu file .gql mengambil data untuk mendukung blok baik di sisi klien maupun server.