Skip to main content
2 of 4
Added note about customization.
othermachines
  • 1.5k
  • 9
  • 16

I have just discover that apparently it was easier to do this in 6.x.

In Drupal 7, turn the comment "Reply" link into a <button> element by overriding core's theme_links() function. It isn't pretty, but it's effective.

The Solution: MYTHEME_links()

Add the function below to your theme's template.php file (replace "MYTHEME" with your theme name). Clear your cache for the change to take effect.

function MYTHEME_links($variables) {
  $links = $variables ['links'];
  $attributes = $variables ['attributes'];
  $heading = $variables ['heading'];
  global $language_url;
  $output = '';

  if (count($links) > 0) {
    // Treat the heading first if it is present to prepend it to the
    // list of links.
    if (!empty($heading)) {
      if (is_string($heading)) {
        // Prepare the array that will be used when the passed heading
        // is a string.
        $heading = array(
          'text' => $heading,
          // Set the default level of the heading.
          'level' => 'h2',
        );
      }
      $output .= '<' . $heading ['level'];
      if (!empty($heading ['class'])) {
        $output .= drupal_attributes(array('class' => $heading ['class']));
      }
      $output .= '>' . check_plain($heading ['text']) . '</' . $heading ['level'] . '>';
    }

    $output .= '<ul' . drupal_attributes($attributes) . '>';

    $num_links = count($links);
    $i = 1;

    foreach ($links as $key => $link) {
      $class = array($key);

      // Add first, last and active classes to the list of links to help out themers.
      if ($i == 1) {
        $class [] = 'first';
      }
      if ($i == $num_links) {
        $class [] = 'last';
      }
      if (isset($link ['href']) && ($link ['href'] == $_GET ['q'] || ($link ['href'] == '<front>' && drupal_is_front_page()))
         && (empty($link ['language']) || $link ['language']->language == $language_url->language)) {
        $class [] = 'active';
      }
      $output .= '<li' . drupal_attributes(array('class' => $class)) . '>';

      if (isset($link ['href'])) {
        if ($key == 'comment-reply') {
          // Special handling for comment 'Reply' link.
          $output .= '<button type="button">' . $link ['title'] . '</button>';
        }
        else {
          // Pass in $link as $options, they share the same keys.
          $output .= l($link ['title'], $link ['href'], $link);
        }
      }
      
      elseif (!empty($link ['title'])) {
        // Some links are actually not links, but we wrap these in <span> for adding title and class attributes.
        if (empty($link ['html'])) {
          $link ['title'] = check_plain($link ['title']);
        }
        $span_attributes = '';
        if (isset($link ['attributes'])) {
          $span_attributes = drupal_attributes($link ['attributes']);
        }
        $output .= '<span' . $span_attributes . '>' . $link ['title'] . '</span>';
      }
      
      $i++;
      $output .= "</li>\n";
    }

    $output .= '</ul>';
  }

  return $output;
}

###Breaking it down...

This bit of code:

      if (isset($link ['href'])) {
        // Pass in $link as $options, they share the same keys.
        $output .= l($link ['title'], $link ['href'], $link);
      }

was changed to

      if (isset($link ['href'])) {
        if ($key == 'comment-reply') {
          // Special handling for comment 'Reply' link.
          $output .= '<button type="button">' . $link ['title'] . '</button>';
        }
        else {
          // Pass in $link as $options, they share the same keys.
          $output .= l($link ['title'], $link ['href'], $link);
        }
      }

Of course you'll need to customize the output with whatever you need, whether it be a <form> wrapper or onclick attribute.

Unfortunately we can't use theme('button'...) because that would give us an input element. Of course we could change that by overriding theme_button() but that would affect all input elements on the site, and you would still need to override theme_links() in order to call it.

othermachines
  • 1.5k
  • 9
  • 16