Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gregrickaby committed Sep 24, 2021
0 parents commit 847be55
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# WDS Headless SEO

Please see <https://webdevstudios.github.io/nextjs-wordpress-starter/> for more information.
23 changes: 23 additions & 0 deletions activation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* Plugin activation functionality.
*
* @author WebDevStudios
* @package WDS_Headless_SEO
* @since 1.0.0
*/

namespace WDS_Headless_SEO;

/**
* Plugin activation callback.
*
* @author WebDevStudios
* @since 1.0.0
*/
function activation_callback() {
do_action( 'wds_headless_seo_activate' );

// Save current plugin version.
update_option( 'wds_headless_seo_version', WDS_HEADLESS_SEO_VERSION );
}
13 changes: 13 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "webdevstudios/wds-headless-seo",
"description": "WDS Headless extension handling SEO functionality.",
"homepage": "https://github.com/WebDevStudios/nextjs-wordpress-starter",
"type": "wordpress-plugin",
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "WebDevStudios",
"email": "contact@webdevstudios.com"
}
]
}
23 changes: 23 additions & 0 deletions deactivation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* Plugin deactivation functionality.
*
* @author WebDevStudios
* @package WDS_Headless_SEO
* @since 1.0.0
*/

namespace WDS_Headless_SEO;

/**
* Plugin deactivation callback.
*
* @author WebDevStudios
* @since 1.0.0
*/
function deactivation_callback() {
do_action( 'wds_headless_seo_deactivate' );

// Delete plugin version.
delete_option( 'wds_headless_seo_version' );
}
43 changes: 43 additions & 0 deletions inc/links.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Link/redirection functionality.
*
* @author WebDevStudios
* @package WDS_Headless_SEO
* @since 1.0.0
*/

namespace WDS_Headless_SEO;

if ( ! defined( 'WPSEO_VERSION' ) ) {
return;
}

/**
* Replace Site URL JAMStack URL as needed.
*
* @author WebDevStudios
* @since 1.0.0
* @param array $breadcrumbs Yoast SEO breadcrumbs.
* @return array Filtered breadcrumbs.
*/
function breadcrumb_links( array $breadcrumbs ) {
if ( ! defined( 'HEADLESS_FRONTEND_URL' ) ) {
return $breadcrumbs;
}

$base_url = rtrim( HEADLESS_FRONTEND_URL, '/' );

// Override domain in breadcrumbs.
return array_map(
function( $breadcrumb ) use ( $base_url ) {
$parsed_url = wp_parse_url( $breadcrumb['url'] );
$path = $parsed_url['path'] ?? '';
$breadcrumb['url'] = "{$base_url}{$path}";

return $breadcrumb;
},
$breadcrumbs
);
}
add_filter( 'wpseo_breadcrumb_links', __NAMESPACE__ . '\breadcrumb_links' );
101 changes: 101 additions & 0 deletions inc/wp-graphql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
/**
* WP GraphQL settings.
*
* @see https://wordpress.org/plugins/wp-graphql/
* @author WebDevStudios
* @package WDS_Headless_SEO
* @since 1.0.0
*/

namespace WDS_Headless_SEO;

use WPSEO_Options;

/**
* Add archive SEO field to CPT archive queries in GraphQL.
*
* @author WebDevStudios
* @since 1.0.0
* @return void
*/
function register_archive_seo() {
if ( ! class_exists( 'WPSEO_Options' ) ) {
return;
}

register_graphql_object_type(
'ArchiveSeo',
[
'description' => esc_html__( 'Archive SEO data', 'wds-headless-seo' ),
'fields' => [
'title' => [ 'type' => 'String' ],
'metaDesc' => [ 'type' => 'String' ],
'metaRobotsNoindex' => [ 'type' => 'String' ],
'metaRobotsNofollow' => [ 'type' => 'String' ],
'canonical' => [ 'type' => 'String' ],
],
]
);

// Get post types that support archives (will not include "post" PT).
$post_types = get_post_types(
[
'has_archive' => true,
],
'objects'
);

// Bail if we don't have an array of post types.
if ( empty( $post_types ) || ! is_array( $post_types ) ) {
return;
}

// Register GraphQL field on each post type's plural/archive connection.
foreach ( $post_types as $post_type => $post_type_object ) {
if ( ! $post_type_object->show_in_graphql || ! $post_type_object->graphql_single_name ) {
break;
}

$pt_singular = ucfirst( $post_type_object->graphql_single_name );

register_graphql_field(
"RootQueryTo{$pt_singular}Connection",
'archiveSeo',
[
'type' => 'ArchiveSeo',
'description' => sprintf(
/* translators: the post type label. */
__( 'The Yoast SEO data of the %s post type archive', 'wds-headless-seo' ),
$post_type_object->label
),
'resolve' => function () use ( $post_type, $post_type_object ) {
// Surface info: https://developer.yoast.com/blog/yoast-seo-14-0-using-yoast-seo-surfaces/.
/* We would ideally use this surface to determine meta title and desc, but the surface is not pulling the correct meta for those fields (as of Yoast 15.9.2, it seems to be pulling some default archive meta title and a blank desc). */
$archive_seo = YoastSEO()->meta->for_post_type_archive( $post_type );

// Retrieve Yoast SEO options for archive title and desc instead.
$wpseo_options = WPSEO_Options::get_instance();
$title = $wpseo_options->get( "title-ptarchive-{$post_type}" );
$description = $wpseo_options->get( "metadesc-ptarchive-{$post_type}", $archive_seo->description );

/* Manually replace title vars that won't get caught in next step (e.g., pt_single, pt_plural) -- these appear to be "advanced" vars that require a single post to be passed, rather than a post type object. */
$title = str_ireplace( '%%pt_single%%', $post_type_object->labels->singular_name, $title );
$title = str_ireplace( '%%pt_plural%%', $post_type_object->labels->name, $title );

// Replace standard title vars with post type object.
$title = wpseo_replace_vars( $title, $post_type_object );

return [
'title' => wp_gql_seo_format_string( $title ?? $archive_seo->title ),
'metaDesc' => wp_gql_seo_format_string( $description ),
'metaRobotsNoindex' => $archive_seo->robots['index'],
'metaRobotsNofollow' => $archive_seo->robots['follow'],
'canonical' => $archive_seo->canonical,
];
},
]
);
}
}
add_action( 'graphql_register_types', __NAMESPACE__ . '\register_archive_seo' );
33 changes: 33 additions & 0 deletions wds-headless-seo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Plugin Name: WDS Headless (SEO)
* Plugin URI: https://github.com/WebDevStudios/nextjs-wordpress-starter
* Description: WDS Headless extension handling SEO functionality.
* Author: WebDevStudios <contact@webdevstudios.com>
* Author URI: https://webdevstudios.com
* Version: 1.0.0
* Requires at least: 5.6
* Requires PHP: 7.4
* License: GPL-2
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
*
* @package WDS_Headless_SEO
*/

namespace WDS_Headless_SEO;

if ( ! defined( 'ABSPATH' ) ) {
return;
}

// Define constants.
define( 'WDS_HEADLESS_SEO_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'WDS_HEADLESS_SEO_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'WDS_HEADLESS_SEO_VERSION', '1.0.0' );

// Register de/activation hooks.
register_activation_hook( __FILE__, __NAMESPACE__ . '\activation_callback' );
register_deactivation_hook( __FILE__, __NAMESPACE__ . '\deactivation_callback' );

require_once 'inc/links.php';
require_once 'inc/wp-graphql.php';

0 comments on commit 847be55

Please sign in to comment.