用 Delphi 做了一个简单的 CMS

news2024/10/5 7:22:26

Delphi 代码上面花的时间最少。

前提是你要熟悉 Delphi 的 WebBroker 框架。不熟悉也没关系,5分钟就可以入门,10分钟就熟悉了。

CMS 就是个基于 WEB 的内容管理嘛。相当于一个简单的没有跟贴功能的 BBS。这样的东西,后边是数据库,存储帖子。前边是表现层,也就是 WEB 前端。对于数据库来说,Delphi 的数据库操作那是简单得不能再简单了。

花费时间最多的还是和前端有关的事情。相关的技术细节,我在本博客之前的文章里面都有提到。这里总结一下。

花费时间最多的前端

当然,前端花费时间多,也有一部分原因是前端我不熟悉。

这里记录一下时间都用到哪里去了。

1. 找了一个简单的 CSS 用来美化页面。熟悉这个 CSS 框架的使用,看它的例子和文档。这个 CSS 功能不是很强大,但确实不错。好处就是它体积小,加载不会花很多网络流量和时间;

2. 找了10来个富文本编辑器,评估一下哪个好用,哪个更简单,哪个的体积更小。单单是评估10多个编辑器,就花掉2天时间。最后选择了 Quill 这个编辑器。

3. 学会使用 Quill 编辑器花了很多时间。如果只是简单地在页面里面使用它,大概几分钟或者十分钟就能用起来。但是,当发现它会被页面上的 Pico.CSS 影响,要解决这个问题,花了我三天时间。上网查资料,各种搜索,评估各种方案,比如我就在采用 iframe 还是采用 Shadow DOM 这两种方案上,花了很多时间测试,看看哪个更好用。最后发现 Shadow DOM 方式对于 Quill 来说是不能用的。

4. 因为想用 Delphi 12.2 最新版的 WebStencils 控件,又要花时间去学习如何使用它。当然也遇到过一些不知道如何解决的问题,花费很多时间摸索和测试。

5. 开发完成后,想采用 IIS CGI 的方式,放到 IIS 下面去使用。然后又想让链接地址简单一些,不要暴露后台程序是 MyCMS.exe 这样的东西,又上网查资料,发现 IIS 可以采用【URL 重写】的方式来实现。然后去搜索资料学习这个 URL 重写该怎么做,又花费了一天。

6. 页面里面使用了 HTMX 来做一些 AJAX 的动作。HTMX 大概是从完全不懂到能够使用,入门最快的前端技术。看着官方页面上的文档和例子,几分钟,就能把它用起来。

总结一下心得

本来做这个玩意,就是想评估一下 Delphi 最新推出的 WebStencils 控件,实际做点东西才能知道它好不好用。东西并不复杂,页面也没有几个。顺便也评估一下 HTMX 是否好用。

选择各种框架,工具,最重要的一点是,要能够达到代码封装,代码重用。不要在很多地方复制粘贴相同的代码。

关于 WebSencils

Delphi 的 WebBroker 框架下,原来就有的 PageProducer 控件,能够让我们把很多个页面里面相同的部分提取出来作为一个单独的文件,也就是组件化了。最后在需要的时候,把需要的页面的各个部分组装到一起。因为页面其实就是字符串文件,所以 PageProducer 提供的功能就是让我们能够在程序里面通过字符串替换掉标记的方式,组装页面。可能需要写一些 Delphi 的代码。

新推出的 WebStencils 则是通过在页面里面嵌入一些标记后,由 WebStencils 自己的代码自动去替换。这样一来,就少写了很多代码。需要修改时,也仅仅改页面代码,Delphi 程序很多时候不需要修改,因此也就不需要重新编译。这样做,非常方便把页面代码组件化。页面代码里面,有很多重复的东西,比如页头,页脚,都不用每个页面都写了。也不用写把这些页面组件组装到一起的代码。确实省了很多代码和开发时间。

更进一步,WebStencils 支持页面上的字符串标记,可以在运行时被 Delphi 程序的对象的值替换,这就给我们带来了更多的便利。我们无需写代码来实现页面上内容被运行期的数据变化了。比如,如果采用 PageProducer 或者我们自己写和页面有关的代码,都需要对页面文件的字符串进行处理。比如我们有个页面是以下代码:

<div>
<label>价格 </label>
<#MyPrice>
</div>

Delphi 程序大概要这样写:

var SL: TStringList;

SL := TStringList.LoadFromFile('MyPage.html');

var S := SL.Text;

S := S.ReplaceText('<#MyPrice>', MyDataSet.FieldByName('Price').ToString);

Response.Content := S;

也就是加载页面文件,把里面的标记找出来,替换为数据库里面的价格字段的值。

如果用了 WebStencils,则上面的 Delphi 代码一行都不用写。只要页面里有对应价格字段的相关标记, WebStencils 加载页面后就会自动找到对应的 DataSet 对象,把价格字段的值替换掉标记。

关于 HTMX

HTMX 更有意思。使用它,可以把页面拆成很多零碎的小组件,然后通过 AJAX 的方式逐个组装页面。而 WEB 程序的不同的路径,就变成了输出不同页面组件的一个 API 接口。更妙的是,这个完全是后端实现,完全不需要在前面用很复杂的前端 JavaScript 框架。

这个就涉及到开发的哲学和方法论的问题了。

简单说,最初的 WEB 开发,就是在后端服务器代码里面,把 HTML 字符串组装好,发送给浏览器呈现。浏览器仅仅是解释 HTML 然后呈现这个页面。

经过了很多年以后,现在比较流行的几个大的前端框架,是用 JavaScript 在前端浏览器里面运行,用运行的代码画出页面。而后端 WEB 服务器只需要输出页面上变化的部分需要的数据就行了。数据则是用 JSON 格式来封装。

这是两种完全不同的极端情况。

HTMX 则是提倡后端输出的不是 JSON 数据,而应该是 HTML 格式的页面元素。HTMX 作为前端的 JavaScript 库,只是把 JavaScript 对于后端的调用(AJAX)和调用后收到的来自后端的 HTML 字符串在页面里面如何呈现,做了封装。使用 HTMX 不需要写代码,只需要写【描述】,或者说写一些属性定义,就能完成工作。

我使用 HTMX 下来的感受是,完全不懂 JavaScript 和类似 jQuery 之类的 JavaScript 代码库,也能做出动态的页面来。我这里说动态页面,是指页面 AJAX 方式局部更新。

从代码架构上来说,使用 HTMX 就可以让后端 WEB SERVER 程序,尤其是 Delphi WebBroker 程序,变成一个有很多特定功能的 WEB 接口。就好比常见的代码里面的各种函数调用。这样做的好处是代码逻辑更清晰,模块化更好。

比较 Delphi WebStencils 和 HTMX

这两个都可以让页面变成组件,把相同的页面代码抽离出来,而不是重复的复制粘贴到很多页面文件里面。

使用 WebStencils 是在服务器上的代码组装页面。一次性组装完成后,发送给浏览器。

HTMX 则是在浏览器页面加载完成后,还可以继续向后端服务器请求某个页面元素,将获得的页面组件显示到 HTMX 代码指定的位置。也就是当页面上有局部的更新时,不需要刷新整个页面,服务器只需要输出对应的页面的局部的代码,可能就是几个 DIV 相关的字符串,数据量很小,因此服务器压力也会很小,占用的流量带宽也很小。

因此,要正确评估某个页面的当前需求,来决定采用哪个方案。

更复杂的页面

对 Delphi 的开发者来说,后端用 Delphi 代码开发完全没问题。可能不熟悉 CSS / JAVASCRIPT 等等前端技术。要开发一个功能强大的前端网页,可能会觉得很难。

1. 页面美化:直接套一个现成的 CSS;比如我这次套了个 PICO.CSS 页面立马变漂亮,不用自己去考虑页面排版之类的事情。当然,要是套个 BootStrap 之类的大框架也不错。

2. 复杂的页面组件,比如动态编辑的表格,或者图表(Chart),那就去找一个开源的组件,直接用起来。甚至还可以用 Delphi 代码把它封装为一个 Delphi 的组件(对象),写 WEB 程序的时候就完全不用考虑它的细节,只需要调用 Delphi 的对象的方法/属性,就可以实现页面上的复杂内容。

3. 页面呈现期间的动态局部内容更新,采用 HTMX,则不需要写 JAVASCRIPT 代码就能实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189508.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国外电商系统开发-运维系统单个添加被管理服务器

提前设置好您的远程主机的信息&#xff0c;这样才能自动执行任务。否则&#xff0c;自动执行根本无从谈起。登录方式有SSH密码登录、SSH-Key登录两种方式。 最后点击保存。 上面的刷新图标表示在请求该服务器的状态。如果该服务器状态正常&#xff0c;则会显示如下图标&#xf…

业务封装与映射 -- 编码方式(QPSK、DQPSK、QAM)

信号在光通信系统中传输&#xff0c;需要在信号的发送端对原始电信号进行调制&#xff0c;接收端进行解调&#xff0c;恢复成原始的二进制电信号。光通信系统有三种基本的调制方式&#xff1a;ASK&#xff08;调幅&#xff09;/FSK&#xff08;调频&#xff09;/PSK&#xff08…

【AIGC】VoiceControl for ChatGPT指南:轻松开启ChatGPT语音对话模式

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;安装VoiceControl for ChatGPT插件&#x1f4af;如何使用VoiceControl for ChatGPT进行语音输入VoiceControl for ChatGPT快捷键注意点 &#x1f4af;VoiceControl for C…

看门狗电路设计

看门狗电路设计 看门狗是什么应用架构图TPV6823芯片功能硬件时序图为什么要一般是要保持200个毫秒左右的这种低电平的时间看门狗电路实际应用与条件 看门狗是什么 硬件看门狗芯片&#xff0c;Watch DogTimer&#xff0c;可用于受到电气噪音、电源故障、静电放电等影响(造成软件…

【AI学习笔记】基于Unity+DeepSeek开发的一些BUG记录解决方案

【AI学习笔记】基于UnityDeepSeek开发的一些BUG记录&解决方案 背景前摇&#xff1a;&#xff08;省流可不看&#xff09; Unity是大学学的&#xff0c;AI是研究生学的&#xff0c;DeepSeek是第一份实习偷师的&#xff0c;三合一的梦是最近开始做的&#xff0c;BUG是今天遇…

VRRP协议个人理解+报文示例+典型配置-RFC2338/RFC3768/RFC5798/RFC9568

个人认为&#xff0c;理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息&#xff0c;更加便于理解协议。 因此本文将在VRRP协议报文的基础上进行介绍。 VRRP协议发展 关于VRRPv2基本原理&#xff0c;可重点参考2004年发布的RFC3768-Virtual Ro…

【python实操】python小程序之函数的方法和赋值的区别

引言 python小程序之函数的方法和赋值 文章目录 引言一、函数的方法和赋值1.1 题目1.2 代码1.2.1 append方法1.2.2 赋值 1.3 代码解释1.3.1 append方法1.3.2 赋值 二、思考2.1 append方法和赋值的区别2.1.1 append方法2.1.2 赋值操作2.1.3 总结 一、函数的方法和赋值 1.1 题目…

通过freepbx搭建小型电话系统的过程

领导说公司的客服电话需要实现语音导航和非工作时间自动接听播放语音提示的功能。任务自然落到了伟大的程序员的头上&#xff0c;本着为公司节约成本原则遂百度了一番&#xff0c;找到了asterisk 和freeswitch两个比较流行的电话系统。经过对比和考虑公司的情况选择了asterisk系…

STM32 通用定时器

一、概述 STM32内部集成了多个定时/计数器&#xff0c;根据型号不同&#xff0c;STM32系列芯片最多包含8个定时/计数器。其中&#xff0c;TIM6、TIM7为基本定时器&#xff0c;TIM2~TIM5为通用定时器&#xff0c;TIM1、TIM8为高级控制定时器。 1.定时器的类型 基本定时器通用定…

C/C++ 中的未定义行为(Undefined Behavior, UB)

0. 简介 在 C/C 编程中&#xff0c;理解未定义行为&#xff08;UB&#xff09;及其相关概念至关重要。本文将对未定义行为进行详细解析&#xff0c;并通过实例展示其影响与处理方法。 1. 概念辨析 在 C/C 中&#xff0c;未定义行为容易与以下两个概念混淆&#xff1a; 1.1 …

【Spring】Spring MVC的项目准备和连接建立

文章目录 1. 什么是 Spring Web MVC1.1 MVC 定义1.2 什么是 Spring MVC 2. 学习 Spring MVC2.1 项目准备2.2 建立连接 1. 什么是 Spring Web MVC Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从已开是就包含在 Spring 框架中。它的正式名称“Spring We…

【pytorch】张量求导

笔者看到了这篇文章&#xff0c;可以很好的解释张量的求导问题&#xff1a; 看到了上面这张图&#xff0c;可以说很好的表示了前向和反向的过程了。 补充几个细节 之前看李沐的d2l&#xff0c;一直不懂为什么矩阵计算时的一些奇奇怪怪的规定&#xff0c;比如为什么一个行向量…

github项目——gpt-pilot自动创建应用

今天扯一扯在github上看到的一个项目gpt-pilot&#xff0c;声称“首个AI程序员”。本来打算玩一下&#xff0c;结果需要配置大语言模型的API&#xff0c;并且只支持OpenAI和claude&#xff08;Qwen呢&#xff09;。有没有玩过的老哥说一下好不好用&#xff01;&#xff01;(对了…

【Postman】接口测试工具使用

干就完啦 Postman发送get请求案例1&#xff1a; Postman发送post请求案例2 Postman发送其他请求 学习目标&#xff1a;能够使用Postman发送get/post/put/delete请求并获取响应结果 Postman发送get请求 首先postman是一款接口调试工具&#xff0c;支持win&#xff0c;mac以及l…

Python | Leetcode Python题解之第456题132模式

题目&#xff1a; 题解&#xff1a; class Solution:def find132pattern(self, nums: List[int]) -> bool:candidate_i, candidate_j [-nums[0]], [-nums[0]]for v in nums[1:]:idx_i bisect.bisect_right(candidate_i, -v)idx_j bisect.bisect_left(candidate_j, -v)if…

Pandas -----------------------基础知识(六)

目录 数据类型 查看类型 类型转换 无法转换的值返回NaN 无法转换的值返回原值 datetime类型 datetime类型数据列作为df索引 Python中的timedelta类型 Pandas中的timedelta类型 pd.to_timedelta函数转换timedelta类型 timedelta类型数据作为df索引 分组groupby 分箱…

开发环境简单介绍

目录 开发环境keil的安装和使用 keil的介绍 keil的安装 keil的简单使用 STC-ISP的安装 STC-ISP简单介绍 开发环境测试 总结 开发环境keil的安装和使用 keil的介绍 Keil uVision5是一个集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于对嵌入式系统中的微控制器…

vue-scrollto实现页面组件锚点定位

文章目录 前言背景操作指南安装及配置步骤vue组件中使用 参考文章 前言 博主介绍&#xff1a;✌目前全网粉丝3W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技术内容&#xff1a;Java后端、大数据…

Java | Leetcode Java题解之第454题四数相加II

题目&#xff1a; 题解&#xff1a; class Solution {public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {Map<Integer, Integer> countAB new HashMap<Integer, Integer>();for (int u : A) {for (int v : B) {countAB.put(u v, countAB.getOrDefa…

多模态—文字生成图片

DALL-E是一个用于文字生成图片的模型&#xff0c;这也是一个很好思路的模型。该模型的训练分为两个阶段&#xff1a; 第一阶段&#xff1a;图片经过编码器编码为图片向量&#xff0c;当然我们应该注意这个过程存在无损压缩&#xff08;图片假设200*200&#xff0c;如果用one-h…