This means that the random function I want to have could decide how many article or section to choose and displayed it according to the total number of the project pages.
Do you have an idea ?
I created this custom pages method to create chunks of random size. Save it in a plugin file, e.g. site/plugins/methods.php.
/**
* Creates chunks of random size
*
* @param int $min Minimum number of items in chunk
* @param int $max Maximum number of items in chunk
* @return object A new collection with an item for each chunk and a subcollection in each chunk
* Usage:
* $projects = page('projects')->children()->shuffle();
* $max = mt_rand(1,$projects->count());
* $min = mt_rand(1, $max);
* $chunks = $projects->randomChunk($min,$max);
*/
pages::$methods['randomChunk'] = function($pages, $min, $max) {
$temp = clone $pages;
$chunks = [];
$size=1;
($min >=1 && $min <= $max)? $min=$min:$min=1;
$max = $max <= $pages->count()? $max: $pages->count();
while ($temp->count() > 0) {
$size = mt_rand($min,$max);
array_push($chunks, array_splice($temp->data,0, $size));
}
$chunkCollections = [];
foreach($chunks as $items) {
$collection = clone $pages;
$collection->data = $items;
$chunkCollections[] = $collection;
}
// convert the array of chunks to a collection object
return new Collection($chunkCollections);
};
Use in your template
<?php
$projects = page('projects')->children()->visible()->shuffle();
/**
**create random $min and $max values;
** these set the range for the random $size variable within the randomChunk() method;
** instead of random values, you can also set one or both parameters to a fixed value,
** depending on what sorts of results you want to get
*/
$max = mt_rand(1,$projects->count());
$min = mt_rand(1, $max);
$chunks = $projects->randomChunk($min,$max);
// $chunks is a nested collection, so we need two foreach loops to get the chunks and then all items in each chunk
foreach($chunks as $items): ?>
<section>
<?php foreach($items as $project): ?>
<article class="">
<?= $project->title()?>
</article>
<?php endforeach ?>
</section>
<hr>
<?php endforeach ?>
WOAW Fantastic !!!
I felt that my question was too complicated, or not logical … but this function works incredibly well!
Thanks also for the comments that explain very well.
I hope it can be used by other people.
Hi,
I could use the first method you send me, and it’s working perfeclty. After some use, I realized I also have to make another condition : I would like to have a minimum of 2 articles inside each sections.
I tried a lot a things, but I don’t really know how to write this. Could you help me with that ?
I didn’t saw the last article in your previous method could generate only one item…For now, I can’t say your second method is better : I have to continue to refresh the page to confirm that there are at least two articles. But I completely trust you !
And sorry for the confusion of accounts, I use one for personal projects, and the other for the professional : it’s easier to find topics.
It helps to test with only a few projects, then you see this immediately. What the last version does is check if the difference between the random number and the current item count is equal to or greater than $min(edited), and if not, it adds all current items to the last chunk.
Hi Sonja
You already helped me a lot with your custom chunk methods to get random section and article with a minimum of 2 articles by sections.
My client asks me for something simple that I can’t do : always display the credits to the first position ! So my goal now is to display the first project from page('projects')->children()->visible() into the first « article » even if the page is refreshed.
I am not a PHP professional and I could never put that in place, but I feel (like the last time) that it looks more complicated than it seems.
I was hoping to exclude the page with ->not() like
Good question, I can’t tell you yet the true difference, but I think if the first page comes first, it doesn’t matter for me because it already exists a minimum of two articles into the first section.
I would love to translate your idea but I’m afraid to don’t get it, could you provide me a simple example of this on a simple layout like this ?