I have a field setup as a list (text) that contains key|label pairs. I'm attempting to use these values in a custom content pane with the token substitutions.

I see two tokens per field:
- %node:field_abc
- %node:field-abc

Is there a difference between the two?

Both seem to render the label when I actually want access to the key. Is there a way to accomplish that?

Comments

merlinofchaos’s picture

Status: Active » Fixed

The one with the - is provided by entity_token module and is generally better than the one with the _ which is provided by token.module. In both cases, these are just core Drupal tokens that CTools is re-using.

Use the one with the -; in my experience, the one with the _ is mostly broken. :(

Tokens don't currently have a way to access the key, sadly. Having had to do this, I've written a little bit of code that will let you do this, which I use in some of my projects but isn't publicly available anywhere.


/**
 * Custom token manipulation.
 *
 * This allows any field api token raw values in this format:
 * [field-fieldname:raw:value]
 * Or to get tokens via delta:
 * [field-fieldname:raw:0:value]
 *
 * To determine if a particular checkbox in a set of checkboxes is checked, you
 * can use:
 * [field-fieldname:has:VALUE]
 * If your value has spaces in it, use dashes instead and they'll be auto-converted properly.
 */
function YOURMODULE_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();
  $info = module_exists('token') ? token_get_info() : token_info();
  foreach ($tokens as $name => $original) {
    $bits = explode(':', $name);
    if (count($bits) > 2 && !empty($bits[1]) && $bits[1] == 'raw') {
      $token = array_shift($bits);
      if (!empty($info['tokens'][$type][$token])) {
        $value = '';
        // Knock off the $raw.
        array_shift($bits);
        if (!is_numeric($bits[2])) {
          // If no delta specified, use zero.
          array_unshift($bits, 0);
        }
        $items = field_get_items($type, $data[$type], str_replace('-', '_', $token));
        if (is_array($items)) {
          $value = (string) drupal_array_get_nested_value($items, $bits);
        }
        if (!empty($options['sanitize'])) {
          $value = check_plain($value);
        }
        $replacements[$original] = $value;
      }
    }
    if (count($bits) > 2 && !empty($bits[1]) && $bits[1] == 'has') {
      $token = array_shift($bits);
      if (!empty($info['tokens'][$type][$token])) {
        $value = '';
        // Knock off the $raw.
        array_shift($bits);
        $key = array_shift($bits);
        $alternate_key = str_replace('-', ' ', $key);
        $items = field_get_items($type, $data[$type], str_replace('-', '_', $token));
        if (is_array($items)) {
          foreach ($items as $delta => $item) {
            if ($item['value'] == $key || $item['value'] == $alternate_key) {
              $replacements[$original] = $item['value'];
            }
          }
        }
      }
    }
  }

  return $replacements;
}

You can use these tokens in CTools with the normal %node:field_foo:raw:value

Unfortunately they won't be selectable or show up in the token list, making them a little less useful for Views.

caschbre’s picture

Thanks merlin for sharing that bit of code. It's very much appreciated.

Status: Fixed » Closed (fixed)

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