Structured data improvement

This commit is contained in:
opportus 2016-05-26 07:57:50 +02:00
parent 384129e130
commit f05eea7117
8 changed files with 175 additions and 50 deletions

View file

@ -7,7 +7,7 @@
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?> itemscope="" itemtype="http://schema.org/BlogPosting">
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php
/**

View file

@ -7,7 +7,7 @@
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?> itemscope="" itemtype="http://schema.org/BlogPosting">
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php
/**

View file

@ -8,7 +8,7 @@
*/
?><!DOCTYPE html>
<html <?php language_attributes(); ?> <?php storefront_html_tag_schema(); ?>>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">

View file

@ -30,8 +30,9 @@ if ( ! class_exists( 'Storefront' ) ) :
add_action( 'wp_enqueue_scripts', array( $this, 'child_scripts' ), 30 ); // After WooCommerce.
add_filter( 'body_class', array( $this, 'body_classes' ) );
add_filter( 'wp_page_menu_args', array( $this, 'page_menu_args' ) );
add_action( 'enqueue_embed_scripts', array( $this, 'print_embed_styles' ) );
}
add_action( 'enqueue_embed_scripts', array( $this, 'print_embed_styles' ) );
add_action( 'wp_footer', array( $this, 'get_structured_data' ) );
}
/**
* Sets up theme defaults and registers support for various WordPress features.
@ -312,7 +313,41 @@ if ( ! class_exists( 'Storefront' ) ) :
}
</style>
<?php
}
}
/**
* As far as I see, it's the most appropriate way to store the data generated from the post and product loop...
*/
private static $structured_data;
/**
* Check if the passed $json variable is an array and store it into the property...
*/
public static function set_structured_data( $json ) {
if ( ! is_array( $json ) ) {
return;
}
self::$structured_data[] = $json;
}
/**
* If self::$structured_data is set, wrap and echo it...
* Hooked into the `wp_footer` action.
*/
public function get_structured_data() {
if ( ! self::$structured_data ) {
return;
}
$json['@context'] = 'http://schema.org/';
if ( count( self::$structured_data ) > 1 ) {
$json['@graph'] = self::$structured_data;
}
else {
$json = $json + self::$structured_data[0];
}
echo '<script type="application/ld+json">' . wp_json_encode( $json ) . '</script>';
}
}
endif;

View file

@ -19,28 +19,6 @@ if ( ! function_exists( 'storefront_display_comments' ) ) {
}
}
if ( ! function_exists( 'storefront_html_tag_schema' ) ) {
/**
* Schema type
*
* @return void
*/
function storefront_html_tag_schema() {
$schema = 'http://schema.org/';
$type = 'WebPage';
if ( is_singular( 'post' ) ) {
$type = 'Article';
} elseif ( is_author() ) {
$type = 'ProfilePage';
} elseif ( is_search() ) {
$type = 'SearchResultsPage';
}
echo 'itemscope="itemscope" itemtype="' . esc_attr( $schema ) . esc_attr( $type ) . '"';
}
}
if ( ! function_exists( 'storefront_comment' ) ) {
/**
* Storefront comment template
@ -276,7 +254,7 @@ if ( ! function_exists( 'storefront_page_header' ) ) {
<header class="entry-header">
<?php
storefront_post_thumbnail( 'full' );
the_title( '<h1 class="entry-title" itemprop="name">', '</h1>' );
the_title( '<h1 class="entry-title">', '</h1>' );
?>
</header><!-- .entry-header -->
<?php
@ -291,7 +269,7 @@ if ( ! function_exists( 'storefront_page_content' ) ) {
*/
function storefront_page_content() {
?>
<div class="entry-content" itemprop="mainContentOfPage">
<div class="entry-content">
<?php the_content(); ?>
<?php
wp_link_pages( array(
@ -316,13 +294,13 @@ if ( ! function_exists( 'storefront_post_header' ) ) {
<?php
if ( is_single() ) {
storefront_posted_on();
the_title( '<h1 class="entry-title" itemprop="name headline">', '</h1>' );
the_title( '<h1 class="entry-title">', '</h1>' );
} else {
if ( 'post' == get_post_type() ) {
storefront_posted_on();
}
the_title( sprintf( '<h1 class="entry-title" itemprop="name headline"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h1>' );
the_title( sprintf( '<h1 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h1>' );
}
?>
</header><!-- .entry-header -->
@ -338,7 +316,7 @@ if ( ! function_exists( 'storefront_post_content' ) ) {
*/
function storefront_post_content() {
?>
<div class="entry-content" itemprop="articleBody">
<div class="entry-content">
<?php
storefront_post_thumbnail( 'full' );
@ -452,9 +430,9 @@ if ( ! function_exists( 'storefront_posted_on' ) ) {
* Prints HTML with meta information for the current post-date/time and author.
*/
function storefront_posted_on() {
$time_string = '<time class="entry-date published updated" datetime="%1$s" itemprop="datePublished">%2$s</time>';
$time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>';
if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
$time_string = '<time class="entry-date published" datetime="%1$s">%2$s</time> <time class="updated" datetime="%3$s" itemprop="datePublished">%4$s</time>';
$time_string = '<time class="entry-date published" datetime="%1$s">%2$s</time> <time class="updated" datetime="%3$s">%4$s</time>';
}
$time_string = sprintf( $time_string,
@ -480,7 +458,6 @@ if ( ! function_exists( 'storefront_posted_on' ) ) {
),
'time' => array(
'datetime' => array(),
'itemprop' => array(),
'class' => array(),
),
) );
@ -779,7 +756,7 @@ if ( ! function_exists( 'storefront_post_thumbnail' ) ) {
*/
function storefront_post_thumbnail( $size ) {
if ( has_post_thumbnail() ) {
the_post_thumbnail( $size, array( 'itemprop' => 'image' ) );
the_post_thumbnail( $size );
}
}
}
@ -797,3 +774,62 @@ function storefront_primary_navigation_wrapper() {
function storefront_primary_navigation_wrapper_close() {
echo '</section>';
}
if ( ! function_exists( 'storefront_init_structured_data' ) ) {
/**
* Generate the structured data...
* Initialize Storefront::$structured_data via Storefront::set_structured_data()...
* Hooked into:
* `storefront_loop_post`
* `storefront_single_post`
* `storefront_page`
* Apply `storefront_structured_data` filter hook for structured data customization :)
*/
function storefront_init_structured_data() {
if ( is_home() || is_category() || is_date() || is_search() || is_single() && ! is_woocommerce() ) {
$image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'normal' );
$logo = wp_get_attachment_image_src( get_theme_mod( 'custom_logo' ), 'full' );
$json['@type'] = 'BlogPosting';
$json['mainEntityOfPage'] = array(
'@type' => 'webpage',
'@id' => get_the_permalink()
);
$json['image'] = array(
'@type' => 'ImageObject',
'url' => $image[0],
'width' => $image[1],
'height' => $image[2]
);
$json['publisher'] = array(
'@type' => 'organization',
'name' => get_bloginfo( 'name' ),
'logo' => array(
'@type' => 'ImageObject',
'url' => $logo[0],
'width' => $logo[1],
'height' => $logo[2]
)
);
$json['author'] = array(
'@type' => 'person',
'name' => get_the_author()
);
$json['datePublished'] = get_post_time( 'c' );
$json['dateModified'] = get_the_modified_date( 'c' );
$json['name'] = get_the_title();
$json['headline'] = get_the_title();
$json['description'] = get_the_excerpt();
}
elseif ( is_page() ) {
$json['@type'] = 'WebPage';
$json['url'] = get_the_permalink();
$json['name'] = get_the_title();
$json['description'] = get_the_excerpt();
}
if ( isset( $json ) ) {
Storefront::set_structured_data( apply_filters( 'storefront_structured_data', $json ) );
}
}
}

View file

@ -63,28 +63,33 @@ add_action( 'homepage', 'storefront_best_selling_products', 70 );
* @see storefront_post_header()
* @see storefront_post_meta()
* @see storefront_post_content()
* @see storefront_init_structured_data()
* @see storefront_paging_nav()
* @see storefront_single_post_header()
* @see storefront_post_nav()
* @see storefront_display_comments()
*/
add_action( 'storefront_loop_post', 'storefront_post_header', 10 );
add_action( 'storefront_loop_post', 'storefront_post_meta', 20 );
add_action( 'storefront_loop_post', 'storefront_post_content', 30 );
add_action( 'storefront_loop_after', 'storefront_paging_nav', 10 );
add_action( 'storefront_single_post', 'storefront_post_header', 10 );
add_action( 'storefront_single_post', 'storefront_post_meta', 20 );
add_action( 'storefront_single_post', 'storefront_post_content', 30 );
add_action( 'storefront_single_post_after', 'storefront_post_nav', 10 );
add_action( 'storefront_single_post_after', 'storefront_display_comments', 20 );
add_action( 'storefront_loop_post', 'storefront_post_header', 10 );
add_action( 'storefront_loop_post', 'storefront_post_meta', 20 );
add_action( 'storefront_loop_post', 'storefront_post_content', 30 );
add_action( 'storefront_loop_post', 'storefront_init_structured_data', 40 );
add_action( 'storefront_loop_after', 'storefront_paging_nav', 10 );
add_action( 'storefront_single_post', 'storefront_post_header', 10 );
add_action( 'storefront_single_post', 'storefront_post_meta', 20 );
add_action( 'storefront_single_post', 'storefront_post_content', 30 );
add_action( 'storefront_single_post', 'storefront_init_structured_data', 40 );
add_action( 'storefront_single_post_after', 'storefront_post_nav', 10 );
add_action( 'storefront_single_post_after', 'storefront_display_comments', 20 );
/**
* Pages
*
* @see storefront_page_header()
* @see storefront_page_content()
* @see storefront_init_structured_data()
* @see storefront_display_comments()
*/
add_action( 'storefront_page', 'storefront_page_header', 10 );
add_action( 'storefront_page', 'storefront_page_content', 20 );
add_action( 'storefront_page_after', 'storefront_display_comments', 10 );
add_action( 'storefront_page', 'storefront_page_header', 10 );
add_action( 'storefront_page', 'storefront_page_content', 20 );
add_action( 'storefront_page', 'storefront_init_structured_data', 30 );
add_action( 'storefront_page_after', 'storefront_display_comments', 10 );

View file

@ -315,5 +315,47 @@ if ( ! function_exists( 'storefront_handheld_footer_bar_account_link' ) ) {
*/
function storefront_handheld_footer_bar_account_link() {
echo '<a href="' . esc_url( get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ) ) . '">' . esc_attr__( 'My Account', 'storefront' ) . '</a>';
}
}
}
if ( ! function_exists( 'storefront_woocommerce_init_structured_data' ) ) {
/**
* Generate product category structured data...
* Hooked into the `woocommerce_before_shop_loop_item` action...
* Apply the `storefront_woocommerce_structured_data` filter hook for structured data customization...
*/
function storefornt_woocommerce_init_structured_data() {
if ( ! is_product_category() ) return;
global $product;
$json['@type'] = 'Product';
$json['name'] = get_the_title();
$json['image'] = wp_get_attachment_url( $product->get_image_id() );
$json['description'] = get_the_excerpt();
$json['sku'] = $product->get_sku();
$json['brand'] = array(
'@type' => 'Thing',
'name' => $product->get_attribute( __( 'brand', 'storefront' ) )
);
if ( $product->get_rating_count() ) {
$json['aggregateRating'] = array(
'@type' => 'AggregateRating',
'ratingValue' => $product->get_average_rating(),
'reviewCount' => $product->get_rating_count()
);
}
$json['offers'] = array(
'@type' => 'Offer',
'priceCurrency' => get_woocommerce_currency(),
'price' => $product->get_price(),
'itemCondition' => 'http://schema.org/NewCondition',
'availability' => 'http://schema.org/' . $stock = ( $product->is_in_stock ? 'InStock' : 'OutOfStock' ),
'seller' => array(
'@type' => 'Organization',
'name' => get_bloginfo( 'name' )
)
);
if ( ! isset( $json ) ) return;
Storefront::set_structured_data( apply_filters( 'storefront_woocommerce_structured_data', $json ) );
}
}

View file

@ -64,6 +64,13 @@ add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_show_pro
add_action( 'storefront_header', 'storefront_product_search', 40 );
add_action( 'storefront_header', 'storefront_header_cart', 60 );
/**
* Structured Data
*
* @see storefront_woocommerce_init_structured_data()
*/
add_action( 'woocommerce_before_shop_loop_item', 'storefornt_woocommerce_init_structured_data' );
if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '2.3', '>=' ) ) {
add_filter( 'woocommerce_add_to_cart_fragments', 'storefront_cart_link_fragment' );
} else {