Creating a new handler to enhance DraggableViews

scmizer - May 17, 2009 - 01:15
Project:DraggableViews
Version:6.x-3.x-dev
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:closed
Description

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!

#1

sevi - May 17, 2009 - 09:35

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

#2

scmizer - May 17, 2009 - 14:13

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!

#3

sevi - May 17, 2009 - 20:18

Yes, there's documentation for this missing :(

You need to implement

<?php
/**
* 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:

<?php
/**
  * 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.

#4

fearlsgroove - May 29, 2009 - 14:14

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?

#5

scmizer - May 30, 2009 - 21:09

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?

#6

davideads - June 12, 2009 - 17:19

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.

AttachmentSize
draggableviews_arg_ordering.patch 6.8 KB

#7

davideads - June 12, 2009 - 18:07

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

#8

fearlsgroove - July 2, 2009 - 04:04

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.

#9

davideads - July 9, 2009 - 04:52

@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.

#10

sevi - July 9, 2009 - 15:03

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

#11

sevi - July 10, 2009 - 18:29

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.

AttachmentSize
draggableviews-464870.patch 1.09 KB

#12

davideads - July 16, 2009 - 17:01

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.

#13

Roger Saner - July 24, 2009 - 18:45

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?

#14

sevi - August 17, 2009 - 12:11
Category:support request» feature request
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

#15

davideads - August 26, 2009 - 22:23

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.

#16

System Message - September 9, 2009 - 22:30
Status:fixed» closed

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

 
 

Drupal is a registered trademark of Dries Buytaert.