sgcHTML: Moderne web-UI’s bouwen vanuit Delphi zonder JavaScript te schrijven

· Componenten

Delphi-ontwikkelaars bouwen al dertig jaar zakelijke applicaties. De back-end is solide: databasetoegang, bedrijfslogica, rapportgeneratie, service-integratie. Het probleem zat altijd aan de front-end. Zodra een klant vraagt om een browsergebaseerde interface, werkt de klassieke Delphi-aanpak niet meer. Je grijpt dan naar IntraWeb (krachtig maar stateful en verouderd), probeert TMS WEB Core (dat Pascal naar JavaScript compileert maar een client-side deploymentmodel vereist), of geeft de front-end aan een JavaScript-team en onderhoudt twee volledig gescheiden codebases.

sgcHTML kiest een andere aanpak. Het is een bibliotheek van meer dan 60 server-side componenten die Bootstrap 5 HTML rechtstreeks genereren vanuit je Delphi-, C++ Builder- of .NET-code. Je stelt properties in, leest de eigenschap HTML uit en serveert het resultaat. Interactiviteit komt van htmx, een kleine JavaScript-bibliotheek die de server in staat stelt pagina-fragmenten te wisselen als reactie op klikken en formulierinzendingen — zonder dat je zelf JavaScript hoeft te schrijven. Het resultaat is een moderne, responsieve webapplicatie die volledig in Object Pascal of C# is gebouwd.

Het probleem dat sgcHTML oplost

De standaard Delphi VCL-architectuur gaat uit van een dikke client: formulieren, rasters en dialoogvensters die op Windows draaien. Dat model werkt goed voor interne hulpmiddelen. Het schiet tekort als de klant een portal wil die vanuit een browser op elk apparaat toegankelijk is, of als het IT-beleid het installeren van desktopapplicaties verbiedt.

De alternatieven vóór sgcHTML hadden allemaal hun beperkingen:

sgcHTML vult het gat: een native Delphi-componentenbibliotheek waarvan de uitvoer standaard, moderne Bootstrap 5 HTML is die elke browser begrijpt, levendig gehouden door htmx, alles aangestuurd vanuit één enkele Pascal- of C#-codebase.

Hoe het werkt

De architectuur bestaat uit drie lagen.

Ten eerste weet een component zoals TsgcHTMLComponent_Chart, TsgcHTMLComponent_DataTable of TsgcHTMLComponent_StatCard zichzelf als Bootstrap 5 HTML te beschrijven. Je configureert het via gewone gepubliceerde properties en roept de eigenschap HTML aan om de opmaak op te halen.

Ten tweede assembleert een page builder (TsgcHTMLPageBuilder) componenten tot een responsief raster. Je wijst elk component een Section, een SectionTitle, een SectionOrder en een ColumnWidth toe (Bootstrap's 1–12 kolomraster). De page builder rangschikt ze automatisch.

Ten derde koppelt een server engine (TsgcHTMLEngine_Server) alles aan een TsgcWSHTTPServer uit sgcWebSockets. Verzoeken komen binnen in je OnCommandGet-handler en je reageert met een volledige HTML-pagina opgebouwd uit je componenten. De Bootstrap CSS en JavaScript zijn ingesloten als binaire resources in de bibliotheek, zodat er niets naast het uitvoerbaar bestand hoeft te worden gedeployed.

uses
  sgcWebSocket_Server, sgcHTML_Engine_Server,
  sgcHTML_Template_Bootstrap, sgcHTML_Page,
  sgcHTML_Component_StatCard, sgcHTML_Component_Chart;

var
  oServer:   TsgcWSHTTPServer;
  oEngine:   TsgcHTMLEngine_Server;
  oTemplate: TsgcHTMLTemplate_Bootstrap;
  oPage:     TsgcHTMLPage;
  oStat:     TsgcHTMLComponent_StatCard;
  oChart:    TsgcHTMLComponent_Chart;
begin
  oServer := TsgcWSHTTPServer.Create(nil);
  oServer.Port := 8080;

  oEngine   := TsgcHTMLEngine_Server.Create(nil);
  oEngine.Server := oServer;

  oTemplate := TsgcHTMLTemplate_Bootstrap.Create(nil);
  oTemplate.Title := 'My Dashboard';

  oPage := TsgcHTMLPage.Create(nil);

  // KPI card: total revenue
  oStat := TsgcHTMLComponent_StatCard.Create(nil);
  oStat.PageBuilder := oPage.PageBuilder;
  oStat.Section := 'kpi';
  oStat.SectionOrder := 1;
  oStat.ColumnWidth := cw3;
  oStat.Title := 'Total Revenue';
  oStat.Value := '$128,450';
  oStat.Trend := stUp;
  oStat.TrendValue := '+12%';

  // Revenue trend chart
  oChart := TsgcHTMLComponent_Chart.Create(nil);
  oChart.PageBuilder := oPage.PageBuilder;
  oChart.Section := 'charts';
  oChart.SectionOrder := 1;
  oChart.ColumnWidth := cw8;
  oChart.ChartType := ctLine;
  oChart.Title := 'Monthly Revenue';
  oChart.AddLabel('Jan'); oChart.AddLabel('Feb'); oChart.AddLabel('Mar');
  oChart.AddDataset('2026', [42000, 58000, 64000], '#0d6efd', '', True);

  oServer.Active := True;
end;

Meer dan 60 kant-en-klare componenten

sgcHTML wordt geleverd met een uitgebreid componentenpalet dat de meest voorkomende web-UI-patronen dekt. Elk component is een standaard Delphi-klasse die je op een formulier kunt neerzetten of in code kunt aanmaken:

DataSource-koppeling

Elk sgcHTML-component ondersteunt een eigenschap DataSource die het koppelt aan elke TDataSource in je applicatie. Stel DataAutoRefresh := True in en het component herdert zich automatisch wanneer de onderliggende dataset verandert. Voor nauwkeurigere controle roep je LoadFromDataSet rechtstreeks aan:

uses
  sgcHTML_Component_DataTable;

// Populate a data table from a FireDAC query
oTable := TsgcHTMLComponent_DataTable.Create(nil);
oTable.PageBuilder := oPage.PageBuilder;
oTable.Section := 'invoices';
oTable.Title := 'Recent Invoices';
oTable.ShowSearch := True;
oTable.ShowExport := True;
oTable.LoadFromDataSet(FDQuery1, 20); // 20 rows per page

Het grafiekcomponent heeft een bijpassende methode LoadFromDataSet die een veldnaam voor labels en een of meer veldnamen voor waarden accepteert, waardoor een omzet-per-maand-query in drie regels een staafgrafiek wordt:

oChart.LoadFromDataSet(fdqRevenue, 'month', ['revenue', 'cost']);

Interactiviteit via htmx — geen JavaScript vereist

Statische HTML is nuttig. Interactieve HTML is noodzakelijk. sgcHTML bereikt interactiviteit via htmx: een kleine bibliotheek (14 KB gecomprimeerd) die klikken en formulierinzendingen onderschept, een HTTP-verzoek naar je server stuurt en de HTML-respons in de pagina verwisselt. Je Delphi-handler OnCommandGet of OnCommandOther ontvangt het verzoek, herbouwt het relevante component en retourneert diens HTML. Geen pagina-herlaad. Geen JavaScript-framework.

// Server-side handler: update the chart fragment when the user changes the date range
procedure TMyServer.HandleChartFragment(aReq: TIdHTTPRequestInfo;
  aResp: TIdHTTPResponseInfo);
var
  oChart: TsgcHTMLComponent_Chart;
  vRange: string;
begin
  vRange := aReq.Params.Values['range']; // 'week', 'month', 'year'
  oChart := TsgcHTMLComponent_Chart.Create(nil);
  try
    oChart.ChartType := ctBar;
    LoadRevenueData(oChart, vRange); // your data-loading procedure
    aResp.ContentText := oChart.HTML;
    aResp.ContentType := 'text/html';
  finally
    oChart.Free;
  end;
end;

De grafiek in de browser bevat een attribuut hx-get dat verwijst naar het fragment-eindpunt. Wanneer de gebruiker een ander bereik selecteert in een vervolgkeuzelijst, vervangt htmx de grafiek-div op zijn plaats — de omringende pagina herlaadt niet.

Realtime-updates via WebSocket

Omdat sgcHTML is gebouwd op sgcWebSockets, is realtime push een eersteklas functie. Wanneer nieuwe gegevens binnenkomen — een nieuwe bestelling, een koerswijziging, een sensorwaarde — stuurt je server een HTML-fragment via WebSocket en voegt htmx dit in het juiste DOM-element in. De client abonneert zich op een WebSocket-eindpunt; de server roept SendMessage aan. Geen polling, geen long-polling, geen externe message broker.

// Push an updated stat card to all connected clients
procedure TDashboardServer.PushRevenueUpdate(aNewRevenue: Double);
var
  oCard: TsgcHTMLComponent_StatCard;
begin
  oCard := TsgcHTMLComponent_StatCard.Create(nil);
  try
    oCard.CardID := 'kpi-revenue';
    oCard.Title := 'Total Revenue';
    oCard.Value := FormatCurr('$#,##0', aNewRevenue);
    oCard.Trend := stUp;
    // Send the HTML fragment to all clients subscribed to this channel
    FWSServer.Broadcast(oCard.HTML);
  finally
    oCard.Free;
  end;
end;

Geen JavaScript-buildketen, geen npm, geen Node.js

Elk JavaScript- en CSS-bestand dat sgcHTML nodig heeft (Bootstrap 5, Chart.js, htmx) is ingesloten als binaire resource in het gecompileerde Delphi-uitvoerbaar bestand. Je deployment bestaat uit één enkel .exe-bestand. Er is geen map node_modules, geen webpack-configuratie, geen Babel-pipeline en geen versieconflicten tussen een front-end pakketbeheerder en je back-end. Je installeert sgcHTML als een Delphi-pakket, compileert en levert op.

Aan de slag

sgcHTML wordt meegeleverd als onderdeel van de sgcWebSockets Enterprise- en All-Access-edities, en is ook afzonderlijk verkrijgbaar. Een gratis proefversie is beschikbaar om te downloaden. De proefversie bevat alle 60+ componenten zonder functiebeperkingen gedurende de proefperiode.

De bibliotheek ondersteunt Delphi 10.2 Tokyo tot en met Delphi 13 en C++ Builder 10.2 tot en met 13, en de .NET-editie richt zich op .NET 6 en later. Volledige broncode is inbegrepen in alle betaalde niveaus.

Vragen of verkoopgerelateerde vragen? Neem contact op. Je ontvangt een antwoord van de mensen die de code hebben geschreven.