Shuffling pages once, and saving that order in a session?

Recently I set up a site that features people in a short article. These people are displayed on an overview page, and the order is shuffled as follows:

foreach($page->children()->visible()->shuffle() as $p

This is to avoid people at the bottom getting less views than those up top.

But now it’s difficult for visitors to navigate the website. Every time they open the overview the people are re-shuffled, and keeping track of which people they have viewed is difficult, even with a :visited state.

I was wondering if I could shuffle the pages once, and then save that order for the remainder of the session or a different timeframe (e.g. shuffle order once per day).

The best I can come up with is to shuffle and then set a cookie, and not shuffle again if that cookie is set. But that only leaves me with a default sorting order, rather than a randomized one (so bottom people will still get less views).

if(isset($_COOKIE['shuffle'])): 

  foreach($page->children()->visible()->shuffle() as $p) :
    ...
  endforeach

else:

  foreach($page->children()->visible() as $p) : 
    ...
  endforeach
  setcookie('shuffle', 'shuffle', time() + (86400), "/");

endif

If I could pass a seed, variable or timecode to the shuffle function which would always end up with the same order for that seed, that would solve this problem, but as far as I know this isn’t possible.

I know I can reorder them manually in panel but there’s about 50 people with more people being added weekly so it would be somewhat tedious.

I would use localstorage for the client and Ajax to PHP for the sorting.

Could you be more specific? What would I be saving in localstorage? The rendered html?

Another approach I thought of would be to show default order to users with an even ip address, and flip the order to those with an odd ip address, as described in Bastian’s A/B testing article. It wouldn’t be random but all people would get about the same number of views.

Still curious for solutions to the initial question though :slight_smile:

I’m on a phone now.

I would save the uri:s and order as array objects in localstorage.

Ajax would be needed to send data between JS and PHP.

Kirby uses the PHP shuffle function to shuffle the page collection. You can seed it by using srand(), for example with the current day:

$todayTimestamp = strtotime(date('Y-m-d'));
srand($todayTimestamp);
foreach($page->children()->visible()->shuffle() as $p):
  ...
endforeach;

Instead of using the timestamp of the current day, you can use every value you can think of (like a session variable). Make sure to use an int though, strings won’t work as seeds.

1 Like

Wow, this is exactly what I needed.
Tried and works perfectly! Thanks a lot :grinning: