sgcHTML 五分钟上手

sgcHTML 将 Object Pascal 转换为 HTML。您将页面构建为组件树,读取一个字符串属性,再把这个字符串写入 HTTP 响应。本页正是这样做的,随后会指向您接下来可能需要的部分:表单、表格、图表和 htmx。

服务器端的 Bootstrap 5 和 htmx
无需编写 JavaScript
Windows、Linux 和 macOS

第一个页面所需的内容

一个能把自己渲染成字符串的页面组件,以及一个把该字符串交给浏览器的 HTTP 服务器。共两个对象。

页面组件

TsgcHTMLComponent_Site,声明在 sgcHTML_Component_Site.pas 中,注册在 SGC HTML 组件面板页上。它会渲染整个外壳:导航、侧边栏、主题和内容。

唯一重要的属性

HTML,继承自 TsgcHTMLComponent。它是只读的,读取它会把当前组件树渲染成完整的 HTML 文档。

服务器

任何能把字符串写入 HTTP 响应的程序都可以。随包附带的演示在有 Professional 构建时使用 sgcWebSocket_Server.pas 中的 TsgcWSHTTPServer,否则回退到 TIdHTTPServer。

平台

仅限桌面和服务器。SGC_HTML 定义在 {$IFNDEF ANDROID} 和 {$IFNDEF IOS} 之内,因此在移动平台上每个 sgcHTML 单元编译后都是空的。Windows、macOS 和 Linux 都没有问题。

要求与版本

版本列给出的是控制代码的定义,以及它在 Source/sgcVer.inc 中所在的行号。

项目 值
IDE Delphi 7 到 RAD Studio 13,以及 C++Builder 2007 到 13。同样支持 Lazarus,并且附带一个已在 Linux 上运行过的 ERP 演示。
uses 子句 页面外壳使用 sgcHTML_Component_Site,再加上您实际用到的节点单元,例如 sgcHTML_Nodes、sgcHTML_Nodes_Bootstrap、sgcHTML_Nodes_Table、sgcHTML_Nodes_Forms 和 sgcHTML_Nodes_Charts。
包定义 SGC_PACK_HTML 定义在第 871 行,位于从第 870 行延伸到第 874 行的 {$IFDEF SGC_EDT_ALL} 块内。在 sgcWebSockets 源代码树中,这意味着由 All-Access 版本启用它。sgcHTML 也作为独立产品销售,拥有自己的安装程序和许可证。
功能定义 位于第 882 行到第 892 行的 {$IFDEF SGC_PACK_HTML} 块内:SGC_HTML 在第 885 行,SGC_HTMX 在第 886 行,两者都位于第 883 行的 {$IFNDEF ANDROID} 和第 884 行的 {$IFNDEF IOS} 之内。设计时可视化界面 SGC_HTML_CONTROL 在第 888 行,位于第 887 行的 {$IFDEF MSWINDOWS} 之内。
这对移动平台意味着什么 每个 sgcHTML 单元都把它的接口部分包裹在 {$IFDEF SGC_HTML} 中,因此 Android 或 iOS 构建会把它们编译成空单元。这是一个服务器端库,这正是它的用意:手机收到的是 HTML,而不是 Pascal。
注册 只有在 SGC_PACK_HTML 和 SGC_HTML 都已定义时,才会注册组件面板页。

有哪些组件?大约八十个,从表格和调度器到图表、富文本编辑器、二维码和摄像头扫描器。功能矩阵按领域对它们进行了分组,每个组件在组件下都有自己的页面。

安装并找到组件面板页

sgcHTML 作为独立的包发布,也包含在 sgcWebSockets 的 All-Access 构建中。两种方式的安装流程相同。

1. 解压

将下载文件解压到一个文件夹,下文称之为 {$DIR}。

2. 库路径

依次选择 Tools、Options、Library。添加 {$DIR}\source 以及与您的 IDE 对应的 lib 文件夹,例如 {$DIR}\libD13\$(Platform)。

3. 构建包

在 {$DIR}\Packages\ 下,打开与您的 IDE 版本对应的包组。先编译运行时 .dpk,再安装设计时 dcl 包。Lazarus 改用 .lpk。

4. 检查组件面板

会出现一个名为 SGC HTML 的页面,包含大约八十个组件。如果在 Android 或 iOS 目标上它缺失,这是正常的,因为那里排除了 SGC_HTML。

5. 先运行一个演示

打开 {$DIR}\Demos\60.HTML\01.RunTime\07.Site,构建并运行它。它是一个控制台服务器,会打印自己的 URL,下面的代码就来自它。

用 Pascal 编写页面,通过 HTTP 提供服务

构建页面,读取 HTML 属性,把它写入响应。第一个选项卡是页面,第二个是服务器,第三个是完整的控制台程序。

sgcSiteDemo_Pages.pas
uses
  SysUtils, Classes,
  // sgc
  sgcHTML_Component_Site;

class function TsgcSiteDemoPages.BuildPage: string;
var
  oSite: TsgcHTMLComponent_Site;
begin
  oSite := TsgcHTMLComponent_Site.Create(nil);
  try
    oSite.Title := 'sgcHTML Site Layouts';
    oSite.Layout := slSidebarLeft;

    oSite.AddMenu('Dashboard', '/');
    oSite.AddMenu('Customers', '/?page=customers');

    oSite.AddSection('Welcome', '<p>Served from Delphi.</p>');

    // reading HTML is what runs the render
    Result := oSite.HTML;
  finally
    oSite.Free;
  end;
end;

Layout 接受 TsgcHTMLSiteLayout:slSidebarLeft、slSidebarRight、slTopNav、slTopNavSidebarLeft、slIconRail 或 slOffcanvas。默认值是 slTopNavSidebarLeft,因此上面那一行只是为了演示如何切换。

sgcSiteDemo_Server.pas
uses
  SysUtils, Classes,
  // sgc
  sgcWebSocket_Server,
{$IFDEF SGC_INDY}
  sgcIdContext, sgcIdCustomHTTPServer;
{$ELSE}
  IdContext, IdCustomHTTPServer;
{$ENDIF}

constructor TsgcSiteDemoServer.Create;
begin
  inherited Create;
  FPort := 8092;
  FHTTP := TsgcWSHTTPServer.Create(nil);
  FHTTP.Port := FPort;
  FHTTP.OnCommandGet := HandleCommandGet;
end;

procedure TsgcSiteDemoServer.Start;
begin
  FHTTP.Active := True;
end;

procedure TsgcSiteDemoServer.SendHTML(AResponseInfo: TIdHTTPResponseInfo;
  const aHTML: string);
begin
  AResponseInfo.ResponseNo := 200;
  AResponseInfo.ContentType := 'text/html; charset=utf-8';
  AResponseInfo.ContentText := aHTML;
end;

Indy 单元之所以是条件编译的,是因为使用自定义 Indy 库的构建会把它们识别为 sgcIdContext 和 sgcIdCustomHTTPServer,而使用标准 Indy 的构建则识别为 IdContext 和 IdCustomHTTPServer。随包附带的演示正是这样做条件编译的。任何能写入字符串的服务器都可以。随包附带的演示在有 Professional 构建时选择 TsgcWSHTTPServer,否则回退到 TIdHTTPServer,因此演示在那里有条件判断,而这段摘录没有。

sgcSiteDemoServer.dpr
program sgcSiteDemoServer;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  sgcSiteDemo_Server in 'sgcSiteDemo_Server.pas',
  sgcSiteDemo_Pages in 'sgcSiteDemo_Pages.pas';

var
  oServer: TsgcSiteDemoServer;
begin
  oServer := TsgcSiteDemoServer.Create;
  try
    oServer.Start;
    WriteLn('sgcHTML Site Layouts Demo - http://localhost:' +
      IntToStr(oServer.Port));
    WriteLn('Press Enter to stop.');
    ReadLn;
    oServer.Stop;
  finally
    oServer.Free;
  end;
end.

这是一个控制台应用程序,因此无需设置窗体,也无需 VCL。这是最短的 sgcHTML 程序,也正是随包附带演示的实际内容。

这三个选项卡都来自随包附带的演示 Demos\60.HTML\01.RunTime\07.Site,并裁剪到了关键部分。完整项目还会通过查询字符串切换布局、主题和配色方案,等第一个页面渲染成功后,值得读一读。

确认页面已渲染

程序会打印它正在监听的 URL。打开它,然后试试这些切换开关。

它打印的 URL

程序启动时会向控制台写入 http://localhost:8092。打开它。如果出现带有导航、侧边栏和您的内容的页面,就说明渲染和服务器都在正常工作。

Active

FHTTP.Active := True 要么成功,要么抛出异常。如果其他程序已经占用了 8092 端口,您会在这里发现。

内容类型

如果浏览器显示的是原始标记而不是页面,说明响应发出时没有带上 text/html。请在为 ContentText 赋值之前设置 ContentType。

切换布局

随包附带的演示会从查询字符串中读取 layout、theme 和 mode,因此 ?layout=topnav&mode=dark 会以另一种方式重新渲染同一个页面。这是了解该组件功能的最快方法。

第一次通常会出什么问题

六个问题几乎涵盖了所有第一次尝试时无法渲染的情况。

组件面板页始终不出现

注册需要同时定义 SGC_PACK_HTML 和 SGC_HTML。前者定义在 All-Access 块内的第 871 行,后者定义在包块内的第 885 行。在 Android 或 iOS 目标上,后者是被有意排除的。

页面是空白的

您构建了组件树,却从未读取 HTML。正是这个属性触发了渲染。读取它就是整个渲染步骤,它返回的是完整的文档,而不是片段。

编辑页面后没有任何变化

演示在每次请求时都会新建一个 TsgcHTMLComponent_Site,并在之后释放它。如果您缓存该对象并重复使用,请记得在重新构建之前用 ClearContent 清除其内容。

浏览器显示原始标记

从未设置响应的内容类型。演示在写入正文之前会设置 ContentType := 'text/html; charset=utf-8',如果没有它,某些客户端会把 HTML 显示为文本。

您在手动编写 HTML 字符串

您没有必要这样做。库中有用于 Bootstrap 布局、表格、表单和图表的节点单元,这个库的全部意义就在于让您组合这些节点,而不是拼接标记。

端口已被占用

演示监听 8092 端口。如果其他程序占用了该端口,服务器将无法启动,因此在深入排查问题之前,请先更改端口。

大家在第一个页面之后会构建什么

四个方向,都在同一个包内。

可回传的表单

表单节点单元可构建输入框、选择框、验证和布局,htmx 无需刷新页面即可提交它们。当您构建节点而不是字符串时,转义会自动为您处理。

表单组件

页面上的数据

支持排序、筛选和分页的表格,以及图表、统计卡片、调度器、甘特图和图表绘制组件。

功能矩阵

完整的应用程序

附带十二个运行时演示,从 ERP 仪表板到销售终端、帮助台、仓库和现场服务应用。它们是了解该库在真实规模下表现的最快方法。

演示库

沿用您现有的 Web 层

提供了适用于 WebBroker 和 DataSnap 的组件,因此现有的 Delphi Web 应用程序无需重写即可渲染 sgcHTML 页面。

WebBroker 和 DataSnap

参考、演示和文档

目录列出了每个组件及其预览。演示项目包含在下载包内,位于 Demos\60.HTML 下。

TsgcHTMLComponent_Site 页面 本快速入门所基于的页面外壳,逐个属性说明。
功能矩阵 布局、表单、数据、图表、身份验证、聊天等,按领域分组。
演示库 随包附带的运行时演示,每个都配有一段简短视频。
WebBroker 和 DataSnap 在现有的 Delphi Web 层中渲染 sgcHTML 页面。
下载试用版 与正式版相同的安装程序,有时间限制。
在线帮助 自动生成的参考,始终与当前版本保持同步。

相关阅读:Site 组件、Delphi 中的 Web UI 组件、更智能的表单和数据表格。每个产品都有自己的快速入门,列在入门页面上。

sgcHTML 快速入门常见问题

TsgcHTMLComponent_Site,来自单元 sgcHTML_Component_Site.pas。它会渲染完整的页面外壳,因此您无需自己组装,就能得到导航、侧边栏、主题和内容区域。构建它,调用 AddMenu 以及 AddContent 或 AddSection,然后读取 HTML 属性。随包附带的 Site 演示正是这样做的。
由您自己把它写入 HTTP 响应。HTML 是一个普通的 string 属性,因此任何服务器都可以。随包附带的演示在 Professional 构建上使用 TsgcWSHTTPServer,否则回退到 TIdHTTPServer,设置 ResponseNo := 200 和 ContentType := 'text/html; charset=utf-8',并把该字符串赋给 ContentText。
门槛是 SGC_PACK_HTML,它定义在 sgcVer.inc 的第 871 行,位于从第 870 行延伸到第 874 行的 {$IFDEF SGC_EDT_ALL} 块内。在该源代码树中,由 All-Access 版本定义它。sgcHTML 也作为独立产品销售,拥有自己的安装程序,因此请查看 sgcHTML 价格页面了解当前的许可证,而不要根据该定义去推断。
不能,而且这是有意为之。SGC_HTML 定义在第 885 行,位于第 883 行的 {$IFNDEF ANDROID} 和第 884 行的 {$IFNDEF IOS} 之内,因此在这些目标上,每个 sgcHTML 单元都会编译成空单元。它是服务器端库:手机通过网络接收 HTML,所以移动目标不需要渲染器。Windows、macOS 和 Linux 都受支持。
不需要。库会生成 Bootstrap 5 标记和 htmx 属性,htmx 使按钮能够回传并在不刷新的情况下替换页面的一部分。您用 Pascal 描述交互,属性会自动为您生成。如果您愿意,仍然可以通过 CustomHead 和 BodyEndHTML 添加自己的脚本。
可以。Layout 接受 TsgcHTMLSiteLayout,其成员有 slSidebarLeft、slSidebarRight、slTopNav、slTopNavSidebarLeft、slIconRail 和 slOffcanvas,默认值为 slTopNavSidebarLeft。Preset 接受 TsgcHTMLSitePreset,其成员包括 spAdmin、spDashboard、spPortal、spDocs、spLanding 和 spApp。颜色以及浅色或深色模式由 Theme 对象控制。
当您把页面构建为节点时,可以,因为节点会写入文本并对其进行转义。当您绕过节点自己拼接标记时就会出现风险,例如通过 AddContent 传入由用户输入构建的字符串。对于任何携带用户数据的内容,请优先使用节点单元。
下载包在 Demos\60.HTML\01.RunTime 下附带十七个运行时演示,包括 ERP 仪表板、帮助台、销售终端、仓库、报表应用和现场服务应用。演示库中有每个演示的简短视频。
超值之选:All-AccesseSeGeCe 全部产品,含高级支持,每年 €1,059 起。
查看 All-Access 价格

准备好用 Pascal 构建 Web 界面了吗?

下载试用版,在编写任何标记之前先运行 Site 演示。