Wiki source code of Architecture
Last modified by gabrielc on 2026/07/13 15:15
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | How the Guided Tour extension is structured and how its components interact. | ||
| 2 | |||
| 3 | |||
| 4 | == Overview == | ||
| 5 | |||
| 6 | The extension follows a layered architecture with a Java backend and a TypeScript/Vue 3 frontend, connected through REST APIs and XWiki's document model. | ||
| 7 | |||
| 8 | |||
| 9 | == Data model == | ||
| 10 | |||
| 11 | Tours use XWiki's document and object model for storage: | ||
| 12 | |||
| 13 | {{prism}} | ||
| 14 | Tour (XWiki document + TourClass XObject) | ||
| 15 | +-- Task1 (child document + TaskClass XObject) | ||
| 16 | | +-- Step1 (StepClass XObject on task document) | ||
| 17 | | +-- Step2 (StepClass XObject on task document) | ||
| 18 | +-- Task2 (child document + TaskClass XObject) | ||
| 19 | +-- Step3 (StepClass XObject on task document) | ||
| 20 | {{/prism}} | ||
| 21 | |||
| 22 | Each tour is a single XWiki document. Tasks are child documents nested under the tour. Steps are XObjects stored on their parent task document. | ||
| 23 | |||
| 24 | User progress is stored in localStorage. This means that user progress will not sync across user devices. | ||
| 25 | |||
| 26 | |||
| 27 | == Module layering == | ||
| 28 | |||
| 29 | === API layer (##guidedtour-api##) === | ||
| 30 | |||
| 31 | Defines the public contract: DTOs (TourDTO, TaskDTO, StepDTO, UserTourStatusDTO), enums (Placement, ActionType, Status, WidgetState), and exceptions (InvalidIdException, DuplicatedIdException). This module has no implementation dependencies. | ||
| 32 | |||
| 33 | |||
| 34 | === Service layer (##guidedtour-default##) === | ||
| 35 | |||
| 36 | Implements the core business logic. Four manager classes handle CRUD operations: | ||
| 37 | |||
| 38 | * ToursManager - tour CRUD operations through DTOs | ||
| 39 | * TasksManager - task CRUD operations through DTOs, with ordering and dependency resolution | ||
| 40 | * StepsManager - step CRUD operations through DTOs, with ordering | ||
| 41 | * UserStatusManager - per-user progress persistence | ||
| 42 | |||
| 43 | Managers use XWiki's document API for storage and Solr queries for listing. | ||
| 44 | |||
| 45 | |||
| 46 | === REST layer (##guidedtour-rest##) === | ||
| 47 | |||
| 48 | Exposes the service layer as REST endpoints. Two sub-modules separate contract (guidedtour-rest-api) from implementation (guidedtour-rest-default). A base class (AbstractGuidedTourResource) handles CSRF validation, authorization checks, and error mapping. | ||
| 49 | |||
| 50 | For a more in-depth description of all available endpoints, see the [[REST API>>doc:documentation.extensions.dev.guided-tour.rest-api.WebHome]] documentation page. | ||
| 51 | |||
| 52 | |||
| 53 | === UI layer (##guidedtour-ui##) === | ||
| 54 | |||
| 55 | An XAR package containing XWiki pages, classes, sheets, translations, and a UI Extension (Bound on ##org.xwiki.platform.template.header.after##) that injects the widget into the page header. The GuidedTour.WebHome page provides a LiveData table for tour management. | ||
| 56 | |||
| 57 | |||
| 58 | === Frontend layer === | ||
| 59 | |||
| 60 | The widget is a Vue 3 application built with TypeScript and driver.js: | ||
| 61 | |||
| 62 | * **@xwiki/contrib-guidedtour-api** - TypeScript interfaces mirroring the Java DTOs | ||
| 63 | * **@xwiki/contrib-guidedtour-xwiki** - XWiki-specific implementations: REST client (GuidedTourRestClient), tour player (DefaultGuidedTourManager), storage manager, and caching (TourStore) | ||
| 64 | * **@xwiki/contrib-guidedtour-ui** - Vue 3 components (GuidedTourWidget and sub-components) | ||
| 65 | |||
| 66 | The widget is packaged as a WebJar and injected into every page via a UI Extension hook. | ||
| 67 | |||
| 68 | |||
| 69 | == Data flow == | ||
| 70 | |||
| 71 | 1. The Vue widget initializes on page load and fetches available tours from the REST API. | ||
| 72 | 1. User progress is loaded from the localStorage | ||
| 73 | 1. When a user starts a task, the frontend fetches the steps and initializes the driver.js overlay. | ||
| 74 | 1. Navigation between steps updates the driver.js highlight position. All data related to a tour in progress (cached steps, current step index, task id) is saved in sessionStorage. | ||
| 75 | 1. Task completion updates the localStorage user progress state. | ||
| 76 | |||
| 77 | |||
| 78 | |||
| 79 | == Key design decisions == | ||
| 80 | |||
| 81 | * **XWiki document model** - Tours leverage XWiki's native storage and permission system. No separate database is required. | ||
| 82 | * **CSS selector-based targeting** - Steps use CSS selectors to determine which elements to target, making tours customizable and adaptable to different skins. | ||
| 83 | * **REST API abstraction** - All CRUD operations are available through REST endpoints, enabling third-party integrations. | ||
| 84 | * **Session storage for multi-page tours** - Active task state is stored client-side to survive page navigation without server round trips. | ||
| 85 | * **Legacy compatibility** - The extension detects the legacy Tour Application and disables itself to prevent conflicts. | ||
| 86 | |||
| 87 | |||
| 88 | |||
| 89 | == Dependencies == | ||
| 90 | |||
| 91 | * **driver.js** - Lightweight overlay engine for step highlights and tooltips | ||
| 92 | * **Vue 3** - Reactive UI framework for the widget | ||
| 93 | * **Vite** - Build tool for the frontend bundle | ||
| 94 | * **XWiki REST API** - Server-side extension points and document APIs | ||
| 95 | * **Solr** - Used for efficient listing queries |