Changes for page Best Practices

Last modified by Vincent Massol on 2017/09/05

<
From version < 4.1 >
edited by Eduard Moraru
on 2012/05/23
To version < 6.1 >
edited by Vincent Massol
on 2012/11/17
>
Change comment: Guidelines for where to put code

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.enygma
1 +XWiki.VincentMassol
Content
... ... @@ -1,5 +1,13 @@
1 1  {{toc/}}
2 += Where to put code? =
2 2  
4 +Since xwiki allows to put code both in wiki pages and in Java you might wonder where you should put your code. Here's some general guidelines:
5 +* Don't put "business logic" code in wiki pages. Use Java for that. This gives you nice IDEs, the ability to easily debug the code and the ability to write automated unit tests. Generally speaking it makes it easy on maintenance.
6 +* In general put the minimum amount of scripts in your wiki pages since that makes it harder to maintain.
7 +* The only scripts that you may put in wiki pages are "presentation logic" code.
8 +
9 +Said differently you should use the [[MVC>>http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller]] approach by separating your Model (what we called "business logic" above) from your View (what we called "presentation logic" above).
10 +
3 3  = XWiki Application Organization =
4 4  
5 5  This [[Best Practices document>>Best Practices XWiki Application Organization]] explains how to best organize an XWiki Application.
... ... @@ -8,7 +8,7 @@
8 8  
9 9  Class sheet documents should be written using the following construct (this is an example for displaying documents containing XWiki.XWikiUsers objects):
10 10  
11 -{{code language='velocity'}}
19 +{{code language="velocity"}}
12 12  #set($obj = $doc.getObject("XWiki.XWikiUsers"))
13 13  #if(!$obj)
14 14   1 User Sheet
... ... @@ -19,7 +19,9 @@
19 19  #end
20 20  {{/code}}
21 21  
22 -{{info}}The 'if' tests first for the non existence. This is so that XWiki extract the title from the //1 User Sheet//, which is a proper title to display when viewsing the sheet page, instead of the computed name which will usually display something wrong.{{/info}}
30 +{{info}}
31 +The 'if' tests first for the non existence. This is so that XWiki extract the title from the //1 User Sheet//, which is a proper title to display when viewsing the sheet page, instead of the computed name which will usually display something wrong.
32 +{{/info}}
23 23  
24 24  = Handling errors when using xredirect for non-Javascript UIs =
25 25  
... ... @@ -31,10 +31,10 @@
31 31  
32 32  A simplified code for this in the background service that produces the error is:
33 33  
34 -{{code language='velocity'}}
44 +{{code language="velocity"}}
35 35  #handleRequest($success)
36 36  #if ($success)
37 - #if ($request.action == 'get' || $request.xpage== 'plain')
47 + #if ($request.action == 'get' || $request.xpage == 'plain')
38 38   ## JavaScript call here.
39 39   Action was successful.
40 40   #elseif ("$!request.xredirect" != '')
... ... @@ -57,10 +57,11 @@
57 57  
58 58  For the background service, it translates to:
59 59  
60 -{{code language='velocity'}}
70 +{{code language="velocity"}}
61 61  ...
62 62   #elseif ("$!request.xredirect" != '')
63 63   ## No-JavaScript here. Redirect and forward error message.
74 + #set ($errorMessageKeyPrefix = "myModule.error.")
64 64   $request.session.setAttribute("${errorMessageKeyPrefix}${request.xredirect}", 'Action was NOT successful')
65 65   $response.sendRedirect($request.xredirect)
66 66   #end
... ... @@ -69,9 +69,10 @@
69 69  
70 70  On the UI side:
71 71  
72 -{{code language='velocity'}}
83 +{{code language="velocity"}}
73 73  ...
74 74   #set ($xredirect = $doc.getURL($context.action, $!{request.queryString}))
86 + #set ($errorMessageKeyPrefix = "myModule.error.")
75 75   #set ($errorMessage = $request.session.getAttribute("${errorMessageKeyPrefix}${xredirect}"))
76 76   #if ("$!errorMessage" != '')
77 77   ## Clean the error and display the message.
... ... @@ -82,7 +82,10 @@
82 82  {{/code}}
83 83  
84 84  Note that using xredirect's value as session key (prefixed or not) is a good idea because:
85 -1.it's already there in both the UI (for sending it as parameter) and the background service (received as parameter)
86 -2.it acts like a namespace, ensuring that the error will only be displayed for the current page/request.
87 87  
98 +1. it's already there in both the UI (for sending it as parameter) and the background service (received as parameter)
99 +1. it acts like a namespace, ensuring that the error will only be displayed for the current page/request.
100 +
101 +Using a prefix as above allows you to have multiple components (wiki macros, gadgets, etc.) in the same page using the same mechanism without collisions.
102 +
88 88  This method works together with the whole purpose for which we are doing the redirect in the first place (so that the user can refresh the page without re-sending the action or re-posting a form), ensuring that after the first display, on a refresh, the error goes away.

Get Connected