Some modules provide many tokens that are not included explicitly in their hook_token_list() for reasons of brevity. For example, Date module provides ~30 tokens that relate to each date field, and (would) provide the same 30 tokens for the optional TO-date part of that field. Instead they provide a wildcard-style result in the list to-???? and a description of how to use this.
This works fine, apart from when use of the tokens are explicitly validated, and the existing wildcard support only allows for numeric-suffix wildcards.
This feature request is to extend the wildcard support in token validation to support -* -? and -???? style wildcards.
Related issue: #376008: Can't use "to-" date tokens in pathauto
Comments
Comment #1
lyricnz commentedHere's a patch that performs this validation. Realising that running preg_match() across all the tokens is inefficient, the code is only invoked if there are invalid tokens after normal validation.
Comment #3
lyricnz commentedUpdate patch for flattened token structure.
Comment #4
lyricnz commentedCan add tests if approach is approved by maintainer.
Go, bot, go.
Comment #5
lyricnz commentedChange to require characters in the wildcard part of the token, not just the right prefix. Added test cases for both validation, and token-value
Comment #6
dave reidI'm not sure why this logic can't go inside the existing 'wildcard' check in token_get_invalid_tokens_by_context(). I don't think it makes sense to run a preg_match() on each token twice. Let's set the standard for a wildcard token that it should be [-_](N|\?) and not -????.
Comment #7
dave reidComment #8
dave reidAlso, I backported the assertTokens() function from token.test in Drupal 7 so you can use 'tokenname' => NULL to test for un-generated tokens.
Comment #9
lyricnz commentedThe current code loops across each of the tokens found in the input string (small number), and checks if they're in the list of available tokens (big number) - using isset() or a single preg_match() for the _N wildcard. This is very efficient.
However, in order to check an input-token against a wildcard available-token, we need to
So, the extra loop is actually around the *available* tokens, not the list of tokens being validated (probably not clear from the patch). By putting it below the existing loop:
Here's just the token.module patch with a bit more context.
Comment #10
lyricnz commentedUpdated patch to use new assertTokens() functionality.
Comment #11
dave reidThis is what I was thinking. There's no need to add another loop with two possible preg calls per loop. With this, we enforce the following standard with wildcard tokens:
You must list your token in hook_token_list as token-name[-_][N?]. Ideally I'd like it to be just '?' rather than both 'N' and '?', but I know location.module already uses -N.
Other changes
1. I have no interest in encouraging and supporting -* as a wildcard token suffix.
2. The test validating the tokens output things is kinda pointless as that code doesn't touch validation at all. There's nothing really new being tested, so I left it out.
Comment #12
lyricnz commentedOK, works for me. Once this is applied, I'll submit a patch for Date module.
PS: the first line of token_test_exit() generates a warning for me. What's that function?
Comment #13
lyricnz commentedMy only thought about -? vs -* is that '?' kindof implies a single letter/number, whereas * makes it clear that there could be quite a bit of stuff after the * (such as provided by date module). This may just be my geek/regex interpretation of that, of course.
Comment #14
lyricnz commentedActually, the regex in your patch
only supports having ONE word-part (as delimited by _-) after the wildcard, which really limits what a module can use the wildcard for. Are you sure?
Comment #15
dave reidYes it is intentional. We are severely limited in the custom/wildcard token API we can provide in D6 without affecting performance. Anything that really wants to do this right should be using D7, which has much better custom token support.
Comment #16
lyricnz commentedYour call, of course - but I disagree with "Anything that really wants to do this right should be using D7". Of course D7 has better token support, but most sites are still D6, and have no realistic chance of upgrading or being implemented in D7 (so many contrib modules not updated, in particular).
Comment #17
dave reidSo looking back on this, I see now that we used to use token-name-???? in token.module's node tokens a while back. So if other modules picked up on that as the 'standard', then we should support that too.
The problem is that with support date token's crazy rules is that I don't think I ever saw an issue in this queue to ask about 'hey we have this crazy wildcard token, how can it be best supported?'.
This patch adds support for token-name-???? wildcard syntax.
Comment #18
lyricnz commentedRegarding your comment on performance - that's exactly why I put the code in a second loop, that is only applied if there are tokens that are still invalid after primary checking.
Comment #19
dave reidSame thing, this code only executes if the isset($valid_tokens[$token]) condition fails, and the token is invalid. lyricnz does #17 look good to you?
Comment #20
lyricnz commentedIt's fine, but doesn't solve my original problem: "proper" wildcard support.
Comment #21
dave reidCommitted #17 to Git: http://drupalcode.org/project/token.git/commit/66bd549.
If there is any other *concrete* use case that we need to support, please give specific examples of what module provides the tokens, and example token names so that we can investigate further. Date.module tokens are now fully supported.
Comment #22
lyricnz commentedThanks. I've updated the patch for Date module to not create multi-word elements in the wildcard part of the tokens.
http://drupal.org/node/593840#comment-4457364