Add Edit button to Teaser in Drupal 8

Sarah Carney
3 min readMar 29, 2019

--

I want to create an edit button on Teasers if a user has access to edit that node.

  • I am using Display Suite to display Teasers of a custom content type Project in a View.
  • I want to show a link on each Teaser to edit that node if the logged in user is the author of the node.
  • Our requirements do not allow us to use Contextual Links with the little hover gear.
If I am logged in as Ishmael, I can only edit my projects.

You will need:

  1. Display Suite
  2. Access to your theme files
  3. A View displaying a list of Teasers of your content type, in my case Project

Create Display Suite Token Field for the button

I use Display Suite for this field because the tokens can automatically grab the node’s edit url, and I can place the field in Manage Display like any other field and create a custom field template like any other field.

Structure > Display Suite > Fields > Add token field

Screenshot of the Add Token Field screen

Entities: Node
Limit field: project|*
Field content:

<a href="[node:edit-url]">Edit <span class="sr-only">[node:title]</span></a>

(I recommend including screenreader-only text so that the button will also announce what is being edited. My class of sr-only hides the text from visual users but reads it to assistive technology.)

Place this field in teaser of the Content Type

Structure > Content Types > Your Content Type > Teaser

Note, you have to activate Display Suite for that content type by choosing a Layout for the Default view, whatever one works, even just One Column. After you do that, you’ll see your custom button field in the list of Disabled fields.

If we stop here, the button will appear on every node regardless of the user is the author including anons. They can click it, but they’ll get an access denied screen.

Code time!

Make the logged in user’s ID available in custom field templates.

In your theme’s .theme file write a preprocess function to create a variable for the current user’s id.

function mytheme_preprocess_field($vars) {
/* Make the current user id availalbe in field templates */
$vars['uid'] = \Drupal::currentUser()->id();
}

uid is the name I came up with for my variable. You can choose your own.

Create a custom field template in your theme

Find out what to name your new field template. You can do this with Twig debugging. My file name is:

field-dynamic-token-field--node-project-edit-button.html.twig

{% if element['#object'].getOwner.uid.value == uid %}
{% for item in items %}
{{ item.content }}
{% endfor %}
{% endif %}
  1. element['#object'].getOwner.uid.value looks up out of the field to its node where it can get information about the node owner. Big big thank you to No Sssweat on the Drupal stack exchange who clued me into this part.
  2. uid is the variable that gets the current user’s id number. So if the owner’s id number is the same as the current user’s id number, then show that field’s content which is our button!

Bonus: Include users who can edit any project

{% if (element['#object'].getOwner.uid.value == uid) or (user.hasPermission('edit any project content')) %}
{% for item in items %}
{{ item.content }}
{% endfor %}
{% endif %}

Add user.hasPermission('edit any project content') as a condition, where project is the machine name of my content type. Don’t forget the new () around each condition.

Done

If everything has gone to plan, edit buttons should only show up on teasers when that user is the owner.

--

--

No responses yet