While pages in Confluence can be written in a variety of languages, there is no built-in support for managing and associating these pages (links, by themselves, are not a solution). Add-ons are certainly worth investigating. But add-ons are not always suitable to one's needs or way of working.
For those interested in an alternative approach, this page shows how to manage multi-language content in Confluence using a macro and a simple, yet effective process and organization to coordinate/associate related pages. The method used here is similar in some ways to how Wikipedia does things as described here.
The key points to how content is organized are:
Rather than putting content from different languages into the same space, a different space is used for each language. This maintains clear lines of separation by language.
A site will typically start off with a space in one, local language (e.g., English) and have a meaningful space key for that language. To support the other languages, the original space key is used as a root to which a suffix will be appended to discriminate between languages.
If one is starting completely from scratch, the original space key above may have been named SCIxEN (English) to fully follow the pattern. Regardless, the point is that SCI serves as the root for all related space keys.
As a practical matter, it is unnecessary for all spaces to have corresponding content. That is, it is possible that one space will have content that another/the others do not.
It is also unnecessary for page names or page content to be translated strictly. That is, the goal is to make associations, not force or intimate full equivalence between the pages.
To be able to inform users that a page is related to others, the association between pages in the different spaces needs to be specified somewhere.
One option is to choose a "master" space (e.g., SCI) and keep all the associations there. But, what if there is no page (yet) in the "master" space. One must then either create a holding, but empty, page in the "master" space or do without the associations. Neither of these choices are good.
Another option is to maintain associations in each page. So, the SCI space would have to contain references to SCIxFR (French) and SCIxDE (German); the SCIxFR space would have to keep references to SCI and SCIxDE; and so on. This approach provides the association wanted, but at significant cost. For n spaces, n pages would need to be updated with n-1 entries. This is completely unmanageable and unscalable (see the graph of interlanguage links before Wikidata).
The approach of Wikidata, and the one used here, is to manage associations in a separate, dedicated "data" space. Pages in the data space contain information about the associations and no content. An association, then, is a collection of links to related pages and managed within a single page. As such. there is only one page to update when creating, adding to, or removing from an association.
Following the naming pattern, with a space key root of SCI, the data space would be named SCIx.
The glue between the content spaces and the data space is the macro called incoming.
This macro is passed the data space key and presented on all pages of the content spaces. The easiest way to do this is to make it a component in the sidebar (the header and footer are not as useful for this). The sidebar is configured once for each space, is loaded automatically for each content page, and most importantly, no content page needs to be modified.
To do its work, the macro:
The macro (
## @param DataSpace:title=Space|type=spacekey|required=true ## @param Label:title=Label|type=string|default=|required=false #set ($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager')) #set ($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null)) #set ($containerManager = $getInstanceMethod.invoke(null,null)) #set ($containerContext = $containerManager.containerContext) #set ($linkManager = $containerContext.getComponent('linkManager')) #set ($i = 0) #set ($refpages = $linkManager.getReferringContent($content)) #foreach ($refpage in $refpages) #if ($refpage.getSpaceKey() == "$paramDataSpace") #if ($i == 0) <strong>$paramLabel <a href="$req.contextPath/pages/viewpage.action?pageId=$refpage.getId()">🔗</a></strong><br><br> #set ($i = 1) #end #foreach ( $link in $refpage.getOutgoingLinks()) #set ($dstpagetitle = $link.getDestinationPageTitle()) #set ($dstpagespacekey = $link.getDestinationSpaceKey()) #set ($dstpage = $pageManager.getPage($dstpagespacekey, $dstpagetitle)) <a href="$req.contextPath/pages/viewpage.action?pageId=$dstpage.getId()">$dstpagetitle</a><br> #end #end #end
linkManager.getReferringContent()returns a list of referring pages (from the whole site).
i == 0), a label is output along with a link to the referring page; easy access to the referring page (from the data space) is helpful if one needs to make an update.
refpage.getOutgoingLinks()returns the list of links (i.e., the association) from the data space page.
To demonstrate how this works:
|1||Create the user macro ([[image:attach:Cog.png]] → General configuration → User Macros → Create a User Macro). Copy the macro code to the Template text field.||[[image:attach:managing-multi-language-content-using-confluence--create user macro.png]] [[image:attach:managing-multi-language-content-using-confluence--create user macro 2.png]]|
|2||Create content space SCI.|
|3||Create content space SCIxFR.||[[image:attach:managing-multi-language-content-using-confluence--create SCIxFR space.png]]|
|4||Create data space SCIx.|
|5||Add macro to sidebar for SCI (Space tools → Look and Feel → Sidebar, header and footer).
Add macro to sidebar for SCIxFR.
|[[image:attach:managing-multi-language-content-using-confluence--add macro to sidebar for SCIxFR.png]]|
|7||Create "hello" page in SCI.|
|8||Create "bonjour" page in SCIxFR.|
|9||Create "hello" page in SCIx.|
Add two links in the SCIx "hello" page: