Back to Top

Better WordPress Google XML Sitemaps

Better WordPress Google XML Sitemaps

The first WordPress XML Sitemap plugin that comes with comprehensive support for Google News sitemap, Sitemap Index and Multi-site. Extend functionality via flexible modules, not just hooks!

A WordPress XML sitemap plugin that has support for Google News sitemap, Sitemap Index and Multi-site. You will no longer have to worry about the 50,000 URL limit or the time it takes for a sitemap to be generated. This plugin is fast, consumes much fewer resources and can be extended via your very own modules (yes, no hooks needed).

Before moving on to the documentation, which can be rather long and boring, I think it’s better to show you the actual sitemapindex this plugin can generate ;).

Plugin Features

Google News Sitemap

Add a Google News sitemap to your sitemap index easily. News sitemap can be used to ping search engines individually if you want. And of course, whenever you publish a new post in a news category, all selected search engines will be pinged.

As of 1.4.0, you can use custom post types and custom taxonomies for your news sitemap.

Image Sitemap

If you have any post (of any post type) that supports the Featured image feature, you will be able to add the current featured image to a post-based sitemap with ease.

This feature is available since 1.4.0.

Sitemap Index

A sitemap index, as its name suggests, is a sitemap that allows you to group several sitemaps inside it.

It gives you many benefits such as: possibility to bypass the 50,000 URL limit (for example you can have 10 custom sitemaps, each has 10,000 URLs), or possibility to make the generation time much faster (because each sitemap is requested separately and is built by its own module), etc.

For a search engine to acknowledge your sitemaps, you only have to submit the sitemap index and you’re done, no need to submit each sitemap individually.

Splitting post-based sitemaps

As of version 1.1.0, this plugin can automatically split large post sitemaps into smaller ones when limit reached. For example if you have 200K posts and would like to have 10K posts for each sitemap, BWP GXS will then split post.xml into 20 parts (i.e. from post_part1.xml to post_part20.xml).

This not only helps you bypass the 50,000 URLs limit without having to build your custom modules, but also helps make your sitemaps smaller, lighter, and of course faster to generate. This plugin has been tested on sites that have nearly 200K posts and it took less than 1 second to generate the sitemap index.

Furthermore, you can set a separate limit for split sitemaps or simply use the global limit.

Multi-site compatible

Each website within your network will have its own sitemap index and sitemaps.

For sub-domain installation, your sitemapindex will appear at http://sub-domain.example.com/sitemapindex.xml. For sub-folder installation, your sitemapindex will appear at http://example.com/sub-folder/sitemapindex.xml.

There’s always a sitemap index for your main site, available at http://example.com/sitemapindex.xml.

If you choose the sub-domain approach, each sub-domain can also have its own robots.txt. More on that in the Robots.txt section.

Custom sitemaps using modules

The unrivaled flexibility this plugin offers is the ability to define your custom sitemaps using modules. Each module is a actually .php file that tell BWP Google XML Sitemap how to build a sitemap file. You can extend default modules or create completely new ones.

This plugin also comes with a convenient base class for developing modules with easy to use and thoroughly documented API. Since modules can be defined by you, there’s no limitation what a sitemap can have (for example you can bypass the 50,000 URL limit, as stated above). There’s one limitation, though: your imagination ;). Oh, did I mention that you can even use module to create another sitemap index?

Detailed Sitemap Log and Debug

Developing modules needs debugging and this plugin makes that so easy for any developers.

If enabled, certain messages are logged when a sitemap is generated, including notices, error or success messages. They should be checked first for potential issues whenever things are not working as expected.

As of version 1.3.0 there are two debug modes, namely “Debugging” and “Extra debugging”, read on if you want to learn more about those two useful modes.

Full Feature List

  • By default, this plugin provides the following sitemaps:
    • Post (including custom post types and static pages)
      • You can choose to split large post sitemaps into smaller ones.
      • You can add featured images to each post sitemap (since 1.4.0).
    • Taxonomy (including custom taxonomies)
    • Date and author archives
    • External pages, using which you can easily add links to pages that do not belong to WordPress. As of 1.4.0 you can add external pages right within your admin page.
    • And of course, a sitemap index to list all of the above. You can enable/disable any sitemap however you see fit.
  • Provides all basic options for creating sitemaps, such as:
    • Maximum number of items per sitemaps
    • Default change frequency
    • Default priority
    • Minimum priority
  • Allows you to add the sitemap to WordPress’s virtual robots.txt. If you have a sub-domain Multi-site installation, each blog will have its own robots.txt. Of course this only works if you don’t have a physical robots.txt in the main site’s root.
  • Have full support for WPMU Domain Mapping plugin.
  • Allows you to style your sitemaps using a built-in XSLT style sheet, or custom-made ones.
  • Allows you to compress you sitemaps, thus making them approximately 70% smaller.
  • Allows you to selectively ping search engines (Google, Bing) as well as set ping limit when you:
    • Publish a new post
    • Publish a draft
    • Publish a pending post
    • Publish a scheduled (future) post
  • Other advanced features:
    • Allows you to cache the sitemap for a certain period of time. You can choose to automatically or manually generate new cache sitemaps.
    • SQL cycling: if you have a lot of URLs, e.g. 30,000, in a single sitemap, it is recommended that you do not query for 30,000 items in just one query as it will result in a very heavy one. We use SQL cycling to split such query into smaller queries, i.e. we will do 30 queries, with 1000 items queried each.
    • Modules: a module is actually a generator that tells this plugin how to build a sitemap. Module gives you the ultimate flexibility when you want to make custom sitemaps or sitemap indexes. This will be covered in great details in the Module API section.
    • To support modules, this plugin provides detailed logging system with two debug modes that help you trace errors.

Plugin Usage

Basic Usage

Using this plugin is super easy, which basically requires two steps:

Step 1: Select what sitemaps to produce

After a successful activation, navigate to BWP Sitemaps >> XML Sitemaps you should see something similar to:

http://betterwp.net/docs/html/_images/bwp-gxs-usage1-thumb.png

BWP Sitemaps – Sitemaps to generate

In the “Sitemaps to generate” section you should select which sitemaps you want BWP GXS to produce. Most of the time it is the Taxonomy sitemaps (categories, tags, etc.) and Site address sitemap that you want to enable.

For post-based sitemaps and taxonomy-based sitemaps, you also have the option to disable any post types or taxonomies you don’t want generated. By default, all post types are enabled.

To generate your sitemap for the very first time, click on “click to generate your Sitemap Index” under “Generated Sitemaps”. If you have already done so, you will see a a list of generated sitemaps along with buttons that allow you to either view or regenerate any of them.

Important note: When the sitemap index is generated for the first time, you won’t see any Last modified date for any child sitemaps because none of them have been generated yet. This is expected and adhered to the official sitemap protocol.

Step 2: Format your sitemap

You can make your sitemap look pretty by enabling the default XSLT stylesheet (via BWP Sitemaps >> XML Sitemaps >> Look and Feel) or by setting a custom one. Note that enabling XSLT stylesheet is completely optional.

You can also choose to use GMT for displaying datetime, and enable sitemap compression via BWP Sitemaps >> Advanced Options >> Formatting if you want.

Step 3: Submit your sitemap

For all your sitemaps to be crawled by search engine bots, you only have to copy the URL (e.g. http://example.com/sitemapindex.xml) and paste it into your webmaster tool of choice.

Please note that sitemaps are only updated when ‘something’ or ‘someone’ requests them. In other words, when you publish new/draft/future/pending posts you will not notice any slowdown at all, as this plugin will only notify (or ping) search engines about the fact that you have just updated your website/blog. When those search engines actually download the sitemaps, they will be updated.

Now just sit back and relax, search engines will crawl your sitemap index and all other sitemaps inside that sitemap index within hours. 90% of URLs on this website were indexed by Google on the third day it is online, just FYI ;).

Advanced Usage

Google News Sitemap

A Google News Sitemap is yet another sitemap that allows you to control which content you submit to Google News. By creating and submitting a Google News Sitemap, you’re able to help Google News discover and crawl your site’s articles.

With this module, you have an option to either include or exclude posts that belong to certain categories/terms. Let’s say you have 4 categories/terms (A, B, C, and D) in which A and D are the ones you want to use. You can select A and D, and choose to include, or select category B and C, and choose to exclude, simple as that!

Each category can be assigned with five pre-defined genres, as per Google News’s guidelines. You can select none or all of them, it’s totally up to you.

Last but not least, it is possible to map some categories/terms in your language to Google News’s suggested keywords in English using the bwp_gxs_news_keyword_map filter hook.

Robots.txt

WordPress by default comes with a virtual robots.txt1 whose contents can be filtered by plugins or themes.

BWP Google XML Sitemaps allows you to dynamically add a Sitemap: http://example.com/sitemapindex.xml entry to such file, thus allowing search engine crawlers to detect your sitemapindex automatically. If you, however, have a real robots.txt file in your website’s root, the sitemap entry won’t be added, so please keep that in mind.

If you’re on a Sub-domain Multi-site installation you will notice that each blog in your network can have its own robots.txt. So with the robots option enabled, if you browse to http://example.com/robots.txt, you will see something similar to this:

User-agent: *
Disallow:

Sitemap: http://example.com/sitemapindex.xml

and if you browse to http://sub-domain.example.com/robots.txt, you will see something like this:

User-agent: *
Disallow:

Sitemap: http://sub-domain.example.com/sitemapindex.xml

Please note that there’s no http://example.com/sub-folder/robots.txt, so you won’t be able to add the sitemap entry dynamically in a Sub-folder Mult-site installation.

Sitemap Cache

When enabled, all sitemaps are cached for a default period of one hour after newly generated. As of version 1.3.0 this feature is turned off by default.

When a sitemap is requested, this plugin will see if the cache is still valid, and will serve the cached sitemap file if so. Otherwise, the sitemap will be re-generated if you enable “Enable auto cache re-generation”.

You can manually flush the cache for each sitemap or for all sitemaps at once. To flush cache for a specific sitemap, navigate to BWP Sitemaps >> XML Sitemaps >> Generated Sitemaps and click on the refresh button. To flush cache for all sitemaps, click on “Flush cache” or “Save changes and flush cache” button.

As of version 1.3.0 you can also specify a custom cache directory, for e.g. /path/to/wordpress/wp-content/cache/sitemaps/. Instead of setting a cache directory via admin setting, it is possible to use a PHP constant:

1
2
// put this in wp-config.php
define('BWP_GXS_CACHE_DIR', '/path/to/wordpress/wp-content/cache/sitemaps/');

or a filter:

1
2
3
4
5
6
add_filter('bwp_gxs_cache_dir', 'bwp_gxs_my_cache_dir');
function bwp_gxs_my_cache_dir()
{
    // if you want different cache dir per blog, add the logic here
    return '/path/to/wordpress/wp-content/cache/sitemaps/';
}

The two alternative methods make it easy for you to programmatically apply a custom cache directory site-wise.

As always, the cache folder must be writable, i.e. you will have to CHMOD it to either 755 or 777.

Debugging

Although completely optional, it is strongly recommended that you always enable the “Message Log” as it tells you in details how each sitemap was generated. All potential errors such as sitemap not found, empty sitemap, or headers already sent are all logged for your convenience.

When there’s an issue with generating a sitemap, or you’re developing a new module, it is a good idea to enable “Debugging mode” as well. In this mode, the plugin will not make use of any caching mechanism, and if you have WP_DEBUG enabled, error messages will be shown as well.

As of version 1.3.0, there’s also a “Extra debugging mode”. This mode is the same as “Debugging mode” except that no headers are sent and no compression is used, i.e. you should see a raw text file that contains sitemap contents. This is especially useful when you encounter “Content Encoding Error” or related ones, because when such errors occur, you can’t easily identify the causes if headers are sent or compression is in use.

SQL Cycling

As mentioned above, it is better to query for items using a light query rather than a heavy one. This plugin comes with a feature called SQL cycling, which means we will do small queries several times instead of doing a heavy query one time.

The only setting you can use to customize this feature is the number of items each cycle will query for. By default the number is 1000, but it can be increased to serve higher number of items. Since it’s not a good idea to go over 30 queries either, if you have 50,000 items in one sitemap, you should change the SQL query limit to at least 1600.

Customization

Custom XSLT stylesheet

The default XSLT stylesheet should look OK in most cases, but if you do require a custom one, simply navigate to BWP Sitemaps >> XML Sitemaps >> Look and feel and set “Custom XSLT stylesheet URL” to an absolute URL containing the desired stylesheet.

Please make sure that you also have an XSLT style sheet for the sitemapindex in the same directory where the above custom stylesheet is found. For example, if your custom XSLT URL looks like this: http://example.com/my-xslt.xsl then http://example.com/my-xsltindex.xsl must be publicly accessible, too.

Exclude items

To exclude items (be it posts or taxonomies), navigate to BWP Sitemaps >> XML Sitemaps >> Exclude items. You should see this:

http://betterwp.net/docs/html/_images/bwp-gxs-advanced-usage2-thumb.png

BWP Sitemaps – Exclude items

After selecting a post type/taxonomy, you can search for items by their titles/names. Note that you can select multiple posts/terms by holding down the “Ctrl” key (Windows) or the “Command” key (OSX) while clicking on each item.

Click “Exclude selected items” to exclude selected items once you’re done selecting.

Note that if you choose to “Exclude posts by terms”, all the posts that belong to excluded terms will be excluded automatically, without having to exclude them manually.

Though excluding posts/terms via admin page is more convenient, sometimes it’s particularly useful to exclude them programmatically. You can:

Add non-WordPress pages

In order to add non-WordPress pages to the Sitemap Index you must first enable the “External pages” sitemap, and then add each page via BWP Sitemaps > XML Sitemaps > External pages.

You can of course do this programmatically by using the bwp_gxs_external_pages action hook.

By default, you will get something similar to this:

http://betterwp.net/docs/html/_images/bwp-gxs-external-page-sitemap-thumb.png

BWP Sitemap – External pages sitemap

Add non-BWP sitemaps to the sitemap index

As of 1.4.0 you can use a filter to add non-BWP sitemaps without having to rely on the Module API.

Simply add this to your theme’s functions.php:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
add_filter('bwp_gxs_external_sitemaps', 'my_external_sitemaps');
function my_external_sitemaps()
{
    return array(
        array(
            'location' => home_url('listings.xml'),
            'lastmod'  => '2015-12-24'
        ),
        array(
            'location' => home_url('items.xml'),
            'lastmod'  => '2015-12-24 12:00:00'
        )
    );
}

With the above snippet, listings.xml and items.xml will be added to sitemapindex.xml.

Module API – Customize your sitemaps like never before

What is a sitemap module?

Before we start building a custom sitemap, let’s talk about how the module system works.

Module is simply a .php file that contains a module class, which has a unique name, i.e. just one module for one sitemap. In the module class you can use all API functions provided by the base module (BWP_GXS_MODULE) if you extends2 it.

Using API functions you will be able to do SQL cycling, calculate priority, calculate change frequency, etc. but the body of the module class needs to be your own codes, i.e. you fetch the needed data in your own way and pass it back to the plugin to handle. It is therefore very easy to create a new module, because most of the time all you have to do is to change the SQL query that is used to get contents from database.

Now if you open the module folder in bwp-google-xml-sitemaps/includes/modules you will notice that each module’s filename is similar to its corresponding sitemap. For example post.php is used to build all post-based sitemaps and taxonomy.php is used to build all taxonomy-based sitemaps.

It is important to understand that a module can be either a parent or a child module. A child module will be used first, and if it is not found, the parent module will be used instead. So if you have a custom sitemap named post_most_popular.xml, this plugin will request post_most_popular.php first, and if that fails, it will request post.php.

You might ask: “If I add more modules, what will happen when this plugin gets updated?” No worry, you have the option to set a custom module directory that will take precedence over the default module directory. Simply speaking, this plugin will look for modules in the custom directory first, and when it can not find the requested module file, it will look for modules in the default one, in the exact same way described above.

Up to this point I believe that you have a better understanding of what module is all about and how it operates, how about we get to the real thing, now ;)?

Basic API functions

If you do not like the default sitemap index, you can always add or remove sitemaps (or modules) from it. Adding or removing a module is easy, using two basic module API functions, namely add_module() and remove_module(), respectively, like so:

1
2
3
4
5
6
add_action('bwp_gxs_modules_built', 'bwp_gxs_add_modules');
function bwp_gxs_add_modules()
{
    global $bwp_gxs;
    $bwp_gxs->add_module('post', 'most popular');
}

In the above snippet, I’m adding a new sub-module named ‘most popular’ to the built-in module ‘post’.

Below’s a list of built-in modules:

post
page
taxonomy
archive
author
site

and some built-in sub-modules:

archive_monthly
archive_yearly
taxonomy_category
taxonomy_post_tag
...

Please note that the name you use for any module can only contain alphanumeric characters plus hyphens, underscores, and spaces. Spaces will be converted to underscores anyway, so it’s best to just use underscores (spaces are still allowed because some people might find them easier to work with).

So now you have a new module named post_most_popular, what are you supposed to do? Just create a custom module directory and then put a new module file named post_most_popular.php there, with your own codes, of course.

For the sake of simplicity, post_most_popular is actually included with this plugin as a sample module, so after you add the module, you should see post_most_popular.xml‘s contents right away (FYI: it lists posts with at least 2 comments, ordered by comment_count and post_modified).

If you are adding a parent module, you will also have to add a new rewrite rule. For example if you want a parent module named ‘most_popular’ (instead of a sub-module like ‘post_most_popular’), you will also need this:

1
2
3
4
5
6
7
8
add_filter('bwp_gxs_rewrite_rules', 'add_rewrite_rules');
function add_rewrite_rules()
{
    $my_rules = array(
        'popular\.xml' => 'index.php?gxs_module=most_popular'
    );
    return $my_rules;
}

You can have popular.xml, or most_popular.xml, or anything you see fit. After you have added the above snippet, make sure you pay a visit to your Permalink Settings and click Save Changes so that WordPress will recognize your new rewrite rules. Otherwise, you will be greeted with a 404 error when you try to visit http://yourdomain.com/popular.xml.

Now if you want to remove a module, the process is similar:

1
2
3
4
5
6
7
8
9
add_action('bwp_gxs_modules_built', 'bwp_gxs_remove_modules');
function bwp_gxs_remove_modules()
{
    global $bwp_gxs;
    // This will remove all modules that have 'taxonomy' as their parent
    $bwp_gxs->remove_module('taxonomy');
    // This will remove 'taxonomy_post_tags' only
    $bwp_gxs->remove_module('taxonomy', 'post_tag');
}

Keep in mind that your sitemap’s name, your module’s name and your module’s filename must be the same when you add a new module.

Advanced API functions

For this section I will take the module file post.php (which is documented rather thoroughly) as an example so you will be able to learn all the advanced API functions easily.

Basically, developing a module from scratch involves three steps:

Step 1: Initialize required properties for the module class

Before you can initialize anything, you must define your class, and the class’ name must start with BWP_GXS_MODULE_, followed by the module’s name. For example the module post will have BWP_GXS_MODULE_POST as its class name.

If you happen to have a post type/taxonomy that has hyphens in its name, they will be automatically converted to underscores when the plugin looks for the child module class (e.g. BWP_GXS_MODULE_POST_THIS_HAS_HYPHEN will be used to serve post_this-has-hyphen).

To actually use the API functions, you have to extend the base module class, like so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
/**
 * Some info about you and the module here would be nice
 */

class BWP_GXS_MODULE_POST extends BWP_GXS_MODULE
{
    function __construct()
    {
    }

    function init_module_properties()
    {
    }

    function generate_data()
    {
    }
}

The body of the module class is currently empty, but this is the expected structure for a module file.

Now it’s time to decide what this module will do, and what it will need to build data. The idea of this module is we will use it to display all kind of post type sitemaps, for example post.xml, post_movie.xml, etc. So what this module needs is the sub-module (to know what post type is being requested) and if sub-module is not found, we display the default post type, which is ‘post’.

To achieve that, you can make use of a property named $requested, which will hold the requested post type (or the sub-module). As of version 1.3.0 all module-related data such as what module/sub-module is being requested are automatically assigned to the module class and ready to be used.

For any properties that are dependent on module data you must init them inside init_module_properties(). For any other properties that are not dependent on module data such as some basic get_option() functions, you can put them inside __construct() (a function that gets called when the module class is initialized).

Step 2: Build the actual data

After all necessary properties are assigned with expected values, always use build_data() inside the construct function to start building your data.

As of version 1.3.0 you don’t have to call build_data() inside __construct() anymore as it is called automatically by BWP GXS.

What’s important now is which builder function you will use, which can be either build_data() or generate_data(). Why the heck are there two similar functions for just one task? If you remember the SQL Cycling feature I talked about earlier, you will understand why we have two options here.

Simply speaking, the build_data() function ignores SQL Cycling while the generate_data() function allows you to make use of SQL Cycling. build_data() is recommended when you’re developing modules for sitemaps that do not have many items, which of course does not require SQL Cycling at all. generate_data() should be used in obviously opposite situations. Since there might be a lot of posts for a website/blog, for post.php we will use generate_data().

When you use generate_data() , you will have to query for posts using two DB API functions, namely get_results() and query_posts().

As you might have guessed, they’re no different than the two functions provided by WordPress: $wpdb->get_results()3 and query_posts()4. The same parameters and syntax are applied.

Remember to always escape your query string with either $wpdb->escape()3 or $wpdb->prepare()3, as shown in the actual codes:

1
2
3
4
5
6
7
8
9
// A standard custom query to fetch posts from database, sorted by their lastmod
// You can use any type of queries for your modules
$latest_post_query = '
            SELECT * FROM ' . $wpdb->posts . "
                WHERE post_status = 'publish' AND post_type = %s" . '
            ORDER BY post_modified DESC';
// Use $this->get_results instead of $wpdb->get_results, remember to escape your query
// using $wpdb->prepare or $wpdb->escape
$latest_posts = $this->get_results($wpdb->prepare($latest_post_query, $requested));

Now you’ve got the $latest_posts data set that contains all information about your posts. It would be pointless to continue the loop if the query returns nothing, so it is a good idea to have a simple check like below:

1
2
3
4
// This check helps you stop the cycling sooner
// It basically means if there is nothing to loop through anymore we return false so the cycling can stop.
if (!isset($latest_posts) || 0 == sizeof($latest_posts))
    return false;

This snippet makes sure things are stopped correctly, and you won’t run into an endless loop somehow (should not happen, though).

Building each item is straightforward:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// Always init your $data
$data = array();
for ($i = 0; $i < sizeof($latest_posts); $i++)
{
    $post = $latest_posts[$i];

    // Init your $data with the previous item's data. This makes sure no item is mal-formed.
    $data = $this->init_data($data);

    if ($using_permalinks && empty($post->post_name))
        $data['location'] = '';
    else
        $data['location'] = get_permalink();

    $data['lastmod']  = $this->get_lastmod($post);
    $data['freq']     = $this->cal_frequency($post);
    $data['priority'] = $this->cal_priority($post, $data['freq']);

    $this->data[] = $data;
}

For a complete reference of what the base class has to offer, see BWP_GXS_MODULE.

Step 3: Pass the built data back

To pass the data you just build using your module back to the plugin, simply use $this->data[] = $data; at the end of each loop, like so:

1
2
3
4
5
for ($i = 0; $i < sizeof($latest_posts); $i++)
{
    // ... build data
    $this->data[] = $data;
}

Since we’re still using SQL Cycling, you will have to add this at the end of generate_data():

1
return true;

This tells the module to continue its cycling process. Otherwise, the module will only loop one time.

Step 4: (Surprised!) Visit the configuration page and browse to your newly created sitemap. Make sure you enable debug mode so that no errors are left out. If you encounter something like ‘XML Parsing Error’, or ‘Content Encoding Error’, you have two options: 1) enable the debug extra mode, or 2) go to your module file and place exit; at the end of the build_data() or the generate_data() function (outside any loop) to see the actual errors in your module.

That’s it! Congratulations on your first module!

Create another Sitemap Index

Creating a custom sitemap index is similar to creating a custom sitemap. First you will have to add a new module, for example:

1
2
3
4
5
6
add_action('bwp_gxs_modules_built', 'bwp_gxs_add_modules');
function bwp_gxs_add_modules()
{
    global $bwp_gxs;
    $bwp_gxs->add_module('mysitemapindex');
}

Then, similar to adding a parent module, you must add a new rewrite rule, like so:

1
2
3
4
5
6
7
8
9
add_filter('bwp_gxs_rewrite_rules', 'add_rewrite_rules');
function add_rewrite_rules()
{
    $my_rules = array(
        'mysitemapindex\.xml' => 'index.php?gxs_module=mysitemapindex'
    );

    return $my_rules;
}

Make sure you flush all rewrite rules by visiting Settings >> Permalinks, and press Save Changes.

Next, in mysitemapindex.php, you need to set the sitemap’s type to “index”:

1
2
3
4
function __construct()
{
    $this->type = 'index';
}

Since a sitemapindex’s item does not need priority or change frequency, in your builder function, be it build_data() or generate_data(), make sure you use something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$data = array();
foreach ($items as $item)
{
    $data = $this->init_data($data);

    $data['location'] = $this->get_sitemap_url($item['slug']);
    $data['lastmod']  = $this->format_local_datetime($item['lastmod']); // use your own function to construct the last modified date

    $this->data[] = $data;
}

More details about get_sitemap_url() and format_local_datetime() can be found in the API References.

Now try browsing to http://example.com/mysitemapindex.xml and you should see your new sitemap index ready to be crawled!

Other Notes

URLs to all generated sitemaps are affected by the current permalink settings on your website/blog. If you don’t use pretty permalinks, your sitemaps’ URLs will be similar to this http://example.com/?bwpsitemap=module. For example your sitemapindex will become http://example.com/?bwpsitemap=sitemapindex.

Search engines can crawl such URLs just fine, and this plugin should be able to change all sitemap URLs for you every time you change your permalink setting. Please note that, however, cached sitemaps won’t be changed when you change permalink settings, you will have to manually flush the cache, or simply wait for them to be refreshed.

In addition, if you don’t like the word bwpsitemap, you can change that using a filter. Refer to the Hook References section for more details.

Hook References

Please refer to Hook References for a complete list of hooks.

Support this plugin!

This plugin is licensed under GPL version 3, and it needs contributions from the community.

Buy me some special coffees!

My plugins and support for them are free. If you like my work and could buy me some (special) coffees, I would be much appreciated!

Rate this plugin 5 stars

If you find this plugin useful, please consider giving it a five-shining-star rating, thank you!

Report issues

Before reporting a new issue, please make sure that you have:

  • read thoroughly the FAQ section of this plugin (there might be none)
  • checked BWP Community for possibly similar issues

If none of the above help, please report found issue to the Github issue tracker. Alternatively, you can report issues to WordPress.org’s support forum, and they will be moved to Github eventually whenever needed.

Please do NOT report issues using the contact form. All issues reported via the contact form will be ignored.

i18n (Translate the plugin)

If you are a translator, please help translating this plugin. Even if you aren’t, you can become one, it is very easy and fun! If you want to know how, please read here: Create a .pot or .po File using Poedit.

References

  1. http://www.robotstxt.org/robotstxt.html []
  2. http://php.net/manual/en/keyword.extends.php []
  3. http://codex.wordpress.org/Function_Reference/wpdb_Clas ... wpdb_Class [] [] []
  4. http://codex.wordpress.org/Function_Reference/query_pos ... uery_posts []

Take Social Sharing to
the Next Level with Monarch!

Take Social Sharing to the Next Level with Monarch!
Print Article Plugin Update Feed