Created
December 31, 2021 21:48
-
-
Save ravewebdev/a04595c3a4842c8422ec0f40ca2f2e5d to your computer and use it in GitHub Desktop.
WordPress post link replacement for use on headless installs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Customize the preview button in the WordPress admin to point to the headless frontend. | |
* | |
* @param string $link WordPress preview link. | |
* @param WP_Post $post Current post object. | |
* @return string The headless WordPress preview link. | |
*/ | |
function set_headless_preview_link( string $link, \WP_Post $post ) { | |
$frontend_url = 'https://my-headless-frontend.test'; | |
$slug = strlen( $post->post_name ) > 0 ? $post->post_name : sanitize_title( $post->post_title ); | |
// Get GraphQL single name for current post type (with regular post type as fallback). | |
$post_type = get_post_type_object( $post->post_type )->graphql_single_name ?? $post->post_type; | |
// Preview link will have format: <domain>/api/preview?name=<slug>&id=<post-id>&post_type=<post-type>&token=<preview-token>. | |
return add_query_arg( | |
[ | |
'name' => $slug, | |
'id' => $post->ID, | |
'post_type' => $post_type, | |
// Preview secret token is used to authenticate frontend requests for post previews. | |
// This line assumes the token is set via `wp-config.php`. | |
'token' => defined( 'PREVIEW_SECRET_TOKEN' ) ? PREVIEW_SECRET_TOKEN : '', | |
], | |
"{$frontend_url}/api/preview" | |
); | |
} | |
add_filter( 'preview_post_link', 'set_headless_preview_link', 10, 2 ); | |
/** | |
* Customize WP home URL to point to frontend. | |
* | |
* @param string $url Complete home URL, including path. | |
* @param string $path Path relative to home URL. | |
* @param string $scheme Context for home URL. | |
* @return string Frontend home URL. | |
*/ | |
function set_headless_home_url( string $url, string $path, $scheme = null ) { | |
// Don't redirect REST requests. | |
if ( 'rest' === $scheme ) { | |
return $url; | |
} | |
// Don't redirect unless in WP admin. | |
if ( ! is_admin() ) { | |
return $url; | |
} | |
$frontend_url = 'https://my-headless-frontend.test'; | |
if ( ! $path ) { | |
return $frontend_url; | |
} | |
// Remove excess slash from beginning of path. | |
$path = ltrim( $path, '/' ); | |
return "{$frontend_url}/{$path}"; | |
} | |
add_filter( 'home_url', 'set_headless_home_url', 10, 3 ); | |
/** | |
* Customize the REST link to point to the headless frontend. | |
* | |
* @param WP_REST_Response $response Response object. | |
* @param WP_Post $post Current post object. | |
* @return WP_REST_Response Response object. | |
*/ | |
function set_headless_rest_link( \WP_REST_Response $response, \WP_Post $post ) { | |
if ( 'draft' === $post->post_status ) { | |
// Manually call preview filter for draft posts. | |
$response->data['link'] = get_preview_post_link( $post ); | |
} elseif ( 'publish' === $post->post_status ) { | |
// Override view link for published posts. | |
$frontend_url = 'https://my-headless-frontend.test'; | |
$permalink = get_permalink( $post ); | |
$site_url = get_site_url(); | |
// Replace site URL if present. | |
if ( false !== stristr( $permalink, $site_url ) ) { | |
$permalink = str_ireplace( $site_url, $frontend_url, $permalink ); | |
} | |
// Replace link with new permalink. | |
$response->data['link'] = $permalink; | |
} | |
return $response; | |
} | |
add_filter( 'rest_prepare_page', 'set_headless_rest_link', 10, 2 ); | |
add_filter( 'rest_prepare_post', 'set_headless_rest_link', 10, 2 ); | |
// For use with custom post types, see https://developer.wordpress.org/reference/hooks/rest_prepare_this-post_type/. | |
/** | |
* Override links within post content on save to point to frontend. | |
* | |
* @param int $post_id Post ID. | |
*/ | |
function override_post_links( $post_id ) { | |
// Unhook function to avoid infinite loop. | |
remove_action( 'save_post', 'override_post_links' ); | |
$post = get_post( $post_id ); | |
if ( ! $post ) { | |
return; | |
} | |
$post_content = $post->post_content; | |
$backend_url = get_site_url(); | |
// Check if post content contains backend WordPress links. | |
if ( false === stripos( $post_content, $backend_url ) ) { | |
return; | |
} | |
$frontend_url = 'https://my-headless-frontend.test'; | |
$new_post_content = $post_content; | |
// Replace backend URL with frontend URL. | |
$new_post_content = str_ireplace( $backend_url, $frontend_url, $post_content ); | |
// Revert media links. | |
// Media links on frontend should point to location on WordPress install. | |
$upload_dir = wp_upload_dir(); | |
$upload_dir = str_ireplace( $backend_url, '', $upload_dir['baseurl'] ); | |
$new_post_content = str_ireplace( "{$frontend_url}{$upload_dir}", "{$backend_url}{$upload_dir}", $new_post_content ); | |
// Revert plugin links. | |
// Links to plugin files on frontend should point to location on WordPress install. | |
$plugin_dir = defined( 'WP_PLUGIN_URL' ) ? WP_PLUGIN_URL : '/wp-content/plugins'; | |
$plugin_dir = str_ireplace( $backend_url, '', $plugin_dir ); | |
$new_post_content = str_ireplace( "{$frontend_url}{$plugin_dir}", "{$backend_url}{$plugin_dir}", $new_post_content ); | |
// Save post. | |
wp_update_post( | |
[ | |
'ID' => $post_id, | |
'post_content' => wp_slash( $new_post_content ), | |
] | |
); | |
// Re-hook function. | |
add_action( 'save_post', 'override_post_links' ); | |
} | |
add_action( 'save_post', 'override_post_links' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment