本篇文章更新時間:2023/04/30
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
過去筆記過給 REST API 新增欄位的這篇 [WordPress] 客製化內容類型(Post Type) REST API 的方法,只是把 API 中沒有的欄位新建立上去。
如果要控制 REST API 輸出的資料,那方向又不同了。
這需求來自使用 Frontity 開發的專案,前端使用 Vercel 部署沒問題,掛的也是客戶的網域。
但! 後端資料來源是我們一個網域下的 WordPress,這導致一些輸出的內容從原始碼去看,能發現是這樣的架構,所以必須要從 REST API 的輸出去「過濾」。
下面提供兩個方法:
rest_request_after_callbacks
事件過濾器
add_filter(
'rest_request_after_callbacks',
function( $response, array $handler, \WP_REST_Request $request ) {
if ( is_get_posts_request( $request ) ) {
mutate_get_posts_response( $response );
}
return $response;
},
10,
3
);
function is_get_posts_request( \WP_REST_Request $request ) {
return '/wp/v2/posts' === $request->get_route()
&& 'GET' === $request->get_method();
}
function mutate_get_posts_response( $response ) {
if ( ! ( $response instanceof \WP_REST_Response ) ) {
return;
}
$data = array_map(
'prefix_post_response',
$response->get_data()
);
$response->set_data( $data );
}
function prefix_post_response( array $post ) {
if ( isset( $post['title']['rendered'] ) ) {
$post['title']['rendered'] = '[TEST] ' . $post['title']['rendered'];
}
return $post;
}
上述方法來自 Is it possible to modify a WordPress REST API built-in response field?
從 rest_request_after_callbacks
這個過濾器去操作每一個輸出是可以,但經過測試與驗證,如果來源請求包含「_embed=true
」參數時,會無法過濾後面才附加的 _embedded
值。
rest_pre_echo_response
事件過濾器
function mxp_rest_pre_echo_response($result, $obj, $request) {
foreach ($result as $index => $item) {
if (isset($result[$index]['_embedded'])) {
unset($result[$index]['_embedded']);
}
if (isset($result[$index]['author'])) {
unset($result[$index]['author']);
}
}
return $result;
}
add_filter('rest_pre_echo_response', 'mxp_rest_pre_echo_response', 111111, 3);
上述這方法直接從最後要準備輸出 JSON 格式之前下手,到這邊會取得到最終會輸出的結果,從這邊切入就可以控制的到 _embedded
欄位。
關於 REST API 這樣的執行順序,研究 wp-includes/rest-api/class-wp-rest-server.php
這個檔案中的 WP_REST_Server
類別方法就可以清楚不少!
後話
除了從 REST API 去管理輸出的內容外,其他小細節像是後台的網站要如何點「檢視」內容時會轉到前端的網址?
我的作法是搭配 Headless Mode 外掛以及設定 wp-config.php
中 WP_SITEURL
與 WP_HOME
兩個常數值。