Display arbitrary number of blog posts

I am trying to include some (I don’t yet know how many) blog posts on the home page. I would like to have a few posts, then some other information in between, and then some more posts. What I’ve tried in my home.php template is this:

<?php $articles = page('nieuws')->children()->visible()->flip();
    $first_set  = array_slice($articles, 0, 2);
    $second_set = array_slice($articles, 2, 4);

    foreach($first_set as $article): ?>

        <article>
            <a href="<?php echo $article->url() ?>">
                <?php $image = $article->coverimage()->toFile();
                if($image): ?>
                <img src="<?= $image->url() ?>" alt="">
                <?php endif ?>
                <h2 class=""><?php echo $article->title()->html() ?></h2>
            </a>
        </article>

    <?php endforeach ?>

However I get this error:

array_slice() expects parameter 1 to be array, object given

So obviously I can’t array_slice() an object. Is there a way to easily return an arbitrary number of blog posts?

$articles is not an array, but an object of type Pages, so you can’t use array methods.

Kirby has the offset() and limit() methods to achieve what you want.

$first_set  = $articles->limit(2);
$second_set = $articles->offset(2)->limit(4);
1 Like

Thank you, that’s exactly what I needed! (In your example it should also be ->limit(2) in the second line.)

I think the code here could get repetitive, always including the whole bit in between <article> and </article>. So I’ve been trying to put this in a snippet.

homepage_article.php:

<article>
    <a href="<?php echo $article->url() ?>">
        <span class="">tag</span>
        <?php $image = $article->coverimage()->toFile();
        if($image): ?>
        <img src="<?= $image->url() ?>" alt="">
        <?php endif ?>
        <h2 class=""><?php echo $article->title()->html() ?></h2>
    </a>
</article>

And home.php:

<?php $articles = page('nieuws')->children()->visible()->flip();
$first_set  = $articles->limit(2);
$second_set = $articles->offset(2)->limit(2);
$third_set  = $articles->offset(4)->limit(2);

foreach($first_set as $article):

    snippet('homepage_article');

endforeach ?>

However, that doesn’t work. The error I get is: Undefined variable: article

Is there a way to set this up as a snippet? I’ don’t know how I could define $article in the snippet without having to duplicate the code that selects the set of articles.

You can pass variables to snippets: https://getkirby.com/docs/templates/snippets/#passing-variables-to-snippets

1 Like

Thanks so much, I probably should have found that myself.

1 Like

<?php foreach($page->children()->listed()->flip()->limit(2) as $article): ?>

should work