Does anyone have any tips for sorting the order of nodes in a view based on the weight given to the node's menu listing?

I have already used CCK to define a field to give the nodes a custom user defined "weight" but it seems a waste of energy to have to define this rather than use the weight already defined for the menu listing, since that is the order I want to use in my view display. . .

Any help is greatly appreciated. . .

I'm new to this so I hope the question makes sense!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

merlinofchaos’s picture

Category: support » feature

Currently Views doesn't offer a method to support by menu weight unless it's in a book outline. This might be something that can come in the future. Changing to feature request.

Bartezz’s picture

subscribing

k3vin’s picture

subscribing

prom3theus’s picture

I'm using a custom solution with a CCK addon (computed field). Add a computed field to the content type what you need to orderable by menu weight, and use the below code as the computed field's 'computed code' value:

$res = db_fetch_array(db_query("SELECT weight FROM {menu_links} WHERE link_path = 'node/%s'", $node->nid));
$weight = is_array($res) ? $res['weight'] : 0;
$node_field[0]['value'] = $weight;

Check in the 'Display this field' and 'Store using the database settings below', use Data Type: int, set Data Length: 4 and save. After this, the saved field appears in views as a normal CCK field, but contents the associated node's menu item weight - now you can use as filter or ordering display.

Ofcourse you need to reupdate all content in this content type - this is just for fun :'(

And, BTW subscribing too :)

Bartezz’s picture

Thanx for sharing!!! Will try asap!

Bartezz’s picture

dindon’s picture

subscribing

marcuslim’s picture

Version: 6.x-2.0-rc3 » 6.x-2.5
FileSize
8.34 KB

I've written a very simple module that does this, while working on a project that requires sorting nodes according to their menu listing weight. Simply install the module, enable it, then in Views UI, under Sort Criteria, add the field 'Menu sorted nodes: Menu item weight' and choose ascending. Then the nodes for the view will be displayed according to their menu listing's weights, in ascending order from least weight to most weight.

Bartezz’s picture

Thanx!

Colin_T’s picture

Status: Active » Closed (duplicate)
Colin_T’s picture

Status: Closed (duplicate) » Active

While it is a duplicate, the solution there doesn't work for me.

merlinofchaos’s picture

Status: Active » Closed (duplicate)

That gives you no right to litter.

Colin_T’s picture

I was assuming that the duplicate I pointed out (assigned to 4.x & resolved by design) was a distinct entity from this one.

Should this work for 6.x?

marcuslim’s picture

Yes, it works for 6.x. I tested it on Druapl 6.10.

Colin_T’s picture

marcuslim - Thanks - hadn't properly realised I needed the weight module as well to achieve that.

Your views sort module seems to do the job nicely without requiring an extra field on the input forms, which seems a neater solution to me.

Matti303’s picture

Many thanks for the module Marcuslim!! \o/

Plascual’s picture

Thank you marcuslim! This is a very nice add-on.

But I have a litte problem with results order since I use Nice_Menus drop-down menus. The parent menu links to the same node as the first child menu, so views_menu_sort module seems to add one more result. That node appears twice in the views list.

I was wondering if it would be complicated to add settings to the module based on menu deepness ? Or maybe just eliminate those duplicates ?

Thanks in advance !

Plascual

EDIT: I realized that setting Distinct => 'Yes' in Views basic settings corrects this.

glennr’s picture

#8 worked well for me too. Thanks, marcuslim.

manumilou’s picture

yes very useful module !

BrightBold’s picture

Perfect, marcuslim! Exactly what I needed.

Leo Pitt’s picture

@marcuslim #8

Thanks for the views_menu_sort module.

Elegant, light-weight, and behaves exactly as I would have wanted.

Seems to work fine on Drupal 6.14 with Views 2.6

obrigado’s picture

Marcuslim, thanks for your great module. Any chance of starting a project page for it, or maybe merging it into Views 3?

monti’s picture

have tried to use "views_menu_sort", provided by marcuslim (comment #8 above).

It is not working for me. I am not sure why. I use the weight module, which outside of views works properly. Inside views, I used marcuslim's function, but there is no impact. any direction, idea?

Cheers !

woodhous@email.unc.edu’s picture

Hi Maruslim,

Thank you for the module. I am unable to set the weight on the nodes I need to sort in my view because they don't have a menu associated with them. The Page content type does not save the weight unless I assign a menu title. My menu nodes use a view reference to pull in related content based on taxonomy and I would like the ability to sort the nodes in the view reference. Is there any way to set the menu weight on a content item without it showing up on a menu.

bwoods’s picture

Sweet, #8 worked for me as well. Thanks!

marcushenningsen’s picture

Version: 6.x-2.5 » 6.x-2.8
Status: Closed (duplicate) » Reviewed & tested by the community

Works beautifully! Thanks a lot. Changing status.

Marcus

merlinofchaos’s picture

Status: Reviewed & tested by the community » Closed (won't fix)

Err, RTBC indicates that there is a patch. This module should probably be its own thing.

BenMirkhah’s picture

After trying out many ways I like the #4 approach however "weight" alone will not be enough in a multi-level menu because then many items will have the same weight so instead I tweaked it to use p1 + p2 as explained here: http://drupal.org/node/141866

as well as depth and weight to get it working in perfect order for a 3 level menu...

$res = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE link_path = 'node/%s'", $node->nid));
$node_field[0]['value'] = is_array($res) ? (
str_pad($res['p1'], 4, '0', STR_PAD_LEFT).'-'.
str_pad($res['p2'], 4, '0', STR_PAD_LEFT).'-'.
str_pad($res['depth'], 4, '0', STR_PAD_LEFT).'-'.
str_pad(100+($res['weight']), 4, '0', STR_PAD_LEFT) ) : '0000-0000-0000-0000';

also in order to do a force update on all existing nodes to calculate the computed cck-field (varchar 20):

print "start ";
$result = db_query("SELECT nid FROM {node}");
while($nid = db_fetch_object($result)) {
$node = node_load($nid->nid);
node_save($node);
}
print "end ";

mattiasj’s picture

#8 worked great for us, a lightweight and clean solution - thanks!

cleanthes’s picture

Thanks @marcuslim. Worked first time, perfectly.

Nimo’s picture

Thanks @marcuslim. Wonderful!

jdln’s picture

BenMirkhah's code from #28 works for me.

However im manually having to update all my nodes. How do I do a 'force update on all existing nodes'? What do I do with the code below?
Thanks

print "start ";
$result = db_query("SELECT nid FROM {node}");
while($nid = db_fetch_object($result)) {
$node = node_load($nid->nid);
node_save($node);
}
print "end ";
jdln’s picture

Anyone?

Bartezz’s picture

Create a node with a php filter instead of filtered or full html (need to enable a core module for this), copy paste code (need to put between and tags. View the node et voila :) Backup first!

Cheers

jdln’s picture

Working. Thanks.

jdln’s picture

The code from #28 has stopped working for me, and not for the first time. My CCK computed filed settings are identical to an older version of the site which is working fine, so I guess this code is unreliable?

By making the field visible I can see in views it doesn't have a value. On the node's display settings ive set the field to have a label and be visible but I cant see it on the node view page.

Ive experimented with 'Data Length' but what should this value be?

Ive created a support request in Computed Fields:
http://drupal.org/node/1005094

$res = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE link_path = 'node/%s'", $node->nid));
$node_field[0]['value'] = is_array($res) ? (
str_pad($res['p1'], 4, '0', STR_PAD_LEFT).'-'.
str_pad($res['p2'], 4, '0', STR_PAD_LEFT).'-'.
str_pad($res['depth'], 4, '0', STR_PAD_LEFT).'-'.
str_pad(100+($res['weight']), 4, '0', STR_PAD_LEFT) ) : '0000-0000-0000-0000';
Bartezz’s picture

Have you tried #8?

jdln’s picture

Yes, but it doesn't work for a hierarchical menu.

Bartezz’s picture

Ah, that could be right indeed. I've only used it for first level menu nodes.... sorry.

Cheers

remaye’s picture

#8 works (still) very well for me!
Thanks @marcuslim !

Is this module maintained ?
And is there any hope to have this feature integrated within Draggable Views ?

It would be great, in addition to sort items by menu weight, to have the ability to re-order the menu itself within the same view ...

Or is there any other solution to reorder menus without having to change the menu weight of each item in the node form or giving access to the menu administration itself ?

If any have a tip ... thanks!

squarecandy’s picture

#8 works great. (single level menu) Thanks!!!

kaido.toomingas’s picture

Thanks a lot @marcuslim and here are little changes to get this work with domain_access module. Worked fine with drupal 6.19 and views 2.x :).

jonaswouters’s picture

Is this available for 7?

jdln’s picture

Sorry to backtrack, but is there a solution for a hierarchical menu? Is there some work around?
Thanks

ofktoubro’s picture

#8 tnx

biwashingtonial’s picture

Just discovered this: http://drupal.org/project/menu_node_views

It provides quite a few Views handlers based on nodes' associated menu links, including sort (which does seem to work in hierarchical menus, based on a short test drive).

steven_kropp’s picture

Any ideas on how to take the module in #8 and make it work for Drupal 7, as far as I can see there is no way STILL to sort by menu weight for drupal 7... seems to me like a very necessary config.

Mitsuko’s picture

FileSize
6.88 KB

This is a version for Drupal 7. Menu node module is required. It provides in views :
- menu weight field
- menu weight sort filter
- menu link id filter to exclude particular entries (based on mlid)

Liaz’s picture

#8 worked perfect and easy for me.
Thanks a lot @marcuslim

2pha’s picture

#46 worked for me, drupal 7

jasonawant’s picture

Hello,

FWIW, for Drupal 7, the following modules provided menu: depth and menu: weight, which allowed me to sort view results according to their menu item hierarchy.

http://drupal.org/project/menu_node
http://drupal.org/project/menu_node_views

Jason

reallybigears’s picture

marcuslim - thank you. I just installed your module and so far so good. Really can't believe this isn't a built in option. Excellent. thanks

ricancie’s picture

Thanks soooooo much marcuslim!!!!

Wtower’s picture

Issue summary: View changes
AdamPS’s picture

@jdln and anyone else interested

As far as I can tell, none of these solutions work for a hierarchical menu, assuming like me you are looking for depth-first ordering.

nno’s picture

#48 works great. Thank you very much

thomaswalther’s picture

My solution, sorting all nodes in views like the sorting from their menu sorting:

function MY_THEME_NAME_views_pre_render(\Drupal\views\ViewExecutable $view) {


  if($view->id() == 'MY_VIEW_NAME' && $view->current_display == 'MY_BLOCK_NAME'){

    $sorted = array();

    foreach($view->result as $index=>$value){
      $node = $value->_entity;

      $menu_link_manager = \Drupal::service('plugin.manager.menu.link');

      /** @var \Drupal\Core\Menu\MenuLinkInterface[] $result */
      $result = $menu_link_manager->loadLinksByRoute('entity.node.canonical', array('node' => $node->id()));
      $result = reset($result);

      if (gettype($result) != "object") {
        $errmsg = "Error for node '".$node->label()."' (".$node->id().") is not placed in a menu." ;
        \Drupal::logger('mytheme')->error($errmsg);
        continue;
      }

      $weight  = $result->getWeight();
      if ($index==0) $firstweight = $weight;     
      $weight += 1000;   
    
      $value->index = $weight;
      $sorted[$weight] = $value;
    }


    ksort($sorted, SORT_NUMERIC);
    $view->result = $sorted;
  }
}