# I can't add item(s) to the end of collection

**URL:** <https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952>\
**Category:** Questions\
**Tags:** v3\
**Created:** [January 22, 2020, 3:18pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952 "2020-01-22T15:18:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 3:18pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/1 "2020-01-22T15:18:36Z")

</div>

Hi there,

I am getting quite desperate here. I can’t for the life of me figure out how to add an item to the end of a collection. I thought that is what `append()` is for, but I can’t get it to work. I tried `add()` and `extend()` as well, they don’t work either.

What I need to do is to (additionally) add a collection’s first and second item to the collections end again.

Trying just to add the first item again, I tried:

```php
$myFiles = page('landingpage')->files()->template('media')->sortBy('sort');
$myFiles->append($myFiles->first());

```

That does not work. What am I doing wrong?

Thanks!

---

<div class="post-metadata">

**Author:** ![Turqueso](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/turqueso/32/8058_2.png) [@Turqueso](https://forum.getkirby.com/u/Turqueso)\
**Post date:** [January 22, 2020, 3:31pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/2 "2020-01-22T15:31:32Z")

</div>

How I see it, you are not creating a collection with that code. I think is [similar to this other post](https://forum.getkirby.com/t/merge-pages-and-files-collection/12833/2) what you want.

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 3:36pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/3 "2020-01-22T15:36:50Z")

</div>

In the linked question the issue is mainly that the user wants to merge collections of different types. Surely there must be an easier way to add an item of the same type to the end of a collection?

Btw., the `prepend()` method works as I expected:

```php
$myFiles = page('landingpage')->files()->template('media')->sortBy('sort');
$myFiles->prepend($myFiles->last()); // adds the last file to the beginning of the collection

```

so I don’t understand why the append method seems to fail altogether?

---

<div class="post-metadata">

**Author:** ![Turqueso](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/turqueso/32/8058_2.png) [@Turqueso](https://forum.getkirby.com/u/Turqueso)\
**Post date:** [January 22, 2020, 3:40pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/4 "2020-01-22T15:40:30Z")

</div>

Because it is not a collection. You can create a collection with `new Collection()` I don’t know the rest of your code but maybe something like

`$myFiles = new Collection(page('landingpage')->files()->template('media')->sortBy('sort');); // here we create a collection`

---

<div class="post-metadata">

**Author:** ![Turqueso](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/turqueso/32/8058_2.png) [@Turqueso](https://forum.getkirby.com/u/Turqueso)\
**Post date:** [January 22, 2020, 3:44pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/5 "2020-01-22T15:44:13Z")

</div>

You can try `new Pages()` too, [the docs](https://getkirby.com/docs/reference/objects/pages/__construct) say it creates a collection

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 3:48pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/6 "2020-01-22T15:48:38Z")

</div>

What is not a collection?

```php
$myFiles = page('landingpage')->files()->template('media')->sortBy('sort');

```

creates a files object that extends the general collection class and should inherit all the collection class methods. That’s why `prepend()` works for example. So why does `append()` not work?

> [@Turqueso](#):
>
> You can create a collection with `new Collection()`

That does not solve the problem. If I do

```php
    $slides = new Collection(page('landingpage')->files()->template('media')->sortBy('sort'));
    $slides->append($slides->first());

```

it still does not add anything to my collection.

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 3:56pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/7 "2020-01-22T15:56:31Z")

</div>

> [@Turqueso](#):
>
> You can try `new Pages()` too, [the docs](https://getkirby.com/docs/reference/objects/pages/__construct) say it creates a collection

I am working with files here, not with pages, but when I use the `new Files()` method instead and follow the advice from the other thread, it also does not work:

```php
    $files1 = new Files(page('landingpage')->files()->template('media')->sortBy('sort'));
    $files2 = new Files(page('landingpage')->files()->template('media')->sortBy('sort')->limit(2));

    $merged = $files1->add($files2); // still only has the length and content of $files1

```

---

<div class="post-metadata">

**Author:** ![Turqueso](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/turqueso/32/8058_2.png) [@Turqueso](https://forum.getkirby.com/u/Turqueso)\
**Post date:** [January 22, 2020, 4:49pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/9 "2020-01-22T16:49:11Z")

</div>

> [@trych](#):
>
> What I need to do is to (additionally) add a collection’s first and second item to the collections end again.

Thinking in what you are tryin to do, maybe it’s because it is already on the collection so you can not add it again? maybe there is another approach to what you want to do? Why do you need to add the same files again?

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 5:00pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/10 "2020-01-22T17:00:29Z")

</div>

> [@Turqueso](#):
>
> Thinking in what you are tryin to do, maybe it’s because it is already on the collection so you can not add it again?

Well, if that were the case, I think this should be considered a bug. I mean, why would a command like like `append()` not allow to add items that are already in the collection? Especially when `prepend()` does it just fine.

> [@Turqueso](#):
>
> Why do you need to add the same files again?

Because I need them to appear at the end of a slideshow again to enable a seemless rollover back to the start of the slideshow. I currently “solving” this by using two separate loops, but that can’t be the right way to do it, so I would still like to know what’s would be the designated way of doing this in Kirby (and also why `append()` and `add()` don’t work as expected).

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 22, 2020, 6:21pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/11 "2020-01-22T18:21:10Z")

</div>

> [@trych](#):
>
> Especially when `prepend()` does it just fine.

I doubt that prepend works. You can’t have the same key twice, that’s why none of these will work.

You could solve this with an array of files.

```auto
$newFiles = [];
$files = page('photography')->children()->first()->files();
foreach ($files as $file) {
  $newFiles[] = $file;
}
$newFiles[] = $files->first();

foreach ($newFiles as $file) {
  echo $file->filename() . '<br>';
}

```

But you might as well do your loop and then render the first file again, instead of trying to create a collection. I don’t see why you would need two loops.

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 7:14pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/12 "2020-01-22T19:14:09Z")

</div>

> [@texnixe](#):
>
> I doubt that prepend works. You can’t have the same key twice, that’s why none of these will work.

Well, I have successfully used this prepend method to duplicate the last file for a few hours now. So is the bug rather in the `prepend()` function then? 😉

> [@texnixe](#):
>
> But you might as well do your loop and then render the first file again, instead of trying to create a collection. I don’t see why you would need two loops.

I need to add the first two elements of the collection to the end, so I was using the second loop to again loop over the files collection with a `limit(2)` option.

So the easiest way to create this collection I came up with now was this:

```php
  <?php
    $newFiles = [];
    $files = page('landingpage')->files()->template('media')->sortBy('sort');
    $files->prepend($files->last());
    foreach ($files as $file) {
      $newFiles[] = $file;
    }
    $newFiles[] = $files->first();
    $newFiles[] = $files->nth(1);
  ?>

```

This still seems incredibly cumbersome, just to add a few items to a collection/array. I guess I will just stick to my 2-loop-solution for now, all in all that seems cleaner to me.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 22, 2020, 7:35pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/13 "2020-01-22T19:35:18Z")

</div>

> [@trych](#):
>
> $files = page(‘landingpage’)-\>files()-\>template(‘media’)-\>sortBy(‘sort’); $files-\>prepend($files-\>last());

Interesting, I tested similar code without success. Which Kirby version are you using? The file is put at the beginning but not duplicated inside the collection.

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 22, 2020, 7:51pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/14 "2020-01-22T19:51:12Z")

</div>

> [@texnixe](#):
>
> Which Kirby version are you using?

3.2.3

> [@texnixe](#):
>
> The file is put at the beginning but not duplicated inside the collection

For me it duplicates in the collection and I can then access its `url()`. Of course it does not duplicate physically in the contents folder.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 22, 2020, 8:12pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/15 "2020-01-22T20:12:57Z")

</div>

> [@trych](#):
>
> Of course it does not duplicate physically in the contents folder.

no, of course not.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 22, 2020, 8:18pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/16 "2020-01-22T20:18:45Z")

</div>

I’m testing in 3.3.2 with this code

```auto
$files = page('photography')->children()->first()->files();
dump($files);

// result
/*
Kirby\Cms\Files Object
(
    [0] => photography/sky/blood-moon.jpg
    [1] => photography/sky/coconut-milkyway.jpg
    [2] => photography/sky/dark-forest.jpg
    [3] => photography/sky/desert-tree.jpg
    [4] => photography/sky/tent-in-the-woods.jpg
)
*/
$files = $files->prepend($files->first());
dump($files);
/*
Kirby\Cms\Files Object
(
    [0] => photography/sky/blood-moon.jpg
    [1] => photography/sky/coconut-milkyway.jpg
    [2] => photography/sky/dark-forest.jpg
    [3] => photography/sky/desert-tree.jpg
    [4] => photography/sky/tent-in-the-woods.jpg
)

*/

```

The number of files and the files themselves are exactly the same.

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 29, 2020, 3:35pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/17 "2020-01-29T15:35:56Z")

</div>

Hm. It seems to work somehow when I prepend the last item, but I admit I don’t understand why.

I basically get this:

```php
$slides = page('landingpage')->files()->template('media')->sortBy('sort');
dump($slides);

// result
/*
Kirby\Cms\Files Object
(
  [0] => landingpage/someVideo.mp4
  [1] => landingpage/testgrafik.jpg
  [2] => landingpage/image_02.jpg
  [3] => landingpage/image_03.jpg
)
*/

$slides->prepend($slides->last());
dump($slides);
/*
Kirby\Cms\Files Object
(
  [0] => 0
  [1] => landingpage/someVideo.mp4
  [2] => landingpage/testgrafik.jpg
  [3] => landingpage/image_02.jpg
  [4] => landingpage/image_03.jpg
)
*/

```

So I get a 0 in the first position. But strangely, when I insert this into my template like this

```auto
      <?php $ix = 0; ?>
      <?php foreach ($slides as $slide): ?>
        {name: 'rs<?= $ix ?>',
         url: '<?= $slide->url() ?>'},
         <?php $ix++ ?>
      <?php endforeach ?>

```

it still correctly extracts the url of the last file? How does that work?

Anyways, so the gist of this all is that `prepend()` and `append()` can not generally be used to add duplicate items to a list, I guess?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2020, 4:12pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/18 "2020-01-29T16:12:25Z")

</div>

> [@trych](#):
>
> Anyways, so the gist of this all is that `prepend()` and `append()` can not generally be used to add duplicate items to a list, I guess?

Excactly. That’s why I would go with either the array solution I suggested above or by simply looping through the files collection and then render the first item again.

```auto
<?php $slides = page('landingpage')->files()->template('media')->sortBy('sort'); ?>
<?php if ($slides->isNotEmpty()): ?>
    <?php foreach ($slides as $slide) : ?>
        <img src="<?= $slide->url() ?>">
    <?php endforeach ?>
    <img src="<?= $slides->first()->url() ?>">
<?php endif ?>

```

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 29, 2020, 4:28pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/19 "2020-01-29T16:28:48Z")

</div>

Yes. That just makes the code really messy in my specific case, as I need to add the last item in the beginning as well as the first two items in the end, but I guess I will have to do it this way.

It would be nice, if Kirby allowed to add duplicates to a collection, but I understand that this is probably a limitation of php arrays and probably also not a requirement that pops up all too often.

One last thing I would like to mention though is that it would be nice, if the `prepend()` and `append()` method would produce some sort of error instead of just silently fail in such a case.

---

<div class="post-metadata">

**Author:** ![Adspectus](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/adspectus/32/189_2.png) [@Adspectus](https://forum.getkirby.com/u/Adspectus)\
**Post date:** [January 29, 2020, 5:32pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/20 "2020-01-29T17:32:30Z")

</div>

Don’t know if you will find this less messy, but you could create an array of files-objects and loop through this array and within the first loop through the objects:

```
$lastitem = page('photography')->children()->first()->files()->slice(-1,1);
$allitems = page('photography')->children()->first()->files();
$first2items = page('photography')->children()->first()->files()->slice(0,2);

dump($allitems);
/*
Kirby\Cms\Files Object
(
    [0] => photography/trees/cheesy-autumn.jpg
    [1] => photography/trees/last-tree-standing.jpg
    [2] => photography/trees/monster-trees-in-the-fog.jpg
    [3] => photography/trees/sharewood-forest.jpg
    [4] => photography/trees/stay-in-the-car.jpg
)
*/
foreach ([$lastitem,$allitems,$first2items] as $files) {
  foreach ($files as $file) {
    dump($file->id());
  }
}
/*
photography/trees/stay-in-the-car.jpg
photography/trees/cheesy-autumn.jpg
photography/trees/last-tree-standing.jpg
photography/trees/monster-trees-in-the-fog.jpg
photography/trees/sharewood-forest.jpg
photography/trees/stay-in-the-car.jpg
photography/trees/cheesy-autumn.jpg
photography/trees/last-tree-standing.jpg
*/
```

---

<div class="post-metadata">

**Author:** ![trych](https://avatars.discourse-cdn.com/v4/letter/t/5e9695/32.png) [@trych](https://forum.getkirby.com/u/trych)\
**Post date:** [January 29, 2020, 8:44pm UTC](https://forum.getkirby.com/t/i-cant-add-item-s-to-the-end-of-collection/16952/21 "2020-01-29T20:44:18Z")

</div>

Thank you @Adspectus, I find this cleaner indeed and this is now how I set up my loop. 👍
