Problem creating a page with prop $page->cover()

When trying to create a page and passing $page->cover() (Being a files field) to one of its content props, this prop is empty ?!

Tipps appreciated …

I’m missing some context here. Where is this page created, via the Panel, programmatically? And where and when do you call $page->cover() then?

I got a migration script, loading in Kirby and then iterating over some pages, creating a set of pages using some of the page information, some other information from APIs etc.

Inside the loop, let’s say the original page is $page and the one to be created is created by $otherPage->createChild():

$otherPage->createChild([
  'slug' => $page->slug(),
  'template' => 'some-template',
  'content' => [
    'title' => $page->title(),
    'cover' => $page->cover(),
    // ...
  )],
]);

You have to assign the value of the field, not the field object:

  'content' => [
    'title' => $page->title()->value(),
    'cover' => $page->cover()->value(),
    // ...

$page->cover() etc. return an object of the Field class, but we need a string here.

Please note that if you want to work with this page object after creation, you have to store it in a variable.

$newPage = $otherPage->createChild([
  'slug' => $page->slug(),
  'template' => 'some-template',
  'content' => [
    'title' => $page->title()->value(),
    'cover' => $page->cover()->value(),
    // ...
  )],
]);

echo $newPage->cover();

In an echo context like the last line, a string is returned, because the magic method __toString() returns that string from the object.

Already tried that, too - doesn’t work (at least for me). Also tried with toFile()->filename() :frowning:

Will try again, though. Something smells fishy

To store the content of a files field, you have to store it in yaml format.

Data::encode($page->cover()->yaml(), 'yaml');

Should work.

I get it, good pointer!

it doesn’t work! :open_mouth:

I don’t get why your approach doesn’t work … dump()ing it gives the correct cover image …

This is correct, just tested it.

However, unless your code above only has a copy/paste issue, the syntax is not correct, the content array is not closed and the number of brackets is not correct either.

If that’s not the issue: Do you use the cover method from the Starterkit album model or something similar? If that is active, the code doesn’t work (but would then throw an error).

I typed in the example code, so the missing bracket is only there, not in the actual code - but how great of you distinguishing both cases!

cover is the name of the files field, nothing special there … this is the content file:

----

Cover:

- eine-schwester_bastien-vives.jpg

----

… the actual code:

$page = page('lesetipps')->children()->listed()->flip()->first();
$kirby->impersonate('kirby');

try {
    $child = page('buecher')->createChild([
        'slug' => $page->slug(),
        'template' => 'book',
        'content' => [
            'cover' => Data::encode($page->cover()->yaml(), 'yaml'),
            'title' => $page->title(),
            'isbn' => $page->isbn(),
            'shop' => $page->shop(),
            'book_title' => $page->book_title(),
            'book_subtitle' => $page->book_subtitle(),
            'author' => $page->author(),
            'illustrator' => $page->illustrator(),
            'narrator' => $page->narrator(),
            'translator' => $page->translator(),
            'participants' => $page->participants(),
            'page_count' => $page->page_count(),
            'publisher' => $page->publisher(),
            'age' => $page->age(),
            'price' => $page->price(),
            'binding' => $page->binding(),
            'categories' => $page->categories(),
            'topics' => $page->topics(),
            'hasAward' => $page->hasAward(),
            'award' => $page->award(),
            'awardEdition' => $page->awardEdition(),
            'leselink' => $page->leselink(),
            'isAudiobook' => $page->isAudiobook(),
        ],
    ]);

    // foreach ($page->files() as $file) {
    //     $file->copy($child);
    // }

} catch (\Throwable $th) {
    echo $th;
}

… and the blueprint portion is this:

fields:
  cover:
    label: Cover
    type: files
    query: page.images.filterBy('extension', 'in', ['jpg', 'jpeg', 'png'])
    layout: cards
    multiple: false
    size: huge
    image:
      ratio: 2/1
      cover: true
    info: "{{ file.dimensions }} ({{ file.niceSize }})"

And what is the result in the newly created content file? What does it store as cover? Nothing at all? While all other fields are stored correctly?

And what do you get when you do this:

$page = page('lesetipps')->children()->listed()->flip()->first();
dump($page->cover());

The result should be a field object.

That is absolutely correct …

See my edited post above.

Kirby\Cms\Field Object
(
    [cover] => - >
  eine-schwester_bastien-vives.jpg
)

… and for $child it gives this:

Kirby\Cms\Field Object
(
    [cover] => 
)

That is all very weird.

If you do this in a fresh Starterkit, do you run into the same issue?

E.g in a Starterkit’s home template, I put this code for testing:

$p = page('photography')->children()->first();
$kirby->impersonate('kirby');
$newPage = $page->createChild([
  'slug' => $p->slug() . '-' . microtime(),
  'template' => 'some-template',
  'content' => [
    'title' => $p->title()->value(),
    'cover' => Data::encode($p->cover()->yaml(), 'yaml')
  ],
]);

It gives this:

Argument 1 passed to Kirby\Data\Data::encode() must be of the type array or null, object given, called in /home/two-brain/Downloads/starterkit-master/site/templates/home.php on line 20

PHP version: PHP 7.4.11 - php -S localhost:3000 kirby/router.php

Ah, sorry, in the Starterkit you first have to remove the cover method from the album model because it gets in the way.

Works as expected:

Title: Trees

----

Cover:

- monster-trees-in-the-fog.jpg

----

Text: 

This is really weird … I also removed all plugins, but nothing works.

Where are you executing your code?

It’s a separate script, loading Composer’s autoloader, initiating Kirby and then calling above code - but executing it from inside a template resulted in the same

I’m lost in this one, especially since it’s hard to debug.