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.
- Create the page folders as subfolders of a parent page
portfolio
- Put the image you want to show as thumbnail into the corresponding page folder
- In your content text file, add a field which you can name whatever you like, and add a value of
true
if the page should appear in the list. - Add all other content
- 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)
- 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?
- 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(); ?>-
<?php foreach($caseStudies as $work) ?>
-
<?php if ($image = $work->images()->first(): ?>
<?php endif ?> <?= $work->title()->html() ?>
<?php endforeach ?>
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)
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>
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>
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.
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): ?>