4

This question already has an answer here:

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).

marked as duplicate by Pierre.Vriens, Scott Joudry, Mołot, Krishna Mohan, kenorb Feb 15 '16 at 11:03

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Did you flush the cache? – No Sssweat Jan 27 '16 at 20:53
1

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;  }
  • 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? – Brent Kerby Feb 6 '16 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 Feb 17 '16 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 Feb 17 '16 at 6:31
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.

  • 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 Feb 8 '16 at 7:59
  • 1
    You probably want to follow drupal.org/node/2463365 – Berdir Feb 8 '16 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 Jun 6 '18 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.

  • 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. – Brent Kerby Feb 6 '16 at 18:04

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