Naming convention for User Interface Extension Points

This topic is a proposal for a naming convention for the identifiers of the User Interface Extension Points (UIXP).

The proposal below is based on existing conversations (here, here, and here) as well as the actual naming of existing UIXP and UIX ( <extensionPointId>.+</extensionPointId> in xml files of the platform).

UIXP naming convention

A UIXP id should be <groupId>.<moduleName>.<uixpQualifier>.

<groupId> must be in the form [a-z]+(\.[a-z]+)* and match the groupId of the module in witch it is first used.

<moduleName> must be in the form [a-z]+ and match the module name, for instance panels for an UIXP declared in xwiki-platform-panels or user.directory for xwiki-platform-user-directory.

<uixpQualifier> must be in the form [a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)* and be descriptive of the intent of the UIXP, especially if a module declared multiple UIXP.

UIX naming convention

Having a strong convention for UIXP ids is critical as they cannot be modified once introduced in a release. Having a naming convention of UIX is not as critical but is still interesting to discuss.

Looking at their use in existing code, the implicit norm tend to follow <groupId>.<moduleName>.<uixQualifier>.

The use of <groupId> and <moduleName> is similar to UIXP.

<uixQualifier> must also be in form [a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)* and be descriptive of the contribution that the UIX does in regard to the UIXP.

WDYT?

Once we reach an agreement, I will report the final naming convention in XWiki’s development documetation.

+1

Example: org.xwiki.platform

Pros:

  • Provides a namespace (e.g. between xwiki github org and xwiki-contrib extensions).

Cons:

  • Makes it harder to move modules around (from xwiki-contrib to xwiki or the opposite). In practice we’ll only be able to make the move if we also introduce the concept of alias.

+1

IMO this leave too much way for interpretation.

I’m proposing to use the following:

  • Single word and with camel case

Rationale:

  • We’re talking about UIXP and thus we don’t need a big naming space with dots
  • Let’s keep dots to separate parts of the id and not put them in each part (note that we have an exception for the full module name that we use).
  • It makes it simpler and we won’t risk devs naming the id differently with one dev using “xxx.menu” and the other “xxxMenu”. We could also decide to not use camel case and use dots. Personally I prefer not dots since it makes it more clear what is the prefix and what is the short UIX id name.

Example:

  • [org.xwiki.platform].[user.profile].menu since we have a single menu but imagine we had 2 menus, we would use: [org.xwiki.platform].[user.profile].xxxMenu and [org.xwiki.platform].[user.profile].yyyMenu.

WDYT?

I’d propose the same the following:

<groupId>.<moduleName>.<short uixp id>.[<qualifier>], with the qualifier being there only if there’s more than 1 UIX for this module for the target UIXP. For example: [org.xwiki.platform].[dashboard].[menu] if we add only 1 entry to the user profile menu. If the dashboard module was adding 2 then it would be [org.xwiki.platform].[dashboard].[menu].[qualifier1] and [org.xwiki.platform].[dashboard].[menu].[qualifier2].

WDYT?

+1 for the short camel case uixpQualifier in UIXP ids.

+1 if by <short uixp id> you mean <uixpQualifier>.

I’m guessing the UIX optional <qualifier> is also a single camel case word?

So according to your example I guess you meant [a-z]+(\.[a-z]+)* since you accept dot in the names.
Trying to take an example: https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/ExtensionPoint/DrawerItem

would became:
org.xwiki.platform.skin.flamingo.resources.drawerMenu

is that correct?
Why not:
org.xwiki.platform.skin-flamingo-resources.drawerMenu?

Besides that I’m +1 with groupId and camel case uixpQualifier.

Now, re UIX:

you mean that it should be the same groupId/moduleName or, they should be chosen the same way?

I don’t a strong opinion in between both alternatives. Using dash removes some ambiguity. In the other hand if find the use of dots nicer, but it’s definitely a question of personal taste.

By that I meant that the use of <groupId> and <moduleName> should always be used relatively to the module in which the id is declared and should conform to the same naming convention (regardless of if it’s an UIX or UIXP).

ok, just to clarify I’m +1 with both solutions, was just wondering :slight_smile:

ok, I was wondering yesterday if it could be helpful to have a common part in the UIX id and its UIXP id but I don’t think so anymore since we need to declare the UIXP we use anyway.

I’ll do a short non-formal summary, mostly for me but I hope it would be useful for others.

UIXP

<groupId>.<moduleName>.<uixpQualifier>

  • <groupId>: reuse maven’s groupId in which the UIXP is declared. lower case, dot separated.
  • <moduleName>: reuse maven’s module in which the UIXP is declared. lower case, dot separated.
  • <uixpQualifier>: descriptive name of the UIXP. Single camel case identifier.

Example: org.xwiki.platform.user.profile.menu

UIX

<groupId>.<moduleName>.<uixpQualifier>(.<uixQualifier>)

  • <groupId>: reuse maven’s groupId in which the UIX is declared. lower case, dot separated.
  • <moduleName>: reuse maven’s module in which the UIX is declared. lower case, dot separated.
  • <uixpQualifier>: reuse the uixpQualifier of the UIXP where the UIX contributes.
  • <uixQualifier>: optional, used only in case of ambiguity, for instance if the UIX is declared in the same module as the UIXP, or if several UIX are declared in the same module. Single camel case identifier.

Examples:
org.xwiki.platform.notifications.menu
org.xwiki.platform.user.profile.menu.userMembership
org.xwiki.platform.user.profile.menu.userNetwork

Small detail: we should always write “xwiki” and not “xWiki”.

EDIT: and in this case we can simply drop the “xwiki” prefix, it doesn’t bring much value… (otherwise we’d also need to write “…xwikiProfile.xwikiMenu.xwikiUserNetwork”… Everything is about xwiki in xwiki land :wink:

+1. I’ve updated the examples in my previous post. Do you agree with my summary after this update?

Sounds good to me.

@tmortagne, @mflorea, @surli, all committers: are we good and can we close this thread and document it on dev.xwiki.org?

Thx

I have an issue with this part. Many UIXP are declared either in xwiki-platform-web or in xwiki-platform-flamingo-skin-resources. I wouldn’t use the skin name in the UIXP name unless the UIXP is really specific to that skin only. That’s not the case for most of the UIXP declared in Flamingo, because Flamingo is just implementing the UIXP that any other skin should implement.

Using “web” in the UIXP name doesn’t sound good to me either, and, as you can see, none of the existing UIXP provided by xwiki-platform-web does that.

I think I addressed this in some proposal in the past and I proposed to use template for UIXP located in platform-web. My rationale was that we should move all templates in a xwiki-platform-template module.

As for the flamingo skin. It makes sense that a UIXP that is specific to a skin (ie the flamingo skin) would have “flamingo” as the module name.

That’s not the case for most of the UIXP declared in Flamingo, because Flamingo is just implementing the UIXP that any other skin should implement.

Then that’s what needs to be fixed. I don’t see the logic of having generic UIXP in the flamingo skin. That needs to be moved back to platform-web.

Not a fan of using the complete groupid for standard XWiki extension points. I would just use org.xwiki, the platform part does not bring any value. It’s also more consistent with Java packages (which is essentially the same need).

The UIXP appear in Velocity template that the Flamingo skin has to overwrite in order to have specific code, e.g. based on Bootstrap. The current practice is to not keep the “original” template in platform web when the Flamingo skin overwrites it (probably because that code wouldn’t be maintained, @gdelhumeau or @evalica to confirm). This means that many UIXP appear only in Flamingo skin templates although they are generic UIXP. So I’m not sure what you propose here.

Yes but I agree with @mflorea that right now being located in the Flamingo skin does not make it specific to the Flamingo skin, it just mean the Flamingo skin (the only skin we have) supports that standard extension point.

Ok but then that doesn’t change anything from the logic defined by @mleduc. It just means that we have a technical debt and that we have UIXP defined in the wrong module (flamingo instead of platform-web) for technical reasons. But since these UIXPs come from another module, they should have the ids of the platform-web module (and I suggest to move them now and use “template”, that’s easy to do - Actually I remember starting this move a long time ago and I don’t recall why I didn’t finish it TBH).

Now regarding the technical debt, I can imagine 3 solutions/ideas:

  • Solution 1: Merge platform-web and flamingo skin and acknowledge that any new skin will either extend flamingo or it’ll copy the flamingo template files and modify them. In practice this is what we said when we said we’d support only 1 skin, and you confirm if when you said that we have generic UIXPs in flamingo. That makes the templates in platform-web unusable as the base for a new skin. Any new skin would need to start from flamingo and have changes made from that.
  • Solution 2: Split the vm files that have UIXP into smaller vm files and have flamingo include them so that all generic UIXP are defined in platform-web, and more generally prevent most code duplication in this manner.
  • Solution 3: Decide that bootstrap should go in platform-web and that it’s a core tech we use (we do anyway), and thus move back some vm files from flamingo (and their UIXPs) to platform-web.

My understanding is that solution 1 is the one that corresponds best to the real current situation we’re in. Marius even mentioned that “probably because that code wouldn’t be maintained” which shows that our platform-web part is really not maintained and usable without flamingo anyway.

WDYT?

The only solution long term is 2 IMO but it requires some refactoring work. If we do 1 now we’ll hit the issue again later when we develop a new skin.

Actually to be complete, there’s also:

  • Solution 4: reimplement everything with UIXPs. Specifically this means having all UIXPs located in platform-web and even add more UIXPs there so that a skin is only a set of UIXs.

TBH I don’t think we’ll ever be able to do that and even less maintain it. In term of effort, it’s very similar to saying that we maintain 2 skins and we would need to define what is a minimal skin and we have no clue what this is. For example, should the concept of panels on the side be part of platform-web? What about a skin that wouldn’t want them? So we could push the minimal idea to the extreme. IMO everything we see in the UI is the flamingo skin and there’s no need to have a “common” set of templates because I don’t think that it makes sense (the concept of “common” doesn’t exist). As I said above, anyone wanting to create a new skin would either extend the flamingo skin and make the modifications they want by overriding stuff or create a new skin from scratch by copying the template files in another directory and refactoring for their needs.

BTW our current situation is also bad for macros.vm that we regularly forget to sync.

So for me the only real solution is solution 1.

Not sure what you mean, macros.vm is not duplicated (it’s appended, not overwritten).

Check the livetable macro for example (you’ll find that 99% of it is duplicated).