robertgarrigos's picture

In my custom module, I'm printing a table with the theme('table') function. How can I add core contextual links to every row (edit node link, exactly)?

Thanks.

Accepted answer

The final version of the code that worked, otherwise, menu_contextual_links() function complaints:

// creation of all the other cells

// contextual link cell

$ra['contextual_link'] = array(

'#type' => 'contextual_links',

'#contextual_links' => array(

'node' => array('node/' . $bt->nid, array()),

),

);

$row[] = render($ra['contextual_link']);

$rows[] = array(

'data' => $row,

'class' => array('contextual-links-region'),

);

Most helpful answers

I think it is contextual-link css doing that.  It probably just needs an override for contextual links within that table.

Yes, I understood that. My answer was simply pointing out how to use the contextual_links element. It's up to him to build the correct links to be displayed. This can be done by using my example, and modifying the #contextual_links element in the array. Please read the documentation I pointed out above.

There is a FAPI element 'contextual_links', which is defined in contextual.module. It's poorly documented (in fact, it's wrongly documented in the Backdrop FAPI page).

Apparently (haven't tried this) this should be fairly straightforward to do. Create a render array and then use backdrop_render() to make it into markup and add the javascript, then add this to your table, most likely in its own table cell.

The render array may look something like this (untested)

$ra['contextual'] = array(
  '#type' => 'contextual_links',
  '#contextual_links' => array(
    'block' => array('admin/structure/block/manage', array('system', 'management')),
    'menu' => array('admin/structure/menu/manage', array('management')),
  ),
);

The #contextual_links element is a tricky one. See the doc block for contextual_pre_render_links() for an explanation. The links in the contextual links apparently must already be registered in the menu system as local tasks.

Then use backdrop_render($ra);. This should generate the necessary HTML markup, which you could add to its own cell.

 

Comments

I'm not sure. Views does this by allowing different links to be added to the view and then a "Global: Dropbutton" puts them in a nice little operations menu.  Perhaps there is some code you can borrow from that.

There is a FAPI element 'contextual_links', which is defined in contextual.module. It's poorly documented (in fact, it's wrongly documented in the Backdrop FAPI page).

Apparently (haven't tried this) this should be fairly straightforward to do. Create a render array and then use backdrop_render() to make it into markup and add the javascript, then add this to your table, most likely in its own table cell.

The render array may look something like this (untested)

$ra['contextual'] = array(
  '#type' => 'contextual_links',
  '#contextual_links' => array(
    'block' => array('admin/structure/block/manage', array('system', 'management')),
    'menu' => array('admin/structure/menu/manage', array('management')),
  ),
);

The #contextual_links element is a tricky one. See the doc block for contextual_pre_render_links() for an explanation. The links in the contextual links apparently must already be registered in the menu system as local tasks.

Then use backdrop_render($ra);. This should generate the necessary HTML markup, which you could add to its own cell.

 

robertgarrigos's picture

Thanks @argiepiano, but this doesn't work. I keep investigating.

What exactly doesn't work? The render array is working for me. Running what I had above produces the following markup, as expected:

<div class="contextual-links-wrapper"><ul class="contextual-links"><li class="menu-list odd first"><a href="/admin/structure/menu/manage/management/list?destination=admin/devel/php">Edit links</a></li><li class="menu-add even last"><a href="/admin/structure/menu/manage/management/add?destination=admin/devel/php">Add link</a></li></ul></div>

 

I think there is a bit of misunderstanding here. I think Robert is after a link like

'node/xx/edit' where xx is the node related to that row.

Any reason why views doesn't work for this? Avoid re-inventing the wheel.

Yes, I understood that. My answer was simply pointing out how to use the contextual_links element. It's up to him to build the correct links to be displayed. This can be done by using my example, and modifying the #contextual_links element in the array. Please read the documentation I pointed out above.

robertgarrigos's picture

This is what I came up with to add a contextual link to a cell. This is within a foreach to fill in the table cells and rows:

$ra['contextual_link'] = array(

'#type' => 'contextual_links',

'#contextual_links' => array(

'node' => array('node/' . $bt->nid),

),

);

$row[] = backdrop_render($ra);

What is not working is that the contextual link is shown in the upper right corner of the table, not of the row.

The first context link is for the block. The second one is mine. An only one context link is printed. No HTML appears for the second and third row.

 

robertgarrigos's picture

With

$row[] = backdrop_render($ra['contextual_link']);

instead, each row has each cell with the proper html for the contextual link. However, it keeps appearing in the upper right corner of the table (in a block). In fact, it appears when hovering the table (or the block), not the row.

I think it is contextual-link css doing that.  It probably just needs an override for contextual links within that table.

robertgarrigos's picture

Found it. This is the code that worked:

// creation of all the other cells

// contextual link cell

$ra['contextual_link'] = array(

'#type' => 'contextual_links',

'#contextual_links' => array(

'node' => array('node/' . $bt->nid),

),

);

$row[] = render($ra['contextual_link']);

$rows[] = array(

'data' => $row,

'class' => array('contextual-links-region'),

);

I needed to add a contextual-links-region to the row. Now, this code prints a contextual link to each row with edit and delete links to the node shown in the row.

robertgarrigos's picture

The final version of the code that worked, otherwise, menu_contextual_links() function complaints:

// creation of all the other cells

// contextual link cell

$ra['contextual_link'] = array(

'#type' => 'contextual_links',

'#contextual_links' => array(

'node' => array('node/' . $bt->nid, array()),

),

);

$row[] = render($ra['contextual_link']);

$rows[] = array(

'data' => $row,

'class' => array('contextual-links-region'),

);