How to create Image XML Sitemap for post, page and Custom Post Type(CPT) in WordPress?

To create Image XML Sitemap, need to use a action hook called publish_{$post->post_type} ( triggered whenever a post, page or custom post type(cpt) is updated and its new status is “publish” ).

Before show you complete code, i need to tell you about XML image tag definition:

<image:image>(required) => Encloses all information about a single image. Each <url> tag can contian up to 1000 <image:image> tags.
<image:loc>(required) => The URL for the image.
<image:caption>(optional) => The caption of the image.
<image:title>(optional) => The title of the image.
<image:geo_location>(optional) => The geographic location of the image.
<image:license>(optional) => A URL to the license of the image.

Here is the complete code to create image XML Sitemap for post, page and custom post type:

add_action( 'init', 'wpartisan_xml_image_sitemap_initialization' );

function wpartisan_xml_image_sitemap_initialization(){
	global $all_post_type_names;
	$default_posts_types = array(
		'page' => 'page',
		'post' => 'post',
	);
	$args = array(
		'public'   => true,
		'_builtin' => false,
	);
	$custom_post_types = get_post_types( $args, 'names' );
	$all_post_types = array_merge( $default_posts_types, $custom_post_types );
	$all_post_type_names = array_keys( $all_post_types );
	
	if( !empty( $all_post_type_names ) ) {
		foreach( $all_post_type_names as $post_type_name ):
			add_action( 'publish_'.$post_type_name, 'xml_image_sitemap', 10, 2 );
		endforeach;
	}
}

function xml_image_sitemap( $ID, $post ) {
	
	global $all_post_type_names;

	$sitemap = '<?xml version="1.0" encoding="UTF-8"?>';
	$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">';
	
	foreach ( $all_post_type_names as $pty_name ) :
	
		if( $pty_name === 'page' ):
			$args = array(
				'sort_order' => 'desc',
				'sort_column' => 'post_modified',
				'hierarchical' => 1,
				'exclude' => '',
				'include' => '',
				'meta_key' => '',
				'meta_value' => '',
				'authors' => '',
				'child_of' => 0,
				'parent' => -1,
				'exclude_tree' => '',
				'number' => '',
				'offset' => 0,
				'post_type' => ''.$pty_name.'',
				'post_status' => 'publish'
			); 
			$posts = get_pages($args); 
		else:
			$args = array(
				'numberposts' => -1,
				'orderby'     => 'modified',
				'order'       => 'DESC',
				'exclude'     => '',
				'post_type'   => ''.$pty_name.'',
			);
			$posts = get_posts($args); 
		endif;
	
		if ( !empty( $posts ) ) {
			foreach( $posts as $post ) {
				setup_postdata($post);
				$page_url = get_permalink( $post->ID );
				
				if ( has_post_thumbnail( $post->ID ) ) {
					
					$title = get_post(get_post_thumbnail_id())->post_title;
				
					$img = '';
					$img .= '<image:image>' . "\n";
						$img .= '<image:loc>' . get_the_post_thumbnail_url( $post->ID ) . '</image:loc>' . "\n";
						$img .= '<image:title>' . esc_html($title) . '</image:title>' . "\n";
						$img .= '<image:geo_location>Dhaka, Bangladesh</image:geo_location>' . "\n";
					$img .= '</image:image>' . "\n";
					
					$sitemap .= "<url>\n";
					$sitemap .= "	<loc>" . $page_url . "</loc>\n";
					$sitemap .= $img;
					$sitemap .= "</url>\n";
				
				}
			}
		}
	endforeach;
	$sitemap .= '</urlset>';
	$fp = fopen(ABSPATH . "sitemap-media.xml", 'w');
	fwrite($fp, $sitemap);
	fclose($fp);
}

Leave a Reply

Your email address will not be published. Required fields are marked *