Auto sort structure field entries in panel

Hi,

is there a way to auto-sort the items in a structure field in the panel. Maybe on save …

  publications:
    label: Publications
    type: structure
    required: true
    entry: >
      Sort-Key: {{sort}} <br>
      Entry: {{entry}}
    fields:
      sort:
        label: Sort-Key
        type: text
        validate: alphanum
        required: true
      entry:
        label: Entry
        type: markdown
        help: Some general formatting rules could stand here …
        required: true

The items should be sorted by the sort field.

Thanks,
Tobi

Unfortunately that’s not a feature right now, but you can use a Panel hook for that.

Thanks (and sorry for the late reply). This is what I coded and the sorting works but I couldn’t figure out how to write the sorted structure object back to the field:

kirby()->hook('panel.page.update', function($page) {
    if(isset($page->content()->data['publications'])) {
        $publications = $page->publications()->toStructure()->sortBy('sort', 'asc');
        try {
            $page->update(array(
                'publications'    => $publications,// doesn't work!
            ));
        } catch(Exception $e) {
            echo $e->getMessage();
        }
    }
});

This is how the relevant part of the content file looks:

Publications: 
-
 sort: campbell2009
 entry: 'Campbell, Neil: **Biology**. Some Place 2009.'
-
 sort: darwin1852
 entry: 'Darvin, Charles: **Living Cirripedia**. London 1852.'
-
 sort: dawkins2006
 entry: 'Dawkins, Richard: **The Selfish Gene**. Oxford 2006.'
-
 sort: gould1993
 entry: 'Gould, Stephen Jay.: **The Panda’s Thumb**. New York 1969.'
-
 sort: watson1969
 entry: 'Watson, James D.: **The Double Helix**. New York 1969.'

You need to convert the data back to a string. yaml::encode($publications->toArray()) should be able to do this correctly.

No unfortunately not … it gives

- campbell2009<br />Campbell, Neil: **Biology**. Some Place 2009.
- darwin1852<br />Darvin, Charles: **Living Cirripedia**. London 1852.
- dawkins2006<br />Dawkins, Richard: **The Selfish Gene**. Oxford 2006.
- gould1993<br />Gould, Stephen Jay.: **The Panda’s Thumb**. New York 1969.
- watson1969<br />Watson, James D.: **The Double Helix**. New York 1969.

as field content …

You can do it like this, but you can’t use sortBy() in this case:

kirby()->hook('panel.page.update', function($page) {
    if(isset($page->content()->data['publications'])) {
        $publications = $page->publications()->yaml();
        
        sort($publications);
        try {
            $page->update(array(
                'publications' => yaml::encode($publications)
            ));
        } catch(Exception $e) {
            echo $e->getMessage();
        }
    }
});
3 Likes

Thanks! That worked. But by what is it sorted?

In this case, it’s sorted by the first array of the multi-dimensional array. You could also use array_multisort() http://php.net/manual/de/function.array-multisort.php, with more options.

so as long as the first field of the entry is sort is kind of like sortBy('sort'), right?

To make sure the structure is always sorted by the sort field, you can use the following code (untested):

usort($publications, function($a, $b) {
  return strcmp($a['sort'], $b['sort']);
});
1 Like

Ok, thanks, again! but as long as I’m the only developer relying on the order of the fields feels save enough :slight_smile:

I tried to sort my dates in a structure field with this hook. I adjusted all variables to mine, but it causes an infinite loop when updating the page. So the page loads, and loads, and loads, … Am I overlooking something?

The sorting field is a date field (YYYY-MM-DD).

Which Kirby and Panel versions are you using? Does it still happen if you uncomment the $page->update() line (to prevent the hook from making changes)?

I tried this with Kirby/Panel 2.1.1 and the new 2.2 - same issue. If i set the $page->update() line in comments, there is no infinite loop any more.

I tested this with a date field in structure and it works without problems (Kirby 2.1.1, having issues in K2.2 beta). Could you post your blueprint and hook?

So at the moment it’s not working with K2.2 beta, right? Then I have to wait for a fix :slight_smile:

Yeah, maybe, haven’t tested it again, there are also other issue with the structure field atm, like select fields with queries not working properly; K2.2 is a beta after all, not ready for production yet.

Have you found to sort the data? Need a solution for the same problem :smile:

No solution yet…tried the following code, but when saving the page, it loads endlessly…

kirby()->hook('panel.page.update', function($page) {
  if(isset($page->content()->data['dates'])) {
    $dates = $page->dates()->yaml();
    sort($dates);
    try {
     $page->update(array(
      'dates' => yaml::encode($dates)
     ));
     } catch(Exception $e) {
      echo $e->getMessage();
    }
  }
});
1 Like

I tested your code with a Kirby 2.2.3 Starter Kit and works for me.