Last modified by Simon Urli on 2023/10/10

Hide last authors
Ricardo Rodríguez 52.1 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
Vincent Massol 1.1 4
Simon Urli 122.3 5 This tutorial will show you how to build a Frequently Asked Questions (FAQs) [[Application>>xwiki:Documentation.UserGuide.Features.Applications]] much like the one you can find on the [[FAQ page>>FAQ.WebHome]]. This is a very simple application that makes use of XWiki's [[classes, properties, and objects>>xwiki:Documentation.DevGuide.DataModel||anchor="HXWikiClasses2CObjects2CandProperties"]]. It also uses a technique that you may frequently use as the basis for several different kinds of applications.
Vincent Massol 96.1 6
Ecaterina Moraru (Valica) 105.1 7 {{info}}
Fawad Ali 117.1 8 It's also possible to follow this tutorial as a [[video tutorial on Youtube>>https://youtu.be/tIzASeJb2Bs]].
Ecaterina Moraru (Valica) 105.1 9 {{/info}}
Vincent Massol 103.1 10
Vincent Massol 96.1 11 = Prerequisites for following the tutorial =
12
Vincent Massol 95.1 13 {{warning}}
Ecaterina Moraru (Valica) 102.1 14 If you've already followed the [[AWM FAQ Tutorial>>Documentation.DevGuide.FAQTutorial.FAQTutorialAWM]] or installed the [[FAQ Application>>extensions:Extension.FAQ Application]] you'll need to do one of 2 things before you can take this tutorial:
Fawad Ali 117.1 15
Vincent Massol 95.1 16 * Delete the ##FAQ## space (if you've followed the AWM FAQ Tutorial) or uninstall the FAQ Application (if you've installed the FAQ Application)
17 * or simply follow the tutorial below but replace the space ##FAQ## with another value everywhere it's used. For example use ##MyFAQ## as the space name instead.
18 {{/warning}}
19
Simon Urli 122.3 20 You should have [[installed XWiki>>xwiki:Documentation.AdminGuide.Installation]] and have a [[basic understanding of how to use it>>xwiki:Documentation.UserGuide.Features.WebHome]].
Vincent Massol 54.2 21
Simon Urli 122.3 22 All through this tutorial you should refer to the [[XWiki Data Model>>xwiki:Documentation.DevGuide.DataModel]] for information on XWiki's data model. You might also use the [[XWiki Scripting Guide>>xwiki:Documentation.DevGuide.Scripting]] to get you started with scripting in XWiki and manipulating XWiki objects. In addition, this tutorial will introduce the concepts of Authoring Templates and Page Design Sheets, patterns that you will find particularly useful in creating XWiki applications. Completing this tutorial is a recommended prerequisite for anyone who wants to build custom applications on the XWiki engine.
Vincent Massol 54.3 23
Vincent Massol 100.3 24 {{warning}}
Simon Urli 122.3 25 Make sure that your user is an [[Advanced user>>xwiki:Documentation.UserGuide.Features.PageEditing||anchor="HAdvancedMode"]] before following this tutorial since you'll need for example to use the wiki editor (##Wiki > Edit## menu).
Vincent Massol 100.2 26 {{/warning}}
27
Silvia Macovei 48.2 28 = Application Overview =
Vincent Massol 1.1 29
Guillaume Lerouge 42.1 30 The FAQ application allows users to post a question by entering the question into a simple form field and then submitting the form. The question then appears in a list along with all other questions that have been previously posted. Users can click on the questions to view both the question and answer in a consistently styled view. If the question has not yet been answered, any user can post an answer to the question by editing the page. In edit mode, the page will display a web form that is the same for every FAQ page.
Vincent Massol 1.1 31
Manuel Smeria 80.1 32 Let us begin by taking a look at what we are going to build. The new application will have the following views:
Vincent Massol 1.1 33
Vincent Massol 112.1 34 * The FAQ [[Class>>FAQ.WhatIsAClass]](((
Vincent Massol 111.1 35 {{image reference="FAQsSummary.png"/}}
Vincent Massol 112.1 36 )))
37
Marius Dumitru Florea 115.1 38 * An FAQ entry in View mode (notice that the properties can be edited in-place starting with XWiki 12.4RC1)(((
Vincent Massol 111.1 39 {{image reference="FAQSheetView.PNG"/}}
Vincent Massol 112.1 40 )))
41 * An FAQ entry in Edit mode(((
Vincent Massol 111.1 42 {{image reference="FAQSheetEdit.PNG"/}}
Vincent Massol 112.1 43 )))
Hassan Ali 110.1 44
Silvia Macovei 48.2 45 = Authoring Templates and Page Design Sheets =
Silvia Macovei 48.1 46
Anca Luca 14.1 47 An Authoring Template is a template for creating documents of a specific type. Unlike a regular content page in edit mode with one field for freeform editing, an Authoring Template presents a custom set of form fields for creating a document with specific type of data. These form elements are defined by the properties of a class.
Vincent Massol 1.1 48
Silvia Macovei 48.1 49 In object oriented programming, remember that a //class// is a template for an object. Using the analogy of a cookie cutter, the //class// is the //cookie cutter// and the //objects// are the actual //cookies//. An Authoring Template provides one way to represent a class visually so that users can fill out a form to set unique properties (values in form fields). When the user submits the form, they are creating a unique //object// of the //class// type.
Vincent Massol 1.1 50
Sergei Kulagin 117.2 51 Precisely, an Authoring Template is a prototype document used to create other specific instances of documents of the same type, along with a method of exposing the creation process to the user: the properties edit form. Remember that an XWiki Document can contain objects and this is the case of an authoring template: it is an XWiki Document with an empty object of a specific class, which is duplicated to create more and more documents based on that model, using the data inserted by the user in the editing form as specific values for the particular object instance in the current copy.
Vincent Massol 1.1 52
Silvia Macovei 31.6 53 The Page Design Sheet is like a style sheet that defines what each document will look like when rendered. Even though the unique object instances will have different values for their properties, they will always have a consistent presentation display because they will be rendered through the Page Design Sheet. The XWiki API available in scripting languages provides a mechanism that will help us use the same sheet for both editing and view modes. We will see how we can achieve this once we get to the FAQ Design Sheet section.
Vincent Massol 1.1 54
Silvia Macovei 48.2 55 = Go to the Class Editor Wizard =
Silvia Macovei 31.6 56
Sergei Kulagin 117.2 57 Five pages, which collectively make up an [[XClass application>>extensions:Extension.XClass Application]] (a.k.a Class Wizard or Class Editor Wizard), have been developed to assist you in this process. Those page are technical pages hidden by default. To navigate to the wizard home page, go to your profile page, select the Preferences tab, edit the page and choose to view Hidden Documents. Enter a search query for the keyword "XWikiClasses". This should return a document called ##XWikiClasses## in the ##XWiki## space (i.e. ##XWiki.XWikiClasses##). (Note that the //title// of this document is "Data types".) This is the homepage of the class wizard creator: you are now ready to start building your FAQs application.
Vincent Massol 1.1 58
Silvia Macovei 48.2 59 = Create the FAQ Class =
Vincent Massol 1.1 60
Vincent Massol 111.1 61 * On the Class Editor wizard entry page (XWiki.XWikiClasses), under the heading "Create a new data type", in the "Title" field, enter ##FAQ## as the name of the page to create:(((
Vincent Massol 84.3 62 {{image reference="CreateANewClass1.png"/}}
Silvia Macovei 48.4 63 )))
Sergei Kulagin 117.3 64 * As you can see in the Breadcrumb below the new page will be created at location ##XWiki > FAQ##. In practice the Class Wizard will automatically add the suffix **//##Class ##//**to the page name(you could also enter ##FAQClass## as the page name directly).
Vincent Massol 111.1 65 * Now it would be nice to have it created in a new location such as ##FAQ > FAQ Class##. Since the ##FAQ## parent doesn't exist we cannot use the Tree picker button. Thus click the Pencil button as shown in the following image and replace ##XWiki## by ##FAQ##.(((
Vincent Massol 84.3 66 {{image reference="CreateANewClass2.png"/}}
67 )))
Vincent Massol 96.2 68 * In technical terms you're creating a page named ##FAQClass## (with a title of "FAQ Class") located in a space also called ##FAQ## and thus the technical reference is ##FAQ.FAQClass##.
Manuel Smeria 80.1 69 * Click the "Create this Class" button. You should then see a page with the following content:(((
Silvia Macovei 48.1 70 {{code language="none"}}
Silvia Macovei 41.1 71 {{velocity}}
Jean SIMARD 60.6 72 ## Replace the default space with the space where you want your documents to be created.
Silvia Macovei 41.1 73 ## Replace the default parent with the one of your choice and save the document.
74 ##
Jean SIMARD 60.6 75 #set($defaultSpace = $doc.space)
76 #set($defaultParent = $doc.fullName)
Silvia Macovei 41.1 77 {{/velocity}}
Silvia Macovei 48.1 78 {{/code}}
Silvia Macovei 48.4 79 )))
Anca Luca 14.1 80
Manuel Smeria 80.1 81 In the code, change the word "$doc.space" with the name of the space where you want you FAQ pages to be created as the commented instructions in the page code suggest.
82 The line of code should look like this:
Vincent Massol 1.1 83
Ricardo Rodríguez 52.1 84 {{code language="none"}}
85 #set($defaultSpace = 'FAQ')
86 {{/code}}
Anca Luca 14.1 87
Manuel Smeria 80.1 88 You can also change the default parent of the new FAQ documents that are going to be created. To do so, replace the "$defaultParent" variable with the name of your document.
89 The line of code should look like this:
Vincent Massol 1.1 90
Ricardo Rodríguez 52.1 91 {{code language="none"}}
92 #set($defaultParent = 'FAQ.WebHome')
93 {{/code}}
Vincent Massol 1.1 94
Guillaume Lerouge 42.1 95 Click the "Save & View" button. The class is now created and you should be looking at a page titled "Class: FAQ" that looks like this:
georgosn 28.1 96
Manuel Smeria 80.1 97 {{image reference="FAQClass1.PNG"/}}
georgosn 29.1 98
Silvia Macovei 48.2 99 = Add Properties to the Class =
Vincent Massol 1.1 100
Silvia Macovei 48.3 101 Under the page title, you should see the words "The class does not have any properties yet. You can use the //__class editor__// to define them." Let's just follow those instructions!
Vincent Massol 1.1 102
Manuel Smeria 80.1 103 * Click on the 'class editor' link
Vincent Massol 92.2 104 * Note that the link trail in the header is something like "Wiki Home / FAQ / FAQ Class". This shows you that you are indeed on the FAQ class page in Class edit mode.
Vincent Massol 1.1 105
Vincent Massol 92.3 106 In our document, we'll store both a //question// and an //answer//. So we need to create a property for each of them.
Vincent Massol 1.1 107
Manuel Smeria 80.1 108 * Enter the text //question// in the "name" field
Vincent Massol 111.1 109 * Choose a TextArea type for the property and then click on "Add". The TextArea will ultimately give us a multi-line text field in our authoring template.(((
Manuel Smeria 80.1 110 {{image reference="AddQuestionProperty.PNG"/}}
Silvia Macovei 48.4 111 )))
Manuel Smeria 80.1 112 * Click on the "+" icon to expand the options for the newly created property
Vincent Massol 111.1 113 * Change the value of the "Pretty Name" field to "Question"(capital Q):(((
Manuel Smeria 80.1 114 {{image reference="QuestionProperty.PNG"/}}
Silvia Macovei 48.4 115 )))
Manuel Smeria 80.1 116 * Now create another property called //answer// the same way that you did for the previous "question" property (choose TextArea for the property type)
117 * Expand it from the property list and change the value of the "Pretty Name" field to "Answer"
118 * When you are done adding and configuring the properties, click the "Save & View" button
Vincent Massol 1.1 119
Silvia Macovei 48.2 120 = Create the Page Design Sheet =
Vincent Massol 1.1 121
Vincent Massol 111.1 122 * After the previous step you are now on the FAQClass page which should look like this:(((
Manuel Smeria 80.1 123 {{image reference="FAQClass2.PNG"/}}
Silvia Macovei 48.4 124 )))
Manuel Smeria 80.1 125 * Click the first button ("Create the document sheet") to create the document sheet (the Page Design Sheet). This sheet determines how your page's objects will be rendered to the user. The document is automatically created.
Vincent Massol 92.4 126 * You should see a warning message with the text "The sheet is not bound to the class so it won't be applied automatically when a page that has an object of this class is displayed". Click the "Bind the sheet to the class" link that appears after the text. **What this does is important**:
Ogis Tarkan 98.1 127 ** It adds an object of type ##XWiki.ClassSheetBinding## to the ##FAQ.FAQClass" document. Basically it ties the FAQ Class to the Sheet.##
Vincent Massol 92.4 128 ** **It's because of this object that users will be sent to form edition mode when editing FAQ entries**
Vincent Massol 111.1 129 * Now click on "View the sheet document". This takes you to the ##FAQ.FAQSheet## page which you can edit in wiki mode and see its default content:(((
Silvia Macovei 48.1 130 {{code language="none"}}
Silvia Macovei 41.1 131 {{velocity}}
132 ## You can modify this page to customize the presentation of your object.
133 ## At first you should keep the default presentation and just save the document.
Anca Luca 14.1 134
Marius Dumitru Florea 116.1 135 ## We have to use wiki=true because $doc.display() can produce wiki syntax.
136 {{html wiki="true" clean="false"}}
137 ## Load the JavaScript code required to make the object properties editable in-place.
138 #set ($discard = $xwiki.jsfx.use('uicomponents/edit/editableProperty.js', {
139 'forceSkinAction': true,
140 'language': $xcontext.locale
141 }))
142 #set ($editing = $xcontext.action == 'edit')
143 ## The object to display.
144 #set ($xobject = $doc.getObject('FAQ.FAQClass'))
145 ## The class that describes the object properties.
146 #set ($xclass = $xobject.xWikiClass)
147 ## Make sure the following display* method calls use the right object.
148 #set ($discard = $doc.use($xobject))
149 ## Using the xform vertical form layout.
150 <div class="xform">
151 <dl>
152 #foreach ($property in $xclass.properties)
153 <dt #if (!$editing && $hasEdit)
154 class="editableProperty"
155 #set ($xobjectPropertyReference = $xobject.getProperty($property.name).reference)
156 data-property="$escapetool.xml($services.model.serialize($xobjectPropertyReference))"
157 data-property-type="object"#end>
158 ## This must match the id generated by the $doc.display() method below.
159 #set ($propertyId = "${xclass.name}_${xobject.number}_$property.name")
160 <label#if ($editing) for="$escapetool.xml($propertyId)"#end>
161 $escapetool.xml($property.translatedPrettyName)
162 </label>
163 ## Support for specifying a translation key as hint in the property definition.
164 <span class="xHint">$!escapetool.xml($services.localization.render($property.hint))</span>
165 </dt>
166 <dd>$doc.display($property.name)</dd>
167 #end
168 #if (!$xclass.properties || $xclass.properties.size() == 0)
169 ## Keep the empty definition term in order to have valid HTML.
170 <dt></dt>
171 <dd>$escapetool.xml($services.localization.render('xclass.defaultObjectSheet.noProperties'))</dd>
172 #end
173 </dl>
174 </div>
175 {{/html}}
Silvia Macovei 41.1 176 {{/velocity}}
Silvia Macovei 48.1 177 {{/code}}
Guillaume Lerouge 42.1 178
Marius Dumitru Florea 116.1 179 Let's take a moment now and analyze this code:
Silvia Macovei 48.1 180
Marius Dumitru Florea 116.1 181 * first, it loads the JavaScript required for in-place editing
182 * then it retrieves the FAQ object from the current page and the FAQ class defintion
183 * then it iterates through all the FAQ class properties displaying:
184 ** the translated pretty name
185 ** the translated hint
186 ** the value from the FAQ object in view mode, or the form field used to input or modify the value in edit mode
187 * it uses a definition list to display the FAQ object, following the [[Vertical Form>>xwiki:Documentation.DevGuide.FrontendResources.VerticalForms.WebHome]] layout
188
189 As we mentioned, XWiki provides a mechanism that helps us create sheets used for both view and edit mode. This is the ##display## function used in the line:
190
Manuel Smeria 83.1 191 {{code language="none"}}
Marius Dumitru Florea 116.1 192 <dd>$doc.display($property.name)</dd>
Manuel Smeria 83.1 193 {{/code}}
Silvia Macovei 48.1 194
Marius Dumitru Florea 116.1 195 It detects the current mode (edit or view) and displays the property referenced by its argument as the mode dictates:
Manuel Smeria 80.1 196
Marius Dumitru Florea 116.1 197 * in view mode it will display the value of the property
198 * in edit mode it will display a form field that will allow the user to edit it
Guillaume Lerouge 42.1 199
Simon Urli 122.3 200 This way we can use a single Design Sheet to both display and edit our FAQ entries. See the [[XWiki API reference>>xwiki:Documentation.DevGuide.API]] and [[XWiki Scripting>>xwiki:Documentation.DevGuide.Scripting]] pages for more details about this.
Marius Dumitru Florea 116.1 201 )))
Guillaume Lerouge 42.1 202 * Click "Save & View"
203
Silvia Macovei 48.2 204 = Create the Authoring Template =
Vincent Massol 1.1 205
Vincent Massol 111.1 206 * Navigate back to the ##FAQ.FAQClass## document (you can use the arrows in the breadcrumb to do so). The document should look like this:(((
Manuel Smeria 80.1 207 {{image reference="FAQClass3.PNG"/}}
Silvia Macovei 48.4 208 )))
Manuel Smeria 80.1 209 * Click on the "Create the document template" button. The Authoring Template will be automatically created.
Vincent Massol 1.1 210
Simon Urli 122.3 211 Note that earlier, we changed the space name preceding the page name because we wanted all of our FAQ pages to reside in a space named FAQ. Remember that all our documents will be copies of the Authoring Template used as a prototype so the content will be copied in all our FAQs documents and will execute the Design Sheet code in the context of the current document. See the [[dedicated page>>xwiki:Documentation.DevGuide.IncludeInVelocity]] for more information regarding this technique.
Guillaume Lerouge 42.1 212
Vincent Massol 92.8 213 Now we need to associate the prototype object with this document to turn it into a true authoring template:
214
215 * If you're on the template page, navigate back to the ##FAQ.FAQClass## document.
216 * At the bottom of the page, look for the following warning message: "The template does not contain an object of type FAQClass. Add a FAQ object to the template »."
Vincent Massol 111.1 217 * Click on "Add a FAQ object to the template »":(((
Manuel Smeria 80.1 218 {{image reference="FAQObject.png"/}}
219 )))
Manuel Smeria 83.1 220
Vincent Massol 92.8 221 Next, we want to remove the title for the newly created template:
Manuel Smeria 83.1 222
Vincent Massol 92.8 223 * Navigate to the ##FAQ.FAQTemplate## document (you can click on the "View the template page (FAQ / FAQ Template)" link for doing that for example.
Manuel Smeria 83.1 224 * Edit this document in Wiki mode
225 * Inside the Title field you have "FAQ Template" written -> delete this text
226 * Save & View
227
228 This step is needed so that all of our future entries don't have "FAQ Template" as their title.
229
230 Congratulations: you just created an Authoring Template! You're almost done now.
Vincent Massol 92.8 231
Manuel Smeria 80.1 232 {{image reference="FAQClass4.PNG"/}}
Ricardo Rodríguez 52.1 233
Alex Cotiugă 105.2 234 = Create the Template Provider =
235
Alex Cotiugă 105.3 236 After the template was created and the object was added, a new section appears with a button to create a template provider to use the existing template.
237 The template provider is created with some default values, but those can be updated to match the needs.
Alex Cotiugă 105.2 238
Alex Cotiugă 107.2 239 {{gallery}}
Alex Cotiugă 108.2 240 image:3-missingTemplateProvider.png
Alex Cotiugă 107.2 241 image:4-addedTemplateProvider.png
242 image:5-templateProviderView.png
243 {{/gallery}}
244
245
Silvia Macovei 48.2 246 = Create a home page for the FAQ application =
Silvia Macovei 38.1 247
Guillaume Lerouge 42.1 248 You want your users to be able to see a list of all existing questions and answers and to add new questions. The best way to do this is to put the FAQ application in its own space and to use that space's homepage to display existing questions.
Vincent Massol 1.1 249
Vincent Massol 93.1 250 Thus we now need to create the ##FAQ.WebHome## page
Vincent Massol 1.1 251
Vincent Massol 93.1 252 * Click on "FAQ" in the breadcrumb to navigate to ##FAQ.WebHome## and notice that the page doesn't exist.
253 * Edit it in wiki mode
254 * Type in the title "FAQs"
255
Silvia Macovei 48.2 256 == Displaying existing FAQ entries ==
Vincent Massol 1.1 257
Manuel Leduc 122.1 258 You have 3 options when it comes to displaying existing FAQ entries:
Guillaume Lerouge 55.2 259
Manuel Leduc 119.1 260 1. Use the [[Live Data macro>>extensions:Extension.Live Data Macro.WebHome]]
261 1. Use the [[Livetable component>>extensions:Extension.Livetable Macro]] {{warning}}Not described below as LiveData is now the advised option{{/warning}}
Manuel Smeria 80.1 262 1. Write custom code in order to display them
263
Manuel Leduc 119.1 264 === Using the Live Data macro ===
Guillaume Lerouge 55.2 265
Manuel Leduc 119.1 266 In this section, we will show how to use the [[Live Data macro>>extensions:Extension.Live Data Macro.WebHome]] to display the existing questions.
Guillaume Lerouge 55.2 267
Manuel Leduc 119.1 268 The Live Data macro will give users the ability to easily list and filter through existing FAQ pages. The macro parameters defines:
Guillaume Lerouge 56.1 269
Manuel Leduc 119.1 270 * the id of the table
271 * the source ##liveTable## is a bridge to reuse existing Livetable sources
272 * the list of properties to display
273 * the source parameters defines addition parameters specific to the ##liveTable## source: the translation prefix to use, and the XClass to list
Guillaume Lerouge 56.1 274
Manuel Leduc 119.1 275 In addition, the body of the macro defines additional display customizations. We use a ##link## displayer to wrap the question with a link to the page containing the FAQ XObject.
Guillaume Lerouge 56.1 276
Manuel Leduc 119.1 277 {{code language='none'}}
278 {{liveData
279 id="faq"
280 source='liveTable'
281 properties='question,doc.creationDate,_actions'
282 sourceParameters="translationPrefix=faq.&className=XWiki.FAQClass"
283 }}{
284 "meta": {
285 "propertyDescriptors": [
286 {
287 "id": "question",
288 "displayer": {"id": "link", "html": true}
289 }
290 ]
291 }
292 }{{/liveData}}
Guillaume Lerouge 55.2 293 {{/code}}
294
Vincent Massol 93.1 295 * Copy this code and paste it as Wiki content (inside ##FAQ.WebHome##)
Guillaume Lerouge 56.1 296 * Click "Save and View"
297 * New FAQ entries will now be displayed on the page once you create them
298
Vincent Massol 93.1 299 The ##FAQ.WebHome## page should look similar to this:
Manuel Smeria 80.1 300
Manuel Leduc 121.1 301 {{image reference="FAQsLiveData.png" width='960'/}}
Manuel Smeria 80.1 302
Vincent Massol 122.2 303 Notice how there are some translation keys displayed inside the Live Data table. Let's create a translations document and change those keys to actual text:
Manuel Smeria 83.1 304
Vincent Massol 93.1 305 * Create a new page inside the FAQ space called Translations, i.e. at ##FAQ.Translations## (using the "+" button)
Manuel Smeria 80.1 306 * Edit it in Wiki mode and paste this content inside:(((
307 {{code language="none"}}
308 faq.question=Question
309 faq.doc.creationDate=Creation Date
310 faq._actions=Actions
Manuel Smeria 83.1 311 {{/code}}
312 )))
Vincent Massol 93.1 313 * Click "Save & View"
314 * Edit it again in Object mode and add a new ##XWiki.TranslationDocumentClass## object to mark the page as a page containing translations. Make sure to select the right scope. Using "Global" means the translations would be visible to all wikis (and it requires having Programming Rights!) and "Wiki" means it's visible to the current wiki only. Choose "Wiki" as the scope.
315 * Click "Save & View" again
Manuel Smeria 80.1 316
Vincent Massol 93.1 317 Now the ##FAQ.WebHome## page should look like this (notice the translations instead of the keys):
Manuel Smeria 80.1 318
Manuel Leduc 121.1 319 {{image reference="FAQsLiveDataWithTranslations.png" width='960'/}}
Manuel Smeria 80.1 320
Guillaume Lerouge 55.2 321 === Using custom code ===
322
Guillaume Lerouge 42.1 323 You will need to write the following code:
Vincent Massol 1.1 324
Sergei Kulagin 117.2 325 * An XWQL query that will find all your FAQ documents. Check the [[Query API documentation>>extensions:Extension.Query Module]] to know more about it.
Vincent Massol 93.1 326 ** The XWQL query looks for all documents that have a ##FAQ.FAQClass## object other than the template
Guillaume Lerouge 42.1 327 ** If no document has been created yet, a warning message is displayed
Guillaume Delhumeau 59.2 328 * A piece of velocity code to display all those documents
Guillaume Lerouge 42.1 329 ** The velocity code loops in that list
330 ** For each item, the full document is loaded in memory so that values can be retrieved from it
331 ** For each document, the question is retrieved and displayed as a link towards the FAQ entry
Vincent Massol 1.1 332
Manuel Smeria 80.1 333 Here is the resulting code:
Vincent Massol 1.1 334
Silvia Macovei 48.1 335 {{code language="none"}}
Guillaume Lerouge 42.1 336 = Existing FAQ entries =
Vincent Massol 1.1 337
Guillaume Lerouge 42.1 338 {{velocity}}
Vincent Massol 93.1 339 #set($xwql = "from doc.object(FAQ.FAQClass) as faq where doc.fullName <> 'FAQ.FAQTemplate'")
340 #set($results = $services.query.xwql($xwql).execute())
Guillaume Lerouge 42.1 341 #if($results.empty)
Thibaut Camberlin 49.1 342 No FAQ has been created yet!
Guillaume Lerouge 42.1 343 #else
Thibaut Camberlin 49.1 344 #foreach ($item in $results)
345 #set($faq = $xwiki.getDocument($item))
Thibaut Camberlin 51.1 346 * [[${faq.display("question").replace("<p>", "").replace("</p>", "")}>>${item}]]
Thibaut Camberlin 49.1 347 #end
Guillaume Lerouge 42.1 348 #end
349 {{/velocity}}
Silvia Macovei 48.1 350 {{/code}}
Vincent Massol 1.1 351
Vincent Massol 93.1 352 * Copy this code and paste it as Wiki content inside ##FAQ.WebHome##
Guillaume Lerouge 42.1 353 * Click "Save and View"
354 * New FAQ entries will now be displayed on the page once you create them
Vincent Massol 1.1 355
Vincent Massol 93.1 356 The ##FAQ.WebHome## page should look similar to this:
Manuel Smeria 80.1 357
358 {{image reference="FAQsCustomCode.png"/}}
359
Silvia Macovei 48.2 360 == Creating new FAQ entries ==
Vincent Massol 1.1 361
Manuel Smeria 80.1 362 There are 2 ways for you to let your users create new FAQ entries:
Manuel Smeria 83.1 363
Manuel Smeria 80.1 364 1. Declare the FAQ as a template
365 1. Add a custom creation form
Anca Luca 14.1 366
Guillaume Lerouge 55.1 367 === Using a Template ===
368
Manuel Smeria 83.1 369 You will have to define a template provider [[as explained on this page>>extensions:Extension.Administration Application||anchor="HCreatethetemplateprovider"]]
Guillaume Lerouge 55.1 370
Alex Cotiugă 107.2 371 Go to your wiki's administration interface, in the "Templates" section (Administration -> Content -> Templates). Create a new template provider in the
Vincent Massol 94.1 372 ##FAQ## space and name it ##FAQTemplateProvider##
Guillaume Lerouge 55.1 373
374 You can then use the following values:
375
Vincent Massol 94.1 376 * Provider name: ##FAQ Template Provider##
377 * Template name: ##New FAQ entry##
378 * Template to use: ##FAQ.FAQTemplate##
Guillaume Lerouge 55.1 379
Vincent Massol 94.1 380 If you'd like, you can restrict FAQ entries so that they're created only in the ##FAQ## space. Once you're done, click "Save & View". Your template is now ready to be used! Users who click on the "Add >> Page" button will now have the option to create a new page using the FAQ template.
Guillaume Lerouge 55.1 381
382 === Custom creation form ===
383
384 If you choose this option, you will need to write some code to let your users create new FAQ entries. To do this, you will have to create a form in which the user can enter the name of the questions she wants to create. Once typed in, the form calls the same page to trigger the new document creation based on the parameters entered by the user:
385
Guillaume Lerouge 42.1 386 * The first part of the code checks whether the page has a parameter. If so:
387 ** The name of the document that will be created is computed
388 ** A check is done to verify the document doesn't exist yet
389 ** If everything's ok, the user is sent to the new document in inline edition mode
390 * The second part of the code is the actual FAQ creation form
Vincent Massol 94.1 391 ** It builds the name of the document to create it in the ##FAQ## space
Guillaume Lerouge 42.1 392 ** It sets the document parent as being the current document
393 ** It defines the template to use to create the new document
Vincent Massol 1.1 394
Silvia Macovei 48.1 395 {{code language="none"}}
Guillaume Lerouge 42.1 396 {{velocity}}
397 #if("$!request.docName" != '')
398 ## Request for creating a new instance
Clemens Robbenhaar 62.1 399 #set($docName = ${request.docName})
Guillaume Lerouge 47.1 400 #set($targetDocName = "${request.spaceName}.${docName}")
Clemens Robbenhaar 62.1 401 #if(!$xwiki.exists($targetDocName) && $xwiki.hasAccessLevel('edit', $xcontext.user, $targetDocName))
Clemens Robbenhaar 61.1 402 $response.sendRedirect($xwiki.getURL($targetDocName, 'inline', "template=${escapetool.url($request.template)}&parent=${escapetool.url($request.parent)}"))
Guillaume Lerouge 42.1 403 ## Stop processing, since we already sent a redirect.
404 #stop
405 #end
406 #end
Vincent Massol 1.1 407
Guillaume Lerouge 42.1 408 = Add a new question =
409
410 #if("$!targetDocName" != '' && $xwiki.exists($targetDocName))
411 {{warning}}The target document already exists. Please choose a different name, or [[view the existing document>>$targetDocName]]{{/warning}}
412 #elseif("$!targetDocName" != '')
413 {{warning}}You don't have permission to create that document{{/warning}}
414 #end
415
416 {{html}}
417 <form action="" id="newdoc" method="post">
418 <div>
419 <input type="hidden" name="parent" value="${doc.fullName}"/>
420 <input type="hidden" name="template" value="FAQ.FAQTemplate"/>
421 <input type="hidden" name="sheet" value="1"/>
422 <input type="hidden" name="spaceName" value="FAQ"/>
423 Document: <input type="text" name="docName" value="Enter your question here" class="withTip" size="50"/>
424 <span class="buttonwrapper"><input type="submit" value="Create this FAQ" class="button"/></span>
425 </div>
426 </form>
427 {{/html}}
428 {{/velocity}}
Silvia Macovei 48.1 429 {{/code}}
Vincent Massol 1.1 430
Vincent Massol 94.1 431 * Copy this code and paste it as Wiki content inside ##FAQ.WebHome##, below the code that's already there
Guillaume Lerouge 42.1 432 * Click "Save and View"
Vincent Massol 111.1 433 * A form to create new FAQ entries is now available on the page:(((
Manuel Smeria 80.1 434 {{image reference="FAQsWithForm.png"/}}
435 )))
Anca Luca 14.1 436
Silvia Macovei 48.2 437 = Test the Application =
jingbo 27.1 438
Manuel Smeria 80.1 439 Now let's just create a new document in our application to test it out.
Vincent Massol 94.1 440
Manuel Smeria 80.1 441 If you previously chose to use a "Custom creation form" for creating new FAQ entries, follow these steps:
Guillaume Lerouge 42.1 442
Vincent Massol 94.1 443 * Go to ##FAQ.WebHome##
Manuel Smeria 80.1 444 * Below the "Add a new question" header, enter a question (which will also be used as the document title) in the //Document// field
445 * Click //Create this FAQ//
Vincent Massol 111.1 446 * You can then enter your question in longer form using the //Question// field on the template, like this:(((
Manuel Smeria 80.1 447 {{image reference="FAQSheetEdit.PNG"/}}
Silvia Macovei 48.4 448 )))
Vincent Massol 111.1 449 * Click //Save & View// and then you will see the newly created document, like this:(((
Manuel Smeria 80.1 450 {{image reference="FAQSheetView.PNG"/}}
Silvia Macovei 48.4 451 )))
Vincent Massol 111.1 452 * Go back to the ##FAQ.WebHome## page (you can use the breadcrumbs) to see the list of existing questions(((
Manuel Smeria 80.1 453 {{image reference="FAQsWithEntry.png"/}}
454 )))
Guillaume Lerouge 42.1 455
Silvia Macovei 48.2 456 = Conclusion =
Vincent Massol 1.1 457
Manuel Smeria 80.1 458 This tutorial has taught you how to use the Class Wizard app and it has detailed the concepts of classes, objects and properties and introduced the authoring templates and page design sheets.
Vincent Massol 94.1 459
Manuel Smeria 80.1 460 You may also have learned a little bit about Velocity scripting in documents. You can use these basic concepts to build custom applications at the document or presentation layer of XWiki without having to compile or deploy code.
Vincent Massol 1.1 461
462 As always, please take the time to make this document better for other users if you find ways that it can be improved as you read it for the first time.

Get Connected