Add single structureObject to structure collection

Hi there!

Sorry, AGAIN a question from me about handling and updating structure objects…

I have a a structure that holds credits (role and name) for a project.
Now I want to add a single row that is generated programmatically to this within my controller.

I thought I could use the StructureObject constructor, as documented here, but if I use that in my controller I get an error Class 'StructureObject' not found?

What is an easy way to add an extra row to the structure field? I don’t want to update the pages field permanently, I just want to add an extra row virtually within my page’s controller.

Thanks!

Code?

Well I did not get much further than

$so = new StructureObject();

and that already raises the error. Or do I not need a structureObject at all? Is there a built-in structure method to use instead?

Edit: And yes, I also tried to pass a key/value array in the structureObject constructor, same error.

The $props array is required and as a minimum need the id. Call it with the full class name*:

$so = new Kirby\Cms\StructureObject(['id' => 'whatever']);

If you dump that, you get something this:

Kirby\Cms\StructureObject Object
(
    [content:protected] => 
    [id:protected] => abc
    [parent:protected] => 
    [structure:protected] => 
    [site:protected] => 
    [propertyData:protected] => Array
        (
            [content] => 
            [id] => abc
            [parent] => 
            [structure] => 
            [site] => 
        )

)

So you see what other props there are.

* Why? Because there is no alias defined for the StructureObject class, see /kirby/config/aliases.php.

Let’s use the Starterkit as an example:

$structure = page('about')->social()->toStructure();
$count = $structure->count();
$so = new Kirby\Cms\StructureObject(['id' => $count, 'parent' => page('about'), 'content' => [
  'platform' => 'Facebookshit',
  'url' => 'https://facebookshit.com'
]]);

foreach ($structure as $item) {
  dump($item->platform());
}

Gave this a try, the new row does not appear in the structure field when I loop over it. Even tried your specific code on the about page of the starterkit and the dump returns only the fields that were already there:

20200320-171627_Screenshot_GoogleChrome

Oops, sorry, I forgot to copy this line before looping though the result:

$structure->add($so);

Ah, now it works. Also, $count = $structure->count()-1; should be $count = $structure->count() instead if the item needs to be added to the end, else the last item will be overwritten.

Thanks!

Why is structureObject missing from the aliases? Should I prepare a PR to add it or is it omitted on purpose?

Because there are only aliases for the most important classes. I don’t think it would make sense to have aliases for all classes.

You can find the full names for all classes in the docs and also a list of aliases.

If you need an object more often within a file, you can use a use statement with the namespace and then use the short form.

use Kirby\Cms\StructureObject;

$so = new StructureObject(['id' => $count, 'something', 'parent' => page('about'), 'content' => [
  'platform' => 'Facebook',
  'url' => 'https://facebook.com'
]]);

Ok, but then should the constructor not be documented differently?

new Kirby\Cms\StructureObject(array $props)

And maybe a hint that the id field is required.

(Sorry that I keep pointing out stuff in the docs, but I think having stuff complete and consistent will help all users in the long term. I am very willing to prepare a PR as well)

No, you can’t change this, because this is generated automatically from the source code. The full class name is given below the headline. We would have to generally change this then.