ビューによって作成されたNIDのリストをインターセプトして、別のビューのフィルターとして使用する方法はありますか?


8

DrupalとViews APIを使用して、カスタムコードレベルでサイトデザインの課題を解決しようとしているDrupalエクスペリエンスの時点にいます。いつものように、明らかに問題を解決しようとする私の単純な試みは、私がまだ知らないことがどれほどあるかを私に示しました!

多くの異なるコンテンツタイプとこれらの各タイプのサブカテゴリで使用される「関連ファクト」コンテンツを指すノード参照フィールドがあります。関係を作成してビューの「関連する事実」を表示することはできますが、問題があります。1つは、関連するファクトを別のブロックに入れて、ビューによって提供される記事のリスト全体について、関連するファクトの単一のリストを表示することです。ビューは、同じ「関連ファクト」参照を持つ複数のnidの重複を適切に処理しません。さらに、コンテンツタイプとサブカテゴリごとに個別の「関連ファクト」ビューを生成する必要があります。

引数としてnidのリストを受け入れることができる個別の関連するファクトビューを作成できれば、関連するファクトビューを簡略化できます。だから私の質問はこれにどう取り組むかです。ビュー内から可能かもしれませんが、カスタムモジュールのphpソリューションを探しているので、次のことを達成する必要があります。

  1. 「コンテンツタイプ」ビューのいずれかの結果を引数のリストとして抽出します。ビューの結果を表示することに加えて、表示されているNIDのリストをロードする必要があります。

  2. 関連するファクトビューを呼び出し、NIDのリストをそれに渡し、「関連するファクト」ビューでフィルターまたはコンテキストフィルターとして使用します。

追加情報:

この戦略を使用して、ビューを定義し、そこから結果を抽出することから始めました。この試みにより、ビューオブジェクトで結果を検索するときに問題が発生しました(この質問を参照してください)。結果を取得したら、それらの結果をフィルターとして含む別のビューを生成する必要があります。すべてのパラメーターがコード化されたインクルードファイルとしてコードから実装されたビューを見ましたが、ビューを定義および生成し、php関数を使用して結果を操作する例は見つかりませんでした。どんな例やリンクもいただければ幸いです。

これまで:

2つの答えが、ビューの結果を適用し、それをコンテキストフィルターとして別のビューに配置するプロセスに対処しています。しかし、私はまだ数十のコンテンツタイプがあり、それぞれに少なくとも12のビューコンテンツペインのバリエーションがあるという問題に直面しています。各ビューを関連するファクトに直接リンクする代わりに、view1コンテンツビューのいずれかの結果を単一の個別の「関連するファクト」ビューに渡す必要があります。

CONTENT TYPE    SUB-CATEGORY       RELATED FACT (nid)
    Type 1 --------- General Info       101, 105 
                     Specifications     103, 105
                     Inspections        102 
                     Quality  
                     etc...   
   Type 2 ----------General Info       101, 106
                    Specifications     102, 103 
                    Cost factors       107
                    etc... 

View1は特定のコンテンツタイプを検索し、サブカテゴリフィールドの値でソートされたさまざまなサブカテゴリの記事を含みます。さらに、関連するファクトのノード参照フィールドが含まれています。コンテンツタイプとサブカテゴリの1つのフィルターを表示します。表示するための公開フィールドと、関連するファクト参照ノードを持つ非表示フィールドがあります。

View2は「関連する事実」の記事をフィルタリングし、nidのコンテキストフィルターセットを含みます(ただし、設定はURLに適用されます)

Letharionの回答のコードを使用して、6行目のforeachループは、関連するファクトIDではなく、記事IDのリストをコンパイルしています(記事は関連するファクトへの参照を保持していますが、関連するファクトには記事へのノード参照がありません) 。各ノードのファクトフィールドから関連するファクトIDを抽出する必要があります。ビュー1の定義にファクトフィールドを含めましたが、コマンドdpm($ node);なので結果を見つけることができません。クラッシュしていて、値が配列のどこに格納されているのかわかりません。

異なるコンテンツタイプに対して複数のView1のクローンが作成されるため、hook_views_post_executeを使用することは理にかなっていると考え、次のようにコーディングしました。

function mymodule_views_post_execute (&$sourceview) {

  $nids = '';
  foreach($sourceview->result as $node) {
    $nids += $node->nid . ',';  //I need field name for $node->facts

  }

  $nids = rtrim($nids, ',');
  $view = views_get_view('get_related');

  //dpm($nids);  // Fatal error: Cannot unset string offsets...

  $view->execute_display('panel_pane_1', array($nids));
  }

最後に、ビューの表示を適切な場所に向ける必要があるのか​​、それとも、パネルのUIを介してパネルの場所に関連するファクトコンテンツペインを配置し、パネルのテーマに残りの部分を処理させるだけでよいのかわかりません。


2
これはDrupal 7ですか?その場合は、EntityFieldQueryを使用して、基準を満たすノードのリストを取得することをお勧めします。
ベス

このAPIが使用されているいくつかのサンプルコードを示すことができますか。私はDrupalコーディングの世界に不慣れであり、実際のタイプの例に従って理解する必要があります。
Ashlar

drupal.org/node/1343708は、「EntityFieldQueriesの使い方」というページです。
ベス

回答:


3

頭のてっぺんから

ビュー 'get_nids'および 'get_related'では、get_relatedはnid引数を取り、複数の値を受け入れるように設定されています。このオプションは、設定ウィンドウの下部にある「詳細」の下に隠されています。

オプション1:

$view = views_get_view('get_nids');
// Repeating query, ensure the View is set to cache the results.
$view->preview('display_machine_name', array($arg1, $arg2));

$nids = '';
foreach($view->result as $node) {
  $nids += $node->nid . ',';
}
$nids = rtrim($nids, ',');
$view = views_get_view('get_related');
$view->execute_display('display_machine_name', array($nids));
print $view->render();

オプション2:

「コンテキスト」表示タイプをget_nidsに追加し、そのコンテキストを引数としてget_relatedのコンテンツペイン表示に渡します。残念ながら、ビューのコンテキストには複数の結果を単一のコンテキストに圧縮するためのサポートがないため、Ctoolsの機能リクエストが必要になる可能性があることを推測する必要があります。

オプション3:

Bethのコメントには、EntityFieldQueryを使用した優れた提案があり、MongoDBでも機能する純粋なコードソリューションが必要な場合に役立ちます。ただし、ビューには、ほとんどの作業をUIで実行できるという利点があり、多くの場合便利です。


-> executeメソッドのViews_db_objectのコードに従ってください(Views.inc行1060)。引数(array($ nid))を読み取るメソッドのコードには何も表示されません。また、array($ nids)引数のフィルター値を受け入れるように「get_related」ビューを構成するにはどうすればよいですか?フィルターを「関連コンテンツ」に設定し、コンテキストフィルターをNIDを受け入れるように設定しますか?
Ashlar

申し訳ありませんが、その通りです。これはexecute_displayである必要があり、回答するコンテキストフィルタに関する情報が追加されました。:)
Letharion

質問に関連する事実のコンテンツを表示する問題を完了するために、さらに情報を追加しました。「これまで」をご覧ください。
Ashlar

申し訳ありませんが、どこに問題があるかわかりません。あなたの投稿によると、ノード参照フィールドはコンテンツタイプ間で共有されているため、「get_nids」ビューは参照されたすべてのエンティティを収集します。ただし、そうでない場合は、最初のビューをループする必要があります。
Letharion

1
うーん!私は混乱していたと思いますし、これを必要以上に複雑にしているのかもしれません。ありがとう
Ashlar

2

ノード内のフィールドを探し、NIDのリストを返すことは、EntityFieldQueriesまさにそのために生まれたものです。(参照:トピックに関する自分自身の質問)。

Webフォームの送信時に実行され、「Quiz Anzwer Key」タイプのノードを検索して、現在有効なWebフォームのNIDが入力された「Quiz Reference」フィールドを持つノードを見つけるコードの例:

    $arg = arg();
    $nid = $arg[1]; //this finds us the NID of the current page
    $query = new EntityFieldQuery;  // this EntityFieldQuery searches through Entities for Nodes that point to the current Webform.
    $result = $query
        ->entityCondition('entity_type', 'node') // find nodes
        ->propertyCondition('status', 1) // that are published
        ->propertyCondition('type', 'quiz_answer_key')  // of type Quiz Answer Key
        ->fieldCondition('field_answer_quiz', 'nid', $nid, '=') // that point to the current node in their Quiz reference field
        ->execute(); // do the query
    $results        = $query->ordered_results; //grab the results

次に、ノードのフィールドから実際に値をロードする場合は、次のように使用node_loadして、必要なノードからより多くの情報を取得します。

    $ans_key_id     = $results[0]->entity_id;
    $ans_node       = node_load($ans_key_id);       //once the correct node has been identified, load the contents of that node and suss out the answers 

これ$ans_nodeで、ノードのすべてのフィールドのすべての情報を含む配列(またはオブジェクト、忘れました)になります。ボイラ!


0

コード化されたソリューション(エリアはほとんどありません)で問題ありませんが、ここに1つあります。

  1. すべてのnidの出力を取得するビュー作成します。これらのnidはコンマ区切りのリストとして取得します。これを行うには、出力としてフィールドを使用し、スタイル設定をStyle Unfomatted、行スタイルフィールドに設定します。> nidフィールドをインラインにして使用します。区切り文字としてのコンマ。
  2. モジュールでこのビューを呼び出して出力を取得する関数作成します
  3. 2番目のビュー(またはディスプレイ)を作成し、実際に表示出力を行う2番目のビューの引数としてこの関数を使用します。したがって、引数の下では、引数はnode:nidである必要があり、実行するアクションは「デフォルトを提供する」に設定する必要があります。次に、PHPコード設定を使用して関数を呼び出します。return mymodule_get_nids(); 「引数ごとに複数の用語を許可する」チェックボックスがチェックされていることを確認します

ステップ2コード

function mymodule_get_nids() {
    $view = views_get_view('getmynids')) // View name
        $view->set_display('mynids'); // Display name
        $view->execute();
        if ($view->result) {
         return $view->preview(); // Can't remember if this needs to be echo or return try both.
        }
    }
}

これは別の答えでなければなりませんか?または編集??


コード化されたソリューションを探しています。質問を明確にします。
Ashlar

私が間違っている場合は修正してください。ただし、アシュラーは複数の関係から同時にデータを取得しようとしているので、添付ファイルは「現在の」もののみであるため、問題を解決することさえできません。 1?(ただし、添付ファイルを使用してからしばらく経っていたため、間違っている可能性があります)
Letharion

お疲れ様でした。質問に関連する事実のコンテンツを表示する問題を完了するために、さらに情報を追加しました。「これまで」をご覧ください。
Ashlar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.