How to make a list of case studies with a thumbnail image?

I have 40 case studies / pages. I wish to show 16 in a list, with one thumbnail image per case study, plus the heading and subheading of each case study. I want to decide which case studies are shown and which image is used. I don’t have the faintest idea how to do this.

  1. Create the page folders as subfolders of a parent page portfolio
  2. Put the image you want to show as thumbnail into the corresponding page folder
  3. In your content text file, add a field which you can name whatever you like, and add a value of trueif the page should appear in the list.
  4. Add all other content
  5. Optionally, if you want to select one of multiple images, create a field from which you can select the image (in that case the code below would have to be slighly changed)
  6. In the parent template, loop through the list of children, as @rasteiner already described in the other thread:
<?php
// get all case studies
$caseStudies = page('portfolio')->children()->published();
?>

<ul>
<?php foreach($caseStudies as $work) ?>
  <li>
    <a href="<?= $work->url() ?>">
      <?php if ($image = $work->images()->first(): ?>
        <img src="<?= $image->resize(300, 200)->url() ?>" alt="">
      <?php endif ?>
      <?= $work->title()->html() ?>
    </a>
  </li>
<?php endforeach ?>
</ul>

Change markup as needed.

I do want to select one of multiple images, to be the thumbnail image (each case study has at least two images and I want to be able to choose which image is used).

So if I have an image called sun.jpg and a corresponding sun.txt file, I would add a field to this file called say Thumbnail: true ?? And then somehow the php would only show those images with this field?

  1. In the parent template, loop through the list of children, as @rasteiner already described in the other thread:

But I want this list to go on all my pages, not just the portfolio (parent page). Is this possible?

Sure, in this case, I’d create a snippet with the code from above (Snippets | Kirby CMS) that you can integrate wherever you want it.

For the thumbnail, make the following change

<?php if ($image = $work->images()->findBy('thumbnail', true): ?>
   <img src="<?= $image->resize(300, 200)->url() ?>" alt="">
<?php endif ?>

Tried the following in a snippet

<?php // get all case studies $caseStudies = page('portfolio')->children()->published(); ?>

but just get a syntax error, unexpected ‘:’

Urm, what does $work relate to?

If you do it like this, the first line is commented. The // style comment needs to be on a separate line

<?php $caseStudies = page('portfolio')->children()->published(); ?>

Yes this is what I’ve done, but I just get the error message about the colon.

<?php
// get all case studies
$caseStudies = page('portfolio')->children()->published();
?>

<ul>
<?php foreach($caseStudies as $work) ?>
  <li>
    <a href="<?= $work->url() ?>">
      <?php if ($image = $work->images()->first(): ?>
        <img src="<?= $image->resize(300, 200)->url() ?>" alt="">
      <?php endif ?>
      <?= $work->title()->html() ?>
    </a>
  </li>
<?php endforeach ?>
</ul>

Colon missing:

<?php foreach($caseStudies as $work): ?>

Still an error “syntax error, unexpected ‘:’” line 9, so the colon after $work): ?>

<?php
// get all case studies
$caseStudies = page('portfolio')->children()->published(); ?>

<ul>
<?php foreach($caseStudies as $work): ?>
  <li>
    <a href="<?= $work->url() ?>">
      <?php if ($image = $work->images()->first(): ?>
        <img src="<?= $image->resize(300, 200)->url() ?>" alt="">
      <?php endif ?>
      <?= $work->title()->html() ?>
    </a>
  </li>
<?php endforeach ?>
</ul>

Is it possible to do this inside the Panel?

This line is wrong

<?php if ($image = $work->images()->first(): ?>

Should be

<?php if ($image = $work->images()->first()): ?>

@ jimbobrjames
Thank you works now!

(sorry for the wrong PHP, I wrote this in the forum without the help of an IDE on which I sadly rely on)

1 Like

I think I am going to hand-code / hard-code this. I think there are too many variables and it is too tricky for me to get my head around it at this stage in my learning Kirby.

The variables:
I only want to list a selection of case studies.
Listed in the order I want.
With one thumbnail image of my choice selected from many images

Rather than having to manually copy and paste each case studies Heading and Sub-heading into my hand-coded list, is there a way to use Kirby to suck these fields into my list? Something like this:

<li>
  <a href="case-study1">
        <img src="sunshine.jpg" alt="">
       <p><?= case-study1->heading()->html() ?><br>
         <?= case-study1->subheading()->html() ?></p>
    </a>
</li>

@ rasteiner
No worries. Thanks for all your help!

In Kirby there’s the concept of page status. That can be “Draft” (not accessible to the public), “Unlisted” (accessible but not listed), “Listed” (Listed and manually sorted). This kinda looks perfect for your usecase.
If I were you, your portfolio page would have a blueprint like this:

sections:
  drafts:
    type: pages
    template: casestudy
    status: draft
  listed:
    type: pages
    template: casestudy
    status: listed
  unlisted:
    type: pages
    template: casestudy
    status: unlisted

In your panel you can then sort the “listed” pages by dragging them around.

Your case study blueprint should then comprehend a field that lets you choose between all images:

# this is only part of your blueprint
fields: 
  cover:
    type: files
    required: true

In the panel you then choose which of the images you want as cover for the project.

Your snippet for the list of case studies would then filter by page status and use the field to choose the correct image:

<?php
// get all case studies
// listed, instead of published
$caseStudies = page('portfolio')->children()->listed(); 
?>

<ul>
<?php foreach($caseStudies as $work): ?>
  <li>
    <a href="<?= $work->url() ?>">
      <?php if ($image = $work->cover()->toFile()): ?>
        <img src="<?= $image->resize(300, 200)->url() ?>" alt="">
      <?php endif ?>
      <?= $work->title()->html() ?>
    </a>
  </li>
<?php endforeach ?>
</ul>
1 Like

Many thanks for your help. I’ve now spent 3 hours on this…

Using the above code I can display a list of case studies filtered by page status. But I don’t understand how to be able to select the image I want. I can get it to display the first image in a particular case study folder, but this isn’t what I want. In the Panel I can move my images up and down a list of images, but this doesn’t make any difference to the image that is displayed, which I find odd.

I’ve added the following to my default blueprint (I don’t have a separate blueprint for case studies)

fields: 
  cover:
    type: files
    required: true
title: Default Page

columns:
	main:
		width: 2/3
		sections:

		fields:

			image_content: 
				type: files
			menu_name: 
				type: text
			description_meta_tag:
				type: text     
			heading:
				type: text
			subheading:
				type: text
			text:
				type: textarea
				size: large

	sidebar:
		width: 1/3
		sections:
			pages:
				type: pages
				template: default
			files:
				type: files

				fields: 
  			cover:
    		type: files
    		required: true

But nothing changes in the Panel. I was expecting the Panel to somehow let me select which image I wish to use. Is this called a ‘cover’ image?

Unless it’s a problem with copying it here, your indentation seems to be wrong for the cover key. And you want this to be a field, not a section, so you have to create a new fields section first, like this:

title: Default Page

columns:
  main:
    width: 2/3
    sections:
      fields:
        image_content: 
          type: files
        menu_name: 
          type: text
        description_meta_tag:
          type: text     
        heading:
          type: text
        subheading:
          type: text
        text:
          type: textarea
          size: large

  sidebar:
    width: 1/3
    sections:
      pages: # this is a pages section
        type: pages
        template: default
      files: # this is a files section
        type: files
      filesfield: # this is a new fields section
        type: fields
        fields:
          cover: # this is the select field for your thumbnail
            type: files
            required: true

So always two spaces for each indentation level.

1 Like

Thank you @ rasteiner and @ texnixe

That all seems to work. I didn’t know that indentation matters.

How come a page can have more than one ‘cover’ image? I was expecting to be able to only choose one ‘hero’ or ‘key’ image per page, not multiple. Or have I misunderstood the idea of a ‘cover’ image?

Thank you for your help. Amazing. The snippet code seems to work, but I don’t know why.

My case studies have content stored in case-studies.txt files. But I don’t think I have anything called ‘work’. So how does the following (for example) know where to pull in content?

<?= $work->title()->html() ?>

or does this give the the process a name. And could be called anything?

<?php foreach($caseStudies as $work): ?>