Skip to content

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.

pascal
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.

pascal
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).

pascal
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.

pascal
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);.

pascal
procedure PopulateRecordFromPost(ARecord: TKViewTableRecord;

Populates a record's field values from the current POST data. Shared by HandleKXSaveRequest, HandleKXDetailSaveRequest, HandleKXWizardFinishRequest.

pascal
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.

pascal
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).

pascal
procedure AdjustControllerForContext(const AController: IKXController);

Adjusts controller modal/size for the current context. Mobile: forces IsModal + Maximized. Desktop non-modal: clears dimensions.

pascal
procedure ActivateInstance;

Sets up thread-local singletons (Authenticator, AccessController, Macros). Must be called before any handler that accesses metadata or stores.

pascal
procedure DeactivateInstance;

Clears the thread-local singletons set by ActivateInstance (call in a finally).

pascal
procedure UpdateObserver(const ASubject: IEFSubject;

IEFObserver hook; reacts to configuration/subject change notifications.

pascal
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.

pascal
property Config: TKConfig read FConfig;

The application's configuration (Config.yaml catalog).

pascal
procedure ReloadConfig;

Reloads the configuration from disk.

pascal
function GetHomeView: TKView;

Returns the application's home view.

pascal
procedure DisplayView(const AName: string);

Displays the view with the given name.

pascal
procedure DisplayView(const AView: TKView);

Displays the given view.

pascal
property Path: string read FPath;

The application base URL path (e.g. '/taskittox').

pascal
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.
pascal
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.
pascal
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.
pascal
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.
pascal
function GetImageURL(const AResourceName: string;

Returns the URL of the named image resource (raises if not found).

pascal
function FindImageURL(const AResourceName: string;

Returns the URL of the named image resource, or '' if not found.

pascal
function GetImagePathName(const AResourceName: string;

Returns the full path of the named image resource (raises if not found).

pascal
function FindImagePathName(const AResourceName: string;

Returns the full path of the named image resource, or '' if not found.

pascal
procedure ReloadOrDisplayHomeView;

Reloads (or displays) the home view, e.g. after a language change.

pascal
function GetLoginView: TKView;

Returns the application's login view.

pascal
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.

pascal
procedure DisplayLoginView;

Renders and serves the login view page.

pascal
procedure Toast(const AMessage: string);

Emits a client-side toast notification with the given message.

pascal
procedure Navigate(const AURL: string);

Emits a client-side navigation to the given URL.

pascal
procedure DownloadFile(const AServerFileName, AFileName: string;

Serves a server file as a download (or inline) response.

pascal
procedure DownloadStream(const AStream: TStream;

Serves the given stream as a download (or inline) response; takes ownership of AStream.

pascal
procedure DownloadBytes(const ABytes: TBytes;

Serves the given bytes as a download (or inline) response.

pascal
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.

pascal
function GetMethodURL(const AObjectName, AMethodName: string): string;

Builds the URL for a method call (AppPath + namespace + object/method).

pascal
function GetHomeURL(const ATCPPort: Integer): string;

Returns the Home URL of the Kitto application assuming the URL is visited from localhost.

pascal
function TooltipsEnabled: Boolean;

True if tooltips are enabled for the application. By default, tooltips are enabled for desktop browsers and disabled for mobile browsers.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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.

pascal
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').

pascal
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.

pascal
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.

pascal
procedure Logout;

Logs the current user out via the authenticator and triggers a full client-side page reload (back to the login page).

pascal
property Authenticator: TKAuthenticator read GetAuthenticator;

Returns the current authenticator instance, creating it on first access from the Auth configuration node.

Released under Apache License, Version 2.0.