There is 1 comment.
 
 
XWiki Platform / cid:jira-generated-image-avatar-562c5a07-1a31-4347-8d45-d58b8b08426a XWIKI-20623 Open

JS function XWiki.Document#getURL does not take into account the wiki name

 
View issue   ยท   Add comment
 

1 comment

 
cid:jira-generated-image-avatar-199953d7-d12b-4b1a-a505-1d5903ab8207 Simon Urli on 15/Oct/26 09:18
 

Still valid on master, and not fixed by XWIKI-25222 (which only changed locationPicker.js). Here is a proposed approach.

Why the wiki can't simply be injected client-side

getURL fills XWiki.Document.ViewURLTemplate / URLTemplate, which xwiki.js renders with $xwiki.getURL('__space__.__page__', ...), so they are always for the current wiki. Unlike the REST template, a __wiki__ placeholder is not enough, because the URL prefix depends on the wiki descriptor (see XWiki#getServletPath and XWikiServletURLFactory#getServerURL):

  • main wiki: /xwiki/bin/view/...
  • path-based subwiki: /xwiki/wiki/<defaultAlias>/view/... (the descriptor's default alias, not the wiki id)
  • domain-based subwiki: an absolute URL on the descriptor's host

Proposed fix

  1. Keep a per-wiki cache of URL templates, e.g. XWiki.Document.URLTemplates mapping each wiki id to its view/action template pair, pre-filled in xwiki.js for the current wiki with today's values. URLTemplate / ViewURLTemplate stay for backward compatibility (used by locationPicker.js and possibly extensions).
  2. getURL picks the template matching this.wiki. If it's not cached, it falls back to today's behaviour and logs a console.warn. Same-wiki calls, i.e. almost all of them, are unchanged.
  3. Add a small server endpoint (an xpage template or a REST resource) returning the template pair for given wikis, rendered with the following (plus the view variant):
    $xwiki.getURL($services.model.createDocumentReference($wiki, '__space__', '__page__'), '__action__')
    

    This handles path/domain mode, aliases and short URLs, and returns 404 for unknown wikis.

  4. Add an async loader, e.g. XWiki.Document.loadURLTemplates(wikis) returning a Promise that fills the cache, and/or a getURLAsync(). Cross-wiki code (pickers, tree, suggest) calls it before getURL. Making getURL itself fetch is ruled out since synchronous XHR is deprecated.

Rejected alternatives:

  • Rendering the templates of every wiki into xwiki.js: costs O(number of wikis) on every page, and farms can have thousands of wikis.
  • Using xwikiRelativeUrl from the REST page resource: one request per page, and only works for existing pages the user can view, which breaks the create/copy pickers that need URLs of pages that don't exist yet.

Tests

  • Unit test (vitest, using the setup added in xwiki-platform-web-war/src/test/node for XWIKI-25222) for the template selection per wiki, the fallback and the cache loading. Since xwiki.js is Velocity-filtered, it's probably easier to move that logic to a plain module.
  • A docker functional test for the server part, since its output depends on the multiwiki configuration: compute getURL() for a page of a subwiki and check that it leads to that subwiki.