Kitto.Web.Application
Main application route for KittoX. TKWebApplication is the top-level handler that owns the app configuration, authenticator and access controller, resolves resource/image URLs, serves the Home and Login pages, exposes the helpers shared with the attribute-based endpoint handlers (view lookup, ACL gating, record population from POST, downloads, JWT hydration) and registers the routing and static-resource routes. Also defines the application macro expander (%SESSION_ID%, %LANGUAGE_ID%, %Auth:*%, %IMAGE(...)%).
TKApplicationMacroExpander class
Macro expander bound to an application. Adds the KittoX runtime macros on top of the inherited tree expansion: %SESSION_ID%, %LANGUAGE_ID%, the %Auth:*% session auth-data macros, and %IMAGE(name)% resolved to a resource URL.
constructor Create(const AApplication: TKWebApplication);Creates the macro expander bound to the given application.
TKWebApplication class
The main KittoX application route. Owns the application configuration, authenticator and access controller; serves the Home and Login pages and every request under its base path; resolves resource and image URLs/paths; and provides the shared helpers used by the attribute-based endpoint handlers. A per-thread Current instance is set for the duration of each request via ActivateInstance/DeactivateInstance.
function IsViewAccessGranted(const AView: TKView;Returns True when AView grants AMode to the current session. On deny: sets TKWebResponse.Current.StatusCode := 404 and logs 'ACL deny: ...' at LOG_DETAILED. UI components (TreePanel, ToolBar, …) already filter on IsAccessGranted; this is the matching server-side gate for every HandleKX* route. Caller pattern: if not IsViewAccessGranted(LView, ACM_X) then Exit(True);. Returning True (not False) tells the engine the request has been handled, so SimpleHandleRequest's "unknown request" fallback does NOT overwrite our empty 404 body with its HTML page (the client would otherwise parse it and accumulate orphan DOM nodes on every retry).
function FindViewOrSetNotFound(const AViewName: string): TKView;Resolves AViewName via Config.Views.FindView. On miss: sets StatusCode := 404 and logs 'View not found: ...' at LOG_DETAILED. Caller pattern: LView := FindViewOrSetNotFound(AViewName); if not Assigned(LView) then Exit(True);. Pair with IsViewAccessGranted to enforce the correct access mode AFTER the view is resolved (modes that depend on request fields like _op cannot be decided before the handler reads them). See IsViewAccessGranted for why Exit(True) is required.
function RequireDataView(const AView: TKView): Boolean;Returns True when AView is a TKDataView (the type required by every data/CRUD endpoint). On miss: sets StatusCode := 404 — a request for /kx/data/<Foo> where Foo exists but is not a data view is "no such resource" at this URL. Caller pattern: if not RequireDataView(LView) then Exit(True);.
procedure PopulateRecordFromPost(ARecord: TKViewTableRecord;Populates a record's field values from the current POST data. Shared by HandleKXSaveRequest, HandleKXDetailSaveRequest, HandleKXWizardFinishRequest.
procedure PopulateRecordFieldFromPost(ARecord: TKViewTableRecord;Applies a single field's POST value to the record, replicating the type-aware logic of PopulateRecordFromPost. Used by the notify endpoint to apply only the trigger field.
function BuildSortExpression(AViewTable: TKViewTable;Builds an ORDER BY expression from CSV sort/dir request fields. Fields not in AViewTable are silently dropped (anti SQL injection).
procedure AdjustControllerForContext(const AController: IKXController);Adjusts controller modal/size for the current context. Mobile: forces IsModal + Maximized. Desktop non-modal: clears dimensions.
procedure ActivateInstance;Sets up thread-local singletons (Authenticator, AccessController, Macros). Must be called before any handler that accesses metadata or stores.
procedure DeactivateInstance;Clears the thread-local singletons set by ActivateInstance (call in a finally).
procedure UpdateObserver(const ASubject: IEFSubject;IEFObserver hook; reacts to configuration/subject change notifications.
procedure AddedTo(const AList: TKWebRouteList;Called when the app is added to the route chain: registers the attribute router and the static-resource route ahead of this legacy handler.
property Config: TKConfig read FConfig;The application's configuration (Config.yaml catalog).
procedure ReloadConfig;Reloads the configuration from disk.
function GetHomeView: TKView;Returns the application's home view.
procedure DisplayView(const AName: string);Displays the view with the given name.
procedure DisplayView(const AView: TKView);Displays the given view.
property Path: string read FPath;The application base URL path (e.g. '/taskittox').
function GetResourceURL(const AResourceFileName: string): string;Returns the URL for the specified resource, based on the first existing file in the ordered list of resource folders. If no existing file is found, an exception is raised.
Parameters:
AResourceFileName— Resource file name relative to the resource folder. Examples: some_image.png, js\some_library.js.
function FindResourceURL(const AResourceFileName: string): string;Returns the URL for the specified resource, based on the first existing file in the ordered list of resource folders. If no existing file is found, returns ''.
Parameters:
AResourceFileName— Resource file name relative to the resource folder. Examples: some_image.png, js\some_library.js.
function GetResourcePathName(const AResourceFileName: string): string;Returns the full pathname for the specified resource, based on the first existing file in the ordered list of resource folders. If no existing file is found, an exception is raised.
Parameters:
AResourceFileName— Resource file name relative to the resource folder. Examples: some_image.png, js\some_library.js.
function FindResourcePathName(const AResourceFileName: string): string;Returns the full pathname for the specified resource, based on the first existing file in the ordered list of resource folders. If no existing file is found, returns ''.
Parameters:
AResourceFileName— Resource file name relative to the resource folder. Examples: some_image.png, js\some_library.js.
function GetImageURL(const AResourceName: string;Returns the URL of the named image resource (raises if not found).
function FindImageURL(const AResourceName: string;Returns the URL of the named image resource, or '' if not found.
function GetImagePathName(const AResourceName: string;Returns the full path of the named image resource (raises if not found).
function FindImagePathName(const AResourceName: string;Returns the full path of the named image resource, or '' if not found.
procedure ReloadOrDisplayHomeView;Reloads (or displays) the home view, e.g. after a language change.
function GetLoginView: TKView;Returns the application's login view.
function RequiredStepView(const AViewName: string): TKView;Renders and serves the home view page. Returns the view an imposed step is completed through, with a message that names the missing YAML file when the application does not declare it.
procedure DisplayLoginView;Renders and serves the login view page.
procedure Toast(const AMessage: string);Emits a client-side toast notification with the given message.
procedure Navigate(const AURL: string);Emits a client-side navigation to the given URL.
procedure DownloadFile(const AServerFileName, AFileName: string;Serves a server file as a download (or inline) response.
procedure DownloadStream(const AStream: TStream;Serves the given stream as a download (or inline) response; takes ownership of AStream.
procedure DownloadBytes(const ABytes: TBytes;Serves the given bytes as a download (or inline) response.
function Authenticate: Boolean;Checks user credentials (read from the POST body fields UserName and Password) and returns True if the current authenticator allows them, or if the user was already authenticated in this session.
function GetMethodURL(const AObjectName, AMethodName: string): string;Builds the URL for a method call (AppPath + namespace + object/method).
function GetHomeURL(const ATCPPort: Integer): string;Returns the Home URL of the Kitto application assuming the URL is visited from localhost.
function TooltipsEnabled: Boolean;True if tooltips are enabled for the application. By default, tooltips are enabled for desktop browsers and disabled for mobile browsers.
procedure AuthorizeJWTRequest;When the active authenticator has a JWT envelope configured (Authenticator.IsJWTEnabled), validates the kx_token cookie, hydrates the session from the verified claims, and slides the cookie expiration if approaching. No-op otherwise. Public so the attribute router (TKXRoutingRoute) can give attribute-routed requests the same JWT hydration as the legacy path.
procedure RenderErrorDialog(const AMessage: string;Renders a modal error dialog into the current response as an HTMX overlay. AIsFatal=True signals a fatal error (session teardown + reload to login); False lets the user dismiss and retry. Public so the error-handler request filter (Kitto.Web.Routing.AppFilters) renders exceptions uniformly for both the attribute and legacy pipelines.
Renders the error dialog and, by default, answers 500. The status is a parameter because not every error is a server failure: pass 4xx where the request was understood and simply cannot be carried out. Pass 0 to leave the status untouched.
procedure RenderWarningDialog(const AMessage: string;Renders AMessage as a dismissible WARNING, for an operation the application refused and is able to explain.
A delete held back by rows that still refer to the record is the case this exists for: nothing went wrong, so presenting it as an error would send people looking for a fault that is not there.
Renders the warning dialog and, by default, answers 422: the request was understood and refused on the application's own terms (a rule, a validation), which is not a failure of the server.
procedure RenderMessageDialog(const AMessage, AKind, ATitle: string;The dialog both of the above are made of. AKind names the CSS variant ('error', 'warning', 'info'), ATitle the heading.
Renders a modal dialog as the whole response, and sets AStatusCode unless it is 0.
The response also carries X-KittoX-Dialog: <AKind>. It is what lets the status be honest: HTMX does not swap a non-2xx response, so a dialog sent with 500 would never appear, and that is why every error used to travel as 200 -- indistinguishable, from the outside, from a success. The page template listens on htmx:beforeSwap and opts a response carrying this header back into the swap, so the dialog appears AND the status tells the truth to logs, proxies and DevTools.
function IsPublicView(const AViewName: string): Boolean;True if the named view exists and is declared public (empty ACURI, i.e. reachable without authentication via ACName in YAML). Used by the authorization filter to exempt public views from the auth gate.
procedure DeclareDatabaseMacros(const AAuthData: TEFNode);Populates AuthData.DatabaseName (raw config name) and AuthData.Environment (Databases/Name/DisplayLabel if present, falling back to the raw name) so the corresponding %Auth:* macros resolve. Public so the auth handler (Kitto.Web.Handler.Auth) can call it.
function RenderViewAsPage(const AView: TKView;Renders AView through its controller and returns the full HTML body (create controller -> Display -> Render). When AView declares no controller type, ADefaultControllerType is used (e.g. 'Login').
procedure ServeViewAsPage(const AView: TKView;Renders AView and serves it wrapped in the _Page template (theme, scripts) via ServeHomePage. Reusable entry point for page handlers.
procedure PrepareStandaloneFormRecord(const AViewName: string;Gives a standalone Form view (a view whose own Controller is a Form) its server-side record: creates the store, loads it for edit/view or appends an initialized one for add, hands it to the controller and registers the store in the session under AViewName, so that the notify cycle, the blob and detail endpoints and the save all find it. Does nothing for any other kind of view or controller. Must be called before the controller's Display. Shared by the kx/view route and by the home page renderer, which serve the same views through different paths.
procedure Logout;Logs the current user out via the authenticator and triggers a full client-side page reload (back to the login page).
property Authenticator: TKAuthenticator read GetAuthenticator;Returns the current authenticator instance, creating it on first access from the Auth configuration node.
