First, let me say, DraggableViews is a lifesaver. Great work!

I'd like to add a custom handler for sorting, similar to the Flag Weights module, but I also want my handler to be aware of a Views argument and save distinct weights dependent on the value of the argument.

Use Case

  • Content type "Tout" has a Title and a CCK Date field, which has From and To values
  • View displays all Touts with Date as an argument.
  • Tout A has Date From:May 20 To:May 25
  • Tout B has Date From:May 21 To:May 22
  • View with argument 2009-05-21 should display Tout B above Tout A
  • View with argument 2009-05-22 should display Tout A about Tout B

I'm pretty sure I need to set up a database table that stores the node id, the view's argument value, and the weight.

The Question
I see that Flag Weights implements hook_draggableviews_handlers to save its weight info to the {flag_content} table. Is it also possible to alter the way a view loads within a draggableviews handler, or would I have to implement my own version of hook_views_pre_execute to make sure that I loaded the weight value that corresponded to the current argument?

Also, if anyone has a simpler idea to get the desired functionality, please chime in.

Thanks!

Comments

sevi’s picture

Great idea. This would solve #447656: Using filters on view changes order values

.., or would I have to implement my own version of hook_views_pre_execute to make sure that I loaded the weight value that corresponded to the current argument?

Why do you need this?
The value will be loaded by views. You simply have to implement a new Views field (see draggableviews.views.inc for an example).

Draggableviews passes the entire $view object to the handlers. You find the arguments at $view->args.

Is this what you expected to hear? :)
greetings,
sevi

Anonymous’s picture

Sorry, I'm new to handlers.

Example database table

-----------------------------------------------------
|     NID     |      ARGUMENT     |      WEIGHT     |
-----------------------------------------------------
|      1      |     2009-05-21    |         1       |
-----------------------------------------------------
|      1      |     2009-05-22    |         0       |
-----------------------------------------------------

I had the saving part down, but I couldn't figure out how implementing draggableviews_handler_modulename would ensure that the view would LOAD the correct data based on both NID and the ARGUMENT.

But it sounds like all I need to do is go back one more level and create an implementation of hook_views_plugins.

I'll follow-up on this thread as I build this. Thanks for the help!

sevi’s picture

Yes, there's documentation for this missing :(

You need to implement

/**
 * Implementing hook_draggableviews_handlers
 */
function draggableviews_draggableviews_handlers() {
  return array(
    'native' => array(
      'file' => 'implementations/draggableviews_handler_native.inc',
      'title' => t('Native'),
      'description' => 'Storage of structure done by draggableviews',
      'handler' => 'draggableviews_handler_native',
    ),
  );
}

You can use additionally the "path" attribute. If not specified it will default to your module dir.

I had the saving part down, but I couldn't figure out how implementing draggableviews_handler_modulename would ensure that the view would LOAD the correct data based on both NID and the ARGUMENT.

You have to implement you own field using hook_views_data, which uses the query you specify.

The fields specified by hook_views_data and the draggableviews-Handler are two different things.

You need to alter the query every time a view is beeing executed. Use the following hook:

/**
  * Implementing hook_views_query_alter
  */
function draggableviews_views_query_alter(&$view, &$query) {
  for ($i = 0; $i < 2; $i++) {
    if (isset($query->table_queue['draggableviews_structure'. $i])) {
      $query->table_queue['draggableviews_structure'. $i]['join']->extra[] = array(
          'field' => 'vid',
          'operator' => '=',
          'value' => is_numeric($view->vid) ? $view->vid : 0,
          'numeric' => TRUE,
      );
    }
  }
}

you can add as many extra[] properties as needed. Look at draggableviews.views.inc for an example.
Or look at flag_weights module for an handler-example.

fearlsgroove’s picture

I've got a need for the same thing -- draggableviews handler that's unique by combination of views and arguments. Have you made any progress on this before I reinvent the wheel?

Anonymous’s picture

No actual coding yet. I'm relatively new to Drupal modules, so I tend to spend a good deal of time researching and planning the implementation before writing.

I've divided my coding plan into these chunks:

  • Create the .install file -- need a schema that accommodates the vid, nid, and delta values, plus a column for a serialized array of view args.
  • Save functionality -- implement hook_draggableviews_handlers and supporting functions to store values per my schema
  • Query functionality -- implement hook_views_query_alter to return draggableviews weights per view/arguments

Questions:

  • Is there any speed benefit for limiting argument storage (e.g. to the first argument only) so we don't have to serialize/unserialize the array?
  • Is there any way to clean up our draggableviews argument handler table when nodes are deleted?

Any other functionality that you would need for your use case, fearlsgroove?

davideads’s picture

StatusFileSize
new6.8 KB

Well, I wrote a patch that adds an args field expressed as a simple string -- it's a possible solution to this problem. I realized this issue was open after I wrote it. I've not tested it extensively, yet, but it seems to be working properly for an image gallery setup with a view path like galleries/gallery_nid/images/image_nid. I will test it with multiple arguments ASAP.

davideads’s picture

Also, I realize there are uniqueness issues with the approach of the above patch.

fearlsgroove’s picture

Sorry had to shelve this one for a while but it's still on the list for me.

@scmizer: no other requirements, just adding uniqueness per view + arguments would solve my problem.

RE: performance gains for arguments, one serialize/unserialize per load shouldn't have a significant performance hit i would think.

RE: clean, sure use nodeAPI and wipe any references that match the nid. see:
http://api.drupal.org/api/function/hook_nodeapi

@davideads: thanks for the patch! Haven't had a chance to look yet, but will in the next few days I hope.

davideads’s picture

@fearisgroove: I should have a new version of the patch up in the next week or so, hopefully sooner -- I'm closing in on a satisfactory solution... I think.

sevi’s picture

Many thanks davideads :)
I looked at the patch and I would wonder if this could be improved any more :)
Works great.

I commited your changes to the DRUPAL-6--3 branch (http://drupal.org/cvs?commit=235300).

Greetings,
sevi

sevi’s picture

StatusFileSize
new1.09 KB

I enabled the "use arguments as well" option to try the new feature.
After disabling the option the view outputted duplicate nodes, because the args was not involved in the query.
I committed the attached patch.

davideads’s picture

Thanks, Sevi -- I'm a little busy at the moment, but I'm really hoping to carve out time early next week to continue with my work on this. I think I have a better technique than the one used in that patch.

burningdog’s picture

The 3.x-dev version works great with using arguments, thanks Sevi. davideads, if you change the technique that Sevi used in his patch and update the -dev code, will my custom ordering still be preserved when I update?

sevi’s picture

Category: support » feature
Status: Active » Fixed

I'll end this discussion now.
@davideads: If you find some time to improve the current technique please create a new issue.

Greetings,
sevi

davideads’s picture

Thanks, Sevi -- I should have some time to tackle it soon. Sorry about the delays. @Roger Saner: I'll ensure there's a proper upgrade path if at all possible.

Status: Fixed » Closed (fixed)

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

charlie-s’s picture