$kirby undefined inside snippet

Hi
I’m trying to build my own sitemap and $kirby doesn’t seems to work (Undefined variable message). I just set this foreach loop inside a /snippets/sitemap.php file

 <?php foreach($kirby->languages() as $language): ?>
    <xhtml:link hreflang="<?= $language->code() ?>" href="<?= html($page->url($language->code())) ?>" rel="alternate" />
 <?php endforeach ?>

This is my entire code :

<?= '<?xml version="1.0" encoding="utf-8"?>'; ?>
<?= '<?xml-stylesheet type="text/xsl" href="https://gitcdn.xyz/repo/pedroborges/xml-sitemap-stylesheet/master/sitemap.xsl"?>' ; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <?php foreach ($pages as $p): ?>
    <?php if (in_array($p->uri(), $ignore)) continue ?>
    <url>
        <loc>
            <?= html($p->url()) ?>
        </loc>
        <lastmod>
            <?= $p->modified('c', 'date') ?>
        </lastmod>
           
    <?php foreach($kirby->languages() as $language): ?>
    <xhtml:link hreflang="<?= $language->code() ?>" href="<?= html($page->url($language->code())) ?>" rel="alternate" />
    <?php endforeach ?>

        <priority>
            <?= ($p->isHomePage()) ? 1 : number_format(0.5 / $p->depth(), 1) ?>
        </priority>
        <changefreq><?php if ($p->isHomePage()): ?>daily<?php elseif($p->depth() == 1): ?>weekly<?php elseif($p->depth() > 1): ?>monthly<?php endif ?></changefreq>
        <?php foreach ($p->images() as $image) : ?>
        <image:image>
            <image:loc>
                <?= html($image->url()) ?>
            </image:loc>

            <?php if ($image->caption()->isNotEmpty()) : ?>
            <image:caption>
                <![CDATA[<?= $image->caption() ?>]]>
            </image:caption>
            <?php elseif ($image->alt()->isNotEmpty()) : ?>
            <image:caption>
                <![CDATA[<?= $image->alt() ?>]]>
            </image:caption>
            <?php endif ?>

            <image:license>
               http://creativecommons.org/licenses/by-nc-nd/4.0/
            </image:license>
        </image:image>
        <?php endforeach ?>
    </url>
    <?php endforeach ?>
</urlset>

My languages settings looks correct on the front page, don’t know why kirby couldn’t be define here…

Where is this snippet called?

It is called by a route inside config like this page explain :

'routes' => [
  [
    'pattern' => 'sitemap.xml',
    'action'  => function() {
        $pages = site()->pages()->index();

        // fetch the pages to ignore from the config settings,
        // if nothing is set, we ignore the error page
        $ignore = kirby()->option('sitemap.ignore', ['error']);

        $content = snippet('sitemap', compact('pages', 'ignore'), true);

        // return response with correct header type
        return new Kirby\Cms\Response($content, 'application/xml');
    }
  ],
  [
    'pattern' => 'sitemap',
    'action'  => function() {
      return go('sitemap.xml', 301);
    }
  ]
],

Ah, that’s what I thought. If you call a snippet outside a template context, you have to pass the variables to it (you can’t use $kirby etc. outside a template context without defining them).

$content = snippet('sitemap', ['pages' => $pages, 'ignore' => $ignore, 'kirby' => kirby()], true);

As an. alternative, you could use kirby() instead of $kirby inside your snippet.

Great, this code works, good to know, I would never guess.
Thks a lot
Good night :slight_smile: