Not() function is not working, even with the example

Hello,

In kirby 3 I tried to exlude the cover image from the photo gallery as I did before in my Kirby 2 portfolio, but I can’t make it work, even with the same code, and even with the example code:

<ul>
  <?php foreach($page->files()->not('7D_IMG_3108.jpg') as $file): ?>
  <li>
    <a href="<?= $file->url() ?>">
      <?= html($file->filename()) ?>
    </a>
  </li>
  <?php endforeach ?>
</ul>

outputs:

7D_IMG_3108.jpg
7D_IMG_3149.jpg
20181022_152913.jpg
Dp9qX_8XgAA8eIT.jpg
Dpnz971XcAEGZD_.jpg
DqGhVU3X4AAgtWQ.jpg

Same thing with variables like $page->cover()->fileName() instead of the hard coded string. I don’t know how to make it work.

My real code is:

<?php $images = $page->images()->not($page->cover()->fileName())->sortBy('sort', 'asc') ?>

when echoed, $page->cover()->fileName() returns the good filename.

In kirby 2, this works fine:

<?php $images = $page->images()->not($page->images()->first()->filename())->sortBy('sort', 'asc') ?>

Also, unrelated minor bug: emojis are not working in tabs icons, but icon: text is OK.

Thank you for your help.

Looks as if it only works with an object, not a string:

<ul>
  <?php foreach($page->files()->not($page->images()->first()) as $file): ?>
  <li>
    <a href="<?= $file->url() ?>">
      <?= html($file->filename()) ?>
    </a>
  </li>
  <?php endforeach ?>
</ul>
<?php 

You can also pass the id:

<ul>
  <?php foreach($page->files()->not('photography/animals/bird-reynolds.jpg') as $file): ?>
  <li>
    <a href="<?= $file->id() ?>">
      <?= html($file->id()) ?>
    </a>
  </li>
  <?php endforeach ?>
</ul>
<?php 

Just the filename doesn’t work.

So to make your real code work, you can change it to this:

<?php $images = $page->images()->not($page->cover()->toFile())->sortBy('sort', 'asc') ?>

Oh OK, I can’t find the topic but if I recall correctly Kirby 2 require a string only for images()->not() (not files()->not()), I think it was a bug and that’s why I coded my Kirby 2 portfolio with fileName(), which is working (because I asked the exact same question few years ago).

Maybe the bug is gone in Kirby 3?

it works with not($page->cover()->toFile()) but I dismissed this solution as I have <?php ($cover = $page->cover()->toFile() ?> earlier in the file and whan I tried not($cover) and this doesn’t work.

//edit the $cover variable was in an if statement <?php if ($cover = $page->cover()->toFile()): ?>, maybe it doesn’t set it for the rest of the page?

Thank you.

Hm, if $cover is a file object, that should actually work, could you please post the complete code so we can find out why it doesn’t?

<?php $cover = $page->cover()->toFile() ?>

//snippet on same page
<?php $images = $page->images()->not($cover)->sortBy('sort', 'asc') ?>
  <?php foreach ($images as $image): ?>
  <figure>
    <a href="<?= $image->link()->or($image->url()) ?>">
      <?= $image->crop(600, 800) ?>
    </a>
  </figure>
  <?php endforeach ?>

What does

dump($cover);

return?

Returns nothing. Weird as I use it above in:

<div class="cover">
  <?php if ($cover = $page->cover()->toFile()): ?>
  <?= $cover->crop(800, 800) ?>
  <?php endif ?>
</div>

And the cover is displayed (it’s just the starter kit template)

But if you don’t pass the cover variable down to the snippet, it won’t work.

Even if the template is on the same page? (like $page variable)

I’m not quite sure what is in your template and what is in your snippet now. I think the picture would be clearer with all the code.

Template:

<?php snippet('header') ?>
<main>

  <header class="intro">
    <h1><?= $page->title() ?></h1>
    <h2><?= $page->subtitle() ?></h2>
  </header>

  <div class="layout">

    <div class="cover">
      <?php if ($cover = $page->cover()->toFile()): ?>
      <?= $cover->crop(800, 800) ?>
      <?php endif ?>
    </div>
    <aside>

      <section>

        <div class="text">
          <?= $page->text()->kt() ?>
        </div>
      </section>

      <?php snippet('specs') ?>

    </aside>

  </div>
  <?php snippet('gallery') ?>
  <?php snippet('specs') ?>

</main>
<?php snippet('product-json') ?>
<?php snippet('footer') ?>

snippet(‘gallery’):

  <section class="gallery">
  <?php $images = $page->images()->not($page->cover()->toFile())->sortBy('sort', 'asc') ?>
  <?php foreach ($images as $image): ?>

  <figure>
    <a href="<?= $image->link()->or($image->url()) ?>">
      <?= $image->crop(600, 800) ?>
    </a>
  </figure>
  <?php endforeach ?>
</section>

I missed that you are talking about the Starterkit and the album page. In the Starterkit, $page->cover() in the album template already returns a file object (either from what is stored in the cover field or the first image), so calling toFile() doesn’t make sense here (the album page uses a page model).

Yes but I dropped the page model in this case so it makes sens again :slight_smile:

Then your above code should actually work. So what exactly doesn’t work?

Yes it works, I was just wondering why $cover alone doesn’t work, but it’s because I don’t pass the variable in the snippet (I though that it was not necessary as it was on the same page)

Thank you for your help.

Exactly, variables have to be passed on to the snippet.