web-stories-wp icon indicating copy to clipboard operation
web-stories-wp copied to clipboard

Shopping: Add structured data in Yoast SEO

Open swissspidy opened this issue 2 years ago • 10 comments

Feature Description

This is a follow-up to #11624.

We wanna do the same thing, but so that Yoast SEO adds this structured data here:

https://github.com/Yoast/wordpress-seo/blob/f3cdaaebed87579839502e8685d4e107f1f0469d/src/integrations/third-party/web-stories.php

Alternatives Considered

Additional Context

swissspidy avatar Sep 05 '22 16:09 swissspidy

In my discovery for this ticket I found Yoast WooCommerce SEO plugin. I wonder if need to do testing against this plugin or intergration points etc.

spacedmonkey avatar Sep 14 '22 15:09 spacedmonkey

Is the plan here to just copy and paste the get_product_data method. This maybe hard, as how this is setup, we don't really have access to Discovery.

If we change our plugin like this

https://github.com/GoogleForCreators/web-stories-wp/blob/e71be362611f257011c0db1e593fe64212845a61/includes/Discovery.php#L172-L183

to

$metadata = $this->get_schemaorg_metadata();
 /**
 * Filters filter to enable / disable schemaorg metadata.
 *
 * @since 1.2.0
 *
 * @param bool $enable_schemaorg_metadata Enable / disable schemaorg metadata. Default to true.
 * @param array $metadata The structured data.
 */
 $enable_schemaorg_metadata = apply_filters( 'web_stories_enable_schemaorg_metadata', true, $metadata );
 if ( ! $enable_schemaorg_metadata ) {
     return;
 }

That was, we can capture the metadata is a class property and means it will be easier to get generate schema in yoast plugin.

Get this data like this.

add_action( 'web_stories_enable_schemaorg_metadata', [ $this, 'capture_data' ], 10, 2 );
function capture_data( $bool, $data ) {
   $this->data = $data;
   return false; 
}

Then you can get product data like this

echo $this->data['mainEntity'];

spacedmonkey avatar Sep 14 '22 16:09 spacedmonkey

The idea is to submit a PR to Yoast that makes changes to https://github.com/Yoast/wordpress-seo/blob/f3cdaaebed87579839502e8685d4e107f1f0469d/src/integrations/third-party/web-stories.php in order to:

  1. Grab the products from post meta
  2. Assemble the products data in the way we need it
  3. Add this information to Yoast's schema output using Yoast's schema API

References:

  • https://developer.yoast.com/features/schema/integration-guidelines/
  • https://developer.yoast.com/features/schema/api

Note: these docs are for third-party plugins, but the integration in Yoast itself is similar with all the Schema classes etc. It gives a general idea of how things work.

We should not need to access the Discovery class or make any changes to it.

swissspidy avatar Sep 14 '22 18:09 swissspidy

Right, what I am trying to avoid here, is having hard code the post meta and basically copy and paste the logic from our plugin to there. Which is what you sound like you. My worry here, is the if we change the structure of the data in our post meta, use a different key, we will have to update the integration. Also our plugin, in the discovery class, is already doing the heavily lifting of get product data and formatting the data completely. The changes are recommended simple but open us up to reuse our data and for us to have a little bit more control.

spacedmonkey avatar Sep 15 '22 11:09 spacedmonkey

What do you think about adding a get_products() method to the Story model instead? That adds a little bit of abstraction.

Also our plugin, in the discovery class, is already doing the heavily lifting of get product data and formatting the data completely.

The formatting doesn't help much because Yoast adds schema data in a different way, so it will be custom anyway.

So get_products() would just return the list of products without formatting.

swissspidy avatar Sep 15 '22 18:09 swissspidy

So get_products() would just return the list of products without formatting.

I like that idea!

I would look something like this.

$story = new Story();
$story->load_from_post( $presentation->model->object_id );
$products = $story->get_products();
...

I wonder if get_products should return an array of Project objects. Might make it a little cleaner and easier to control.

spacedmonkey avatar Sep 16 '22 13:09 spacedmonkey

I put together a POC move the get_products method into story model. I like it, it is clean.

One thing, we are going to have to do a check for method_exists in the story model. For backwards compatibility reasons / if someone has an older version of the plugin installed.

spacedmonkey avatar Sep 16 '22 16:09 spacedmonkey

Sounds good 👍

swissspidy avatar Sep 16 '22 19:09 swissspidy

Should we also look at adding video data? See #12221

spacedmonkey avatar Sep 26 '22 10:09 spacedmonkey

Should we also look at adding video data? See #12221

Yeah why not 👍

swissspidy avatar Sep 28 '22 07:09 swissspidy

Created #12409 as a follow-up

swissspidy avatar Oct 02 '22 10:10 swissspidy