Instantly share code, notes, and snippets.
Last active
November 4, 2023 02:01
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save EarthmanWeb/448d574ddb68351bde8abb6318a8baf9 to your computer and use it in GitHub Desktop.
SEO / OG Meta Tags
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: OG Meta Tags | |
* Description: Adds OG meta tags to the head of the document with dynamic default values. | |
* Version: 1.0.0 | |
*/ | |
/** | |
* Adds the SEO meta tags to the head of the document. | |
* | |
* @return void | |
*/ | |
function og_insert_meta_tags() { | |
// og_log( 'meta', get_post_meta( get_the_ID() ), 1, 1 ); | |
// if this is the home page, use the site description for the description | |
// and use the site url instead of permalink | |
// and use the logo image instead of the featured image | |
if ( is_front_page() ) { | |
$description = get_bloginfo( 'description' ); | |
$url = home_url( '/' ); | |
$image = wp_get_attachment_image_url( get_theme_mod( 'custom_logo' ), 'full' ); | |
} else { | |
$post_id = get_the_ID(); | |
$description = get_the_excerpt(); | |
// trim only the first instance of wp_get_document_title() | |
$description = preg_replace( '/^' . get_bloginfo( 'name' ) . ' /', '', $description, 1 ); | |
$url = get_permalink(); | |
$image = get_the_post_thumbnail_url( $post_id, 'large' ); | |
if ( ! $image ) { | |
$image = wp_get_attachment_image_url( get_theme_mod( 'custom_logo' ), 'full' ); | |
} | |
// check for reading time meta | |
$reading_time = get_post_meta( $post_id, 'estimated_reading_time_minutes', true ); | |
if ( empty( $reading_time ) ) { | |
$post_content = strip_tags( get_post_field( 'post_content', $post_id ) ); | |
if ( ! empty( $post_content ) ) { | |
$word_count = str_word_count( strip_tags( $post_content ) ); | |
$reading_time = ceil( $word_count / 300 ) . ' minutes'; | |
} | |
} else { | |
$reading_time .= ' minutes'; | |
} | |
} | |
// Dynamic defaults based on current site | |
$values = array( | |
'og_locale' => get_locale(), | |
'og_type' => 'website', | |
'og_title' => wp_get_document_title(), | |
'og_description' => $description, | |
'og_url' => $url, | |
'og_site_name' => get_bloginfo( 'name' ), | |
'article_modified' => get_the_modified_date( 'c' ), | |
'og_image' => $image, | |
'twitter_card' => 'summary_large_image', | |
'reading_time' => ! empty( $reading_time ) ? $reading_time : '', | |
); | |
// get all the locale alternatives from polylang, if they exist | |
if ( function_exists( 'pll_languages_list' ) ) { | |
$locale_alternatives = pll_languages_list( array( 'fields' => 'locale' ) ); | |
$locale_alternatives = array_filter( $locale_alternatives ); | |
$locale_alternatives = array_values( $locale_alternatives ); | |
} | |
// Output the meta tags | |
echo '<!-- Custom OG Tags -->' . "\n"; | |
echo '<meta property="og:locale" content="' . esc_attr( $values['og_locale'] ) . '" class="og-meta-tag" />' . "\n"; | |
// add all locales atlernatives, one tag for each alternate | |
if ( ! empty( $locale_alternatives ) ) { | |
foreach ( $locale_alternatives as $locale ) { | |
echo '<meta property="og:locale:alternate" content="' . esc_attr( $locale ) . '" class="og-meta-tag" />' . "\n"; | |
} | |
} | |
echo '<meta property="og:type" content="' . esc_attr( $values['og_type'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta property="og:title" content="' . esc_attr( $values['og_title'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta property="og:description" content="' . esc_attr( $values['og_description'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta property="og:url" content="' . esc_url( $values['og_url'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta property="og:site_name" content="' . esc_attr( $values['og_site_name'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta property="article:modified_time" content="' . esc_attr( $values['article_modified'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta property="og:image" content="' . esc_url( $values['og_image'] ) . '" class="og-meta-tag" />' . "\n"; | |
echo '<meta name="twitter:card" content="' . esc_attr( $values['twitter_card'] ) . '" class="og-meta-tag" />' . "\n"; | |
// add these only if the value is set for reading time | |
if ( ! empty( $values['reading_time'] ) ) { | |
echo '<meta name="twitter:label1" content="Est. reading time" class="og-meta-tag" />' . "\n"; | |
echo '<meta name="twitter:data1" content="' . esc_attr( $values['reading_time'] ) . '" class="og-meta-tag" />' . "\n"; | |
} | |
echo '<script type="application/ld+json" class="og-schema-graph">' . og_insert_schema_graph() . '</script>' . "\n"; | |
echo '<!-- / Custom OG Tags -->' . "\n"; | |
} | |
add_action( 'wp_head', 'og_insert_meta_tags' ); | |
/** | |
* Returns the schema graph for the current post. | |
* | |
* @return void | |
*/ | |
function og_insert_schema_graph() { | |
$post = get_post(); | |
if ( ! $post ) { | |
return; | |
} | |
$image = get_the_post_thumbnail_url( $post->ID, 'full' ); | |
if ( ! $image ) { | |
$image = wp_get_attachment_image_url( get_theme_mod( 'custom_logo' ), 'large' ); | |
} | |
$schema_graph = array( | |
'@context' => 'https://schema.org', | |
'@graph' => array( | |
array( | |
'@type' => 'WebPage', | |
'@id' => get_permalink(), | |
'url' => get_permalink(), | |
'name' => wp_get_document_title(), | |
'isPartOf' => array( | |
'@id' => home_url( '#website' ), | |
), | |
'about' => array( | |
'@id' => home_url( '#organization' ), | |
), | |
'primaryImageOfPage' => array( | |
'@id' => home_url( '#primaryimage' ), | |
), | |
'image' => array( | |
'@id' => home_url( '#primaryimage' ), | |
), | |
'thumbnailUrl' => get_the_post_thumbnail_url( $post->ID, 'full' ), | |
'datePublished' => get_the_date( 'c', $post->ID ), | |
'dateModified' => get_the_modified_date( 'c', $post->ID ), | |
'breadcrumb' => array( | |
'@id' => home_url( '#breadcrumb' ), | |
), | |
'inLanguage' => get_locale(), | |
'potentialAction' => array( | |
array( | |
'@type' => 'ReadAction', | |
'target' => array( | |
get_permalink(), | |
), | |
), | |
), | |
), | |
array( | |
'@type' => 'ImageObject', | |
'inLanguage' => get_locale(), | |
'@id' => home_url( '#primaryimage' ), | |
'url' => $image, | |
'contentUrl' => $image, | |
'width' => 900, | |
'height' => 675, | |
'caption' => get_the_post_thumbnail_caption( $post->ID ), | |
), | |
array( | |
'@type' => 'BreadcrumbList', | |
'@id' => home_url( '#breadcrumb' ), | |
'itemListElement' => array( | |
array( | |
'@type' => 'ListItem', | |
'position' => 1, | |
'name' => get_bloginfo( 'name' ), | |
'item' => home_url(), | |
), | |
array( | |
'@type' => 'ListItem', | |
'position' => 2, | |
'name' => wp_get_document_title(), | |
'item' => get_permalink(), | |
), | |
), | |
), | |
array( | |
'@type' => 'WebSite', | |
'@id' => home_url( '#website' ), | |
'url' => home_url(), | |
'name' => get_bloginfo( 'name' ), | |
'description' => get_bloginfo( 'description' ), | |
'publisher' => array( | |
'@id' => home_url( '#organization' ), | |
), | |
'potentialAction' => array( | |
array( | |
'@type' => 'SearchAction', | |
'target' => array( | |
'@type' => 'EntryPoint', | |
'urlTemplate' => home_url( '/?s={search_term_string}' ), | |
), | |
'query-input' => 'required name=search_term_string', | |
), | |
), | |
'inLanguage' => get_locale(), | |
), | |
array( | |
'@type' => 'Organization', | |
'@id' => home_url( '#organization' ), | |
'name' => get_bloginfo( 'name' ), | |
'url' => home_url(), | |
'logo' => array( | |
'@type' => 'ImageObject', | |
'inLanguage' => get_locale(), | |
'@id' => home_url( '#/schema/logo/image/' ), | |
'url' => wp_get_attachment_image_url( get_theme_mod( 'custom_logo' ), 'full' ), | |
'contentUrl' => wp_get_attachment_image_url( get_theme_mod( 'custom_logo' ), 'full' ), | |
'width' => 200, | |
'height' => 75, | |
'caption' => get_bloginfo( 'name' ), | |
), | |
'image' => array( | |
'@id' => home_url( '#/schema/logo/image/' ), | |
), | |
), | |
), | |
); | |
return wp_json_encode( $schema_graph ); | |
} | |
/** | |
* Adds a reading time meta value to the post. | |
* | |
* @param [type] $post_id The post ID. | |
* @return void | |
*/ | |
function og_save_estimated_reading_time( $post_id ) { | |
// only do this for pages and posts | |
if ( ! in_array( get_post_type( $post_id ), array( 'news', 'page' ) ) ) { | |
$post_content = get_the_content( 'post_content', $post_id ); | |
$word_count = str_word_count( strip_tags( $post_content ) ); | |
$reading_time = ceil( $word_count / 300 ); // Average reading speed is around 300 words per minute. | |
update_post_meta( $post_id, 'estimated_reading_time_minutes', $reading_time ); | |
} | |
} | |
add_action( 'save_post', 'og_save_estimated_reading_time' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment