Tutorial: Write a Sitemap Plugin Day 3

Now we have a working even if stupid plugin. Today we look at how get all the posts from WordPress to generate the real sitemap.

WordPress have a special function named get_posts. But functions like that extract to many data from the database, we usually need only the post date and the permalink.

We try to make a direct query which will extract the post id and date of the published posts.

$posts = $wpdb->get_results("select ID, post_modified from " . $wpdb->prefix .
"posts where post_type in ('post', 'page') and
post_status='publish' order by post_modified desc", ARRAY_N);

To better understand the WordPress tables read here.

$wpdb is a famous WordPress object used to access the database. In the example we execute a query and ask the object to return a list of array (ARRAY_N). Arrays (not the associative arrays) are the most performant ones (speed and memory consumption).

Considering we can have hundreds of posts we choose to use the classic non associative arrays.

With a posts list or better with a list of post id(s) and post dates, we still are missing the link of a post which is the core information to build a sitemap.

WordPress comes with a function (get_permalink) to create such link starting from a post id. So we don’t have to do nothing else than call it.

Before print each post link, we need to send the content type to the client requesting the sitemap. We are generating XML and the content type for XML is the mime type “text/xml”. We “force” this value since usually web server send a content type of “text/html”.

This information is sent with:

header('Content-Type: text/xml');

to understand it you have to understand better the HTTP protocol and you can study it by your self…

A sitemap is not made only of “url” entries. The XML must have a root element, as specified in the sitemap standard. So after the content type is setted, we output the first part of the sitemap:

    echo '<' . '?xml version="1.0" encoding="UTF-8"?>' . "n";
    echo '<urlset xmlns="">' . "n";

Special note for the:

    echo '<' . '?...

we have to separate the < from the question mark otherwise PHP intepreter will be confused.

The “sitemap_init” function now looks like:

function sitemap_init()
    global $wpdb;

    if (!isset($_GET['sitemap'])) return;

    $posts = $wpdb->get_results("select ID, post_date from " . $wpdb->prefix .
        "posts where post_type in ('post', 'page') and post_status='publish'
        order by post_date desc", ARRAY_N);

    header('Content-Type: text/xml');

    echo '<' . '?xml version="1.0" encoding="UTF-8"?>' . "n";
    echo '<urlset xmlns="">' . "n";

    // url items printing here...


The code to print out the items on next day.

The plugin is already working:

Leave a Reply