User defined shortcuts: storage implementation

Problem

In order to add user defined shortcut settings, we need a storage implementation that can easily be extended (so that extensions can add customization for their own shortcuts). The shortcuts used to be stored as a key-value translation pair. This system has quite some limitations when we want every user to be able to pick their own shortcuts. The main one is that as far as I know there’s no clear priority system for the same translation key with different values coming from different files (we’d need at least priority between the default and the user preference).

Proposed solution of storage

Instead of adding additional properties to the user object, I decided to store shortcut preferences in a different object. Those XWiki.UserPreferenceShortcutsClass objects are contained on each user page.

Each UserPreferenceShortcut has two fields:

  • a translationKey that contains the translation key used to store the shortcut. This translationkey model for shortcut is already implemented and IMO it’s okay to keep working with it as a fallback and its key as an unique identifier for each shortcut.
  • a value that contains the value of the shortcut defined by the user, the one that would override the default provided at the wiki level

In order to make it work properly, we expect the shortcut preference object to be on the page of the user it’s defined for. Moving them around would break them.

UserPreferenceShortcuts are udpated live when the user edits their profile preferences.

If a preference is set to be empty, the shortcut will be unbound (no way to activate the action from the keyboard). If a preference is set to be the same value as the default value (the one from the translation), the UserPreferenceShortcuts is removed. There is only one UserPreferenceShortcuts per user per translationKey. There might be as much UserPreferenceShortcuts as there are shortcuts for each user. By default, there is no UserPreferenceShortcuts on a user profile.

This model allows to keep the amount of stored data to a minimum, there are no field stored that do not contain any information.

Conclusion

What do you think of this implementation for the storage of user shortcut preferences?
Do you think another solution would be more appropriate? Did you spot a weakness in this implementation that should be addressed?

Thank you in advance for your feedback and help!
Lucas C.

Extra resources

You can view the whole implementation proposal at https://design.xwiki.org/xwiki/bin/view/Proposal/Implementinguserpreferenceshortcuts . The position of this UI has been discussed on Shortcut settings position . The design is under discussion at XWIKI-16216: Allow users to rebind the shortcuts from their user profile UI by Sereza7 · Pull Request #2981 · xwiki/xwiki-platform · GitHub .

That’s not exactly true. org.xwiki.localization.TranslationBundle components (what translation resources actually are once they are loaded) do have a priority. TranslationDocumentClass xobjects don’t expose one currently, but it would be easy to add it.

Right now, the default priorities are:

  • ApplicationResources: 1000
  • TranslationDocumentClass pages: 900
  • Translation pages explicitly listed in XWikiPreferences: 300

(as usually with priorities in XWiki, the lowest priority wins)

1 Like

I think the main limitation with shortcuts based on translations is that they require script right and aren’t straightforward to create for a user (you need to use the object editor). Further, in multilingual wikis, you’ll need to customize the shortcuts again for every language you’re using. Therefore, I think it is a good idea to introduce shortcuts stored in XObjects on the user profile. The proposed XClass sounds reasonable to me.

1 Like

Yes, using a standard TranslationDocumentClass may not be the best for users, the point of my previous message was mainly to give a more accurate information.

One thing that could still be interesting is to load/expose the proposed UserPreferenceShortcuts xobjects into a high priority TranslationBundle, if that makes the implementation easier (I did not really check how shortcuts are actually working right now) and potentially more retro-compatible. But that’s provided there is a protection to make sure that nobody can inject anything else than shortcuts keys in those xobjects.

You mean if the value property of the XWiki.UserPreferenceShortcutsClass object is left empty?

How do you plan to “publish” the information from the XWiki.UserPreferenceShortcutsClass objects as shortcut keys? With an event listener that catches changes to the user profile documents and looks for the presence of XWiki.UserPreferenceShortcutsClass objects? What do you do with the information from these objects? Create a translation bundle on the fly? You’d have to register it for all supported languages so that the shortcut keys work also when the user changes the UI locale.

Thanks,
Marius

:+1:
I didn’t know how we could publish all the changes at once on the preference page save (number of items can change, we could need to delete, update and create a lot of items all at once). So I went with this ‘live update’ solution, which looked easier to implement with my experience.

I created a velocity macro getShortcutValue that queries the objects from the current user with the appropriate translationKey field. If there’s one, it returns this value, else it just returns the actual translation value.
All the places where we used the translation values, I replaced it with a call to this velocity macro instead. Everywhere where this call isn’t updated still works as it did before (nothing breaks), but it won’t take advantage of this new feature. This would make sure we keep compatibility with non-updated extensions.

Let me know if there’s still something I failed to explain clearly :slight_smile:
Thank you for your interest in the question,
Lucas C.

1 Like

Sounds good to me then.

Since nothing against the solution proposed emerged from this brainstorming, I’ll continue with the solution proposed in the topic. Feel free to add anything to this discussion even if it’s closed. The solution will not be merged instantly. See the current state of the PR at XWIKI-16216: Allow users to rebind the shortcuts from their user profile UI by Sereza7 · Pull Request #2981 · xwiki/xwiki-platform · GitHub