How to get visible subpage image URL


#1

Howdy!

I need to display cover image from every visible subpage on my home/frontpage

My blueprint looks like this:

title: Article

pages: false

fields:
  title:
    label: Title
    type:  title
    
  cover_image:
    label: Cover
    type: image
    width: 1/2

…and I use following loop:

<?php foreach($pages->visible() as $item): ?>
  <a href="<?= $item->url() ?>"></a>
  <img class="image" src="<?= $item->cover_image->url() ?>" alt="">
  <h3><?= $item->title()?></h3>
<?php endforeach ?>

Page link and title works fine but the cover_image is not

The solution must be fairly simple but I can’t figure it out. Any suggestions?


#2

I came into to this solution

<img class="image" src="<?= $item->file()->url() ?>" alt="">

But what if page has multiple files/images and I only need to show the one stored in cover_image?


#3

This should be:

<img class="image" src="<?= $item->cover_image()->toFile()->url() ?>" alt="">

You should check the field has a value though, before trying to use it. There are shorter ways but, one way to do this is like:

<?php if($item->cover_image()->isNotEmpty()): ?>
<img class="image" src="<?= $item->cover_image()->toFile()->url() ?>" alt="">
<?php endif ?>

And you have closed your link tag without putting anything inside it :slight_smile:


#4

Thank you so much for the quick reply! That solved the problem.

Link tag is used to cover whole content (title and image etc) to prevent scroll issues on some touch based devices (in my experience).

OFF TOPIC They use this approach on theverge.com


#5

Glad you sorted it.

Regarding the anchor tag. I can’t think why that would cause scroll issue without doing that, but empty tags are bad practice. You could at least put a non-breaking space in it.

<a href="#">&nbsp;</a>

The trouble with an empty anchor is that a screen reader wont have anything to read out, so a person with sight impairment wont be able to understand what this link is for, particularly as you have also omitted the title property.


#6

True that! I need to review my “empty tag” solution before moving on.


#7

Smashing :slight_smile:

Remember that CSS and javascript are largely progressive enhancements. Your page should make sense and be useable with both disabled in the browser.


#8

It is more important to check if you have an image object, not if the field is empty or not:

<?php if($image = $item->cover()->toFile()): ?>
<img class="image" src="<?= $image->url() ?>" alt="">
<?php endif ?>

The condition will return false if the field is empty, anyway.

If you just check if the field is empty, it doesn’t help you, because even if the field contains a value, the file might have been removed. You site will then break with a PHP error, saying that you are trying to use an object method on a non-existing object.


#9

Great! Thanks for clarifying this. This is the case right now.

But what if I need to display predefined/default image when cover_image is empty

<?php if($item->cover_image()->isNotEmpty()): ?>
<img class="image" src="<?= $item->cover_image()->toFile()->url() ?>" alt="">
<?php else: ?>
// display default image
<?php endif ?>

is it OK to use isNotEmpty() in this scenario?


#10

No, same as above, display a default image if there is no image (no matter if the field is empty or the image doesn’t exist:

<?php if($image = $item->cover()->toFile()): ?>
<img class="image" src="<?= $image->url() ?>" alt="">
<?php else: ?>
<!-- display default image -->
<?php endif ?>

#11

@lindeman Sorry to confuse you, isNotEmpty() is best used on a field that contains a plain text value (like a page title). If you dealing with files and images, its best to use the method @texnixe explained to check that the file physically exists. My bad, sorry.

You can pull your default image from the assets folder, so you do not have to store it in your article(s). This way you only have one copy of the image to maintain.

<?php if($image = $item->cover()->toFile()): ?>
<img class="image" src="<?= $image->url() ?>" alt="">
<?php else: ?>
<!-- display default image -->
<?php $fallbackimg = new Asset('assets/images/default.jpg'); ?>
<img class="image" src="<?= $fallbackimg->url() ?>" alt="<?= $page->title() ?">
<?php endif ?>

Alternatively you can store it in your site folder (accessible through the Site Options menu item in the panel dropdown menu).

<?php if($image = $item->cover()->toFile()): ?>
<img class="image" src="<?= $image->url() ?>" alt="">
<?php else: ?>
<!-- display default image -->
<?php $fallbackimg = $site->image('default.jpg');?>
<img class="image" src="<?= $fallbackimg->url() ?>" alt="<?= $page->title() ?">
<?php endif ?>

That way is slightly better because it will allow you set your alt tag via file meta data files.

Again, remember to check it physically exists :slight_smile:


#12
<?php if($image = $item->cover()->toFile()): ?>
  <img class="image" src="<?= $image->url() ?>" alt="">
<?php else: ?>
  <!-- display default image -->
  <?php if($fallbackimg = $site->image('default.jpg'));?>
    <img class="image" src="<?= $fallbackimg->url() ?>" alt="">
  <?php endif ?>
<?php endif ?>