XML Sitemap plugin

I’m excited to share with you all that I just release a new plugin: XML Sitemap

A flexible & powerful XML Sitemap generator for Kirby CMS!

Main features

  • Cache support
  • Human-readable XML sitemap
  • Image attribute
  • Multi-language support
  • Powerful options

After installing the plugin using any of the methods documented on the plugin’s repo you should be able to visit https://yoursite.com/sitemap.xml to see an human-readable sitemap without doing any initial configuration. Enjoy it :slight_smile:

Feedback is welcome!

12 Likes

Wow! Beautiful work right there :clap:

1 Like

It seems to be similar to the other sitemap plugins out there, but with that little extra, like the stylesheet. It looks good visually. :slight_smile:

How does it work with routed urls? To have complete control, I route all my pages. Because no sitemap plugins support it (as far as I know) I’ve build my own really simple plugin called Kirby Sitemap Query. It’s not as visual as yours but really powerful in terms of complete control.

Do you have plans to include features like that, complete control of the sitemap? Or could it be done with sitemap.process?

2 Likes

There’s really a bunch of XML Sitemap plugins out there. I needed a few extra things so I built my own. Besides the stylesheet which is great for checking what’s sent to search engines, there are some other differences too:

  • Cache support
  • Image attribute
  • Multi-language support
  • Option for custom priority and changefreq logic
  • Powerful filter control

Right now I can’t think of a way to easily add routes, I’ll keep that in mind for future features. Shouldn’t be hard to add that.

In my plugin it’s this simple to add urls. Hopefully you can be inspired by it or make another solution as awesome as this. :wink:

<?php
foreach( site()->index() as $page ) {   
    $url['priority'] = ( $page->isHomePage() ) ? 1 : '0.5';

    sitemapQuery::add(array(
        'loc' => $page->url(),
        'lastmod' => $page->modified('Y-m-d'),
        'priority' => $url['priority'],
    ));
}
1 Like

Yeah, that’s great!

I’ll see what I can do when I get some free time. Thanks for the inspiration :wink:

Hi @pedroborges, I’m testing your sitemap plugin and I have a question.

Is it possible to ignore a subpage?

I’ trying do it including the URI but it seems it doesn’t work:

c::set('sitemap.include.invisible', true);
c::set('sitemap.ignored.pages', [contact/thank-you, error]);

Hi @11bits! Yes, it’s possible to exclude any page. The values passed inside the array to the sitemap.ignored.pages option should be strings, try this:

c::set('sitemap.include.invisible', true);
c::set('sitemap.ignored.pages', [
    site()->errorPage(),
    'contact/thank-you'
]);

In my case, if I use the code of your example, it doesn’t work. But if I use only strings it works perfectly:

c::set('sitemap.ignored.pages', [
    'error',
    'contact/thank-you'
]);

Thanks!

@pedroborges:

With Docs: $site->errorPage():

Returns the $page object for the error page.

I have not tested, but something like using ->uri([$lang = null]) may help you.

This is really a great sitemap tool.
Is it also possible to exclude a certain language from the sitemap? I need this because this language has not yet been fully translated, but the website is supposed to go online anyway.
Could

// URI of pages to remove
c::set('sitemap.ignored.pages', []);

be used for this task? If so, what would you have to put between the square brackets to exclude i.e. all ‘en’ pages?

You could try:

c::set('sitemap.ignored.pages', [
    $site->pages()->find('mypage')->content('en'),
    $site->pages()->find('mypagetwo')->content('en'),
    ...
]);

However, i’ve used sitemap on translated sites and if the content isnt there for a language, it doesn’t end up in the sitemap as i recall, so I don’t think this actually necessary?

You need to pass an array of page Uris, not content objects…

One thing you can probably do is to remove the language from the language definition (only for the production site config, unless content creation takes place on the live site), or manually exclude the language from this snippet:
https://github.com/pedroborges/kirby-xml-sitemap/blob/master/xml-sitemap.php (line 5).

Not sure if there are other ways, haven’t really used the plugin yet.

This Sitemap tool displays all language versions of the page as a link.

Anyway, thanks for the support, but the mentioned methods are simply too complicated for me, so I will add a ‘manual’ sitemap until the website is translated.

It has turned out that I might well need it more often to exclude a language temporarily in this sitemap-plugin. So here’s another try:

The instructions for the sitemap-xml-plugin say that setting ‘sitemap.process’ in the config.php allows you “to process the pages collection in any way you want, such as removing or adding a specific set of pages”.
The example for this is the following:

// Filter a set of pages based on a field value
c::set('sitemap.process', function($pages) {
return $pages->filter(function($page) {

    // Remove future posts
    if ($page->intendedTemplate() === 'post') {
        return $page->date() < time();
    }

    // Keep all other pages
    return true;
    });
});

How can I filter out all English pages instead of removing the future posts? Is that possible?

if($page->content() == 'en'){}

doesnt work. Do you need “$page->language” instead or am I on the completely wrong trail?

I’ve tried to filter out the English pages as described in the Kirby Filter instructions (I’m not a programmer, so I’m pretty much dabbling around). As described there, I first created the file ‘filters.php’ in site/plugins with the following content:

<?php
// Anything that matches a given language attribute

collection::$filters['languageIs'] = function($collection, $field, $value) {

  foreach($collection->data as $key => $item) {
    if(collection::extractValue($item->content()->language(), $field) != $value) {
      unset($collection->$key);
    }
  }

  return $collection;

};

and then I added the following code to config.php (see old before-code in last post) to remove all english pages from the sitemap:

// Filter a set of pages based on a field value
c::set('sitemap.process', function($pages) {
    return $pages->children()->visible()->filterBy('code', 'languageIs', 'en');
    });

The result of this is that no pages at all are displayed in the sitemap. Which is some progress, it shows that the code in ‘sitemap.process’ does at least something.

Is my encoding wrong (very likely :wink: ) or does this filter not work in config.php because it is in the plugin folder? How do I correctly write the filter code (if it’s wrong)?

Hello @pedroborges … will you be updating this plugin for K3?

If this plugin is no longer being developed, what would be recommended as an equivalent replacement? I have several K2 sites that need to get migrated to K3 in the next few weeks and a compatible sitemap plugin is necessary to make this happen.

1 Like

Since it doesn’t appear that @pedroborges is updating his plugin for K3, here’s a bit of a follow up.

Rather than try to fight with yet another sitemap plugin, I implemented @bastianallgeier’s super simple sitemap for search engines recipe in the Cookbook and then appended the great looking XSL stylesheet from @pedroborges’ original plugin by adding the following decalration in the sitemap.php snippet.

<?= '<?xml-stylesheet type="text/xsl" href="' . url('sitemap.xsl') . '"?>'; ?>

Enjoy.

3 Likes