/** * Return an array of Schema.org metatags suitable for the author object of * the content. Accepts the $post object as argument. */ function amt_get_schemaorg_author_metatags($author_id, $options) { //$author_obj = get_user_by( 'id', $author_id ); $metadata_arr = array(); // name $display_name = get_the_author_meta('display_name', $author_id); $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr($display_name) . '" />'; // description // Here we sanitize the provided description for safety $author_description = sanitize_text_field(amt_sanitize_description(get_the_author_meta('description', $author_id))); if (!empty($author_description)) { $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($author_description) . '" />'; } // Profile Image // First use the global image override URL $image_data = amt_get_image_data(amt_get_user_meta_image_url($author_id)); if (!empty($image_data)) { $image_size = apply_filters('amt_image_size_index', 'full'); $image_meta_tags = amt_get_schemaorg_image_metatags($options, $image_data, $size = $image_size); if (!empty($image_meta_tags)) { $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; $metadata_arr = array_merge($metadata_arr, $image_meta_tags); $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; } } else { $author_email = sanitize_email(get_the_author_meta('user_email', $author_id)); $avatar_size = apply_filters('amt_avatar_size', 128); $avatar_url = ''; // First try to get the avatar link by using get_avatar(). // Important: for this to work the "Show Avatars" option should be enabled in Settings > Discussion. $avatar_img = get_avatar(get_the_author_meta('ID', $author_id), $avatar_size, '', get_the_author_meta('display_name', $author_id)); if (!empty($avatar_img)) { if (preg_match("#src=['\"]([^'\"]+)['\"]#", $avatar_img, $matches)) { $avatar_url = $matches[1]; } } elseif (!empty($author_email)) { // If the user has provided an email, we use it to construct a gravatar link. $avatar_url = "http://www.gravatar.com/avatar/" . md5($author_email) . "?s=" . $avatar_size; } if (!empty($avatar_url)) { //$avatar_url = html_entity_decode($avatar_url, ENT_NOQUOTES, 'UTF-8'); //$metadata_arr[] = '<meta itemprop="image" content="' . esc_url_raw( $avatar_url ) . '" />'; $image_data = amt_get_image_data(sprintf('%s,%dx%d', $avatar_url, $avatar_size, $avatar_size)); if (!empty($image_data)) { $image_size = apply_filters('amt_image_size_index', 'full'); $image_meta_tags = amt_get_schemaorg_image_metatags($options, $image_data, $size = $image_size); if (!empty($image_meta_tags)) { $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; $metadata_arr = array_merge($metadata_arr, $image_meta_tags); $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; } } } } // url // The URL to the author archive is added as the url. //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( get_author_posts_url( $author_id ) ) . '" />'; $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(amt_get_local_author_profile_url($author_id, $options)) . '" />'; // sameAs // Social Profile Links are added as sameAs properties // Those from the WordPress User Profile page are used. // Google+ Author $googleplus_author_url = get_the_author_meta('amt_googleplus_author_profile_url', $author_id); if (!empty($googleplus_author_url)) { $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw($googleplus_author_url, array('http', 'https')) . '" />'; } // Facebook $facebook_author_url = get_the_author_meta('amt_facebook_author_profile_url', $author_id); if (!empty($facebook_author_url)) { $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw($facebook_author_url, array('http', 'https')) . '" />'; } // Twitter $twitter_author_username = get_the_author_meta('amt_twitter_author_username', $author_id); if (!empty($twitter_author_username)) { $metadata_arr[] = '<meta itemprop="sameAs" content="https://twitter.com/' . esc_attr($twitter_author_username) . '" />'; } // The User URL as set by the user in the WordPress User Profile page. $user_url = get_the_author_meta('user_url', $author_id); if (!empty($user_url)) { $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw($user_url, array('http', 'https')) . '" />'; } // Allow filtering of the Author meta tags $metadata_arr = apply_filters('amt_schemaorg_author_extra', $metadata_arr, $author_id); return $metadata_arr; }
/** * Filter function that generates and embeds Schema.org metadata in the content. */ function amt_add_schemaorg_metadata_content_filter($post_body) { if (is_feed()) { return $post_body; } if (!is_singular() || is_front_page()) { // is_front_page() is used for the case in which a static page is used as the front page. // In this filter function we only deal with content and attachments. return $post_body; } // Get the options the DB $options = get_option("add_meta_tags_opts"); $do_auto_schemaorg = $options["auto_schemaorg"] == "1" ? true : false; if (!$do_auto_schemaorg) { return $post_body; } // Check if the microdata or the JSON-LD schema.org generator should be used. if ($options["schemaorg_force_jsonld"] == "1") { return $post_body; } // Get current post object $post = get_queried_object(); $metadata_arr = array(); // Since this is a function that is hooked to the 'the_content' filter // of WordPress, the post type check has not run, so this happens here. // Check if metadata is supported on this content type. $post_type = get_post_type($post); if (!in_array($post_type, amt_get_supported_post_types())) { return $post_body; } // Get an array containing the attachments $attachments = amt_get_ordered_attachments($post); //var_dump($attachments); // Get an array containing the URLs of the embedded media $embedded_media = amt_get_embedded_media($post); //var_dump($embedded_media); // Products if (amt_is_product()) { // Scope BEGIN: Product: http://schema.org/Product $metadata_arr[] = '<!-- Scope BEGIN: Product -->'; $metadata_arr[] = '<div itemscope itemtype="http://schema.org/Product"' . amt_get_schemaorg_itemref('product') . '>'; // URL - Uses amt_get_permalink_for_multipage() $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(amt_get_permalink_for_multipage($post)) . '" />'; // name // Note: Contains multipage information through amt_process_paged() $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(amt_process_paged(get_the_title($post->ID))) . '" />'; // headline - contains title information $metadata_arr['microdata:headline'] = '<meta itemprop="headline" content="' . esc_attr(amt_get_title_for_metadata($options, $post)) . '" />'; // Description - We use the description defined by Add-Meta-Tags // Note: Contains multipage information through amt_process_paged() $content_desc = amt_get_content_description($post); if (empty($content_desc)) { // Use the post body as the description. Product objects do not support body text. $content_desc = sanitize_text_field(amt_sanitize_description($post_body)); } if (!empty($content_desc)) { $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr(amt_process_paged($content_desc)) . '" />'; } // Dates $metadata_arr[] = '<meta itemprop="releaseDate" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />'; // Images // First check if a global image override URL has been entered. // If yes, use this image URL and override all other images. $global_image_override_url = amt_get_post_meta_image_url($post->ID); if (!empty($global_image_override_url)) { $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw($global_image_override_url) . '" />'; $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; // Further image processing } else { // Set to true if any image attachments are found. Use to finally add the default image // if no image attachments have been found. $has_images = false; // Scope BEGIN: ImageObject: http://schema.org/ImageObject // Image - Featured image is checked first, so that it can be the first associated image. if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) { // Get the image attachment object $image = get_post(get_post_thumbnail_id($post->ID)); // metadata BEGIN $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; // Allow filtering of the image size. $image_size = apply_filters('amt_image_size_product', 'full'); // Get image metatags. $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($image, $size = $image_size)); // metadata END $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; // Images have been found. $has_images = true; } // Scope END: ImageObject // If no images have been found so far use the default image, if set. // Scope BEGIN: ImageObject: http://schema.org/ImageObject if ($has_images === false && !empty($options["default_image_url"])) { $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw($options["default_image_url"]) . '" />'; $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; } // Scope END: ImageObject } // Extend the current metadata with properties of the Product object. // See: http://schema.org/Product $metadata_arr = apply_filters('amt_product_data_schemaorg', $metadata_arr, $post); // Scope END: Product $metadata_arr[] = '</div> <!-- Scope END: Product -->'; // Filtering of the generated Schema.org metadata $metadata_arr = apply_filters('amt_schemaorg_metadata_product', $metadata_arr); // Add post body // Remove last closing '</div>' tag, add post body and re-add the closing div afterwards. $closing_product_tag = array_pop($metadata_arr); // Product objects do not support a 'text' itemprop. We just add a div for now // for consistency with Article objects. // TODO: it should allow filtering '<div>' $metadata_arr[] = '<div> <!-- Product text body: BEGIN -->'; $metadata_arr[] = $post_body; $metadata_arr[] = '</div> <!-- Product text body: END -->'; // Now add closing tag for Article $metadata_arr[] = $closing_product_tag; // Attachemnts } elseif (is_attachment()) { $mime_type = get_post_mime_type($post->ID); //$attachment_type = strstr( $mime_type, '/', true ); // See why we do not use strstr(): http://www.codetrax.org/issues/1091 $attachment_type = preg_replace('#\\/[^\\/]*$#', '', $mime_type); // Early metatags - Scope starts if ('image' == $attachment_type) { // Scope BEGIN: ImageObject: http://schema.org/ImageObject $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<div itemscope itemtype="http://schema.org/ImageObject"' . amt_get_schemaorg_itemref('attachment_image') . '>'; } elseif ('video' == $attachment_type) { // Scope BEGIN: VideoObject: http://schema.org/VideoObject $metadata_arr[] = '<!-- Scope BEGIN: VideoObject -->'; $metadata_arr[] = '<div itemscope itemtype="http://schema.org/VideoObject"' . amt_get_schemaorg_itemref('attachment_video') . '>'; } elseif ('audio' == $attachment_type) { // Scope BEGIN: AudioObject: http://schema.org/AudioObject $metadata_arr[] = '<!-- Scope BEGIN: AudioObject -->'; $metadata_arr[] = '<div itemscope itemtype="http://schema.org/AudioObject"' . amt_get_schemaorg_itemref('attachment_audio') . '>'; } else { // we do not currently support other attachment types, so we stop processing here return $post_body; } // Metadata common to all attachments // Publisher // Scope BEGIN: Organization: http://schema.org/Organization $metadata_arr[] = '<!-- Scope BEGIN: Organization -->'; $metadata_arr[] = '<span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"' . amt_get_schemaorg_itemref('organization') . '>'; // Get publisher metatags $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_publisher_metatags($options, $post->post_author)); // Scope END: Organization $metadata_arr[] = '</span> <!-- Scope END: Organization -->'; // Author // Scope BEGIN: Person: http://schema.org/Person $metadata_arr[] = '<!-- Scope BEGIN: Person -->'; $metadata_arr[] = '<span itemprop="author" itemscope itemtype="http://schema.org/Person"' . amt_get_schemaorg_itemref('person_author') . '>'; // Get author metatags $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_author_metatags($post->post_author)); // Scope END: Person $metadata_arr[] = '</span> <!-- Scope END: Person -->'; // name $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(get_the_title($post->ID)) . '" />'; // headline - contains title information $metadata_arr['microdata:headline'] = '<meta itemprop="headline" content="' . esc_attr(amt_get_title_for_metadata($options, $post)) . '" />'; // Description - We use the description defined by Add-Meta-Tags $content_desc = amt_get_content_description($post); if (!empty($content_desc)) { $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($content_desc) . '" />'; } // Dates $metadata_arr[] = '<meta itemprop="datePublished" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />'; $metadata_arr[] = '<meta itemprop="dateModified" content="' . esc_attr(amt_iso8601_date($post->post_modified)) . '" />'; $metadata_arr[] = '<meta itemprop="copyrightYear" content="' . esc_attr(mysql2date('Y', $post->post_date)) . '" />'; // Language $metadata_arr[] = '<meta itemprop="inLanguage" content="' . esc_attr(str_replace('-', '_', amt_get_language_content($options, $post))) . '" />'; // Thumbnail // A featured image is supported by video and audio attachments. // If one is set, then it is set as the thumbnail of the video/audio object. if ('video' == $attachment_type || 'audio' == $attachment_type) { if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) { // Thumbnail URL of the featured image $image_size = apply_filters('amt_image_size_attachment', 'full'); $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), $image_size); $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />'; // Currently we do not add a full ImageObject for the attachment's featured image. // TODO: future } } // Metadata specific to each attachment type if ('image' == $attachment_type) { // Allow filtering of the image size. $image_size = apply_filters('amt_image_size_attachment', 'full'); // Get image metatags. $post is an image object. $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($post, $size = $image_size, $is_representative = true)); // Add the post body here $metadata_arr[] = $post_body; // Scope END: ImageObject $metadata_arr[] = '</div> <!-- Scope END: ImageObject -->'; } elseif ('video' == $attachment_type) { // Video specific metatags // URL (for attachments: links to attachment page) $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(get_permalink($post->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($post->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />'; // Required by Google $metadata_arr[] = '<meta itemprop="uploadDate" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />'; // Add the post body here $metadata_arr[] = $post_body; // Scope END: VideoObject $metadata_arr[] = '</div> <!-- Scope END: VideoObject -->'; } elseif ('audio' == $attachment_type) { // Audio specific metatags // URL (for attachments: links to attachment page) $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(get_permalink($post->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($post->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />'; // Add the post body here $metadata_arr[] = $post_body; // Scope END: AudioObject $metadata_arr[] = '</div> <!-- Scope END: AudioObject -->'; } // Filtering of the generated Schema.org metadata $metadata_arr = apply_filters('amt_schemaorg_metadata_attachment', $metadata_arr); // Content } else { // Set main metadata entity. By default this set to Article. $main_content_object = 'Article'; // Check for Page // Main entity is set to WebPage on pages // DEV NOTE: Since many themes already set the WebPage itemscope on the // body element of the web page, set it to WebPage automatically would // result in duplicate entities. So this has to be done manually via // a filtering function. // if ( is_page() ) { // $main_content_object = 'WebPage'; // } // Check for Review $review_data = amt_get_review_data($post); if (!empty($review_data)) { $main_content_object = 'Review'; } // Allow filtering the main metadata object for content. $main_content_object = apply_filters('amt_schemaorg_object_main', $main_content_object); // Scope BEGIN: Article: http://schema.org/Article $metadata_arr[] = '<!-- Scope BEGIN: ' . esc_attr($main_content_object) . ' -->'; $metadata_arr[] = '<div itemscope itemtype="http://schema.org/' . esc_attr($main_content_object) . '"' . amt_get_schemaorg_itemref('content') . '>'; // Publisher // Scope BEGIN: Organization: http://schema.org/Organization $metadata_arr[] = '<!-- Scope BEGIN: Organization -->'; $metadata_arr[] = '<span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"' . amt_get_schemaorg_itemref('organization') . '>'; // Get publisher metatags $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_publisher_metatags($options, $post->post_author)); // Scope END: Organization $metadata_arr[] = '</span> <!-- Scope END: Organization -->'; // Author // Scope BEGIN: Person: http://schema.org/Person $metadata_arr[] = '<!-- Scope BEGIN: Person -->'; $metadata_arr[] = '<span itemprop="author" itemscope itemtype="http://schema.org/Person"' . amt_get_schemaorg_itemref('person_author') . '>'; // Get publisher metatags $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_author_metatags($post->post_author)); // Scope END: Person $metadata_arr[] = '</span> <!-- Scope END: Person -->'; // URL - Uses amt_get_permalink_for_multipage() $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(amt_get_permalink_for_multipage($post)) . '" />'; // Dates $metadata_arr[] = '<meta itemprop="datePublished" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />'; $metadata_arr[] = '<meta itemprop="dateModified" content="' . esc_attr(amt_iso8601_date($post->post_modified)) . '" />'; $metadata_arr[] = '<meta itemprop="copyrightYear" content="' . esc_attr(mysql2date('Y', $post->post_date)) . '" />'; // Language $metadata_arr[] = '<meta itemprop="inLanguage" content="' . esc_attr(str_replace('-', '_', amt_get_language_content($options, $post))) . '" />'; // name // Note: Contains multipage information through amt_process_paged() $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(amt_process_paged(get_the_title($post->ID))) . '" />'; // headline - contains title information $metadata_arr['microdata:headline'] = '<meta itemprop="headline" content="' . esc_attr(amt_get_title_for_metadata($options, $post)) . '" />'; // Description - We use the description defined by Add-Meta-Tags // Note: Contains multipage information through amt_process_paged() $content_desc = amt_get_content_description($post); if (!empty($content_desc)) { $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr(amt_process_paged($content_desc)) . '" />'; } /* // Section: We use the first category as the section $first_cat = sanitize_text_field( amt_sanitize_keywords( amt_get_first_category($post) ) ); if (!empty($first_cat)) { $metadata_arr[] = '<meta itemprop="articleSection" content="' . esc_attr( $first_cat ) . '" />'; } */ // Add articleSection in Article object only. if ($main_content_object == 'Article') { $categories = get_the_category($post->ID); $categories = apply_filters('amt_post_categories_for_schemaorg', $categories); foreach ($categories as $cat) { $section = trim($cat->cat_name); if (!empty($section) && $cat->slug != 'uncategorized') { $metadata_arr[] = '<meta itemprop="articleSection" content="' . esc_attr($section) . '" />'; } } } // Add review properties if Review if ($main_content_object == 'Review') { $metadata_arr[] = '<!-- Review Information BEGIN -->'; $metadata_arr[] = amt_get_review_info_box($review_data); $metadata_arr[] = '<!-- Review Information END -->'; } // Keywords - We use the keywords defined by Add-Meta-Tags $keywords = amt_get_content_keywords($post); if (!empty($keywords)) { $metadata_arr[] = '<meta itemprop="keywords" content="' . esc_attr($keywords) . '" />'; } // Referenced Items $referenced_url_list = amt_get_referenced_items($post); foreach ($referenced_url_list as $referenced_url) { $referenced_url = trim($referenced_url); if (!empty($referenced_url)) { $metadata_arr[] = '<meta itemprop="referencedItem" content="' . esc_url_raw($referenced_url) . '" />'; } } // Images // First check if a global image override URL has been entered. // If yes, use this image URL and override all other images. $global_image_override_url = amt_get_post_meta_image_url($post->ID); if (!empty($global_image_override_url)) { $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw($global_image_override_url) . '" />'; $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; // Further image processing } else { // Media Limits $image_limit = amt_metadata_get_image_limit($options); $video_limit = amt_metadata_get_video_limit($options); $audio_limit = amt_metadata_get_audio_limit($options); // Counters $ic = 0; // image counter $vc = 0; // video counter $ac = 0; // audio counter // We store the featured image ID in this variable so that it can easily be excluded // when all images are parsed from the $attachments array. $featured_image_id = 0; // Set to true if any image attachments are found. Use to finally add the default image // if no image attachments have been found. $has_images = false; // Scope BEGIN: ImageObject: http://schema.org/ImageObject // Image - Featured image is checked first, so that it can be the first associated image. if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) { // Thumbnail URL // First add the thumbnail URL of the featured image $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'thumbnail'); $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />'; // Add full image object for featured image. // Get the image attachment object $image = get_post(get_post_thumbnail_id($post->ID)); // metadata BEGIN $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; // Allow filtering of the image size. $image_size = apply_filters('amt_image_size_content', 'full'); // Get image metatags. $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($image, $size = $image_size)); // metadata END $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; // Finally, set the $featured_image_id $featured_image_id = get_post_thumbnail_id($post->ID); // Images have been found. $has_images = true; // Increase image counter $ic++; } // Scope END: ImageObject // Process all attachments and add metatags (featured image will be excluded) foreach ($attachments as $attachment) { // Excluded the featured image since if ($attachment->ID != $featured_image_id) { $mime_type = get_post_mime_type($attachment->ID); //$attachment_type = strstr( $mime_type, '/', true ); // See why we do not use strstr(): http://www.codetrax.org/issues/1091 $attachment_type = preg_replace('#\\/[^\\/]*$#', '', $mime_type); if ('image' == $attachment_type && $ic < $image_limit) { // metadata BEGIN $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; // Allow filtering of the image size. $image_size = apply_filters('amt_image_size_content', 'full'); // Get image metatags. $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($attachment, $size = $image_size)); // metadata END $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; // Images have been found. $has_images = true; // Increase image counter $ic++; } elseif ('video' == $attachment_type && $vc < $video_limit) { // Scope BEGIN: VideoObject: http://schema.org/VideoObject $metadata_arr[] = '<!-- Scope BEGIN: VideoObject -->'; $metadata_arr[] = '<span itemprop="video" itemscope itemtype="http://schema.org/VideoObject">'; // Video specific metatags // URL (for attachments: links to attachment page) $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(get_permalink($attachment->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($attachment->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />'; // name $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(get_the_title($attachment->ID)) . '" />'; // Description - We use the description defined by Add-Meta-Tags $content_desc = amt_get_content_description($attachment); if (!empty($content_desc)) { $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($content_desc) . '" />'; } // Thumbnail // A featured image is supported by video and audio attachments. // If one is set, then it is set as the thumbnail of the video/audio object. if (function_exists('has_post_thumbnail') && has_post_thumbnail($attachment->ID)) { // Thumbnail URL of the featured image $image_size = apply_filters('amt_image_size_content', 'full'); $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($attachment->ID), $image_size); $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />'; // Currently we do not add a full ImageObject for the attachment's featured image. // TODO: future } // uploadDate $metadata_arr[] = '<meta itemprop="uploadDate" content="' . esc_attr(amt_iso8601_date($attachment->post_date)) . '" />'; // Scope END: VideoObject $metadata_arr[] = '</span> <!-- Scope END: VideoObject -->'; // Increase video counter $vc++; } elseif ('audio' == $attachment_type && $ac < $audio_limit) { // Scope BEGIN: AudioObject: http://schema.org/AudioObject $metadata_arr[] = '<!-- Scope BEGIN: AudioObject -->'; $metadata_arr[] = '<span itemprop="audio" itemscope itemtype="http://schema.org/AudioObject">'; // Audio specific metatags // URL (for attachments: links to attachment page) $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(get_permalink($attachment->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($attachment->ID)) . '" />'; $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />'; // name $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(get_the_title($attachment->ID)) . '" />'; // Description - We use the description defined by Add-Meta-Tags $content_desc = amt_get_content_description($attachment); if (!empty($content_desc)) { $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($content_desc) . '" />'; } // Thumbnail // A featured image is supported by video and audio attachments. // If one is set, then it is set as the thumbnail of the video/audio object. if (function_exists('has_post_thumbnail') && has_post_thumbnail($attachment->ID)) { // Thumbnail URL of the featured image $image_size = apply_filters('amt_image_size_content', 'full'); $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($attachment->ID), $image_size); $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />'; // Currently we do not add a full ImageObject for the attachment's featured image. // TODO: future } // uploadDate $metadata_arr[] = '<meta itemprop="uploadDate" content="' . esc_attr(amt_iso8601_date($attachment->post_date)) . '" />'; // Scope END: AudioObject $metadata_arr[] = '</span> <!-- Scope END: AudioObject -->'; // Increase audio counter $ac++; } } } // Embedded Media foreach ($embedded_media['images'] as $embedded_item) { if ($ic == $image_limit) { break; } // Scope BEGIN: ImageObject: http://schema.org/ImageObject $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; // name (title) $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr($embedded_item['alt']) . '" />'; // caption $metadata_arr[] = '<meta itemprop="caption" content="' . esc_attr($embedded_item['alt']) . '" />'; // alt $metadata_arr[] = '<meta itemprop="text" content="' . esc_attr($embedded_item['alt']) . '" />'; // URL (links to web page containing the image) $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw($embedded_item['page']) . '" />'; // thumbnail url $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($embedded_item['thumbnail']) . '" />'; // main image $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw($embedded_item['image']) . '" />'; if (apply_filters('amt_extended_image_tags', true)) { $metadata_arr[] = '<meta itemprop="width" content="' . esc_attr($embedded_item['width']) . '" />'; $metadata_arr[] = '<meta itemprop="height" content="' . esc_attr($embedded_item['height']) . '" />'; $metadata_arr[] = '<meta itemprop="encodingFormat" content="image/jpeg" />'; } // embedURL $metadata_arr[] = '<meta itemprop="embedURL" content="' . esc_url_raw($embedded_item['player']) . '" />'; // Scope END: ImageObject $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; // Images have been found. $has_images = true; // Increase image counter $ic++; } foreach ($embedded_media['videos'] as $embedded_item) { if ($vc == $video_limit) { break; } // Scope BEGIN: VideoObject: http://schema.org/VideoObject // See: http://googlewebmastercentral.blogspot.gr/2012/02/using-schemaorg-markup-for-videos.html // See: https://support.google.com/webmasters/answer/2413309?hl=en $metadata_arr[] = '<!-- Scope BEGIN: VideoObject -->'; $metadata_arr[] = '<span itemprop="video" itemscope itemtype="http://schema.org/VideoObject">'; // Video Embed URL $metadata_arr[] = '<meta itemprop="embedURL" content="' . esc_url_raw($embedded_item['player']) . '" />'; // playerType $metadata_arr[] = '<meta itemprop="playerType" content="application/x-shockwave-flash" />'; // size $metadata_arr[] = '<meta itemprop="width" content="' . esc_attr($embedded_item['width']) . '" />'; $metadata_arr[] = '<meta itemprop="height" content="' . esc_attr($embedded_item['height']) . '" />'; // Scope END: VideoObject $metadata_arr[] = '</span> <!-- Scope END: VideoObject -->'; // Increase video counter $vc++; } foreach ($embedded_media['sounds'] as $embedded_item) { if ($ac == $audio_limit) { break; } // Scope BEGIN: AudioObject: http://schema.org/AudioObject $metadata_arr[] = '<!-- Scope BEGIN: AudioObject -->'; $metadata_arr[] = '<span itemprop="audio" itemscope itemtype="http://schema.org/AudioObject">'; // Audio Embed URL $metadata_arr[] = '<meta itemprop="embedURL" content="' . esc_url_raw($embedded_item['player']) . '" />'; // playerType $metadata_arr[] = '<meta itemprop="playerType" content="application/x-shockwave-flash" />'; // Scope END: AudioObject $metadata_arr[] = '</span> <!-- Scope END: AudioObject -->'; // Increase audio counter $ac++; } // If no images have been found so far use the default image, if set. // Scope BEGIN: ImageObject: http://schema.org/ImageObject if ($has_images === false && !empty($options["default_image_url"])) { $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->'; $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">'; $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw($options["default_image_url"]) . '" />'; $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->'; } // Scope END: ImageObject } // Article Body // The article body is added after filtering the generated microdata below. // TODO: also check: comments, contributor, copyrightHolder, , creator, dateCreated, discussionUrl, editor, version (use post revision if possible) // Scope END: Article $metadata_arr[] = '</div> <!-- Scope END: ' . esc_attr($main_content_object) . ' -->'; // Filtering of the generated Schema.org metadata $metadata_arr = apply_filters('amt_schemaorg_metadata_content', $metadata_arr); // Add articleBody to Artice // Now add the article. Remove last closing '</span>' tag, add articleBody and re-add the closing span afterwards. $closing_article_tag = array_pop($metadata_arr); // Use the 'text' itemprop by default for the main text body of the CreativeWork, // so it can be used by more subtypes than Article. // But set it explicitly to 'articleBody if the main entiry is 'Article' // or 'reviewBody' if the main entity is a 'Review'. $main_text_property = 'text'; if ($main_content_object == 'Article') { $main_text_property = 'articleBody'; } elseif ($main_content_object == 'Review') { $main_text_property = 'reviewBody'; } // Allow filtering of the main text property. $main_text_property = apply_filters('amt_schemaorg_property_main_text', $main_text_property); $metadata_arr[] = '<div itemprop="' . esc_attr($main_text_property) . '">'; $metadata_arr[] = $post_body; $metadata_arr[] = '</div> <!-- Itemprop END: ' . esc_attr($main_text_property) . ' -->'; // Now add closing tag for Article $metadata_arr[] = $closing_article_tag; } // Add our comment if (count($metadata_arr) > 0) { array_unshift($metadata_arr, "<!-- BEGIN Schema.org microdata added by Add-Meta-Tags WordPress plugin -->"); array_unshift($metadata_arr, ""); // Intentionaly left empty array_push($metadata_arr, "<!-- END Schema.org microdata added by Add-Meta-Tags WordPress plugin -->"); array_push($metadata_arr, ""); // Intentionaly left empty } //return $post_body; return implode(PHP_EOL, $metadata_arr); }