Wiki source code of How to Customize XWiki Without Creating Upgrade Problems
Last modified by Agnease on 2026/05/26 11:00
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | {{velocity}} | ||
| 2 | #set ($discard = $xwiki.ssx.use('PublicWebSite.WebHome')) | ||
| 3 | {{html clean="false"}} | ||
| 4 | |||
| 5 | <section class="resource-header" aria-labelledby="hero-title"> | ||
| 6 | <div class="container"> | ||
| 7 | <div class="text-center"> | ||
| 8 | <div class="hero-kicker"> | ||
| 9 | <i class="fa fa-code" aria-hidden="true"></i> | ||
| 10 | XWiki custom development guidance | ||
| 11 | </div> | ||
| 12 | </div> | ||
| 13 | |||
| 14 | <h1 id="hero-title">Why XWiki custom development needs structure, documentation and upgrade awareness</h1> | ||
| 15 | |||
| 16 | <p class="resource-summary"> | ||
| 17 | XWiki can be adapted to complex business needs. The important part is to keep custom work documented, | ||
| 18 | versioned and easy to validate during future upgrades. | ||
| 19 | </p> | ||
| 20 | </div> | ||
| 21 | </section> | ||
| 22 | |||
| 23 | <section class="resource-page"> | ||
| 24 | <div class="container"> | ||
| 25 | <div class="resource-layout"> | ||
| 26 | <aside class="resource-sidebar" aria-label="Page summary"> | ||
| 27 | <h4>In this guide</h4> | ||
| 28 | <ul> | ||
| 29 | <li><a href="#why-customize">Why customize XWiki</a></li> | ||
| 30 | <li><a href="#where-risk-appears">Where risk appears</a></li> | ||
| 31 | <li><a href="#safe-model">Safe model</a></li> | ||
| 32 | <li><a href="#upgrade-validation">Upgrade validation</a></li> | ||
| 33 | <li><a href="#practical-checklist">Checklist</a></li> | ||
| 34 | <li><a href="#strategic-advantage">Strategic advantage</a></li> | ||
| 35 | <li><a href="#custom-development-faq">FAQ</a></li> | ||
| 36 | </ul> | ||
| 37 | </aside> | ||
| 38 | |||
| 39 | <article class="resource-content"> | ||
| 40 | |||
| 41 | <p> | ||
| 42 | Many organizations choose XWiki because it can grow beyond a simple documentation space. A platform may start | ||
| 43 | with pages, attachments and permissions, then evolve into structured applications, approval workflows, custom | ||
| 44 | dashboards, branded PDF exports, integrations or internal tools built around the company’s real processes. | ||
| 45 | </p> | ||
| 46 | |||
| 47 | <p> | ||
| 48 | This flexibility is valuable, but it also raises a legitimate concern: will custom development make upgrades | ||
| 49 | harder? The answer depends less on the existence of custom code and more on the way it is organized. A controlled | ||
| 50 | customization can remain stable for years. An undocumented change applied directly in production can become a | ||
| 51 | maintenance problem after the next upgrade. | ||
| 52 | </p> | ||
| 53 | |||
| 54 | <div class="resource-note"> | ||
| 55 | <p> | ||
| 56 | <strong>In practice:</strong> XWiki custom development should be separated from standard platform pages, | ||
| 57 | documented, kept under source control, tested on staging and reviewed during upgrades. This makes custom | ||
| 58 | features easier to maintain instead of turning them into hidden dependencies. | ||
| 59 | </p> | ||
| 60 | </div> | ||
| 61 | |||
| 62 | <p> | ||
| 63 | XWiki custom development is the process of adapting the platform with custom pages, classes, objects, sheets, | ||
| 64 | templates, scripts, macros, UI extensions, Java components or integrations. The goal is to support real | ||
| 65 | business processes while keeping the instance understandable, maintainable and upgrade-aware. | ||
| 66 | </p> | ||
| 67 | |||
| 68 | <div class="resource-note"> | ||
| 69 | <p> | ||
| 70 | <strong>The main point:</strong> custom code is not the problem. Uncontrolled custom code is. XWiki can be | ||
| 71 | customized safely when changes are separated from standard pages, tracked, documented and tested. | ||
| 72 | </p> | ||
| 73 | </div> | ||
| 74 | |||
| 75 | <h2 id="why-customize">Why XWiki custom development exists</h2> | ||
| 76 | |||
| 77 | <p> | ||
| 78 | Avoiding all customization may look safer at first, but it can create other costs. Users may start maintaining | ||
| 79 | side spreadsheets, sending approvals by email, duplicating data in external tools or bypassing the wiki because | ||
| 80 | it does not match their daily work. In these cases, a well-designed XWiki customization can simplify the process | ||
| 81 | and improve adoption. | ||
| 82 | </p> | ||
| 83 | |||
| 84 | <p> | ||
| 85 | Typical examples include custom metadata for documents, templates for recurring content, dashboards for teams, | ||
| 86 | approval flows, notifications, PDF layouts, page actions, UI extensions, macros and integrations with systems | ||
| 87 | such as authentication providers, ticketing tools, storage services, CRM platforms or AI assistants. These | ||
| 88 | features can be implemented at different levels, from wiki pages and scripts to packaged Java extensions. | ||
| 89 | </p> | ||
| 90 | |||
| 91 | <h2 id="where-risk-appears">Where customization becomes risky</h2> | ||
| 92 | |||
| 93 | <p> | ||
| 94 | Problems usually appear when nobody can quickly explain where a customization is implemented, why it exists or | ||
| 95 | how it should be tested. Business logic mixed into regular content pages, standard pages changed without notes, | ||
| 96 | scripts that exist only in production, hardcoded group names or missing upgrade checks are common signs that the | ||
| 97 | customization process needs more structure. | ||
| 98 | </p> | ||
| 99 | |||
| 100 | <p> | ||
| 101 | This is especially important in XWiki because custom logic can live in several places: classes, objects, sheets, | ||
| 102 | templates, Velocity or Groovy scripts, panels, UI extensions, macros, scheduled jobs and Java components. The | ||
| 103 | flexibility is useful, but each important customization should have a clear location and a clear maintenance | ||
| 104 | path. | ||
| 105 | </p> | ||
| 106 | |||
| 107 | <p> | ||
| 108 | Customizations should also be reviewed as part of the wider platform risk model. See | ||
| 109 | <a href="$xwiki.getURL('resources.xwiki-security-review')">what an XWiki security review should actually include</a> | ||
| 110 | for related checks around permissions, authentication, extensions, infrastructure and operational practices. | ||
| 111 | </p> | ||
| 112 | |||
| 113 | <div class="resource-inline-cta"> | ||
| 114 | <p> | ||
| 115 | <strong>Unsure how maintainable your XWiki customizations are?</strong> | ||
| 116 | A customization review can help identify hidden scripts, undocumented logic, | ||
| 117 | upgrade risks and features that should be documented, cleaned up or packaged properly. | ||
| 118 | </p> | ||
| 119 | <a class="btn btn-secondary" href="$xwiki.getURL('contact.WebHome')">Request a customization review</a> | ||
| 120 | </div> | ||
| 121 | |||
| 122 | <h2 id="safe-model">A safer model for XWiki custom work</h2> | ||
| 123 | |||
| 124 | <h3>1. Keep custom code separate from standard XWiki pages</h3> | ||
| 125 | <p> | ||
| 126 | Custom classes, scripts, templates and configuration should usually live in dedicated technical spaces, for | ||
| 127 | example a company-specific <code>Code</code>, <code>Applications</code>, <code>Templates</code> or | ||
| 128 | <code>Config</code> area. This makes it easier to see what belongs to the standard distribution and what belongs | ||
| 129 | to the organization. | ||
| 130 | </p> | ||
| 131 | |||
| 132 | <h3>2. Document the purpose, not only the implementation</h3> | ||
| 133 | <p> | ||
| 134 | A short technical note is often enough: what the customization does, who uses it, where it is implemented, what | ||
| 135 | assumptions it makes and what should be checked after an upgrade. This turns custom work from a hidden script | ||
| 136 | into a maintainable part of the platform. | ||
| 137 | </p> | ||
| 138 | |||
| 139 | <h3>3. Keep custom code under source control</h3> | ||
| 140 | <p> | ||
| 141 | Custom development should not exist only inside the production wiki. Java code, scripts, XAR packages, | ||
| 142 | deployment files and templates should be stored in a source control system, such as Git. This gives the team a | ||
| 143 | history of what changed, when it changed and why. | ||
| 144 | </p> | ||
| 145 | |||
| 146 | <h3>4. Choose the right implementation level</h3> | ||
| 147 | <p> | ||
| 148 | Many useful features can start as wiki-based customizations using XWiki classes, sheets, templates, Velocity or | ||
| 149 | UI extensions. When a feature becomes complex, reusable or business-critical, packaging it as an extension is | ||
| 150 | often a better long-term option. Event listeners, custom services, scheduled jobs, integrations and advanced | ||
| 151 | workflow logic usually benefit from this approach. | ||
| 152 | </p> | ||
| 153 | |||
| 154 | <h3>5. Keep configuration outside the code</h3> | ||
| 155 | <p> | ||
| 156 | Group names, target spaces, template references, email recipients, external URLs and workflow settings should | ||
| 157 | not be hardcoded when they are likely to change. Configuration pages or preference objects make the feature | ||
| 158 | easier to adapt without rewriting the implementation. | ||
| 159 | </p> | ||
| 160 | |||
| 161 | <h2 id="upgrade-validation">Validate custom features during upgrades</h2> | ||
| 162 | |||
| 163 | <p> | ||
| 164 | A successful upgrade is not only one where XWiki starts and standard pages load. The upgrade plan should also | ||
| 165 | include the features that make the instance specific to the organization: custom dashboards, templates, macros, | ||
| 166 | workflows, permissions, notifications, PDF exports, scheduled jobs and integrations. | ||
| 167 | </p> | ||
| 168 | |||
| 169 | <p> | ||
| 170 | For each important customization, the team should know what to test and what a successful result looks like. A | ||
| 171 | staging environment or temporary clone is usually the safest place to run this validation before production is | ||
| 172 | touched. | ||
| 173 | </p> | ||
| 174 | |||
| 175 | <p> | ||
| 176 | For a broader upgrade preparation model, see | ||
| 177 | <a href="$xwiki.getURL('resources.why-upgrade-xwiki')">why regular XWiki upgrades matter</a>. | ||
| 178 | </p> | ||
| 179 | |||
| 180 | <div class="resource-note"> | ||
| 181 | <p> | ||
| 182 | <strong>A practical rule:</strong> production can receive urgent fixes when necessary, but it should not become | ||
| 183 | the only place where the real version of a customization exists. After the emergency, the change should be | ||
| 184 | reviewed, documented and added to the normal maintenance process. | ||
| 185 | </p> | ||
| 186 | </div> | ||
| 187 | |||
| 188 | <div class="resource-inline-cta"> | ||
| 189 | <p> | ||
| 190 | <strong>Not sure how risky your current XWiki version is?</strong> | ||
| 191 | A short technical review can clarify the upgrade path, extension compatibility, | ||
| 192 | custom code risks and validation needs before production is touched. | ||
| 193 | </p> | ||
| 194 | <a class="btn btn-secondary" href="$xwiki.getURL('contact.WebHome')">Request a quick review</a> | ||
| 195 | </div> | ||
| 196 | |||
| 197 | <h2 id="practical-checklist">XWiki custom development checklist</h2> | ||
| 198 | |||
| 199 | <p> | ||
| 200 | A maintainable XWiki customization should be easy to locate, explain, test and update. The following checklist | ||
| 201 | can be used as a starting point when reviewing existing custom work or planning a new feature. | ||
| 202 | </p> | ||
| 203 | |||
| 204 | <ul class="resource-checklist"> | ||
| 205 | <li>Separate custom pages, scripts and configuration from standard XWiki content.</li> | ||
| 206 | <li>Document the business purpose, technical location and validation steps.</li> | ||
| 207 | <li>Keep custom code and important assets under source control, for example in Git.</li> | ||
| 208 | <li>Test custom features on staging before production upgrades.</li> | ||
| 209 | <li>Review old customizations and remove what is no longer used.</li> | ||
| 210 | </ul> | ||
| 211 | |||
| 212 | <h2 id="strategic-advantage">Custom code can become a strategic advantage</h2> | ||
| 213 | |||
| 214 | <p> | ||
| 215 | Many useful platform features start as custom development for one concrete need. A workflow, dashboard, | ||
| 216 | integration or structured application may first solve a private business problem, then become a reusable | ||
| 217 | internal component or even a public extension. This is how practical solutions often mature. | ||
| 218 | </p> | ||
| 219 | |||
| 220 | <p> | ||
| 221 | The goal is not to customize everything. The goal is to customize the right parts, in a way that can be | ||
| 222 | understood and maintained later. When custom work is separated, documented, versioned and tested, XWiki can stay | ||
| 223 | flexible without becoming fragile. | ||
| 224 | </p> | ||
| 225 | |||
| 226 | <h2 id="custom-development-faq">XWiki custom development FAQ</h2> | ||
| 227 | |||
| 228 | <details class="resource-faq-item" open> | ||
| 229 | <summary>Does custom development make XWiki harder to upgrade?</summary> | ||
| 230 | <p> | ||
| 231 | Not automatically. Custom development becomes harder to upgrade when it is undocumented, mixed with regular | ||
| 232 | content, applied directly in production or missing from the upgrade validation plan. Well-organized custom work | ||
| 233 | can remain maintainable across upgrades. | ||
| 234 | </p> | ||
| 235 | </details> | ||
| 236 | |||
| 237 | <details class="resource-faq-item"> | ||
| 238 | <summary>Where should XWiki custom code be stored?</summary> | ||
| 239 | <p> | ||
| 240 | Custom wiki pages, scripts, templates and configuration should usually be kept in dedicated technical spaces. | ||
| 241 | Code and important assets should also be tracked in a source control system, such as Git, so changes are not | ||
| 242 | stored only in the production wiki. | ||
| 243 | </p> | ||
| 244 | </details> | ||
| 245 | |||
| 246 | <details class="resource-faq-item"> | ||
| 247 | <summary>When should an XWiki customization become an extension?</summary> | ||
| 248 | <p> | ||
| 249 | Packaging a customization as an extension is useful when the feature becomes complex, reusable, business-critical | ||
| 250 | or shared across multiple instances. Java components, event listeners, scheduled jobs and integrations often | ||
| 251 | benefit from an extension-based approach. | ||
| 252 | </p> | ||
| 253 | </details> | ||
| 254 | |||
| 255 | <details class="resource-faq-item"> | ||
| 256 | <summary>What should be tested after an XWiki upgrade?</summary> | ||
| 257 | <p> | ||
| 258 | Besides standard pages, the validation should include custom dashboards, templates, macros, workflows, | ||
| 259 | permissions, notifications, PDF exports, scheduled jobs, integrations and any custom applications used by the | ||
| 260 | organization. | ||
| 261 | </p> | ||
| 262 | </details> | ||
| 263 | |||
| 264 | <details class="resource-faq-item"> | ||
| 265 | <summary>Why should configuration be kept outside custom code?</summary> | ||
| 266 | <p> | ||
| 267 | Values such as group names, target spaces, external URLs, email recipients and workflow settings can change over | ||
| 268 | time. Keeping them in configuration pages or preference objects makes custom features easier to adapt without | ||
| 269 | changing the implementation. | ||
| 270 | </p> | ||
| 271 | </details> | ||
| 272 | |||
| 273 | <div class="resource-note"> | ||
| 274 | <p> | ||
| 275 | Related resources: | ||
| 276 | <a href="$xwiki.getURL('resources.xwiki-security-review')">what an XWiki security review should actually include</a> | ||
| 277 | and | ||
| 278 | <a href="$xwiki.getURL('resources.why-upgrade-xwiki')">why regular XWiki upgrades matter</a> | ||
| 279 | </p> | ||
| 280 | </div> | ||
| 281 | |||
| 282 | <div class="resource-cta"> | ||
| 283 | <h3>Need help reviewing XWiki customizations?</h3> | ||
| 284 | <p> | ||
| 285 | If your XWiki instance includes custom scripts, dashboards, workflows, templates, integrations or Java | ||
| 286 | extensions, a customization review can help identify what is safe, what needs documentation and what should be | ||
| 287 | tested before the next upgrade. | ||
| 288 | </p> | ||
| 289 | <a class="btn btn-primary" href="$xwiki.getURL('contact.WebHome')">Request a customization review</a> | ||
| 290 | </div> | ||
| 291 | |||
| 292 | </article> | ||
| 293 | </div> | ||
| 294 | </div> | ||
| 295 | </section> | ||
| 296 | |||
| 297 | <script type="application/ld+json"> | ||
| 298 | { | ||
| 299 | "@context": "https://schema.org", | ||
| 300 | "@type": "FAQPage", | ||
| 301 | "mainEntity": [ | ||
| 302 | { | ||
| 303 | "@type": "Question", | ||
| 304 | "name": "Does custom development make XWiki harder to upgrade?", | ||
| 305 | "acceptedAnswer": { | ||
| 306 | "@type": "Answer", | ||
| 307 | "text": "Not automatically. Custom development becomes harder to upgrade when it is undocumented, mixed with regular content, applied directly in production or missing from the upgrade validation plan. Well-organized custom work can remain maintainable across upgrades." | ||
| 308 | } | ||
| 309 | }, | ||
| 310 | { | ||
| 311 | "@type": "Question", | ||
| 312 | "name": "Where should XWiki custom code be stored?", | ||
| 313 | "acceptedAnswer": { | ||
| 314 | "@type": "Answer", | ||
| 315 | "text": "Custom wiki pages, scripts, templates and configuration should usually be kept in dedicated technical spaces. Code and important assets should also be tracked in a source control system, such as Git, so changes are not stored only in the production wiki." | ||
| 316 | } | ||
| 317 | }, | ||
| 318 | { | ||
| 319 | "@type": "Question", | ||
| 320 | "name": "When should an XWiki customization become an extension?", | ||
| 321 | "acceptedAnswer": { | ||
| 322 | "@type": "Answer", | ||
| 323 | "text": "Packaging a customization as an extension is useful when the feature becomes complex, reusable, business-critical or shared across multiple instances. Java components, event listeners, scheduled jobs and integrations often benefit from an extension-based approach." | ||
| 324 | } | ||
| 325 | }, | ||
| 326 | { | ||
| 327 | "@type": "Question", | ||
| 328 | "name": "What should be tested after an XWiki upgrade?", | ||
| 329 | "acceptedAnswer": { | ||
| 330 | "@type": "Answer", | ||
| 331 | "text": "Besides standard pages, the validation should include custom dashboards, templates, macros, workflows, permissions, notifications, PDF exports, scheduled jobs, integrations and any custom applications used by the organization." | ||
| 332 | } | ||
| 333 | }, | ||
| 334 | { | ||
| 335 | "@type": "Question", | ||
| 336 | "name": "Why should configuration be kept outside custom code?", | ||
| 337 | "acceptedAnswer": { | ||
| 338 | "@type": "Answer", | ||
| 339 | "text": "Values such as group names, target spaces, external URLs, email recipients and workflow settings can change over time. Keeping them in configuration pages or preference objects makes custom features easier to adapt without changing the implementation." | ||
| 340 | } | ||
| 341 | } | ||
| 342 | ] | ||
| 343 | } | ||
| 344 | </script> | ||
| 345 | |||
| 346 | {{/html}} | ||
| 347 | {{/velocity}} |