I really like the contextual links in D7. Currently, you get contextual links as a 'bonus' when you set the row style to 'node'. I would like to have contextual links when use the 'fields' row style. The contextual links could be added as a field, just like you can add a node edit link, but maybe it would be better to create an option on the row style options form.

I haven't looked into contextual links yet, so I don't know if it's hard to do... but it would be a great feature.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wolfgang Reszel’s picture

Subscribe

dawehner’s picture

Status: Active » Postponed (maintainer needs more info)

A special row style plugin in contrib could put some links into an extra contextual links part.

What would the contextual links field contain? Any kind of link? A special kind of link?

marcvangend’s picture

FileSize
2.08 KB

IMHO, a contextual links field should contain the contextual links dropdown, just like you get with a node view or on the /node front page, including the styling and javascript behavior. In other words, I'm looking for this:
Drupal 7 contextual actions

Just like contextual.module does, a contextual links field should automatically contain all actions that are available to the current user for that object, without specifying exactly which links need to be shown.

(Thanks to Swentel @ http://realize.be/contextual-links-backport-more-or-less for the image.)

marcvangend’s picture

Status: Postponed (maintainer needs more info) » Active

Setting back to active - if you still need more info, please tell me!

merlinofchaos’s picture

To do this, the contextual links would be attached to the base table. The unformatted row style works for any type, not just nodes, so that data isn't quite as simple as it is when displaying node teasers.

marcvangend’s picture

Status: Active » Postponed

Thanks Earl, I see now that contextual links aren't built the way I thought they would. I figured they were something like local tasks, stored in the database, attached to a certain entity. Instead they are not stored anywhere, but simply added while building a renderable array. I assume this should at least be abstracted into a separate function (like <?php node_get_contextual_links($node); ?>) to make it available to other modules like Views.

That said, contextual links aren't limited to nodes. Menu module and Block module also add contextual_links items to their render arrays, and modules like Comment and User could do the same.

I'm postponing this issue because (as far as I can see) the original feature request would require either a change in core or a hackish workaround in Views.

Idea for a contrib module: would it be possible to manually move certain views fields (like a node edit link) into a contextual links block?

merlinofchaos’s picture

Oooh, now *that* is an interesting idea. I don't think that would actually be contrib, though. Maybe it would need to be part of the core. Need to think about how that might work.

marcvangend’s picture

Thanks Earl, that feels like a compliment coming from you :-)
I'm not sure if I can turn this idea in to a patch all by myself, but if there's anything I can do, I'd like to help.

xandeadx’s picture

subscribe

dawehner’s picture

Category: feature » task
Status: Postponed » Active

So make this a task.

marcvangend’s picture

Title: Add contextual links to 'fields' row style » Display fields in a contextual links block

And let's change the title since we're heading in another direction now.

jtwalters’s picture

I like this idea.

jeffschuler’s picture

subscribe

tomgf’s picture

subscribe

mordonez’s picture

subscribe

Flowster’s picture

Where are we now about this idea ?

marcvangend’s picture

@Flowster: it's still a good idea. So far, nobody has tried to turn the idea into code.

@merlinofchaos: you wrote "Need to think about how that might work" and of course your thoughts are highly appreciated. I would love to help out, but I have only limited knowledge about Views' internals so I wouldn't know where to start. Maybe if you can us some general guidance, we can work on the patch in this thread.

mariagwyn’s picture

like this idea a lot!

merlinofchaos’s picture

Priority: Normal » Major

I still don't know how to make this work, but I do see that it is something that is needed, moving forward. I've already run into wanting it.

dawehner’s picture

Assigned: Unassigned » dawehner

In general i would like to have this feature as well, but please don't subscribe to this issue :)

dawehner’s picture

Okay so far the progress

The problem is when you hover over a single one, all get displayed.

marcvangend’s picture

Status: Active » Needs review

Excellent, we have a patch! Thanks Dereine. I'll try to test it later this week.

dawehner’s picture

Status: Needs review » Needs work

Update status

dawehner’s picture

Status: Needs work » Needs review

If this really should work properly it needs #1216776: Two nested contextual links regions are active, when the outer region is hovered.

But with this patch it works as expected.

marcvangend’s picture

Status: Needs review » Needs work
FileSize
58.96 KB

I'm excited to see this take shape. The contextual links blocks are rendered like they should and the patch from #1216776: Two nested contextual links regions are active, when the outer region is hovered. works as advertised. Great work.

The one thing I'm not sure about, is how this is solved in the admin UI. Conceptually it doesn't seem right to me yet and there are some practical problems.

The patch implements a contextual links block as a separate field, to which other fields can be added. The way I see it, a contextual links block shouldn't be a field itself, but only a method of displaying other fields - much more like the 'exclude from display' setting. When I first tested the patch, it didn't occur to me that I had to add another field; I was either expecting a checkbox in the field options (see attachment for a mockup) or a list of checkboxes in the row options (just like the 'inline field' checkboxes).

In its current shape, I see a couple of problems:
- The 'Global: Contextual Links' field is too hard to find in the long list of available fields. Users really have to know it's there, it's not something they will easily find themselves.
- A field that is added to a contextual links block is still visible as normal field. That's not logical, usually you don't need to display a field twice. IMO a field that is a contextual link should automatically be hidden from the 'normal' fields.
- You can add more multiple contextual links fields, which doesn't make sense. (Only the last one is used.)
- You can add a contextual links field to itself. (No strange side effects, but it's weird.)
- You can add one contextual links field to another. (Results in a contextual links block filled with html code :-))

Finally, two minor nitpicks:

+++ b/handlers/views_handler_field_contextual_links.inc
@@ -0,0 +1,70 @@
+    $options = array();

Isn't this line redundant?

+++ b/handlers/views_handler_field_contextual_links.inc
@@ -0,0 +1,70 @@
+      '#description' => t('Which fields should be included into the contextu links'),

Typo, 'contextu' should be 'contextual'. I'd also say that 'include in' is more common than 'include into'.

marcvangend’s picture

One more bug:
Fields that are added to a 'contextual links' field, but come after it in the field order, are not displayed in the contextual links block. Interesting detail: this only happens on the final view page, but not in the view preview below the view edit form.

dawehner’s picture

- The 'Global: Contextual Links' field is too hard to find in the long list of available fields. Users really have to know it's there, it's not something they will easily find themselves.

Why will they not find it easy? There are many ones using global: custom field without problems and this is in the same region.

- A field that is added to a contextual links block is still visible as normal field. That's not logical, usually you don't need to display a field twice. IMO a field that is a contextual link should automatically be hidden from the 'normal' fields.

That's an arguable point, shouldn't the user be able to decide whether the links itself might be still visible?

- You can add more multiple contextual links fields, which doesn't make sense. (Only the last one is used.)
- You can add a contextual links field to itself. (No strange side effects, but it's weird.)
- You can add one contextual links field to another. (Results in a contextual links block filled with html code :-))

You can also have multiple node edit links, and use tokens to embed the same field into another field. There is a problem that views is such flexible.... If you want you can always find bugs.
So what are your conceptual suggestions to add it?

+    $options = array();

That's right.

Fields that are added to a 'contextual links' field, but come after it in the field order, are not displayed in the contextual links block. Interesting detail: this only happens on the final view page, but not in the view preview below the view edit form.

Sure ... it's basically the same as tokens. I agree that the fields which are listed after the contextual link, should be removed from the list.

The other possibility would be to add this to the row style plugin but you are lost here, because it would require to change every row style plugin from my perspective which will lead to many non-working ones(contrib is full of them).
Additional just from the visual behaviour it seems to me really a good fit for a field.

yoroy’s picture

Marc pointed me to this. Subscribe for now, sorry :)

marcvangend’s picture

Thanks Dereine, I'll try to post a reply to #28 later today.

Quick thought for now: I didn't see a if (module_exists('contextual')) in the patch. Is that intentional? I guess if contextual.module is not enabled, we could either hide the 'global: contextual links' fields completely, or add a warning to the description that it will not show up until the module is enabled.

dawehner’s picture

Yes that's already in my local branch.

David_Rothstein’s picture

Subscribing.

Ideally this would be done using the #contextual_links property - that way it wouldn't be necessary to duplicate all that code from the contextual links module, or to add a module_exists('contextual') at all. However, after thinking about it for a while I haven't been able to come up with a simple way to do that :(

If we do continue copying the contextual links module's code, note that the patch above is missing some parts of it - e.g., adding drupal_get_destination() to the query (so that you are taken back to where you started after going off and performing the contextual action).

In terms of the UI (separate field vs something else) I could see either option making sense personally. One good thing about having it be a separate field is that when you look at each row in a rendered view, you tend to see the contextual links gear as its own separate "thing", so in that sense it makes sense to have it show up as its own field. However, it does seem buggy to have it there for the reasons mentioned above. Also, right now at least, testing out the patch it only seems to work well with the "Unformatted list" and "HTML list" style plugins. With tables or grids (or especially jump menus) it's kind of a mess. So if only certain styles support this, it might make sense for it to be controlled at the style plugin level instead.

dawehner’s picture


Ideally this would be done using the #contextual_links property - that way it wouldn't be necessary to duplicate all that code from the contextual links module, or to add a module_exists('contextual') at all. However, after thinking about it for a while I haven't been able to come up with a simple way to do that :(

Everytime i try to use #contextual_links , there is a problem that you can't specify custom paths, which are quite often required here.
That's sometimes i would personally try to fix in d8.

If we do continue copying the contextual links module's code, note that the patch above is missing some parts of it - e.g., adding drupal_get_destination() to the query (so that you are taken back to where you started after going off and performing the contextual action).

This should be an option because technically it's just the fields like node-edit/delete which can currently decide whether they want to redirect or not.

In terms of the UI (separate field vs something else) I could see either option making sense personally. One good thing about having it be a separate field is that when you look at each row in a rendered view, you tend to see the contextual links gear as its own separate "thing", so in that sense it makes sense to have it show up as its own field. However, it does seem buggy to have it there for the reasons mentioned above. Also, right now at least, testing out the patch it only seems to work well with the "Unformatted list" and "HTML list" style plugins. With tables or grids (or especially jump menus) it's kind of a mess. So if only certain styles support this, it might make sense for it to be controlled at the style plugin level instead.

The main problem with providing it on the style plugin level is that it would require quite some custom code on special style plugins.
Can we really expect each developer of a style plugin(which are many ...) to implement contextual links. But i see the problems as well.

marcvangend’s picture

The main problem with providing it on the style plugin level is that it would require quite some custom code on special style plugins. Can we really expect each developer of a style plugin(which are many ...) to implement contextual links. But i see the problems as well.

I see your point. Would it be possible to provide a reusable form, that other style plugins can easily include in their own code? I'm thinking along the lines of system_settings_form() - just call it and it adds functionality to your form.
On the other hand, if the current field-based approach doesn't work with tables or grids, doesn't that imply that custom code will also be needed for the field-based approach? In that case, implementing this in the style plugin would at least give style plugin developers the choice if they want to support it or not. Implemented as a field, they don't have that choice, they just have to deal with a new field type that breaks their plugin.

awm’s picture

subscribe

kmadel’s picture

I wanted to point out a sandbox module of mine that doesn't in any way replace all that contextual links would give your from a view, but if you want a simple way to make text fields in a view contextually editable, you may want to check out my sandbox module: HTML5 contentEditable at http://drupal.org/sandbox/kmadel/1218202. This will allow you to choose the contentEditable formatter for any text field and the field will be wrapped with the HTML contentEditable attribute and a basic JavaScript based WYSIWYG toolbar for some basic styling and a 'Save' button to save via AJAX. Again, I am not trying to take anything away from adding contextual links on a node by node basis, as this contentEditable approach will in no way replace a full node edit form, but it may be a good fit for when you have some simple text fields that you would like to display in a Views based table and make them easily editable.

Kevin Morse’s picture

This would be excellent! I need to use the Fields display type for a front page redesign and was disappointed that it removed the easy to use Contextual Edit buttons that my client was used to for editing other aspects of the site.

emattias’s picture

Here's a tiny patch that adds an access check to the $build array. It will check against the general "Use contextual links" permission.

You will have to apply the patch from #22 before you apply this patch.

michaelfillier’s picture

subscribe

emattias’s picture

Here's another tiny patch that adds the current page as destination on links.

dawehner’s picture

Please merge the small patches into the big one, as it would be easier to test etc.

emattias’s picture

Here you go. The patches from #22, #39 and #41 combined into one, applicable to the current HEAD.

emattias’s picture

Hmm, I guess we have learned that drupal.org doesn't url encode the links to attached files.. Here is the same patch but with a url friendly name..

nagiek’s picture

.

jeffschuler’s picture

Along with the core fix in 1216776:#1, the patch in #44 is working well for me.

I think that the "separate field UI" -- adding a field for Contextual Links and assigning fields to it -- is a decent way to do this, and I prefer it to adding a checkbox on every field options form. Showing the fields twice if they are chosen for Contextual Links requires a bit of figuring out, but I think it would be less intuitive if the field did not show up without having clicked "Exclude."

I could actually see making a new section entirely on the view form for Contextual Links -- right after Fields -- which would only be available for certain styles, and operate similarly to the Fields section, but I haven't looked into how that would work.

I'm working on a patch that incorporates some other suggestions from throughout this issue's comments, and will post shortly.

jeffschuler’s picture

Status: Needs work » Needs review
FileSize
4.82 KB

This patch makes a number of changes addressing suggestions from comments throughout this issue. The patch is against HEAD, but my inline diffs here are against the last patch.

You can add a contextual links field to itself. (No strange side effects, but it's weird.)[#26]

I agree that the fields which are listed after the contextual link, should be removed from the list.[#28]

  function options_form(&$form, &$form_state) {
-    $options = array();
-    $options = $this->view->display_handler->get_field_labels();
+    $all_fields = $this->view->display_handler->get_field_labels();
+    // Offer to include only those fields that follow this one
+    $field_options = array_slice($all_fields, 0, array_search($this->options['id'], array_keys($all_fields)));
    $form['fields'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Fields'),
      '#description' => t('Fields to be included as contextual links.'),
-      '#options' => $options,
+      '#options' => $field_options,
      '#default_value' => $this->options['fields'],
    );
I didn't see a if (module_exists('contextual'] in the patch.[#30]
+  if (module_exists('contextual') {
    $data['views']['contextual_links'] = array(
      'title' => t('Contextual Links'),
      'help' => t('Display fields in a contextual links menu.'),
      'field' => array(
        'handler' => 'views_handler_field_contextual_links',
      ),
    );
+  }

Actually... shouldn't this code being added to modules/views.views.inc technically be in a new modules/contextual.views.inc?
In modules/views.views.inc:

/**
 * @file
 * Provide views data and handlers that aren't tied to any other module.
 */
[drupal_get_destination()] should be an option because technically it's just the fields like node-edit/delete which can currently decide whether they want to redirect or not.[#33]
+    $options['destination'] = array('default' => 1);
+    $form['destination'] = array(
+      '#type' => 'select',
+      '#title' => t('Include destination'),
+      '#description' => t('Include a "destination" parameter in the link to return the user to the original view upon completing the contextual action.'),
+      '#options' => array(
+        '0' => t('No'),
+        '1' => t('Yes'),
+      ),
+      '#default_value' => $this->options['destination'],
+    );
         $links[$field] = array(
           'href' => $path,
           'title' => $title,
-          'query' => array(
-            'destination' => $_GET['q']
-          )
         );
+        if (!empty($this->options['destination'])) {
+          $links[$field]['query'] = array(
+            'destination' => $_GET['q'],
+          );
+        }
       }
     }
Typo, 'contextu' should be 'contextual'. I'd also say that 'include in' is more common than 'include into'.[#26]
-      '#description' => t('Which fields should be included into the contextu links'),
+      '#description' => t('Fields to be included as contextual links.'),

Also:

-    'help' => t('Show multiple fields as contextual link'),
+    'help' => t('Display fields in a contextual links menu.'),
jeffschuler’s picture

Permission was not named properly.

       ),
-      '#access' => user_access('Use contextual links')
+      '#access' => user_access('access contextual links')
     );
jeffschuler’s picture

Trivial re-roll of #48 to apply to 7.x-3.x-dev without offsets.

xandeadx’s picture

FileSize
24.95 KB

#49 works for me

Kevin Morse’s picture

Is there a way for me to deploy this patch on a production site? Is it safe to do so or should I wait for this to get released.

marcvangend’s picture

Kevin,

The way to deploy this patch on a production site, is to apply the patch to your code (see http://drupal.org/node/707484) and follow your own deployment work flow.

If it's safe depends on your definition of "safe". This patch does not alter content or user permissions, so (at least in theory) it should not open security holes or prevent you from returning to the previous state. If that's safe enough for you, I suggest that you give it a try (make backups, test on a test server) and report back how it works for you.

ddunn’s picture

#49 also works for me when applied to 7.x 3.1

Could there be a way to restrict this contextual link's visibility to certain users (beyond the 'Use contextual links' permission?

I'd like it only to be displayed to the author of the node in which the view is shown (or, as I also have this as a field in the view itself, through uid, then visibility is set only to that specified user).

This would be great, as then the person with editing rights only sees the contextual link being offered.

Could this be possible? Or is there already a mechanism to achieve this?

ddunn’s picture

To answer my question, yes there is a mechanism to achieve this ...

I used a Views PHP field with the following snippet in the output area:

global $user;
if ($user->uid == $row->uid) {
print ('Edit/Action this');
}

With an appropriate rewrite link to where I want the link to go, and hide if empty appropriately configured, it achieves my goal.

Thanks for a great feature!

The next thing I would like, would be the functionality of preserving rel="lightframe" for Lightbox2, or perhaps to select the overlay for the particular link. How might that be achieved?

ddunn’s picture

I've also noticed that replacement patterns used in 'Output this field as a link' are not being respected in the output of fields in the contextual links.

e.g. as a field it outputs as /user/145/contact (correct)
but in the contextual links it appears as /user/[uid]/contact (goes nowhere)

This is in the use-case of View PHP field, if that's relevant.

amateescu’s picture

FileSize
4.76 KB
+++ b/handlers/views_handler_field_contextual_links.inc
@@ -0,0 +1,88 @@
+    $options = parent::option_definition();
+    $options['fields'] = array('default' => array());

A blank line between those two would be nice.

+++ b/handlers/views_handler_field_contextual_links.inc
@@ -0,0 +1,88 @@
+    // Offer to include only those fields that follow this one

Needs a period at the end.

+++ b/handlers/views_handler_field_contextual_links.inc
@@ -0,0 +1,88 @@
+          $links[$field]['query'] = array(
+            'destination' => $_GET['q'],
+          );

Hell no! We have drupal_get_destination().

+++ b/handlers/views_handler_field_contextual_links.inc
@@ -0,0 +1,88 @@
+}
\ No newline at end of file

meh.. :/

All of the above are fixed in the attached patch. Functionality-wise looks good to me, and now the code as well :)

dqd’s picture

dereine / merlinofchaos: if you worry about implementing this into views momentary, we can merge it into CLE as an additional views feature, since it isnt 100% sure what the future of contextual links will be, as we can see here: http://drupal.org/node/648370 - http://drupal.org/node/842328#comment-5613818 and many more if you search for contextual links core issues.

Or if the belief is strong enough that contextual links will stay in core :) we can merge any ideas from CLE into this patch here of course. I don't mind. Let me know.

Dreditor says: the code is fine :) and applying the patch on views latest --dev here at a Drupal 7.12 Ubuntu stage works as expected. After adding a global field "contextual links" and adding the edit and delete field to it, the contextual links appear on the view. But the default fields are still there in the normal view. I can exclude them from display after adding them to the "contextual links" field, but I think it still needs to be discussed, if this option should stay or if it should be excluded automaticly after adding them to the contextual links field.

dereine++
emattias++
jeffschuler++
amaatescu++
and all others of course :-)

Feel free to join #drupal-cle for further discussion

Kevin Morse’s picture

This works awesome for what I need it to do! I will probably manually keep this in the version of Views I used on at least one production site just because of the convenience it brings to my users.

Hopefully contextual links stick around because IMHO they're the most useful Drupal feature for getting non tech savvy users to administer their own websites.

dqd’s picture

Status: Needs review » Reviewed & tested by the community
dawehner’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for the review and all the hard work on this issue. Committed to 7.x-3.x

dqd’s picture

Status: Fixed » Reviewed & tested by the community

woot!

that are good news. So CLE can concentrate on fine grained permission and region on/off settings for contextual links in general. Thanks to all.

dereine++

dqd’s picture

Status: Reviewed & tested by the community » Fixed

oops

Kevin Morse’s picture

Just a quick word of advice for anyone who goes to add contextual links to existing Views. The Contextual Links field did not appear on a few of my sites until I cleared all caches from the Performance page.

Status: Fixed » Closed (fixed)

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

rol’s picture

i love this idea

i love drupal

i love you all!

OFF’s picture

Subscribe

mcfilms’s picture

Version: 7.x-3.x-dev » 7.x-3.7
Category: task » support
Priority: Major » Normal

Maybe I don't understand how the "Global: Contextual Links" are supposed to work. (Or maybe it was not rolled into Views 3.7 ??)

I have a Views slideshow made up of several fields. One of the fields is "Content: Edit link" which is hidden from display. After that, I have "Global: Contextual Links" and I have selected the Edit Link. What I am expecting should happen is that I should see an Edit Link under the contextual member gear. But, alas, all I see is the link to "Edit View." I have no idea why. Should I be seeing a link to edit the original content?

NaX’s picture

@mcfilms
I just ran into the same problem having the same expectations as you. After looking at the handler code I worked out that the Global: Contextual Links field is specifically looking at fields that have been re-written to be a link so you have to tick "Rewrite the output of this field" and set some text and you have to tick "Output this field as a link" and then build a path using tokens. Once I did that it started to work. Some help text on the "Global: Contextual Links" field could prevent these sort of questions in the future.

BrightBold’s picture

Thanks NaX! I couldn't figure this out either but your solution works.

bsandor’s picture

Issue summary: View changes

#68 works for me

brynj’s picture

#68 works for me too - although I found I only had to do this when I was trying to add an Edit contextual link for taxonomy terms (edit links for nodes worked without any rewriting).

LaurensV’s picture

I can't get the contextual links field to show up in Drupal 8. I tried to include all sorts of fields and also tried to "rewrite the output of this field" fix from #68, but the contextual link field stays empty.. Is this a bug or am I doing something wrong?