Site Map for on Plone 5 Using Rapido

How to write a Rapido element that will generate a multi-language XML site map (on the fly) if you have installed.

As of the date this was written (27-10-2016) there is an issue with in which once installed on a Plone 5.x site, the site maps are not rendered properly (your sitemap.xml.gz file is empty).

Here is the issue that was logged on the Plone Community page that helped me with the below information:

You can get around this by generating a sitemap that will render on the fly (once the URL is called) using Rapido.


First you should install Rapido.

Once you have activated the Rapido add-on, go to Theming in Plone Control Panel and modify your theme.

Create a folder structure as per the Rapido tutorial. It should be structured the same as below:


For this particular situation we do not need the .html file.

Rapido Files

Copy and paste the following into the sitemap.yaml file:

type: BASIC

Copy and paste the following into the file (please see below the code as there are some important things you will need to change):

# The URL structure of our dev server is 
# Thus every sub language is on URLs such as:,
# etc.

def sitemap(context):
    language = str(context.content.language)
    results = context.api.content.find(Language=language)
    languages = {
        'en-gb' : '',
        'fr'    : '.fr',
        'de'    : '.de',
        'it'    : '.it',
        'cz'    : '.cz'
    language_tlds = languages.copy()
    del languages[language]
    html = '''<?xml version="1.0" encoding="UTF-8"?>
        <urlset xmlns=""
    purl = str(context.portal.absolute_url())
    url_structure = 1 # default inc for TLD set to 2
    for r in results:
        html += '<url>'
        html += '<loc>%s</loc>' %r.getObject().absolute_url()
        for l in languages:
            url = r.getObject().absolute_url()

            if url_structure == 1:
                url = url.replace(language+'/', '')
                url = purl + '/' + l + str(url.replace(purl, ''))
                if url.endswith('/' + language):
                    url = purl + '/' + l
            if url_structure == 2:
                for tld in language_tlds:
                    url = url.replace( language_tlds[tld], languages[l] )
            html += '''<xhtml:link
                    href="%s" />
            ''' % (l, url)
        html += '</url>'

    html += '</urlset>'

    context.request.response.setHeader('content-type', 'application/xml')

    return html

Modifications necessary to

You will need to update the languages dictionary variable to a list of the language codes that you have enabled on your site, first put in the language code, followed by the domain suffix.

If you are using URLs structured as follows: or leave the url_structure variable set to 1. If you are using top level domains, such as or etc then set this variable to 2.

View the site map

To view the outputted XML just go to<language>/@@rapido/sitemap/blocks/sitemap/sitemap.

NOTE: For Plone < 5.0.5 users you'll need to go to the singular 'block' not 'blocks' (a bug that was fixed in later Rapido releases) so if you're on any version of Plone less than version 5.0.5 you'll need to go to:<language>/@@rapido/sitemap/block/sitemap/sitemap instead.


Obviously this is a little ugly but it'll do the trick for anyone in a bind. The good news is a proper fix is being worked on by the community so make sure to keep an eye on Rapido / for updates.


The script is still to be fully tested so it may misbehave, I will be testing it fully over the next few days.