web-dev-qa-db-ja.com

ビューの残りのJSON出力にラッパーを追加する

DrupalでAPIを再構築しています。 JSONの構造は同じままにする必要があります。

ユーザーが概要ページでアイテムを注文できるように、ビューとドラッグ可能なビューを使用しています。 REST JSONをエクスポートするためにビューを有効にしました。

応答JSONはこのような構造でなければなりません

{
  items: [{...},{...}]
}

しかし、現在のビューの出力はこのようなものです

{[{...},{...}]}

ビューと特別なエクスポートコントローラーなしで目的の出力を取得できましたが、残念ながら、ビューに加えてドラッグ可能なビューが必要です。また、エンティティノーマライザを使用してネストされた構造をアイテム内に作成することもできましたが、ビューの出力全体を「アイテム」でラップしたいと考えています。任意の助けいただければ幸いです。

2
Oliver Pal

ビュースタイルのプラグインを作成して、これを高速に処理できます。以下にその例を示します。これは、resultsの外側のラッパーとtotalCountアイテムを追加します。

<?php

namespace Drupal\mymodule\Plugin\views\style;

use Drupal\rest\Plugin\views\style\Serializer;

/**
 * The style plugin for serialized output formats.
 *
 * @ingroup views_style_plugins
 *
 * @ViewsStyle(
 *   id = "serializer_count",
 *   title = @Translation("Serializer with Count"),
 *   help = @Translation("Serializes views row data using the Serializer component and adds a count."),
 *   display_types = {"data"}
 * )
 */
class SerializerCount extends Serializer {

  /**
   * {@inheritdoc}
   */
  public function render() {
    $rows = [];

    if (isset($this->view->pager)) {
      $count = $this->view->pager->getTotalItems();
    }
    else {
      $count = 0;
    }

    // If the Data Entity row plugin is used, this will be an array of entities
    // which will pass through Serializer to one of the registered Normalizers,
    // which will transform it to arrays/scalars. If the Data field row plugin
    // is used, $rows will not contain objects and will pass directly to the
    // Encoder.
    foreach ($this->view->result as $row_index => $row) {
      $this->view->row_index = $row_index;
      $rows[$row_index] = $this->view->rowPlugin->render($row);
    }

    unset($this->view->row_index);

    // Get the content type configured in the display or fallback to the
    // default.
    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(['results' => ['items' => $rows, 'totalCount' => (int) $count]], $content_type, ['views_style_plugin' => $this]);
  }

}

次に、キャッシュをクリアし、「スタイル」の下のビューのプラグインを変更します。

したがって、あなたの場合、最終行は次のようになります。

return $this->serializer->serialize(['items' => $rows], $content_type, ['views_style_plugin' => $this]);
1
Kevin

Drupalのコアシリアライザーは、jsonをカスタマイズするオプションを提供せず、ページネーションデータも含みません。

Pager Serializer モジュールにはページ付け情報が含まれており、プロパティ名はカスタマイズ可能であるため、APIは変更しないでおくことができます。

デフォルトでは、次のようになります。

{
  rows: [
    {...},
    {...}
  ],
  pager: {
    current_page: 0,
    total_items: 6,
    total_pages: 2,
    items_per_page: 5,
  }
}

モジュールの構成フォームを使用してrowsキーをカスタマイズし、必要に応じて不要なプロパティを無効にします。

{
  items: [
    {...},
    {...}
  ]
}

または@kevinによる回答で提供されている合計数が必要な場合。

{
  items: [
    {...},
    {...}
  ],
  totalCount: 6
}

または

{
  items: [
    {...},
    {...}
  ],
  pager: {
    total_items: 6
  }
}
0