Use case : list nodes referenced by a noderef field
Works fine using a Node:nid argument + noderef relationships, but only if using the 'Fields' row style. The 'Node' row style doesn't not follow relationships.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

drewish’s picture

subscribing

yched’s picture

I started to look into this.
I'm having a hard time figuring out how a row plugin could alter the query to add the related nid the SELECT.

Earl, do you have suggestions ?

merlinofchaos’s picture

Urk. The default query() method on views_plugin_style (currently inherited from views_plugin) will need to delegate to the row plugin if one exists. *Then* row plugins can do query modifications.

yched’s picture

Status: Active » Needs review
FileSize
5.07 KB

OK, here's my ugly initial stab at this :
- Plugin_style->query() defers to row_plugin->query() if applicable
- The code to display relationships on the settings form is a shameless copy/paste from views_ui_config_item_form(), with the 'annoying' parts (that apply to an 'item' context) conveniently commented out for now. Meaning that it currently doesn't restrict to valid relationships (the ones that bring to a node table, I guess ?)
- Also raises the question of how this code could be abstracted out to avoid duplication when other row styles want to get the feature too. The patch only deals with views_plugin_row_node_view, but potentially any non-field row style would be interested in the feature.
- the new views_plugin_row_node_view::query() and the way it saves the alias to be used by template_preprocess_views_view_row_node() will probably make you cringe - suggestions welcome on how to make that 'safe and clean'.

With all the restrictions above, it seems to work well :-)

So, obviously needs work, but needs review first.

merlinofchaos’s picture

Ok:

+      $base = $data[$relationship['field']]['relationship']['base'];
+      // TODO : no $form_state['type']
+//      $base_fields = views_fetch_fields($base, $form_state['type']);
+//      $base_fields = views_fetch_fields($base, 'relationship');
+//      if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
+          $relationship_handler->init($view, $relationship);
+          $relationship_options[$relationship['id']] = $relationship_handler->label();
+//      }

For the purposes of this we could do if ($base == 'node') which pretty much gets us what we want, right?

For extra points, we could make it $this->base_table and we could have the base views_handler_style check -- if isset($this->base_table) -- add the relationship widget and stuff.

+        // TODO: not sure exatcly what to do with this.
+        //$view->set_item_option($display_id, $type, $id, 'relationship', $rel);
+

Just cut that, I think.

+      $this->value_alias = $this->view->query->add_field($relationship->alias, 'nid');

We'll obviously want to find a way to set this up. We could just rely in the primary field, but $this->base_field = 'nid' probably works well and is not particularly burdensome.

Otherwise we're looking good, but we definitely do want to try to remove as much of this code as possible from views_view_row_node and make this universal so that all of the nodes that don't use fields can take advantage of this.

yched’s picture

Attached patch should do the above, and moves the feature up to views_plugin_row class.

To actually use the feature, row plugins have to
- make sure their options_form() call parent::options_form()
- grab the correct value for 'id' before displaying their items, as template_preprocess_views_view_row_node() does. Not sure how that part could be handled or made easier by the superclass as well.

The patch just updates views_plugin_row_node_view. What other plugins should we update ?

Hm - now that I think of it, adding this unconditionally to views_plugin_row might be a little too much.
views_plugin_row_fields is not affected, since its form does not call the parent form.
I think I didn't fully get the part where you say '...and we could have the base views_handler_style check -- if isset($this->base_table) -- add the relationship widget and stuff'.

merlinofchaos’s picture

The idea would be that the handler would do this as part of its definition:

class my_handler extends views_handler_style_row {
  var $base_table = 'node';
  var $base_field = 'nid';
  // ...

Then the parent stuff would see that and automatically do the necessary work, knowing that the handler requires a field from a base table.

yched’s picture

Title: let 'Node' row style follow relationship » Let row plugins follow relationship
FileSize
8.36 KB

OK, updated patch :
- uses $row_style->base_table / $row_style->base_table as advised in #7
- streamlines the way row theme preprocessors can fetch the right id alias in the row results (passes it as an additional param of the theme function)
- fixes a warning about undefined $comment var in views-view-row-node.tpl.php, which the patch just raised more chances to trigger (when there's nothing at the other end of the relationship).

To actually use the feature, row plugins have to :
- declare $base_table and $base_field as class properties
- make sure their options_form() call parent::options_form()
- make sure they fetch the result ids in $row->{$this->field_alias} instead of hardcoding 'nid' or something.

The patch updates Node and Node RSS row plugins. Is there any other row plugin that should get the feature right now ?

merlinofchaos’s picture

Status: Needs review » Fixed

Finally! This looks good, and I've gotten a good test report that it works. Committed!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.