sgcHTML: JavaScript 없이 Delphi에서 모던 웹 UI 구축하기

· 컴포넌트

Delphi 개발자들은 30년 동안 비즈니스 애플리케이션을 구축해 왔습니다. 백엔드는 탄탄합니다. 데이터베이스 접근, 비즈니스 로직, 보고서 생성, 서비스 통합. 문제는 항상 프론트엔드에 있었습니다. 고객이 브라우저 기반 인터페이스를 요청하는 순간, 기존 Delphi 방식은 한계에 부딪힙니다. IntraWeb(강력하지만 상태 저장 방식이고 노후화됨)에 손을 뻗거나, TMS WEB Core(Pascal을 JavaScript로 컴파일하지만 클라이언트사이드 배포 모델을 강제함)를 시도하거나, 프론트엔드를 JavaScript 팀에 맡기고 완전히 분리된 두 개의 코드베이스를 유지해야 합니다.

sgcHTML은 다른 접근 방식을 취합니다. Delphi, C++ Builder 또는 .NET 코드에서 직접 Bootstrap 5 HTML을 생성하는 60개 이상의 서버사이드 컴포넌트 라이브러리입니다. 속성을 설정하고 HTML 속성을 읽어 결과를 제공하면 됩니다. 인터랙티비티는 htmx에서 제공됩니다. htmx는 서버가 클릭 및 폼 제출에 응답하여 페이지 조각을 교체할 수 있게 해주는 소형 JavaScript 라이브러리로, 직접 JavaScript를 작성할 필요가 없습니다. 결과는 Object Pascal 또는 C#으로 완전히 구축된 모던하고 반응형인 웹 애플리케이션입니다.

sgcHTML이 해결하는 문제

표준 Delphi VCL 아키텍처는 두꺼운 클라이언트를 가정합니다. Windows에서 실행되는 폼, 그리드, 대화 상자가 그것입니다. 이 모델은 내부 도구에는 잘 작동합니다. 하지만 고객이 어떤 기기의 브라우저에서도 접근 가능한 포털을 원하거나, IT 정책이 데스크톱 애플리케이션 설치를 금지할 때는 한계를 드러냅니다.

sgcHTML 이전의 대안들은 모두 마찰이 있었습니다:

sgcHTML은 이 공백을 채웁니다. 네이티브 Delphi 컴포넌트 라이브러리로, 그 출력물은 모든 브라우저가 이해하는 표준적이고 모던한 Bootstrap 5 HTML이며, htmx로 활성 상태를 유지하고, 단일 Pascal 또는 C# 코드베이스에서 모두 제어됩니다.

작동 방식

아키텍처는 세 개의 레이어로 구성됩니다.

첫째, TsgcHTMLComponent_Chart, TsgcHTMLComponent_DataTable 또는 TsgcHTMLComponent_StatCard와 같은 컴포넌트는 자신을 Bootstrap 5 HTML로 표현하는 방법을 알고 있습니다. 일반 공개 속성을 통해 구성하고 HTML 속성을 호출하여 마크업을 가져옵니다.

둘째, 페이지 빌더(TsgcHTMLPageBuilder)가 컴포넌트들을 반응형 그리드로 조합합니다. 각 컴포넌트에 Section, SectionTitle, SectionOrder, ColumnWidth(Bootstrap의 1–12 컬럼 그리드)를 지정하면 페이지 빌더가 자동으로 배치합니다.

셋째, 서버 엔진(TsgcHTMLEngine_Server)이 모든 것을 sgcWebSockets의 TsgcWSHTTPServer에 연결합니다. 요청은 OnCommandGet 핸들러에서 수신되며, 컴포넌트로 구성된 완전한 HTML 페이지로 응답합니다. Bootstrap CSS와 JavaScript는 라이브러리 내부에 임베디드 리소스로 포함되어 있으므로, 바이너리와 함께 배포할 것이 아무것도 없습니다.

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;

60개 이상의 기성 컴포넌트

sgcHTML은 가장 일반적인 웹 UI 패턴을 포괄하는 다양한 컴포넌트 팔레트를 제공합니다. 각 컴포넌트는 폼에 드롭하거나 코드로 생성할 수 있는 표준 Delphi 클래스입니다:

DataSource 바인딩

모든 sgcHTML 컴포넌트는 애플리케이션의 TDataSource에 연결하는 DataSource 속성을 지원합니다. DataAutoRefresh := True로 설정하면 기저 데이터셋이 변경될 때 컴포넌트가 자동으로 다시 렌더링됩니다. 더 세밀한 제어를 원하면 LoadFromDataSet을 직접 호출하세요:

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

차트 컴포넌트에는 레이블 필드명과 하나 이상의 값 필드명을 받는 동일한 LoadFromDataSet 메서드가 있어, 월별 매출 쿼리를 세 줄로 막대 차트로 변환할 수 있습니다:

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

htmx를 통한 인터랙티비티 — JavaScript 불필요

정적 HTML은 유용합니다. 인터랙티브 HTML은 필수입니다. sgcHTML은 htmx를 통해 인터랙티비티를 구현합니다. htmx는 클릭과 폼 제출을 가로채고, 서버에 HTTP 요청을 전송하고, 응답 HTML을 페이지에 교체하는 소형 라이브러리(압축 시 14KB)입니다. Delphi의 OnCommandGet 또는 OnCommandOther 핸들러가 요청을 받아 관련 컴포넌트를 재구성하고 HTML을 반환합니다. 페이지 새로고침 없음. JavaScript 프레임워크 없음.

// 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;

브라우저의 차트는 프래그먼트 엔드포인트를 가리키는 hx-get 속성을 가집니다. 사용자가 드롭다운에서 다른 범위를 선택하면, htmx가 차트 div를 제자리에서 교체합니다. 주변 페이지는 새로고침되지 않습니다.

WebSocket을 통한 실시간 업데이트

sgcHTML은 sgcWebSockets 위에 구축되어 있으므로, 실시간 푸시가 핵심 기능입니다. 새 주문, 가격 틱, 센서 판독값 등 새 데이터가 도착하면 서버가 WebSocket을 통해 HTML 조각을 푸시하고 htmx가 올바른 DOM 요소에 삽입합니다. 클라이언트는 WebSocket 엔드포인트를 구독하고, 서버는 SendMessage를 호출합니다. 폴링 없음, 롱폴링 없음, 외부 메시지 브로커 없음.

// 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;

JavaScript 빌드 체인 없음, npm 없음, Node.js 없음

sgcHTML에 필요한 모든 JavaScript 및 CSS 에셋(Bootstrap 5, Chart.js, htmx)은 컴파일된 Delphi 실행 파일 내부에 바이너리 리소스로 임베드됩니다. 배포물은 단일 .exe 파일입니다. node_modules 디렉터리도, webpack 설정도, Babel 파이프라인도, 프론트엔드 패키지 매니저와 백엔드 간의 버전 충돌도 없습니다. sgcHTML을 Delphi 패키지로 설치하고, 컴파일하고, 배포하면 끝입니다.

시작하기

sgcHTML은 sgcWebSockets Enterprise 및 All-Access 에디션의 일부로 제공되며, 단독 구매도 가능합니다. 무료 체험판을 다운로드할 수 있습니다. 체험판은 체험 기간 동안 기능 제한 없이 60개 이상의 모든 컴포넌트를 포함합니다.

이 라이브러리는 Delphi 10.2 Tokyo부터 Delphi 13, C++ Builder 10.2부터 13을 지원하며, .NET 에디션은 .NET 6 이상을 대상으로 합니다. 전체 소스 코드는 모든 유료 플랜에 포함되어 있습니다.

문의 사항이나 구매 전 질문이 있으신가요? 연락하기. 코드를 직접 작성한 담당자로부터 답변을 받을 수 있습니다.