I have create a view of badges and set anchor name references for each badge. In this way, if I manually type the view url with the named tag, it automatically jumps to that spot on the page.
For example:
http://mysite.com/badges#fan-badge
This work great when I type in manually, but I'm trying to set the link on the badge image, so if someone views a user profile with that badge and clicks on it, it should take him to the above link. However, it really takes him here (and I get a page not found error).
http://mysite.com/badges%2523fan-badge

Comments

NancyDru’s picture

That looks like it might be a double-encoding error. Can you explain in greater detail, please, so that I can better understand the situation?

benlotter’s picture

Here is greater detail including exact steps to reproduce.

Go to /admin/user/user_badges/list. Then click Edit next to one of the badges (ex /admin/user/user_badges/edit/1). In the Description URL enter "badges#fan-badge". Then click Submit.
Finally view your badge and click on it's link. It will take you to this URL "/badges%2523fan-badge" which is not the desired behavior. The desired behavior is to take you to "/badges#fan-badge".

I have also tried entering (in place of the "#") the url encoding for it. But that does not work either.

FYI, my workaround was to create a separate node for each page to view. But what I really want is a list (view) of all the badges but to jump to the anchor name of the badge you just clicked on.

NancyDru’s picture

Status: Active » Postponed (maintainer needs more info)

At the end of function theme_user_badge, replace the return l(... with:

    $pieces = parse_url($href);
    $pieces['html'] = TRUE;
    if (isset($pieces['scheme'])) {
      $pieces['path'] = $pieces['scheme'] . '://' . $pieces['host'] . $pieces['path'];
    }

    return l($image, $pieces['path'], $pieces);

This works for me and will be in the next commit unless you say it doesn't.

benlotter’s picture

Issue tags: +Solution

I may have done something wrong because now all the badges simply link to the home page. Here is the entire function after I attempted to edit it per your instructions. When I changed it back everything started working again (including the bug, of course).

/**
 * Return html representation of a badge image
 * (note: theme_image does the check_plaining)
 */
function theme_user_badge($badge) {
  $image = theme('image', $badge->image, $badge->name, $badge->name);
  if ($badge->href != "") {
    //return l($image, $badge->href, array('html' => TRUE));
	$pieces = parse_url($href);
    $pieces['html'] = TRUE;
    if (isset($pieces['scheme'])) {
      $pieces['path'] = $pieces['scheme'] . '://' . $pieces['host'] . $pieces['path'];
    }
    return l($image, $pieces['path'], $pieces);
  }
  else {
    return $image;
  }
}

UPDATE: I did look at the code and noticed you had change $badge->href to $href. Anyway, I made a couple of attempts to adapt your code and came up with this. The following works (note, my changes in bold below) on my installation and fixes the # bug. :) Thank you very much.

Okay, so I couldn't get it to highlight in bold but the change I made was here: $pieces = parse_url($badge->href);

/**
 * Return html representation of a badge image
 * (note: theme_image does the check_plaining)
 */
function theme_user_badge($badge) {
  $image = theme('image', $badge->image, $badge->name, $badge->name);
  if ($badge->href != "") {
    //return l($image, $badge->href, array('html' => TRUE));
	$pieces = parse_url($badge->href);
    $pieces['html'] = TRUE;
    if (isset($pieces['scheme'])) {
      $pieces['path'] = $pieces['scheme'] . '://' . $pieces['host'] . $pieces['path'];
    }
    return l($image, $pieces['path'], $pieces);
  }
  else {
    return $image;
  }
}
NancyDru’s picture

Sorry, my suggestion was based on 6.x-1.6. There are a ton of fixes above 1.5; I highly suggest updating. The new Token support sets $href.

sophievn107’s picture

Just curious. badges#fan-badge is a new page on your site? where do u define and create this?

benlotter’s picture

I have a badge content type which include the Title: Name, Body: Description and a CCK imagefield for the badge image. Then I created a view with a page output of badges. Also it outputs the . I do this so that when someone clicks on any badges they see all the badges but the page is scrolled to the one they clicked on. But then they will see all badges so they will be curious how to earn those as well.

NancyDru’s picture

@benlotter: That sounds like an awesome idea! And it sounds like it might be a good highlight site for the project page.

benlotter’s picture

Version: 6.x-1.5 » 6.x-1.6
Category: support » bug
Issue tags: -Solution +broken

I love the new token support in 1.6. :) Unfortunately it broke the named tag (#) functionality that I had from #3 and #4. I tried for 1/2 hour to integrate the token code with the $pieces code with no success. In the end, I had to yank the token code in favor of the $pieces code since that is the functionality I desire. Here's what my full theme_user_badge() looks like now.

<?php
/**
 * Return html representation of a badge image
 * (note: theme_image does the check_plaining)
 */
function theme_user_badge($badge, $account = NULL) {
  //If we haven't been supplied with a user, use whoever is logged in
  global $user;
  if (is_null($account)) {
    $account = $user;
  }

  //If we have a full image URL, don't require theme_image to get the size (it only breaks)
  $get_size = valid_url($badge->image, TRUE);
  if (variable_get('user_badges_imagecache', 0)) {
    $image = theme('imagecache', 'user-badges', $badge->image, $badge->name, $badge->name, array('class' => $badge->class));
  }
  else {
    $image = theme('image', $badge->image, $badge->name, $badge->name, array('class' => $badge->class), !get_size);
  }

  //We don't link the badge if there is no link and no default, or if the default is overridden
  if (
    ($badge->href == "" && !variable_get('user_badges_defaulthref', ''))
    || drupal_strtolower($badge->href) == '<none>') {
    return $image;
  }
  else {
    $href = $badge->href ? $badge->href : variable_get('user_badges_defaulthref', '') ;
/*	
    //Implement token replacement
    if (module_exists('token')) {
      $href = token_replace($href, $type = 'userbadge', $object = $badge);
      $href = token_replace($href, $type = 'user', $object = $account);
    }
	return l($image, $href, array('html' => TRUE));
*/

	$pieces = parse_url($badge->href);
    $pieces['html'] = TRUE;
    if (isset($pieces['scheme'])) {
      $pieces['path'] = $pieces['scheme'] . '://' . $pieces['host'] . $pieces['path'];
    }
	
	return l($image, $pieces['path'], $pieces);
	
  }
}
?>
benlotter’s picture

@NancyDru Thanks for all your help. Once I can get everything working and get the site out of BETA, I can submit it as an example. Sorry, I hate showing my unfinished work off except to those who have been warned that I'm constantly breaking it to make it better.

sophievn107’s picture

Hi, for my site, I would like to link the badge image to the new page, which show that particular badge's image, details as well as the date that the user earned the badge (not redirect to the badge list page), so basically different badges will link to different pages (eg. user/232/badges/agagtqtq111 or something like that.

Any thoughts? Please help.

benlotter’s picture

Have you tried the new token support in 1.6? You should be able to link to the user's profile page where you can see the badges if they are displayed. Beyond that, you might need to create a view which accepts the user-id as a parameter to accomplish your goal.

NancyDru’s picture

@sophievn107: At least the current -dev version does most of that already; I can't recall if that was in 1.6. Every badge has a setting for "Description URL" which allows you to create a node and fill this in with "node/1234" (where 1234 is the correct node ID). That node can describe the badge. As benlotter suggested the "Default badge link URL" could contain user/[uid]/badges.

Unfortunately, we don't currently keep track of the date it was earned. And with the issues requesting multiple badge earning, which date would you show, the first or the most recent? However, I would appreciate it if you would open a new feature request for this.

NancyDru’s picture

Status: Postponed (maintainer needs more info) » Fixed

I have removed drupal_get_destination() (apparently it is not needed any way) from the theme_user_badge function. You should be able to revert to the standard code, complete with token support.

Status: Fixed » Closed (fixed)
Issue tags: -broken

Automatically closed -- issue fixed for 2 weeks with no activity.