As discussed in #860082: BIKESHED: Token for a term or menu item's entire tree/hierarchy it would be useful if we can provide an array token type since it can be re-used by both a [menu-link:parents] token, a [term:parents] token, as well as [entity:field-name] tokens since fields are just an array of values. Plus this gives us implementations of a simple and complex use case.

Proposed tokens
[array:first] - first element of the array
[array:last] - last element of the array
[array:value:key] - dynamic token where 'key' is array[key]
[array:keys] - a chained 'array' token type of the keys of the array
[array:count] - the number of elements in the array
[array:join] - a comma-separated string of the values
[array:join:value] - this is a dynamic token, results of implode(value, array)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

BenK’s picture

Subscribing

effulgentsia’s picture

subscribe

fago’s picture

In hook_entity_property_info() of the entity API, arrays are treated via the special data type "list". They are represented via numerically indexed arrays, thus the keys are always just numeric. So they are really just a list of items, where the keys have no meaning it all.
I think it would make sense the same way for token too, as if you support arbitrary key:value pairs there is not really difference to all other data structures supported in token.

Then other useful tokens I could think of, would be [array:count] and perhaps a variant imploding all strings with commas.

Also in case you don't mind, calling the array type 'list' in token too, would probably help to streamline both data description worlds a bit.

Dave Reid’s picture

Naming it list is also something I'm not sold on. It could possibly confuse/conflict with the list field module? Note that most people are not going to be seeing the [array:] part of the token. It will mainly be a token that is used for things like [node:menu-link:parents] and [term:parents] as an array 'type' token.

fago’s picture

I like 'list' as it makes clear that we are not talking about associative arrays. But having not list/array part as the token is a good thing anyway.

manimejia’s picture

subscribe ... great idea!

Scott J’s picture

Would this help replace Array Tokens module?

Dave Reid’s picture

Yes it would, but it would likely be a Drupal 7 only solution.

Dave Reid’s picture

Status: Active » Needs review
FileSize
7.83 KB
Dave Reid’s picture

Title: Add an [array:*] token type » Add an [array:*] token type and a [user:roles] token

Merging #1012202: Add 'Roles' token like [current-user:roles] and [user:roles] into this issue since it gives us a good real-world implementation of an array token type.

Status: Needs review » Needs work

The last submitted patch, 1047740-token-array-type.patch, failed testing.

fago’s picture

What about array items that would require chaining, e.g. a list of nodes (node reference)?

bfroehle’s picture

Status: Needs work » Needs review
FileSize
7.38 KB
1.97 KB
+++ token.tokens.inc	14 Feb 2011 23:12:50 -0000
@@ -555,6 +601,64 @@ function token_tokens($type, $tokens, ar
+          $reversed = array_reverse($array);

The test case makes me think this should be array_reverse($array, TRUE) so that we preserve the array keys.

+++ token.module	14 Feb 2011 23:12:49 -0000
@@ -770,6 +770,23 @@ function _token_build_tree($token_type, 
+    $rendered = check_plina($rendered);

This should be check_plain, of course.

Attached a patch which fixes these bugs and makes the tests pass. One slight modification to the test was required, namely

-      'keys:value:3' => 4,
+      'keys:value:3' => '4',

which I believe is correct since value should return a text string.

I've also attached a diff of the changes since #9 for easy review.

Powered by Dreditor.

bfroehle’s picture

+++ token.tokens.incundefined
@@ -555,6 +601,64 @@ function token_tokens($type, $tokens, array $data = array(), array $options = ar
+    // @todo Handle if the array values are not strings and could be chained.

I don't know how to handle this todo, or even if it needs to be handled before this patch is committed.

Powered by Dreditor.

daviesap’s picture

+1

tsvenson’s picture

+1 Follow

SilviaT’s picture

+1

Dave Reid’s picture

Status: Needs review » Needs work

Committed #13 for now to CVS. Working on how to handle the rest now while we're switching to Git.
http://drupal.org/cvs?commit=505086

bfroehle’s picture

@Dave Reid: not sure what you mean by "the rest"

One unintended problem here is core doesn't allow spaces in tokens, so a token like

[user:roles:join:, ]

will not actually work.

There might need to be a different character which is substituted in for a space in a replacement.

pillarsdotnet’s picture

... core doesn't allow spaces in tokens, so a token like [user:roles:join:, ] will not actually work ...

urlencode() immediately comes to mind, but it would make the above [user:roles:join:%2C+] which is not exactly intuitive.

bryancasler’s picture

subscribe

quimrovira’s picture

What about complex array types?
Let's suppose we've got a node reference field, set up as a multiple value field. How should we try to handle this using token module? Could we just allow chaining the token expression to apply to each array element?

Some examples:

[node:field-nref:join:title]
Join (using ', ') referenced node titles
[node:field-nref:first:url:alias]
Return alias path to first referenced node
[node:audience:first:manager]
Return the manager's user name of the first audience group (organic group related)
[node:field-nref:n(2):title]
Second referenced ndoe title... is this already implemented? Can parenthesis be used on tokens?

Ideally, we could have some sort of string/render fallback by default, but be able to treat arrays of values with a known corresponding token type definition. To handle this, we would need to add a "subtype" key to the tokens structure returned by hook_token_info, and get it on array type generate_token call.
If we had this, everything else would be a matter of ripping the array function (first,last,join,nth,etc.) off the token, mapping the array using the remaining token expression using the given subtype as token_generate's type, and applying the array function to the resulting list.

In the end, all that matters would be offering some token definitions for other modules like:

$res['tokens']['node']['audience'] = array(
  name => t("Node audience groups"),
  description => t("don't trust grasshoppers who ride sports cars"),
  type => "array",
  subtype => "group"
);

An idea to work around the array problem might be by creating additional token types on the fly, or maybe using hook_token_info_alter itself to allow "array-of-subtype" declarations, which seems like a neater idea.

What do you think?

Trunkhorn’s picture

sub

ldweeks’s picture

Subscribing...

bryancasler’s picture

bump

anruether’s picture

subscribe

rorymadden’s picture

Subscribe. Is this still a blocker for #691078: Field tokens?

bryancasler’s picture

Dave Reid, I just upgraded to the new Beta 2 Token release and I noticed some possibly new options.
http://awesomescreenshot.com/09edg9551
http://awesomescreenshot.com/024dg9add

Is this issue resolved?

EDIT: I just remembered I am using this token patch from #143 as suggested by #262. #691078: Field tokens

Jackinloadup’s picture

subscribe

Dave Reid’s picture

Status: Needs work » Fixed

I'm going to consider this part of the issue fixed, the rest will be a follow-up as a part of #691078: Field tokens which will solve the complex use case.

Status: Fixed » Closed (fixed)

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

Ahmed Pc’s picture

Version: 7.x-1.x-dev » 6.x-1.x-dev
Priority: Normal » Critical
Status: Closed (fixed) » Active

I have a problem, I want to get the first item of [upload_fid] token, I have tried to use [upload_fid:first] but it did not work, I am a beginner in drupal, could you please help me ???

bfroehle’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Priority: Critical » Normal
Status: Active » Closed (fixed)

Ahmed Pc: Please create a new issue.

Ahmed Pc’s picture

I have created a new issue

http://drupal.org/node/1833130