Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: override get_head search request metadata #663

Merged
merged 9 commits into from
Jan 26, 2024
116 changes: 116 additions & 0 deletions wp/headless-wp/includes/classes/Integrations/YoastSEO.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public function register() {
add_filter( 'wpseo_sitemap_url', array( $this, 'maybe_override_sitemap_url' ), 10, 2 );

add_filter( 'robots_txt', array( $this, 'maybe_override_sitemap_robots_url' ), 999999 );

// Override Search results yoast head, get_head endpoint currently does't detect search page.
add_filter( 'wpseo_canonical', array( $this, 'override_search_canonical' ), 10, 1 );
add_filter( 'wpseo_title', array( $this, 'override_search_title' ), 10, 1 );
add_filter( 'wpseo_opengraph_title', array( $this, 'override_search_title' ), 10, 1 );
add_filter( 'wpseo_opengraph_url', array( $this, 'override_search_canonical' ), 10, 1 );
}

/**
Expand Down Expand Up @@ -162,4 +168,114 @@ public function maybe_override_sitemap_robots_url( $output ) {

return $output;
}

/**
* Return list of query vars if the request is /yoast/v1/get_head?url and for search URL based on ?s= parameter.
*
* @return boolean|array False if it's not a yoast search rest api request. Search $query_vars if otherwise.
*/
public function get_yoast_search_query_vars() {

if ( ! ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
return false;
}

$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
lucymtc marked this conversation as resolved.
Show resolved Hide resolved

if ( false === strpos( $request_uri, '/yoast/v1/get_head' ) ) {
return false;
}

$url_param = isset( $_GET['url'] ) ? sanitize_url( wp_unslash( $_GET['url'] ) ) : '';

if ( filter_var( $url_param, FILTER_VALIDATE_URL ) !== false ) {
$query = wp_parse_url( $url_param, PHP_URL_QUERY );
parse_str( $query, $query_vars );

// Return query vars if search request.
if ( isset( $query_vars['s'] ) ) {
return apply_filters( 'tenup_headless_wp_search_request_query_vars', $query_vars );
}
}

return false;
}

/**
* Custom helper to replace Yoast search title placeholders.
* Assuming only some of the basic variables.
*
* @todo Support for page number.
*
* @param string $title The search SEO title
* @param array $query_vars The search query vars.
*
* @return string
*/
public function replace_yoast_search_title_placeholders( $title, $query_vars ) {

$str_replace_mapping = apply_filters(
'tenup_headless_wp_search_title_variables_replacments',
array(
'%%sitename%%' => get_bloginfo( 'name' ),
'%%searchphrase%%' => $query_vars['s'] ?? '',
' %%page%%' => '',
lucymtc marked this conversation as resolved.
Show resolved Hide resolved
'%%sep%%' => \YoastSEO()->helpers->options->get_title_separator() ?? ' ',
)
);

return str_replace( array_keys( $str_replace_mapping ), array_values( $str_replace_mapping ), $title );
}

/**
* Set the missing Yoast Search title.
*
* @param string $title The title.
* @return string
*/
public function override_search_title( $title ) {

$search_request_query_vars = $this->get_yoast_search_query_vars();

if ( ! $search_request_query_vars ) {
return $title;
}

$wpseo_titles = get_option( 'wpseo_titles' );

$title_search_wpseo = '';

// Get user setting for search title, fallback to default search from Yoast SEO.
if ( ! empty( $wpseo_titles ) && ! empty( $wpseo_titles['title-search-wpseo'] ) ) {
$title_search_wpseo = $wpseo_titles['title-search-wpseo'];
} else {
$default_titles = \WPSEO_Option_Titles::get_instance()->get_defaults();
if ( ! empty( $default_titles['title-search-wpseo'] ) ) {
$title_search_wpseo = $default_titles['title-search-wpseo'];
}
}

if ( empty( $title_search_wpseo ) ) {
return $title;
}

return $this->replace_yoast_search_title_placeholders( $title_search_wpseo, $search_request_query_vars );
}

/**
* Yoast doesn't have a canonical for search and returns URL as the homepage URL. Generally https://gus.test/?s=test
* But with headstartwp nextjs app usually there is a route for search page.
* Default is 'search'.
*
* @param string $canonical The canonical URL.
* @return string
*/
public function override_search_canonical( $canonical ) {
if ( $this->get_yoast_search_query_vars() ) {
$search_route = apply_filters( 'tenup_headless_wp_search_route', 'search' );
$canonical = rtrim( $canonical, '/' ) . '/' . $search_route;
}

return $canonical;
}
}
Loading