Mixing multiple child pages from two parents on front page

I’m working on a new website for the design agency where I work and we would like to mix a list of latest work (portfolio) and latest news (blog) in a grid thing on the front page. Currently I have the two as separate sections with foreach-loops listing the latest 5 work posts and the latest three blog posts, but we want to mix them together and do something like Huge Inc does on their front page.

I’m not that experienced with PHP, but I manage to hack together things. Tried nesting foreach-loops, but that obviously does not work and lists items more than once. So do I need to make some kind of arrays first and then fetch from the arrays somehow?

Anyone got any tips?

You can merge the two collections first, there are two ways of doing it:

//Merge two collections
<?php 
  $exhibitions = $pages->find('exhibitions')->visible()->children()->filterB('now', 'noo');
  $news  = $pages->findBy('news')->visible()->children();
  $homeflux = new Pages(array($exhibitions, $news));
?>

//Appending stuff to a collection:
<?php 
  $homeflux = new Pages();
  $homeflux->add($pages->find('exhibitions')->visible()->children()->filterBy('now', 'noo'));
  $homeflux->add( $pages->findBy('news')->visible()->children());
// etc...
?>

Thanks, I will give the merge a try!

I also need to give the two types of posts (work and blog) different markup when populating them to the page. If I merge to one array, how can I know what post type it is? Maybe by adding som if statements that targets specific tags/fields that only the work or blog template has? Or any other idea to do it more elegant?

Adapted to your case @pixlpusher it would become:

<?php 
  $portfolio= page('portfolio')->visible()->children();
  $blog= page('blog')->visible()->children();
  $homeflux = new Pages(array($portfolio, $blog));
?>

You can then order the new Pages collection, shuffle it, limit it, etc.

For your second question, I think the best way would be to use the intendedTemplate (or just template) in an if… else statement. This assumes your blog and portfolio pages use different templates (or just different file names in the case of intendedTemplate)

Maybe you can use a different snippets for each page type and include one or the other depending on template:

if($page->intendedTemplate() == 'sometemplate') {
  snippet('a');
} else {
  snippet('b');
}

Thanks! I will get to it and se what I manage to hack togehter :wink:

This is my first post on the forum and I must say I am delighted by quick response and helpful answers!

Don’t hesitate to ask if you get stuck :slight_smile:

Ok, stuck again …

I got the merge working and it now lists all work posts first and all blog posts after that.

Next issue is that I want to mix them up, but not just alternating work, blog, work, blog, but in a more controllable way like 3 work posts, then one blog post, then x more work posts, another blog post, and so on…

Any ideas on how to construct some kind of output to get that working?

You could add a select field for the “priority” of the pages and then use ->sortBy("priority", "desc").

Another option would be a structure or list field on the parent page that includes all the pages (updated by a hook) so you can use drag and drop to rearrange.

It’s very similar to my problem here which was solved similarly.

Interesting solutions!

Currently I’m trying to build a set layout with all the markups and no loop just using nth() to display the posts. Like first three posts will be nth(0), nth(1), nth(2) (all work posts). Then the next one is nth(6) - the latest blog post, then nth(3), nth(4) - work posts, then nth(7) blog post again, and so on… Will probably work, but not very elegant solution :stuck_out_tongue: