web-dev-qa-db-ja.com

Views Datasource JSON出力を変更するためにどのフックを使用できますか?

Views および Views Datasource を使用して、サイトのJSONフィードを生成しています。ビデオとサムネイル画像の両方がある Video フィールドがあります。

Jsonフィードにサムネイル画像のURLを含めたいのですが。ビューのフィールドリストに[ビデオ]フィールドを追加し、[ビデオプレーヤー]形式ではなく[ビデオサムネイル]形式を選択して、ビデオではなくサムネイルが表示されるようにします。通常のビューでこれを行うと、完全に機能します。ただし、JSONドキュメントビューを使用すると、正しく機能しません。サムネイル画像にURLをレンダリングするのではなく、ビデオにU​​RLをレンダリングします。

これを適切に機能させる方法について説明する別の質問を作成しますが、この質問は私のバックアップソリューションです。

サムネイル画像のfidが含まれるようにフィールドを書き換えることができるので、私の現在のアイデアは、レンダリングされたjsonを後処理したり、jsonに変換される前にデータ構造を操作したりできるようにするフックを実装することです。 fidで画像を検索し、配列内のそのデータを適切な画像のURLに置き換えます。

これまでに多くのフックを試しましたが、jsonデータを表すデータを提供するフックはありません。

  • hook_views_pre_view
  • hook_views_pre_render
  • hook_views_post_render
  • hook_views_post_execute

私の推測では、フックの実装でデータを確認した後、Views Datasourceがデータを処理しています。

どのフックを使用できるので、jsonに変換される前にデータ構造を操作しますか、またはjsonに変換された後、json文字列を操作するためにどのフックを使用できますか?

4
Kenny Wyland

1つ目の回答は、viewsおよびviews_datasourceに関する補助情報に関する有益な情報です。だからここに私があなたが望むURLを得ると思う1つの方法があります。

あなたが言った:

私の推測では、フックの実装でデータを確認した後、Views Datasourceがデータを処理しています。

views_json_view_pre_render() が何をしているのかを見てください:

function views_json_views_pre_render(&$view) {
  if(isset($view->plugin_name) && $view->plugin_name == 'views_json') {
    // Support for Video field.
    if(!empty($view->result)) {
      // Process each View result.
      foreach($view->result as $row => $result) {
        // Only process the entity fields defined by the View.
        foreach($view->field as $field_name => $field) {
          if($field instanceof views_handler_field_field) {
            if($field->field_info['type'] == 'video') {

              // Get the Video URL.
              $video = $field->get_value($view->result[$row]);
              // -- See this line !!
              $url = file_create_url($video[0]['uri']);
              $render_array = array(
                '#type' => 'markup',
                '#markup' => filter_xss($url),
              );
              // Substitute embed code with URL. @todo Add support for escaped embed codes.
              // See this line !!
              $view->result[$row]->{'field_'. $field_name}[0]['rendered'] = $render_array;
            }

ビデオフィールドviews_jsonが各結果を取得し、埋め込みコードをビデオのURLに置き換えている場合。これはあなたが見ているものです。

では、これをどのように修正しますか? beforeviews_jsonの事前レンダリングを実行する独自のhook_views_pre_render()を記述します。事前レンダリング関数で、$video[0]['uri']を任意のURLに変更します。最終的には、views_jsonが使用する値になります。ここで画像のFIDまたは完全なURLを取得できる場合は、その値を簡単に設定できるはずです。

したがって、独自のモジュールで2つの関数を記述します。

// File: mymodule.install
function MYMODULE_install() {
// Set the weight of the mymodule.module to a value lower than views_datasource's views_json module.
  db_update('system')
   ->fields(array('weight' => -1))
   ->condition('name', 'mymodule')
   ->execute();
}


// File: mymodule.module
/**
 * Implements hook_views_pre_render().
 */
function mymodule_views_pre_render(&$view) {
  if(isset($view->plugin_name) && $view->plugin_name == 'views_json' && $view->name == 'YOUR_SPECIFIC_VIEW') {
    // Support for Video field.
    if(!empty($view->result)) {
      // Process each View result.
      foreach($view->result as $row => $result) {
        // Only process the entity fields defined by the View.
        foreach($view->field as $field_name => $field) {
          if($field instanceof views_handler_field_field) {
            if($field->field_info['type'] == 'video') {
              // Change the video uri to the image you want ...
              $view->result[$row][0]['uri'] = /* some logic here */;
            }
          }
        }
      }
    }
  }
}

Pre renderフックは、views_datasourceの前に実行されます。それは単にあなたが望むものにURLを変更します。次に、views_datasourceのviews_jsonフックが実行され、想定どおりに使用されます。正しい値を入力しただけです。これはうまくいくはずです。コードはテストされていません。

4
tenken

この問題のキューを参照してください。 現在(一部の人々)は、ビューのフィールドの書式設定は脆弱であると考えています。 Drupal8では次のように変更されます。

私はこれを行っていませんが、これはvery完全な問題の投稿で、現在ビューフィールドを変更する方法について説明しています。

現在、Views Datasourceは、各フィールドに付属するデフォルトのフィールドAPIフォーマッターを使用するようにハードコーディングされています。私はこの問題を調査し、@ merlinofchaosのような人たち(この時点では私を憎む必要があります)と話し合って、問題がコアまたはビュー自体にあるのではないと結論付けるのに十分な時間を費やしました。どちらも、ビュー内からField APIレンダリングエクスペリエンスを完全にカスタマイズするための適切なインフラストラクチャを提供します。ビューでフィールドレンダリングエクスペリエンスをカスタマイズする方法は、 ビュープラグイン を使用することです。

Viewsデータソースの問題は、OOP継承を介して厳密にViewsプラグインを実装していることです。このモジュールの動作をオーバーライドしたくない場合は完全に問題ありませんが、必要になると機能しなくなります。たとえば、「空かどうかに関係なく、すべてのフィールドをレンダリングしてください」、「タイトルフィールドでHTMLを許可する、これは私のマネージャーが要求したものだからです。」さらに複雑にするために、独自のビューを実装する場合プラグイン、Views Datasourceに明確な方法がない:「ねえ、私のViewsプラグインを使用してください!」つまり、広範囲にわたるパッチやフォークをしないと、Views Datasourceを手際よく整えるエレガントな方法がないようです。

TLTR:必要な明示的なURLを出力する独自のフィールドフォーマッターを作成します。あなたが説明するプレイヤーのものはおそらくビューモードの宛先(HTML宛先、ページvsフィードvs Mediaからのjson)を見て、あなたが説明するように出力を何らかの方法で変更しています。

1
tenken