Wiki source code of XWiki Color Themes

Last modified by Alex Cotiuga on 2026/07/27 08:39

Show last authors
1 {{velocity wiki="false"}}
2 #if ($xcontext.action == 'get')
3 #set ($statusCode = 400)
4 #set ($message = 'The theme collection could not be sent. Please try again or contact Agnease by email at alex@agnease.com.')
5
6 #set ($email = $stringtool.trim($request.get('email')))
7 #set ($contactWebsite = $stringtool.trim($request.get('contactWebsite')))
8 #set ($startedAtRaw = $stringtool.trim($request.get('contactStartedAt')))
9 #set ($sourcePage = $stringtool.trim($request.get('sourcePage')))
10
11 #set ($spamScore = 0)
12
13 ## Honeypot: real users should never fill this field.
14 #if ("$!contactWebsite" != '')
15 #set ($spamScore = $spamScore + 5)
16 #end
17
18 ## Submission timing check.
19 #if ("$!startedAtRaw" == '')
20 #set ($spamScore = $spamScore + 2)
21 #else
22 #set ($startedAt = $numbertool.toNumber($startedAtRaw))
23 #if ("$!startedAt" == '')
24 #set ($spamScore = $spamScore + 2)
25 #else
26 #set ($now = $datetool.systemDate.time)
27 #set ($elapsed = $now - $startedAt)
28
29 ## Reject very fast submissions.
30 #if ($elapsed > 0 && $elapsed < 5000)
31 #set ($spamScore = $spamScore + 3)
32 #end
33 #end
34 #end
35
36 #if ("$!email" == '')
37 #set ($message = 'Please enter your email address.')
38 #elseif (!$email.matches('^[^@\s]+@[^@\s]+\.[^@\s]+$'))
39 #set ($message = 'Please enter a valid email address.')
40 #elseif ($spamScore >= 3)
41 #set ($message = 'The theme collection could not be sent. Please try again or contact Agnease by email.')
42 #else
43 #try('themeRequestException')
44 #set ($themePackageName = 'AgneaseXWikiColorThemes.xar')
45 #set ($themePackageAttachment = $doc.getAttachment($themePackageName))
46 $themePackageAttachment
47
48 #if (!$themePackageAttachment)
49 #set ($statusCode = 400)
50 #set ($message = "The theme package attachment could not be found on this page: ${themePackageName}.")
51 #else
52
53 ## Save a lightweight lead using the same ContactRequest storage approach.
54 #try('saveLeadException')
55 #set ($className = 'Agnease.Code.ContactRequest.ContactRequestClass')
56 #set ($now = $datetool.get('yyyyMMddHHmm'))
57 #set ($random = $mathtool.random(100000, 999999))
58 #set ($uniqueName = "ProductRequest-${now}-${random}")
59 #set ($contactRequestDoc = $xwiki.getDocumentAsAuthor('ContactRequests.' + $uniqueName))
60 #set ($contactRequestObj = $contactRequestDoc.getObject($className, true))
61
62 #set ($discard = $contactRequestObj.set('email', $email))
63
64 #if ("$!sourcePage" != '')
65 #set ($discard = $contactRequestObj.set('sourcePage', $sourcePage))
66 #else
67 #set ($discard = $contactRequestObj.set('sourcePage', $doc.fullName))
68 #end
69
70 #set ($discard = $contactRequestObj.set('scope', 'Requested the free Agnease XWiki color theme collection.'))
71 #set ($discard = $contactRequestDoc.saveAsAuthor())
72 #end
73
74 ## The ProductsMailTemplate page is protected and only viewable to administrators,
75 ## so the mail template must be prepared with the rights of the product page author.
76 #set ($originalCurrentUserReference = $xcontext.context.userReference)
77 #set ($discard = $xcontext.context.setUserReference($doc.author))
78
79 #try('sendProductEmailException')
80 ## Send the product email to the visitor.
81 #set ($emailSubject = 'Agnease XWiki color theme collection')
82 #set ($templateReference = $services.model.createDocumentReference('', 'Newsletter', 'ProductsMailTemplate'))
83 #set ($themePackageAttachments = [$themePackageAttachment])
84
85 #set ($templateParameters = {
86 'velocityVariables': {
87 'subject': $emailSubject,
88 'productName': 'Agnease XWiki Theme Moods',
89 'themePackageName': $themePackageName,
90 'recipientEmail': $email,
91 'sourcePage': $doc.fullName,
92 'isNewsletter': false
93 },
94 'attachments': $themePackageAttachments
95 })
96
97 #set ($productMessage = $services.mail.sender.createMessage($email, $emailSubject))
98 #set ($discard = $productMessage.setType('Agnease Product Download'))
99
100 #set ($templatePartAdded = false)
101
102 #try('templatePartException')
103 #set ($templatePart = $productMessage.addPart('xwiki/template', $templateReference, $templateParameters))
104 #if ($templatePart)
105 #set ($templatePartAdded = true)
106 #end
107 #end
108
109 #if ("$!templatePartException" != '')
110 #set ($statusCode = 400)
111 #set ($message = "Template part error: $exceptiontool.getStackTrace($templatePartException)")
112 #elseif ($services.mail.sender.lastError)
113 #set ($statusCode = 400)
114 #set ($message = "Mail sender error while preparing template: $exceptiontool.getStackTrace($services.mail.sender.lastError)")
115 #elseif (!$templatePartAdded)
116 #set ($statusCode = 400)
117 #set ($message = 'The mail template body part could not be added.')
118 #else
119 #set ($productMailResult = $services.mail.sender.send([$productMessage], 'database'))
120
121 #set ($productMailErrorCount = 0)
122 #set ($productMailErrorSummary = '')
123
124 #foreach ($mailError in $productMailResult.statusResult.getAllErrors())
125 #set ($productMailErrorCount = $productMailErrorCount + 1)
126 #set ($productMailErrorSummary = "$!mailError.errorSummary $!mailError.errorDescription")
127 #end
128
129 #if ($productMailErrorCount > 0)
130 #set ($statusCode = 400)
131 #set ($message = "Mail send error: $productMailErrorSummary")
132 #else
133 #set ($statusCode = 200)
134 #set ($message = 'The XWiki color theme collection was sent to your email address.')
135 #end
136 #end
137 #end
138
139 ## Always restore the original current user after preparing/sending the visitor email.
140 #set ($discard = $xcontext.context.setUserReference($originalCurrentUserReference))
141
142 #if ("$!sendProductEmailException" != '')
143 #set ($statusCode = 400)
144 #set ($message = "Product email error: $exceptiontool.getStackTrace($sendProductEmailException)")
145 #end
146
147 ## Send an internal notification to Agnease.
148 ## Best-effort only; this should not fail the visitor request.
149 #try('notificationException')
150 #set ($notificationRecipient = 'alex@agnease.com')
151 #set ($notificationSubject = 'New Agnease product request: XWiki Color Themes')
152 #set ($notificationBody = "
153 Email:
154 $email
155
156 Product:
157 Agnease XWiki Color Themes
158
159 Theme package:
160 $themePackageName
161
162 Source page:
163 $doc.getExternalURL()
164
165 Lead request page:
166 $!contactRequestDoc.getExternalURL()
167 ")
168
169 #set ($notificationMessage = $services.mail.sender.createMessage($notificationRecipient, $notificationSubject))
170 #set ($discard = $notificationMessage.setType('Agnease Product Request'))
171 #set ($discard = $notificationMessage.addPart('text/plain', $notificationBody))
172 #set ($discard = $services.mail.sender.sendAsynchronously([$notificationMessage], 'database'))
173 #end
174 #end
175 #end
176
177 #if ("$!themeRequestException" != '')
178 #set ($statusCode = 400)
179 #set ($message = 'The theme collection could not be sent. Please try again or contact Agnease by email.')
180 #end
181 #end
182
183 #set ($discard = $response.setStatus($statusCode))
184 #jsonResponse({'message': $message})
185 #end
186 {{/velocity}}
187
188 {{velocity}}
189 ## Page title: Agnease XWiki Atmospheres
190 ## Meta title: Accessible XWiki Color Themes | Agnease Atmospheres
191 ## Meta description: Explore five WCAG-compliant XWiki color themes by Agnease, from Alpine Day to Polar Night, compatible with XWiki 17.10.10, 18.4.2 and 18.5.0.
192
193 #set ($discard = $xwiki.ssx.use('PublicWebSite.WebHome'))
194
195 #set ($themes = [{
196 'id': 'polar-night',
197 'name': 'Polar Night',
198 'paragraphs': [
199 'Polar Night is a refined dark theme for focused work and comfortable reading in low-light environments. Deep navy surfaces, restrained borders and clear blue accents create a precise modern interface inspired by professional development and operations tools.',
200 'It is particularly well suited to technical documentation, developer portals, engineering knowledge bases and IT operations environments. Carefully balanced text, status and interaction colors keep navigation accessible and content readable without making the interface feel heavy.'
201 ],
202 'images': [
203 'polar-night-user-profile.png',
204 'polar-night-home.png',
205 'polar-night-search.png',
206 'polar-night-notifications.png',
207 'polar-night-sandbox.png',
208 'polar-night-mfa.png'
209 ]
210 },{
211 'id': 'alpine-day',
212 'name': 'Alpine Day',
213 'paragraphs': [
214 'Alpine Day combines glacier-blue and cool blue-gray surfaces with deep teal navigation and crisp navy typography. The restrained palette gives XWiki a fresh, contemporary mood while preserving the clarity and visual hierarchy expected from a professional knowledge platform.',
215 'It is a natural fit for customer portals, service platforms, modern intranets and technical knowledge bases. Alpine Day offers a cooler and more expressive alternative to the default Iceberg theme while remaining calm, practical and comfortable throughout the working day.'
216 ],
217 'images': [
218 'alpine-day-home.png',
219 'alpine-day-search.png',
220 'alpine-day-notifications.png',
221 'alpine-day-user-profile.png',
222 'alpine-day-sandbox.png',
223 'alpine-day-mfa.png'
224 ]
225 },{
226 'id': 'ivory-ledger',
227 'name': 'Ivory Ledger',
228 'paragraphs': [
229 'Ivory Ledger is a warm, paper-inspired theme for content-rich XWiki environments. Ivory surfaces, muted earthy accents and carefully balanced typography create an editorial atmosphere designed to make substantial pages and long reading sessions feel more comfortable.',
230 'It is especially well suited to legal documentation, policies, educational resources, research material and long-form technical content. The warmer palette softens the clinical appearance of a conventional white interface while retaining strong contrast, structure and readability.'
231 ],
232 'images': [
233 'ivory-ledger-mfa.png',
234 'ivory-ledger-home.png',
235 'ivory-ledger-search.png',
236 'ivory-ledger-notifications.png',
237 'ivory-ledger-user-profile.png',
238 'ivory-ledger-sandbox.png'
239 ]
240 },{
241 'id': 'ember-night',
242 'name': 'Ember Night',
243 'paragraphs': [
244 'Ember Night pairs deep charcoal surfaces with controlled amber and copper accents for a dark theme with a confident industrial character. Warm highlights make navigation and important actions easy to identify without adding excessive brightness or visual noise.',
245 'Designed for engineering teams, industrial operations, monitoring environments and technical organizations, it brings the comfort of a dark interface to sustained everyday work. Its warmer character provides a clear alternative to the cool blue direction of Polar Night.'
246 ],
247 'images': [
248 'ember-night-notifications.png',
249 'ember-night-home.png',
250 'ember-night-search.png',
251 'ember-night-user-profile.png',
252 'ember-night-sandbox.png',
253 'ember-night-mfa.png'
254 ]
255 },{
256 'id': 'verdant-office',
257 'name': 'Verdant Office',
258 'paragraphs': [
259 'Verdant Office introduces a composed green visual language associated with balance, clarity and structured work. Soft neutral surfaces keep the content at the center, while restrained forest and sage accents guide users through navigation, links and important actions.',
260 'The theme suits healthcare, sustainability, HSE, public-sector and corporate knowledge platforms particularly well. It creates a dependable and welcoming working environment without becoming decorative, overly branded or visually demanding.'
261 ],
262 'images': [
263 'verdant-office-home.png',
264 'verdant-office-search.png',
265 'verdant-office-notifications.png',
266 'verdant-office-user-profile.png',
267 'verdant-office-sandbox.png',
268 'verdant-office-mfa.png'
269 ]
270 }])
271
272 {{html clean="false"}}
273 <section class="hero hero-centered" aria-labelledby="themes-title">
274 <div class="container hero-inner">
275 <div class="hero-kicker">
276 <i class="fa fa-paint-brush" aria-hidden="true"></i>
277 Agnease color themes for XWiki
278 </div>
279
280 <h1 id="themes-title">XWiki Color Themes by Agnease</h1>
281
282 <p class="lead">
283 Explore five carefully designed light and dark alternatives to the default Iceberg theme,
284 each giving XWiki a distinct visual mood without changing the familiar platform experience.
285 </p>
286
287 <ul class="benefits">
288 <li>XWiki 17.10.10 LTS</li>
289 <li>XWiki 18.4.2 Intermediary LTS</li>
290 <li>XWiki 18.5.0 Stable</li>
291 <li>WCAG-compliant color contrast</li>
292 </ul>
293 </div>
294 </section>
295
296 #foreach ($theme in $themes)
297 <section aria-labelledby="${theme.id}-title">
298 <div class="container">
299 <div class="product-gallery-panel">
300 <h2 id="${theme.id}-title">$theme.name</h2>
301
302 #foreach ($paragraph in $theme.paragraphs)
303 <p class="gallery-note">$paragraph</p>
304 #end
305
306 {{/html}}
307
308 {{gallery}}
309 #foreach ($image in $theme.images)
310 [[image:$image]]
311 #end
312 {{/gallery}}
313
314 {{html clean="false"}}
315 </div>
316 </div>
317 </section>
318 #end
319
320 <section class="cta-section" aria-labelledby="themes-final-cta-title">
321 <div class="container">
322 <div class="cta-panel">
323
324 <h2 id="themes-final-cta-title">Explore XWiki in a different mood</h2>
325
326 <p>
327 Start with the five ready-made themes or send your colors and logo to receive
328 a custom light and dark theme for your organization.
329 </p>
330
331 <form id="themeCollectionForm" class="form-inline">
332 <div class="form-group">
333 <label class="sr-only" for="themeCollectionEmail">Email address</label>
334 <input
335 id="themeCollectionEmail"
336 type="email"
337 name="email"
338 class="form-control"
339 placeholder="your@email.com"
340 required
341 />
342 </div>
343
344 <div class="contact-hp-wrapper" aria-hidden="true">
345 <label for="themeCollectionWebsite">Website</label>
346 <input
347 id="themeCollectionWebsite"
348 type="text"
349 name="contactWebsite"
350 autocomplete="off"
351 tabindex="-1"
352 />
353 </div>
354
355 <input type="hidden" name="contactStartedAt" value="$datetool.systemDate.time" />
356 <input type="hidden" name="sourcePage" value="$doc.fullName" />
357
358 <div class="hero-actions">
359 <input
360 id="themeCollectionSubmit"
361 type="submit"
362 class="btn btn-secondary"
363 value="Get the free theme collection"
364 />
365
366 <a
367 id="customThemeButton"
368 class="btn btn-secondary"
369 href="$xwiki.getURL('contact.WebHome')"
370 >
371 Request a custom theme
372 </a>
373 </div>
374 </form>
375 {{/html}}
376 {{html clean="false" wiki="true"}}
377 <div class="reviewNotifications">
378 <div class="hidden reviewNotificationSuccess">
379
380 {{success}}reviewNotification{{/success}}
381
382 </div>
383
384 <div class="hidden reviewNotificationError">
385
386 {{error}}reviewNotification{{/error}}
387
388 </div>
389 </div>
390
391 </div>
392 </div>
393 </section>
394 {{/html}}
395 {{/velocity}}