Search code examples
phpviewdrupalhookdrupal-views

How to add a root name and child name to drupal view REST?


I have a doubt, i've created a REST with View and i formated like JSON, but the output is like this:

[{"item1":"123","item2":"123","item3":"123","item4":"","item5":"123","item5":"123"},    {"item1":"345","item2":"345","item3":"345","item4":"","item5":"345","item5":"345"}]

And i need something like this:

{"elements":
 [
  {"element":
   {"item1":"123","item2":"123","item3":"123","item4":"123","item5":"123"}
  },
  {"element":    {"item1":"345","item2":"345","item3":"345","item4":"345","item5":"345"}
  }
 ]
}

How can i add a root name and child name? is some configuration on views that i can do?

I've tried with views_post_execute hook like this:

function mymodule_views_post_execute(ViewExecutable $view) {
    if (isset($view) && ($view->storage->id() == 'myrestjson')) {
        $result = ['elements' => array_map(
            function ($subarray) {
                return ['element' => $subarray];
            },$view->result
        )];
        $view->result = $result;
    }
  }

but i'm getting this error:

TypeError: Argument 1 passed to Drupal\views\Plugin\views\field\FieldPluginBase::advancedRender() must be an instance of Drupal\views\ResultRow,array given, called in mysite\core\modules\rest\src\Plugin\views\row\DataFieldRow.php on line 147 in Drupal\views\Plugin\views\field\FieldPluginBase->advancedRender() (line 1142 of core\modules\views\src\Plugin\views\field\FieldPluginBase.php).

Could you please help me? Regards Mario


Solution

  • You can use a custom Serializer to alter the output:

    1. Create a new custom serializer class in your custom module with the path: .../your_module/src/Plugin/views/style/CustomSerializer.php.
    2. Custom serializer class should be extended from the core Serializer class: Drupal\rest\Plugin\views\style\Serializer.php
    3. Override the render() method (you can compare with core Serializer class to see what I modified)
    <?php
    namespace Drupal\your_module\Plugin\views\style;
    
    use Drupal\rest\Plugin\views\style\Serializer;
    
    /**
     * The style plugin for serialized output formats.
     *
     * @ingroup views_style_plugins
     *
     * @ViewsStyle(
     *   id = "custom_serializer",
     *   title = @Translation("Custom serializer"),
     *   help = @Translation("Serializes views row data using the Serializer
     *   component."), display_types = {"data"}
     * )
     */
    class CustomSerializer extends Serializer {
    
      /**
       * {@inheritdoc}
       */
      public function render() {
        $rows = [];
        foreach ($this->view->result as $row_index => $row) {
          $this->view->row_index = $row_index;
          $rows[] = ['element' => $this->view->rowPlugin->render($row)];
        }
        unset($this->view->row_index);
        
        if ((empty($this->view->live_preview))) {
          $content_type = $this->displayHandler->getContentType();
        }
        else {
          $content_type = !empty($this->options['formats']) ? reset($this->options['formats']) : 'json';
        }
        return $this->serializer->serialize(['elements' => $rows], $content_type, ['views_style_plugin' => $this]);
      }
    }
    
    1. Go to your view > REST Export > FORMAT > Format > Select newly created serializer enter image description here
    2. Result: enter image description here