Sort Paragraphs programmatically from the theme

Created on 9 June 2023, about 2 years ago

Problem/Motivation

I have a paragraph of paragraphs, and I would like to be able to sort it via 1 field inside the child paragraphs, but I am having issues with it. (I can only do it from the template, as I have no access to create or modify modules)

Employment changes
Employmentchange1
Title: Mr Power
Rank: 2
Employmentchange2
Title: Mr Ben
Rank: 1
Employmentchange3
Title: Mr Ahoy
Rank: 3

And I want these to be rendered by Rank. So they show like so:

Employmentchange2
Title: Mr Ben
Rank: 1
Employmentchange1
Title: Mr Power
Rank: 2
Employmentchange3
Title: Mr Ahoy
Rank: 3

Proposed resolution

I have tried it via 3 different approaches and none of them worked. Here are the issues I had with each:
(There might be some small typos in the code here and there, as I quickly renamed some variables and stuff to simplify my explanation, but thats probably not the issue if you find any)

APPROACH 1. From the .theme file, with the hook THEME_preprocess_layout:

The preprocess_paragraph hook is not called. Presumably because display suite is handling the rendering? So I am trying in preprocess_layout.

function THEME_preprocess_layout(array &$variables) {
  //......  
    foreach ($variables['content']['#paragraph']->field_items as $thiskey => $thisvar){
      $target_id= $thisvar->target_id;
      $paragraph = Paragraph::load($target_id);
      $rank = $paragraph->field_rank->value;
      $newkey = $foo . $thiskey;
  }

I create a new key, with a mixture of the RANK field and the current ID of the array (to avoid repetitions). But I do not know how to override the field_items object/array with my new one which would already have the right order. I believe here I can create a new entity "EntityReferenceFieldItemList". But I dont think I can replace it in the variables. Or at least I do not know how.

APPROACH 2: From the TWIG file of the paragraph, using the sorting function

{% set field_items = _context.ds_content.field_items|sort((a, b) => a.['#paragraph'].field_rank[0].value <=> b.['#paragraph'].field_rank[0].value %}

And then printing field_items. But nothing happens here. I did check with a loop, and _context.ds_content.field_items has the items with the paragraph I need.

APPROACH 3: From the TWIG file of the paragraph, manually looping thorough the objects and individually printing each field.

 {% for key, value in _context.ds_content.field_items[0]['#paragraph'].field_rank[0].value  %}
      <li>{{ value }}  </li>
    {% endfor %}

Now here I am aware I am not looping thorough each individual item, as right now I am just trying to get the value of 1 field to get the syntax right. When I print the keys of "_context.ds_content.field_items[0]['#paragraph'].field_rank[0]" I get only "value" as key. But when I try to print it with {{ value }} it comes up empty. And the same with key.

When I print that value with the debugger, I get it as "protected" if I use the default variable dumper. Which makes me think I need to use "Getfield" or getvalue or some of those functions somewhere. But I tried in a couple places after printing the callable functions of each object and I just cant get it to work.

I am aware this would override the drag/drop feature. And for that I will just add a tickbox to see if I run this or not "Order by default" kind of thing.

Any help would be appreciated.

💬 Support request
Status

Active

Version

1.15

Component

User interface

Created by

Live updates comments and jobs are added and updated live.
  • theming

    Used in Documentation issues related to theming

Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024