Multiple FAQ Spaces - Combining into one main page

I would like to know if there is a way to set the {{faq}} macro to include all spaces or to include several spaces like {{faq filter="space=FAQorPublicFAQorAdminFAQ" /}}.

I looked into the code for the {{faq}} macro at FAQMacro.xml - xwiki-contrib/application-faq.

The script uses the LiveTable macro.

To produce a table listing all documents with FAQCode.FAQClass objects from all spaces, not just ${doc.space} when using {{faq filters="space=${doc.space}"/}}, the extraParams field in the options for the livetable macro must be an empty string or removed; however, using {{faq filters=""/}} shows an empty table with no results. Upon further inspect of the {{faq}} macro code, I found the livetable parameter resultPage was set to FAQCode.FAQJSON. From the velocity code, I found an additional filter, filtering the space to the “request” space.

At this point, I realized the {{faq}} macro can not be used to produce the table I desired, as it currently is written; however, I did some copying and minor modifications and was successful! This is what I did:

  1. Make a copy of the FAQHomeClass and FAQHomeSheet pages. I named them AllFAQHomeClass and AllFAQHomeSheet respectively.
  2. Modify the bindings in AllFAQHomeClass objects to use AllFAQHomeSheet as the template.
  3. Replace references in AllFAQHomeSheet referring to FAQHomeSheet to AllFAQHomeSheet
  4. Make a copy of the FAQJSON page. I named it All FAQ JSON (pay attention to spacing in the script below if you decide to change the name). To be sure of the class name, open the page and go to the class option under edit dropdown.
  5. Replace the {{faq}} macro call in AllFAQHomeSheet with the velocity code for the livedata table:
#set($columns = ["doc.title", "doc.creationDate", "doc.date", "_actions"])
#set($columnsProperties = {
  "doc.title" : { "type" : "text", "link" : "view" },
  "doc.creationDate" : { "type" : "date" },
  "doc.date" : { "type" : "date" },
  "_actions" : { "sortable" : false, "filterable" : false, "html" : true, "actions" : ["edit","delete"]}
})
#set($options = { 
   "tagCloud":true,
   "resultPage":"FAQCode.All FAQ JSON",
   "className":"FAQCode.FAQClass",
   "selectedColumn":"doc.creationDate",
   "defaultOrder":"desc",
   "translationPrefix" : "faq.",
   "rowCount": 30
})
#livetable("faqs" $columns $columnsProperties $options)
  1. Replace FAQHomeClass object on desired FAQ homepage with the AllFAQHomeClass object.
  2. Create separate FAQ “sections” using the method outlined here.

This way, you can section off separate topics into different FAQs, allowing you to administrate the sections appropriately for various user groups, appropriately limiting user access rights, while still providing the possibility to combine the results together to create one place to search.

Next Related Steps (for those who might be interested):

  • Create custom FAQ template (right?), where the user has to select the FAQ section to create the FAQ in.
  • Check pages/sections users don’t have access to view do not show up in the combined list. (currently unverified)
  • FAQ section selection similar to tag selection on All FAQ home page.

Other plans:

  • Adding answered field, allowing filtering on whether the FAQs have been answered or not.
  • Implement system that accurately tracks the contribution efforts of team members to properly reward for contribution per our incentive plan we are trying to develop.

Inputs on plans would be greatly appreciated. I hope this modification is helpful to someone else. It’s quite simple but combining the knowledge between the different sources took a bit of figuring out for an unfamiliar and quite inexperienced (I’m 22) programmer.

UPDATE #1:
I added the space as a column of the table, which links to the space as well.

#set($columns = ["doc.space", "doc.title", "doc.creationDate", "doc.date", "_actions"])
#set($columnsProperties = {
  "doc.space" : { "type" : "text", "link" : "space", "filterable" : true},
  "doc.title" : { "type" : "text", "link" : "view" },
  ## ...remaining column properties...
})

## ...remainder is the same...

UPDATE #2:
I tested the following scenario to make sure FAQs restricted from certain users to not show up in the list of All FAQs.

The user does not have access to the AdminFAQ space (page and children). When viewing the All FAQs homepage, this user can view All FAQs from every space they have access to, except the AdminFAQ space, as expected.

Hello, in order to implement your need, you could simply remove the condition based on the space in FAQCode.FAQJSON:

From: #gridresultwithfilter($request.classname $request.collist.split(",") "" " and doc.fullName<>'FAQCode.FAQTemplate' and doc.space='$!request.space'")

To:

#if ("$!request.space" != '')
  #set ($spaceCondition = " and doc.space='$!request.space'")
#end
#gridresultwithfilter($request.classname $request.collist.split(",") "" " and doc.fullName<>'FAQCode.FAQTemplate'$!spaceCondition")

Then {{faq/}} will display all FAQ entries from all the wiki, and if you need to filter for a space you need to use {{faq filter="space=..."/}}.

I think it’s worth opening a feature request at FAQ Application - XWiki.org JIRA

Thanks

Technically, your solution is the simplest solution, if no other differences in formatting are desired. I have decided to make the “All FAQs” page, the one without a space condition, have different formatting than the homepages for the individual FAQ spaces.

I created an improvement request at FAQ-34.