5

I'm fairly new to Drupal theming, and I am trying to customize the HTML output the Flag module for Drupal 8 produces for flag/unflag links; more specifically, I would like to make the links appear as buttons using Bootstrap classes. Does anyone know a good way to do this? I'm placing the flag link on the user profile page to enable users to follow other users. Here are some approaches which I have tried, so far without success:

  • Using the Twig replace filter to modify the output. This does not work, apparently because a "lazy builder" is used, delaying the production of the actual HTML output until a later stage after Twig's rendering is already complete.

  • Overriding the flag.tpl.php template with a customized version. This has no effect; maybe this functionality is no longer active in Drupal 8 (which did away with PHP templates in general)?

  • Using flag_create_link in a theme preprocess function. I got an error that this function does not exist; maybe it no longer exists in the Drupal 8 version of the module? (or else maybe I'm missing a necessary import).

1
  • Did you flush the cache?
    – No Sssweat
    Commented Jan 27, 2016 at 20:53

3 Answers 3

2

This works in D7, but I am sure it transfers to D8.

One approach is to use Views

  1. Under Advanced, RELANTIONSHIP add a relationship of flag, in order to get access to the flag link field.

  2. In FIELDS, add flag link field, and under Style Settings >> Checkmark customize field HTML >> Select DIV >> type your bootstrap class name.

enter image description here

In your theme's css file add this, ex:

.ddd .flag-action { border: solid green; }
.ddd .flag.unflag-action { border: solid red;  }
4
  • This seems like a good approach, but I'm having some trouble making it fit my use case. I probably should have explained -- the flag applies to users, and I'm placing the link on the user profile page to enable users to follow other users. So I wasn't using a view. I could embed a view in the user profile page, but I couldn't figure out how to set up an appropriate filter on the view so that it just shows the flag for the selected user (i.e., the user whose ID is given at the end of the URL). Any idea how to do that? Commented Feb 6, 2016 at 17:59
  • 1
    @BrentKerby sorry of the late reply, somehow I missed your comment. Under Advanced, CONTEXTUAL FILTER add, User ID, select provide default value >> User ID from route context. example
    – No Sssweat
    Commented Feb 17, 2016 at 6:25
  • 1
    PS: After adding the contextual filter, your view preview will disappear/be empty. Don't worry, the view will show up when you visit the user page.
    – No Sssweat
    Commented Feb 17, 2016 at 6:31
  • 8 years on this is the only reply to still work for me, as far as having the toggle/untoggle a flag goes.
    – Matt
    Commented Apr 24 at 16:51
2

Here is a solution that ended up working for me. In my MYTHEME.theme file, I put the following:

function MYTHEME_preprocess_user(&$vars){
  $f = \Drupal::service('flag.link_builder');
  $link = $f->build('user',$vars['user']->id(),'followed');
  $link['link']['#attributes']['class'][]="btn";
  $vars['follow_link'] = $link;
}

Then, in the user.html.twig template, I put {{ follow_link }} in the appropriate place. It's not a perfect solution, though, because it is not compatible with AJAX links (in which case the button styling is lost after the button is clicked). But with normal links, it works.

3
  • 1
    Have you tried that with different users and caching enabled? This will likely be cached unless you disable caching completely for different users.
    – Berdir
    Commented Feb 8, 2016 at 7:59
  • 1
    You probably want to follow drupal.org/node/2463365
    – Berdir
    Commented Feb 8, 2016 at 8:01
  • if you want to use flag in your custom file then use this code: $variables['variable_name'] = [ '#lazy_builder' => ['flag.link_builder:build', [ $entity->getEntityTypeId(), $entity->Id(), 'flag_name' ]], '#create_placeholder' => TRUE, ]; Here $entity->getEntityTypeId() is entity type like 'node', 'user', 'coment' $entity->Id(), is id of the content like 'nid', 'uid', 'cid' etc flag_name is name of the flag which you have created. For more infor please follwot this link : (drupal.org/node/295383)
    – Manav
    Commented Jun 6, 2018 at 9:03
1

From what I could discover, the flag links are just link render elements, which can be modified by hook_link_alter().

The following code is not actually tested, (and may break in the future)

function MYMODULE_link_alter(&$variables) {
  if (strpos($variables['options']['attributes']['id'], 'flag-') === 0) {
    $variables['options']['attributes']['class'] += [
      'new-class',
    ];
  }
}

I hope that there is a better approach possible, but they only other alternative I could find was swapping out the flag.link_builder service to apply your desired classes instead of relying on the alter hook.

1
  • I tried defining a function MYTHEME_link_alter in my .theme file, but it appears to never be called. I tried MYTHEME_preprocess_link instead, and it is called on some links but not on the links generated by the Flag module. Commented Feb 6, 2016 at 18:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.