Random front page

Hello,

I want to call a random page as front page. How can I achieve this? :flushed:

You can set the home option in your config inside the ready callback:+

1 Like

Let us say I want to shuffle all projects shown on a website. A project page is a subpage of the projects page.

return [
  'home' => page('projects')->children()->shuffle()
];

As I said, you need to do this within the ready callback, you cannot use the page helper directly with the home option.

Like this?

<?php

return [
    'ready' => function() {
        return [
            'home' => page('projects')->children()->shuffle()
        ];
    }
];

You need to get a single page, though:

 page('projects')->children()->shuffle()->first()
1 Like

Thanks, I will try it.

Dear @pixelijn,

I get an empty page. My config.php so far:

<?php

return [
  '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);
      }
    ]
  ],
  [
      'debug'  => true,
      'languages' => true
  ],
  [
    'ready' => function() {
        return [
            'home' => page('home/works')->children()->shuffle())->first()
        ];
    }
  ]
];

Did I miss anything? I also tried:

'home' => $page->hasTemplate('work')->shuffle())->first()

and got the same empty page.

Your syntax is not correct debug, languages and ready must be on the same level as routes, not inside their own arrays:

<?php

return [
  '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);
      }
    ]
  ],
  'debug'  => true,
  'languages' => true
  'ready' => function() {
        return [
            'home' => page('home/works')->children()->shuffle())->first()
        ];
    }
];

On a side note, be careful with 301 redirects.

1 Like

This works:

<?php

return [
  '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', 'home/works', 'home/info/about', 'home/info/contact', 'home/info/privacy']);

        $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);
      }
    ]
  ],
  'debug'  => true,
  'languages' => true
];

But as soon as I add ready, I get an empty page:

    <?php

    return [
      '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', 'home/works', 'home/info/about', 'home/info/contact', 'home/info/privacy']);

        $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);
      }
    ]
  ],
  'debug'  => true,
  'languages' => true,
  'ready' => function() {
      return [
          'home' => page('home/works')->children()->shuffle())->first()
      ];
  }
];

I got the sitemap routes from here. Why should I be careful with 301 redirects? Should I delete action?

      'action'  => function() {
        return go('sitemap.xml', 301);
      }

301 redirects are called permanent redirect, because they are cached in browsers. So a 302 redirect is usually the better choice unless you are sure never to need the redirected URL anymore.

There is an extra parenthesis after shuffle that you have to remove

1 Like

:bouquet: Thank you very much! Now, it’s works perfectly.

Besides this, I doubt having a random home page is a good idea. It’ll probably confuse the heck out of search engines.

Dear @texnixe,

there’s a bug!

For a specific content called work, I have a random frontpage (random work instead of home), an automatically generated index (of all work pages) and a previous/next navigation (for work pages). Somehow, one work link randomly disappears/changes to home as soon as I add the random frontpage script. See the screenshots:

Bildschirmfoto 2021-03-18 um 13.24.23

Link to home/works/alphabet-forest exists.

Bildschirmfoto 2021-03-18 um 13.24.35

Link to home/works/self-portrait misses.

<?php

return [
  'routes' => [
    [
      'pattern' => 'sitemap.xml',
      'action'  => function() {
        $pages = site()->pages()->index();
        $ignore = kirby()->option('sitemap.ignore', ['error', 'home/works', 'home/info/about', 'home/info/contact', 'home/info/privacy']);
        $content = snippet('sitemap', compact('pages', 'ignore'), true);
        return new Kirby\Cms\Response($content, 'application/xml');
      }
    ],
    [
      'pattern' => 'sitemap',
      'action'  => function() {
        return go('sitemap.xml', 302);
      }
    ]
  ],
  'debug'  => true,
  'languages' => true,
  'ready' => function() {
      return [
          'home' => page('home/works')->children()->shuffle()->first()
      ];
  }
];

The random frontpage script part of config.

<?php if (page('home/works')->hasListedChildren()): ?>
<ul>
  <?php foreach (page('home/works')->children()->listed() as $item): ?>
  <li><a href="<?= $item->url() ?>"><i><?= $item->title() ?></i></a></li>
  <?php endforeach ?>
</ul>
<?php endif ?>

The previous/next navigation script part of work pages.

  <ul>
      <?php if ($page->hasPrevListed()): ?>
      <li><a href="<?= $page->prevListed()->url() ?>">&larr;</a></li>
      <?php else: ?>
      <li><span>&larr;</span></li>
      <?php endif ?>
      <?php if ($page->hasNextListed()): ?>
      <li><a href="<?= $page->nextListed()->url() ?>">&rarr;</a></li>
      <?php else: ?>
      <li><span>&rarr;</span></li>
      <?php endif ?>
    </ul>

The index script part of home.

The random frontpage script removes the link of the randomly chosen work. Is there a way to prevent this? It messes up the site navigation (index and previous/next).

Maybe it would make sense to not set a random homepage, but to return a given page when the home page is called.

1 Like

I see.

The new config calls works now:

<?php

return [
  'routes' => [
    [
      'pattern' => 'sitemap.xml',
      'action'  => function() {
        $pages = site()->pages()->index();
        $ignore = kirby()->option('sitemap.ignore', ['error', 'home/works', 'home/info/about', 'home/info/contact', 'home/info/privacy']);
        $content = snippet('sitemap', compact('pages', 'ignore'), true);
        return new Kirby\Cms\Response($content, 'application/xml');
      }
    ],
    [
      'pattern' => 'sitemap',
      'action'  => function() {
        return go('sitemap.xml', 302);
      }
    ]
  ],
  'debug'  => true,
  'languages' => true,
  'ready' => function() {
      return [
          'home' => page('home/works')
      ];
  }
];

Works calls a random work subpage but only its path:

<?= $page->children()->shuffle()->first() ?>

home/works/walden-or-life-in-the-woods

How do I call the page itself?

That’s not really what I meant. I meant instead of setting a different home page, use a route that listens to / and return a random page.

1 Like

Sorry but I don’t get it. :cowboy_hat_face:

Remove the ready stuff completely. Instead under routes

  [
      'pattern' => '/',
      'action'  => function() {
        return page('home/works')->children()->listed()->shuffle()->first();
      }
    ]

This approach requires that you still have a home folder.

1 Like

Now, the bug is gone. Thank you! :beetle: