Structure with dynamic select field

Hi - I’m trying to use a dynamic select field inside of a Structure element in the panel. My blueprint is as follows:

  artists:
    label: Artist(s)
    type: structure
    fields:
      artist:
        label: Artist
	    type: select
	    options: query
	    query:
	      page: artists

When I run this from my browser I get the following errors:

Warning: Illegal string offset 'name' in ~/panel/app/lib/blueprint/fields.php on line 16

Warning: Illegal string offset 'page' in ~/panel/app/lib/blueprint/fields.php on line 17

Warning: Illegal string offset 'type' in ~/panel/app/lib/blueprint/field.php on line 29

Warning: Illegal string offset 'default' in ~/panel/app/lib/blueprint/field.php on line 33

Warning: Invalid argument supplied for foreach() in ~/kirby/toolkit/lib/obj.php on line 17

Warning: Illegal string offset 'name' in ~/panel/app/lib/blueprint/fields.php on line 16

Warning: Illegal string offset 'page' in ~/panel/app/lib/blueprint/fields.php on line 17

Warning: Illegal string offset 'type' in ~/panel/app/lib/blueprint/field.php on line 29

Warning: Illegal string offset 'default' in ~/panel/app/lib/blueprint/field.php on line 33

Warning: Invalid argument supplied for foreach() in ~/kirby/toolkit/lib/obj.php on line 17

Warning: Missing argument 1 for FieldAbstract::__construct(), called in ~/panel/app/lib/form.php on line 240 and defined in ~/kirby/core/field.php on line 20

Warning: Missing argument 2 for FieldAbstract::__construct(), called in ~/panel/app/lib/form.php on line 240 and defined in ~/kirby/core/field.php on line 20

Notice: Undefined variable: page in ~/kirby/core/field.php on line 21

Notice: Undefined variable: key in ~/kirby/core/field.php on line 22

Any ideas? Thanks for your help!

If your indents are like in the example above,then there is sth wrong, the label, type and options of the artist field should be unindented and in line with the label.

Sorry something must have happened to the formatting when I pasted in – this is how it’s structured in the file itself:

http://imgur.com/0tXJrSg

Thanks for your help!

Nevertheless, I am missing what you are trying to fetch:

artists:
    label: Artist(s)
    type: structure
    fields:
      artist:
        label: Artist
	    type: select
	    options: query
	    query:
	      page: artists
              fetch: children //or images or whatever ...

I’m trying to fetch children (I believe fetch defaults to children) – when I specify it explicitly I get the same errors…

Thanks again,

Oh, you are right :blush: Then the code seems to be correct. Maybe there’s sth else in the file that is causing the error. I suppose you are using the lasted Kirby version?

Arg - yes, my apologies, had a tab in there instead of a double space.

One more question though, if you don’t mind.

Now that I am able to select pages from my Artists section, is there a way to have the system display the page Title instead of the URI? I tried the following:

  artists:
    label: Artist(s)
    type: structure
    entry: >
      {{title}}
    fields:
      artist:
        label: Artist
        type: select
        options: query
        query:
          page: artists

But it makes the entry area appear blank from within the panel. Is there documentation I can read somewhere on the entry template beyond what’s mentioned here:

http://getkirby.com/docs/cheatsheet/panel-fields/structure

Thanks again for all your help!

There are two options, text and value that determine what is shown to the user (text) and what is entered into the text file (value):

artists:
    label: Artist(s)
    type: structure
    entry: >
      {{artist}}
    fields:
      artist:
        label: Artist
        type: select
        options: query
        query:
          page: artists
          text: '{{title}}'
         value: '{{uid}}' //this is the default, can be change to e.g. title

You can read more about it here http://getkirby.com/docs/cheatsheet/panel-fields/select in the section on Option Queries.

And as regards the entry section: The entry section determines what is shown in the field after it was created, so you would have to put the name of the field there, in your case that would be {{artist}} not {{title}}. This would, however, still show the uid of the selected page in the list view. To avoid that, you would have to change the value from uid to title in you template you would then have to find the file by its title.

Got it - thank you, very helpful. Is there an easy way to show the title in the list view but store the uid?

Thanks again for all your help,

Hi there, @griffiths.

Wanted to throw this in as this may be of some help. I’m working on a project where I need to have a person’s name be selectable via a query from a structure field, similar to your artist problem. I want the person’s name to appear as text (as John Doe) vs. john-doe AND I want the user to be able to click on the name to get to the person’s profile page.

This is a two-part approach for the link and for changing up the uid that require the blueprint to be exactly as above from @texnixe. So use that blueprint, and then the list view in the panel will be formatted the way you want the administrator to read it in the panel. It actually outputs the UID, which is perfect for creating the link that the user clicks on the front end.

But the artist’s name appears to be OK in the panel, and on the site itself it looks like the UID comes out! Ew. We need to explode the UID in the template if it is a two-word artist name. For example, Andy Warhol would usually have an UID of andy-warhol, right? So we want to remove the - and replace it with a space, then capitalize the names. So here’s how we explode the UID in the template:

    <?php
$uid = $page->artist();
$names = explode("-", $uid);
//first name is $names[0]; first artist name
//last name is $names[1]; last artist name
?>

Obviously, if you have an artist with more than two names, you can refer to each additional name as $names[3] and so forth. When we echo $names[0], we get andy as a value. and with an echo of $names[1] we get warhol. This is pretty spiffy but when you echo them together, you get andywarhol with no space in between. So we need to echo them separately. And we need to capitalize the names too, which we can do just by calling ucwords before our strings, like so:

<?php echo ucwords($names[0]); ?>

Let’s focus on the link in the template that appears when the artist name is printed:

    <a href='<?php echo $site->url() . '/' . 'insertyourfoldernamehere' . '/' . urlencode($page->artist()) ?>'><?php echo ucwords($names[0]); ?> <?php echo ucwords($names[1]); ?></a></strong></a>

The above code points to the artist page (you’ll likely need to change stuff up depending on your folder structure and where your artist pages are stored). You now have a link to Andy Warhol’s artist page that looks like Andy Warhol. That space is tons better than the andy-warhol that would appear if left on its own, and it points directly to the artist page!

Hope this was helpful for you, @griffiths!

Edited my comments above to include the capitalization portion!

@griffiths I don’t know of a way to display the title in the panel list view and store the uid in the file. However, you can store the title (and it should then get displayed) and then fetch the corresponding page in your template.

@texnixe Thanks for the tip. When I try your suggestion, it outputs the UID of my person, not her name.

It was helpful in replacing the urlencode($page->artist()) part of the URL reference above, though!

Hm, I wonder if it just doesn’t work with structure fields?

@texnixe Thanks for this - I think I will just stick with displaying the UID in the panel, not a huge deal. I’m a little weary of storing the page title as it’s not necessarily a unique identifier.

The code above does not work, in fact the new method is called toPage() but that only seems to work on first level pages … So I will delete it as not to confuse people.

I had the same problem. I solved it by using a hook.

I let the user store the {{uid}} and then I add the {{title}} with a hook.

Code is something like this:

foreach ($coll as $c)
        {
            $c_title = page('collezioni')->children()->findBy('autoid',trim($c->collection_id()))->title();
            
            array_push($coll_upd, ["collection_id" => $c->collection_id(), 
                               "collection_title" => $c_title]);
        }

        $page->update(array('collections' => yaml::encode($coll_upd)));

If it is just a matter of displaying the title instead of the UID in the Panel, I’d use the snippet field instead of the structure field. The snippet field gives you full control about what is displayed in the Panel, including images.

Thanks. It looks promising!