I tried to modify a function that create images sitemap and I got stuck with it.
My test site has post with the title "post-title-1"
, images "picture-01.jpg"
, "picture-02.jpg"
and "picture-03.jpg"
are attached to this post.
In the library, every image has filled fields:
----
Title: picture-01
Alt attribute: picture-alt-01
Caption: picture-caption-01
Description: picture-description-01
----
Title: picture-02
Alt attribute: picture-alt-02
Caption: picture-caption-02
Description: picture-description-02
----
Title: picture-03
Alt attribute: picture-alt-03
Caption: picture-caption-03
Description: picture-description-03
----
Here is the function:
function image_sitemap_create() {
global $wpdb;
$posts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_type<>'revision' AND post_status IN ('publish','inherit')");
$thumbs = $wpdb->get_results("
SELECT p.ID,i.guid FROM $wpdb->posts p
INNER JOIN $wpdb->postmeta pm ON p.id=pm.post_id
INNER JOIN $wpdb->posts i ON pm.meta_value=i.id
WHERE p.post_type<>'revision' AND p.post_status='publish' AND pm.meta_key='_thumbnail_id'
");
if(empty($posts) && empty($thumbs)) {
return 0;
} else {
$images = array();
foreach($posts as $post) {
if($post->post_type == 'attachment') {
if($post->post_parent != 0) {
$images[$post->post_parent][$post->guid] = 1;
}
} elseif(preg_match_all('/img src=("|')([^"']+)("|')/ui',$post->post_content,$matches,PREG_SET_ORDER)) {
foreach($matches as $match) {
$imgurl = $match[2];
if(strtolower(substr($imgurl,0,4)) != 'http') {
$imgurl = get_site_url() .$imgurl;
}
$images[$post->ID][$imgurl] = 1;
}
}
}
foreach($thumbs as $post) {
$images[$post->ID][$post->guid] = 1;
}
if( count($images) == 0 ) {
return 0;
} else {
$xml = '<?xml version="1.0" encoding="UTF-8"?>' ."n";
$xml .= '<!--' .date("F j, Y, g:i a") .'" -->' ."n";
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">' ."n";
global $cc_licenses;
$license = $cc_licenses[$_REQUEST['license']];
if( $license != '' ) {
$license = "<image:license>" .$license ."</image:license>";
}
foreach($images as $k=>$v) {
unset($imgurls);
foreach(array_keys($v) as $imgurl) {
if(is_ssl()) {
$imgurl = str_replace('http://','https://',$imgurl);
} else {
$imgurl = str_replace('https://','http://',$imgurl);
}
$imgurls[$imgurl] = 1;
}
$permalink = get_permalink($k);
foreach (array_keys($imgurls) as $imgurl) {
$guids = $wpdb->get_results("SELECT id, post_name, post_mime_type, guid, post_excerpt, post_title, post_content, post_parent
FROM $wpdb->posts
WHERE guid LIKE '" . $imgurl . "' order by post_date DESC");
foreach ($guids as $guid) {
$skipimages = ["skopje", "pinterest"];
$imgpath = $guid->guid;
foreach ($skipimages as $skipimg) {
if (strpos($imgpath, $skipimg)) {
}
}
$img_caption = get_post_meta($guid->id, '_wp_attachment_image_alt', TRUE);
$img_title = $guid->post_title;
$img_geo_location = $guid->post_excerpt;
}
}
if(!empty($permalink)) {
$img = '';
foreach( array_keys($imgurls) as $imgurl ) {
$img .=
"<image:image>" .
"<image:loc>" .$imgurl ."</image:loc>" .
"<image:caption>" .$img_caption ."</image:caption>" .
"<image:geo_location>" .$img_geo_location ."</image:geo_location>" .
"<image:title>" .$img_title ."</image:title>" .
$license .
"</image:image>";
}
$xml .= "<url><loc>" .escape_xml_entities($permalink) ."</loc>" .$img ."</url>n";
}
}
$xml .= "</urlset>";
}
}
$image_sitemap_url = $_SERVER["DOCUMENT_ROOT"].'/sitemap-images.xml';
if(is_file_writable($_SERVER["DOCUMENT_ROOT"]) || is_file_writable($image_sitemap_url)) {
if(file_put_contents($image_sitemap_url, $xml)) {
return count($images);
}
}
return -1;
}
And here is the result that the function makes:
<!--November 9, 2021, 12:33 pm" -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
<url>
<image:loc>http://site.ru/post-title-1/</loc>
<image:image>
<image:loc>http://site.ru/wp-content/uploads/2021/11/picture-01.jpg</image:loc>
<image:caption>picture-alt-03</image:caption>
<image:geo_location>picture-caption-03</image:geo_location>
<image:title>picture-03</image:title>
<image:license>https://creativecommons.org/licenses/by-nc/4.0</image:license>
</image:image>
<image:image>
<image:loc>http://site.ru/wp-content/uploads/2021/11/picture-02.jpg</image:loc>
<image:caption>picture-alt-03</image:caption>
<image:geo_location>picture-caption-03</image:geo_location>
<image:title>picture-03</image:title>
<image:license>https://creativecommons.org/licenses/by-nc/4.0</image:license>
</image:image>
<image:image>
<image:loc>http://site.ru/wp-content/uploads/2021/11/picture-03.jpg</image:loc>
<image:caption>picture-alt-03</image:caption>
<image:geo_location>picture-caption-03</image:geo_location>
<image:title>picture-03</image:title>
<image:license>https://creativecommons.org/licenses/by-nc/4.0</image:license>
</image:image>
</url>
</urlset>
As you can see from the result, <image: loc>
and <image: license>
tags are processed correctly, which cannot be said about the remaining <image: caption>
, <image: geo_location>
and <image: title>
, the values of which are repeated in each image and taken from the last one attached to the post.
What needs to be changed in the code to make the caption, geo_location
and title
tags unique in the XML map for each image? I would be very grateful for your help.