We frequently have a need to use UserIdentity, PageIdentity, LinkTarget and user groups as message parameters. But since they are not supported directly, we are converting them to strings first. This conversion requires context (customized namespace names, localized group names, etc).
Code that constructs messages (internationalization) should not do such formatting (localization). This code often lacks the context for correct localization (such as user preferences) and goes to global state to acquire it.
To solve this problem, we should support user groups, PageIdentity, LinkTarget, and UserIdentity as message parameters. Use groups will have to be encoded as an array, in the same way we encode parameters that represent e.g. a duration, with the array key identifying the value type: [ 'user-group' => $groupName ]. We could do the same for PageIdentity, LinkTarget, and UserIdentity, or we could support them directly, and format them based on their type.
The following places will have to be touched to support this:
- Message::extractParam. This is where the actual formatting logic goes. Message will have to use the global service container instance to access the NamespaceInfo service, but that's no worse than the other things that happen in Message. This will be resolved in a future refactoring when we convert from Message to MessageValue.
- MediaWiki\Message\Converter and MediaWiki\Message\ParamType will need to know about the new types. Perhaps we need a new MessageParam subclass (or several). MessageValue::params(...) may need to know about these types as well.
- ApiResult::validateValue() will need to be able to support the types of value we add. user group names are strings, and UserIdentity can be converted to a string without loss. But a TitleFormatter will be needed to turn PageIdentity and LinkTarget into their external representation.
The parameter values should be formatted follows:
- PageIdentity and LinkTarget: TitleFormatter::getPrefixedText(). We may want to generate links, but let's just do the plain name as a default for now.
- On UserIdentity we can just call getName. We may want to generate a link to the user page, but let's leave that for later.
- For user groups, use the static UserGroupMembership::getGroupName( $group ) method. That should become a service object, but we don't have to worry about that right now.