|
@@ -132,6 +132,7 @@ function dw_seo_jsonld() {
|
|
|
$person = array(
|
|
$person = array(
|
|
|
'@context' => 'https://schema.org',
|
|
'@context' => 'https://schema.org',
|
|
|
'@type' => 'Person',
|
|
'@type' => 'Person',
|
|
|
|
|
+ '@id' => DW_CANONICAL . '/#person', // stable identity per-page nodes reference
|
|
|
'name' => DW_SITE_NAME,
|
|
'name' => DW_SITE_NAME,
|
|
|
'url' => DW_CANONICAL,
|
|
'url' => DW_CANONICAL,
|
|
|
'image' => DW_CANONICAL . '/og-image.jpg',
|
|
'image' => DW_CANONICAL . '/og-image.jpg',
|
|
@@ -162,10 +163,88 @@ function dw_seo_jsonld() {
|
|
|
echo '<script type="application/ld+json">' . wp_json_encode( $website, JSON_UNESCAPED_SLASHES ) . "</script>\n";
|
|
echo '<script type="application/ld+json">' . wp_json_encode( $website, JSON_UNESCAPED_SLASHES ) . "</script>\n";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/** BlogPosting JSON-LD on single posts. author/publisher reference the site Person
|
|
|
|
|
+ * (@id) emitted by dw_seo_jsonld() on the same page, so it all resolves to one entity. */
|
|
|
|
|
+function dw_seo_jsonld_article() {
|
|
|
|
|
+ if ( ! is_single() ) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ $id = get_queried_object_id();
|
|
|
|
|
+ $url = get_permalink( $id );
|
|
|
|
|
+ $author = array( '@type' => 'Person', '@id' => DW_CANONICAL . '/#person', 'name' => DW_SITE_NAME );
|
|
|
|
|
+ $node = array(
|
|
|
|
|
+ '@context' => 'https://schema.org',
|
|
|
|
|
+ '@type' => 'BlogPosting',
|
|
|
|
|
+ '@id' => $url . '#article',
|
|
|
|
|
+ 'mainEntityOfPage' => $url,
|
|
|
|
|
+ 'url' => $url,
|
|
|
|
|
+ 'headline' => get_the_title( $id ),
|
|
|
|
|
+ 'datePublished' => get_the_date( 'c', $id ),
|
|
|
|
|
+ 'dateModified' => get_the_modified_date( 'c', $id ),
|
|
|
|
|
+ 'author' => $author,
|
|
|
|
|
+ 'publisher' => $author,
|
|
|
|
|
+ 'image' => dw_seo_image(),
|
|
|
|
|
+ 'description' => dw_seo_description(),
|
|
|
|
|
+ );
|
|
|
|
|
+ echo '<script type="application/ld+json">' . wp_json_encode( $node, JSON_UNESCAPED_SLASHES ) . "</script>\n";
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** BreadcrumbList JSON-LD — hierarchical pages (Home > ancestors > page), posts
|
|
|
|
|
+ * (Home > first category > post), and term archives (Home > term). */
|
|
|
|
|
+function dw_seo_jsonld_breadcrumbs() {
|
|
|
|
|
+ if ( is_front_page() ) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ $crumbs = array( array( 'name' => 'Home', 'url' => home_url( '/' ) ) );
|
|
|
|
|
+
|
|
|
|
|
+ if ( is_singular() ) {
|
|
|
|
|
+ $id = get_queried_object_id();
|
|
|
|
|
+ if ( is_page() ) {
|
|
|
|
|
+ foreach ( array_reverse( get_post_ancestors( $id ) ) as $ancestor ) {
|
|
|
|
|
+ $crumbs[] = array( 'name' => get_the_title( $ancestor ), 'url' => get_permalink( $ancestor ) );
|
|
|
|
|
+ }
|
|
|
|
|
+ } elseif ( is_single() ) {
|
|
|
|
|
+ $cats = get_the_category( $id );
|
|
|
|
|
+ if ( ! empty( $cats ) ) {
|
|
|
|
|
+ $crumbs[] = array( 'name' => $cats[0]->name, 'url' => get_category_link( $cats[0]->term_id ) );
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $crumbs[] = array( 'name' => get_the_title( $id ), 'url' => get_permalink( $id ) );
|
|
|
|
|
+ } elseif ( is_category() || is_tag() || is_tax() ) {
|
|
|
|
|
+ $term = get_queried_object();
|
|
|
|
|
+ $link = get_term_link( $term );
|
|
|
|
|
+ $crumbs[] = array( 'name' => $term->name, 'url' => is_wp_error( $link ) ? home_url( '/' ) : $link );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return; // home / search / date views get no meaningful trail
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ( count( $crumbs ) < 2 ) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $items = array();
|
|
|
|
|
+ foreach ( $crumbs as $i => $c ) {
|
|
|
|
|
+ $items[] = array(
|
|
|
|
|
+ '@type' => 'ListItem',
|
|
|
|
|
+ 'position' => $i + 1,
|
|
|
|
|
+ 'name' => $c['name'],
|
|
|
|
|
+ 'item' => $c['url'],
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ $node = array(
|
|
|
|
|
+ '@context' => 'https://schema.org',
|
|
|
|
|
+ '@type' => 'BreadcrumbList',
|
|
|
|
|
+ 'itemListElement' => $items,
|
|
|
|
|
+ );
|
|
|
|
|
+ echo '<script type="application/ld+json">' . wp_json_encode( $node, JSON_UNESCAPED_SLASHES ) . "</script>\n";
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/** Emit the whole head block. Hooked to wp_head; front-page.php calls it directly. */
|
|
/** Emit the whole head block. Hooked to wp_head; front-page.php calls it directly. */
|
|
|
function dw_seo_head() {
|
|
function dw_seo_head() {
|
|
|
dw_seo_favicon();
|
|
dw_seo_favicon();
|
|
|
dw_seo_opengraph();
|
|
dw_seo_opengraph();
|
|
|
dw_seo_jsonld();
|
|
dw_seo_jsonld();
|
|
|
|
|
+ dw_seo_jsonld_article();
|
|
|
|
|
+ dw_seo_jsonld_breadcrumbs();
|
|
|
}
|
|
}
|
|
|
add_action( 'wp_head', 'dw_seo_head', 5 );
|
|
add_action( 'wp_head', 'dw_seo_head', 5 );
|