<?php
  if (isset($link_options['attributes']['class'])) {
    $link_options['attributes']['class'] = array($link_options['attributes']['class']);
  }
?>

The above doesn't work when passing an array of classes with a preprocess function in the way that classes are normally added to things in Drupal. Like this:

<?php
function mymodule_preprocess_node(&$vars) {
  $vars['content']['field_link'][0]['#element']['attributes']['class'] = array('class1', 'class2');
}
?>

A potential solution is as follows, although something more elegant should probably done.

<?php
  if (isset($link_options['attributes']['class']) && !is_array($link_options['attributes']['class'])) {
    $link_options['attributes']['class'] = array($link_options['attributes']['class']);
  }
?>

Comments

wernerglinka’s picture

I just ran into this problem. I am using multiple classes to add icon fonts to links. Multiple classes must be in an array, one class per array key. That is how the menu system creates the links. The link module puts multiple classes into an array as well but all classes are located in ['options']['attributes']['class'][0]. So I don't think the above will work since $link_options['attributes']['class'] is always set.

wernerglinka’s picture

In link.module at line 922 there is this code:

if (isset($link_options['attributes']['class'])) {
  $link_options['attributes']['class'] = array($link_options['attributes']['class']);
}

if you change this to:

if (isset($link_options['attributes']['class'])) {
  $link_options['attributes']['class'] = explode(" ",($link_options['attributes']['class']));
}

This adds an array of classes rather than a string of classes to the classes array.

mfernea’s picture

Status: Active » Needs review
StatusFileSize
new738 bytes

I think both ideas are good. I'm uploading a patch based on both.

cinnamon’s picture

Not sure if this is related to the original problem/use case, but we still have problems with link module and classes.

As it turned out it was a serialized array of classes! This patch also accounts for that

cinnamon’s picture

Nevermind, although I did see serialized data with dpm, it turned out we still got the fatal array to string conversion error :(

Am on a deadline and a link field is not that hard to implement, sorry....

dqd’s picture

Can anyone can pick on this? Reproduce? And/Or confirm this bug again please? If this is still an issue, I would love to see progress on this and chime in later, but there are other issues of link module already on my table. Thanks for the patches so far ...

mfernea’s picture

Yes, this is still an issue on 7.x-1.x branch. The patch at #4 doesn't fix the array problem. So, I would go for #3. Please check, maybe I'm subjective :).

dalemoore’s picture

Is there a preferred method for adding classes programmatically to the anchor rather than through the UI in the Additional Classes input? I've been trying to add additional classes using template_preprocess_field but it's completely ignored.

Here's a non-working example:

function intranet_preprocess_field(&$variables, $hook) {
  $content_type = $variables['element']['#bundle'];
  $view_mode = $variables['element']['#view_mode'];
  $field_name = $variables['element']['#field_name'];
  
  // Uncomment to see what's in the render array...
  dpm($variables);
  
  switch ($field_name) {
    // We make sure it only effects the correct field ...
    case 'field_app_link':
    
      // Loop through the Link field's items
      foreach ($variables['items'] as $delta => $item) {

        // Add classes to elements to add proper app download icon
        $element_title = $item['#element']['title'];
        if ($element_title == 'Apple App Store') {
          echo 'I\'m an App Store app!';
          $variables['items'][0]['#element']['attributes']['class'][] = 'test';
        } elseif ($element_title == 'Google Play Store') {
          echo 'I\'m a Google/Android app!';
        } elseif ($element_title == 'Web App') {
          echo 'I\'m a Web App!';
        }
      }
    break;
  }
}
ambient.impact’s picture

I can confirm I've run into this with 7.x-1.4. I set classes as an array in template_preprocess_field(), and I got a drupal_attributes() error about a string to array conversion, and the classes didn't apply. The patch in #3 seems to fix that, and give us the expected behaviour. I hope this can be released soon. :|

ambient.impact’s picture

@dalemoore: I'd suggest opening a separate issue/support request in the future. At first glance, it looks like you're looping through all field items (good), but then setting the class only on the first index ($variables['items'][0] - not so good), which might be the culprit. Either use $delta in place of 0 there, or do what I usually do and make $item a reference (&$item) in the foreach statement, allowing you to set the class without the full nested array:

$item['#element']['attributes']['class'][] = 'test';

If none of that works, the standard advice is to check the function name to make sure you've got the name of your theme or module right, and also to clear the cache so Drupal will pick up the function.

  • pifagor committed c13b372 on 7.x-1.x
    Issue #2901656 and #2210297 by nightwalkr, mfernea: validates that the...
pifagor’s picture

Status: Needs review » Fixed

Fixed

pifagor’s picture

Status: Fixed » Closed (fixed)
ciss’s picture

Note: This change was reverted in 6f1bf5 (no associated issue).