Is there a plugin to create automatically a sitemap for multilanguage website?
i am using the one from the kirby blog. its a template actually.
https://getkirby.com/blog/xmlsitemap
or if you want more control maybe this one
http://www.getkirby-plugins.com/enhanced-sitemap
Yeah, I also use the one from the blog with a multi-lang site.
To keep the site structure clean, I’ve put my sitemap in a route and mine doesn’t work with multi language out of the box - I’m curious to know how your sitemap working with multi language @texnixe ?
$exclude = c::get('sitemap.exclude', array('error'));
$important = c::get('sitemap.important', array('contact'));
kirby()->routes(array(
array(
'pattern' => 'sitemap.xml',
'action' => function() use ($exclude, $important) {
$sitemap = '<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
foreach(site()->pages()->index() as $p){
if(!in_array($p->uri(), $exclude) and $p->isVisible()){
$sitemap .= '<url><loc>' . html($p->url());
$sitemap .= '</loc><lastmod>' . $p->modified('c') . '</lastmod><priority>';
$sitemap .= ($p->isHomePage()||in_array($p->uri(), $important)) ? 1 : 0.6/$p->depth();
$sitemap .= '</priority></url>';
}
}
$sitemap .= '</urlset>';
return new Response($sitemap, 'xml');
}
)
));
On a multi language website you can use
$exclude = c::get('sitemap.exclude', array('error'));
$important = c::get('sitemap.important', array('contact'));
kirby()->routes(array(
array(
'pattern' => 'sitemap.xml',
'action' => function() use ($exclude, $important) {
$sitemap = '<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
foreach(site()->languages() as $l) {
foreach(site()->pages()->index() as $p){
if(!in_array($p->uri(), $exclude) and $p->isVisible()){
$sitemap .= '<url><loc>' . html($p->url($l->code()));
$sitemap .= '</loc><lastmod>' . $p->modified('c') . '</lastmod><priority>';
$sitemap .= ($p->isHomePage()||in_array($p->uri(), $important)) ? 1 : 0.6/$p->depth();
$sitemap .= '</priority></url>';
}
}
}
$sitemap .= '</urlset>';
return new Response($sitemap, 'xml');
}
)
));
Change the order of the two foreach
lines if you want!
Your solution shows the pages only in the default language!
Thank you @anon77445132
I’ve now added support for both single and multi language situations
kirby()->routes(array(
array(
'pattern' => 'sitemap.xml',
'action' => function() {
$sitemap = '<?xml version="1.0" encoding="utf-8"?>';
$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
if(!empty(site()->languages())) {
foreach(site()->pages()->index() as $page){
foreach(site()->languages() as $language) {
$sitemap .= add_sitemap_url($page, $language);
}
}
} else {
foreach(site()->pages()->index() as $page){
$sitemap .= add_sitemap_url($page);
}
}
$sitemap .= '</urlset>';
return new Response($sitemap, 'xml');
}
)
));
function add_sitemap_url($page, $language = null){
$exclude = c::get('sitemap.exclude', array('error'));
$important = c::get('sitemap.important', array('contact'));
if(!in_array($page->uri(), $exclude) and $page->isVisible()){
$url = '<url>';
$url .= '<loc>' . ($language ? html($page->url($language->code())) : html($page->url())) . '</loc>';
$url .= '<lastmod>' . $page->modified('c') . '</lastmod>';
$url .= '<priority>' . (($page->isHomePage()||in_array($page->uri(), $important)) ? 1 : 0.6/$page->depth()) . '</priority>';
$url .= '</url>';
return $url;
}
}
You may want to look at Google . Search Console Help: Use a sitemap to indicate alternate language pages.
When I put it on test on a live server i have an error.
Fatal error: Can’t use method return value in write context in
How can I resolve it?
Thank you for your code! It looks it works for me! Just a stupid issue… $page->modified(‘c’) doesn’t render any date but it just print c …!!!
Do you know why?
Thanks!
Have you set the date handler to strftime
? If so, you need to modify your date format: http://php.net/manual/de/function.strftime.php
Oh thank you! I just solved editing
c::set('date.handler','strftime');
to
c::set('date.handler','date');
in config.php
What a great community!!!
My solution as a route according to @anon77445132’s link. Works with multilang and regular sites:
[
'pattern' => 'sitemap.xml',
'action' => function () {
$ignore = ['error'];
$pages = site()->pages()->index();
$languages = site()->languages() ?: [];
$sitemap = '<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">';
foreach ($pages as $page) {
if (in_array($page->uri(), $ignore)) continue;
$sitemap .= '<url><loc>'.html($page->url()).'</loc>';
foreach ($languages as $lang) {
$sitemap .= '<xhtml:link rel="alternate" hreflang="'.$lang->code().'" href="'.html($page->url($lang->code())).'"/>';
}
$sitemap .= '</url>';
}
$sitemap .= '</urlset>';
return new Response($sitemap, 'text/xml');
}
]