Merge articles and events on homepage

Hey good morning friends,

i´ve a problem merge articles from Blog-Page and Events from Event-Page on Homepage.
I figured out the collection but not the filtering-method i would like to have.
Well the Posts should be filtered first by date but they also should rotate. First a post from Blog, than a Post from Events.

Here is the snippet loading on homepage:

<?php
    $article = $site->find('de/aktuelles/blog')->children()->visible()->shuffle();
    $event = $site->find('de/aktuelles/termine')->children()->visible()->shuffle();
    $posts = new Pages(array($article, $event)); 
    if(isset($limit)) $posts = $posts->limit($limit);    
?>
<ul class="row">
  <?php foreach($posts as $post): ?>
    <li class="col-md-4">
        <a href="<?= $post->url() ?>" class="">
          <?php if($image = $post->images()->first()): $thumb = $image->crop(600, 600); ?>
            <img src="<?= $thumb->url() ?>" alt="Thumbnail for <?= $post->title()->html() ?>" class="img-fluid" />
          <?php endif ?>
          <div class="">
            <h2 class=""><?= $post->title()->html() ?></h2>
          </div>
        </a>
    </li>
  <?php endforeach ?>
</ul>

Hope anyone could give a little help :wink:
Thank you in advance.
Martin

Hm, shuffling and sorting is a bit contradictory, isn’t it?

As for alternating posts and events, see this thread: Alternate Merging of Two Page Arrays

Yes, the shuffle was just a test :wink:
I´ll have a look at the link. Thank you.

Good morning @texnixe,
cause of i´m a php-gimp i can´t get it running.

this is my code with an error: “ParseError / syntax error, unexpected end of file”

<?php

return function($site, $pages, $page) {

   $collection = pages();
   $article = $site->find('de/aktuelles/blog')->children()->visible()->sortBy('date', 'desc', 'time', 'desc');
    $event = $site->find('de/aktuelles/termine')->children()->visible()->sortBy('date', 'asc', 'time', 'asc');
  
   $max    = max($article->count(), $posts->count());

   for ($i = 0; $i < $max; $i++) {
      if ($p1 = $article->nth($i)) {
         $collection->add($p1);
      }
      if ($p2 = $event->nth($i)) {
         $collection->add($p2);
      }
   }

   return ['collection' => $collection];
?>


<ul class="row">

  <?php foreach($collection as $collection): ?>

    <li class="col-md-4">
       
       	<?php if($collection->template() == 'article'): ?>
       	
       		<div class="article">
	       	<?php if($image = $collection->images()->first()): $thumb = $image->crop(600, 600); ?>
            <img src="<?= $thumb->url() ?>" alt="Thumbnail for <?= $collection->title()->html() ?>" class="img-fluid" />
          <?php endif ?>
            <h2 class=""><?= $collection->title()->html() ?></h2>
          </div>
          
		  <?php else: ?>
	   		
          <div class="event">
            <h2 class=""><?= $collection->title()->html() ?></h2>
          </div>
          
          <?php endif ?>
       
    </li>

  <?php endforeach ?>

</ul> 

I believe the magic is this one:

for ($i = 0; $i < $max; $i++) {
      if ($p1 = $article->nth($i)) {
         $collection->add($p1);
      }
      if ($p2 = $event->nth($i)) {
         $collection->add($p2);
      }

Well this one works perfect but without rotating the posts.

<?php
    $article = $site->find('de/aktuelles/blog')->children()->visible()->sortBy('date', 'desc', 'time', 'desc');
    $event = $site->find('de/aktuelles/termine')->children()->visible()->sortBy('date', 'asc', 'time', 'asc');
    $posts = new Pages(array($article, $event));
    
    if(isset($limit)) $posts = $posts->limit($limit);
    
?>
<ul class="row">
  <?php foreach($posts as $post): ?>
    <li class="col-md-4">
       
       	<?php if($post->template() == 'article'): ?>
       	
       		<div class="">
	       	<?php if($image = $post->images()->first()): $thumb = $image->crop(600, 600); ?>
            <img src="<?= $thumb->url() ?>" alt="Thumbnail for <?= $post->title()->html() ?>" class="img-fluid" />
          <?php endif ?>
            <h2 class=""><?= $post->title()->html() ?></h2>
          </div>
		  <?php else: ?>
	   		
          <div class="">
            <h2 class=""><?= $post->title()->html() ?></h2>
          </div>
          
          <?php endif ?>
       
    </li>
  <?php endforeach ?>
</ul>

Hope you can help a little :wink:
Regards

There are a few issues:

  1. The return function has to go into a controller, not the template.
  2. There is a closing curly brace missing after the return statement.
  3. You are using a $post variable that is not defined, replace with $event.

Put the following code into a controller for the template (/site/controllers/name-of-template.php)

return function($site, $pages, $page) {

   $collection = pages();
   $article = $site->find('de/aktuelles/blog')->children()->visible()->sortBy('date', 'desc', 'time', 'desc');
   $event = $site->find('de/aktuelles/termine')->children()->visible()->sortBy('date', 'asc', 'time', 'asc');
  
   $max    = max($article->count(), $event->count());

   for ($i = 0; $i < $max; $i++) {
      if ($p1 = $article->nth($i)) {
         $collection->add($p1);
      }
      if ($p2 = $event->nth($i)) {
         $collection->add($p2);
      }
   }

   return ['collection' => $collection];
};

Also, within the foreach loop, I would change this line

<?php foreach($collection as $collection): ?>

to

<?php foreach($collection as $item): ?>

So that you don’t use the same variable here, it will work but is not good code
(and then use $item in the following code bits).

Also, personally, I would name $article > $articles etc. if it is a collection, not a single article, everything else is rather irritating.

1 Like

Nice one! Works like a charme. THX one moretime @texnixe!!!
Regards
Martin