用 Delphi 做了一个简单的 CMS
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 代码就能实现。
相关文章:
用 Delphi 做了一个简单的 CMS
Delphi 代码上面花的时间最少。 前提是你要熟悉 Delphi 的 WebBroker 框架。不熟悉也没关系,5分钟就可以入门,10分钟就熟悉了。 CMS 就是个基于 WEB 的内容管理嘛。相当于一个简单的没有跟贴功能的 BBS。这样的东西,后边是数据库࿰…...
ASK, PSK, FSK, DPSK
ASK, PSK, FSK, DPSK详解: 这四种调制方式都是数字调制技术,用于将数字信号转换成适合在信道上传输的模拟信号。它们的主要区别在于如何用模拟信号的变化来表示数字信息。 1. ASK (Amplitude Shift Keying) 幅移键控: 原理: ASK 通过改变载波信号的幅…...
【Linux】认识Linux内核中进程级别的文件结构体【files_struct】&文件IO模型初步演示
前言 大家好吖,欢迎来到 YY 滴 系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《Linux》…...
[Offsec Lab] ICMP Monitorr-RCE+hping3权限提升
信息收集 IP AddressOpening Ports192.168.52.218TCP:22,80 $ nmap -p- 192.168.52.218 --min-rate 1000 -sC -sV -Pn PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9p1 Debian 10deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 de:b5:23:89:bb:9f:d4:1…...
Studying-多线程学习Part4 - 异步并发——async future、packaged_task、promise
异步并发——async future packaged_task promise 1.async、future 是C11引入的一个函数模版,用于异步执行一个函数,并返回一个future对象,表示异步操作的结果。使用 async 可以方便地进行异步编程,避免了手动创建线程和管理线程…...
【Java基础】用Scanner类获取控制台输入
目录 Scanner类是什么导入并创建读取一个数读取字符串读取一行读取直到空白字符为止读取多个数直到^z读取一个字符 Scanner类是什么 在Java中,Scanner 是一个非常有用的类,用于从各种输入源(如键盘、文件或其他输入流)读取数据。…...
微服务seata解析部署使用全流程
官网地址: Seata 是什么? | Apache Seata 1、Seata术语 用来管理分布式事务,由阿里巴巴出品。 【1、TC (Transaction Coordinator) - 事务协调者】 用来维护事务的,包括主事务和分支事务。 【2、TM (Transaction Manager) - …...
Linux性能调优技巧
目录 前言1. CPU性能优化1.1 调整CPU调度策略1.2 合理分配多核处理 2. 内存性能优化2.1 调整内存分配策略2.2 缓存和分页优化 3. 磁盘I/O性能优化3.1 使用合适的I/O调度器3.2 磁盘分区和文件系统优化 4. 网络性能优化4.1 优化网络参数4.2 调整网络拥塞控制算法 5. 系统监控与优…...
python 实现sha1算法
sha1算法介绍 SHA-1(Secure Hash Algorithm 1,安全散列算法1)是一种密码散列函数,由美国国家安全局(NSA)设计,并由美国国家标准技术研究所(NIST)发布为联邦数据处理标准…...
ejb-ref元素
ejb-ref 是用于在 Java EE (现在称为 Jakarta EE) 中引用 Enterprise JavaBeans (EJB) 的一个元素,主要用于定义和配置 SLEE (Service Logic Execution Environment) 组件中的 EJB 依赖关系。通过这个引用,SBB (Service Building Block) 可以轻松地访问和…...
Perl 子程序(函数)
Perl 子程序(函数) Perl 是一种高级、解释型、动态编程语言,广泛用于CGI脚本、系统管理、网络编程、 finance, bioinformatics, 以及其他领域。在Perl中,子程序(也称为函数)是组织代码和重用代码块的重要方…...
ElasticSearch 备考 -- Snapshot Restore
一、题目 备份集群下的索引 task,存储快照名称为 snapshot_1 二、思考 这个涉及的是集群的备份,主要是通过创建快照,涉及到以下2步骤 Setp1:注册一个备份 snapshot repository Setp2:创建 snapshot 可以通过两种方…...
【Linux】进程替换、命令行参数及环境变量(超详解)
目录 进程替换 替换函数的含义 命令行参数 环境变量 PATH 进程替换 我们先看代码: 1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5 printf("process...begin!\n");6 7 execl("/usr/bin/ls","ls"…...
MySQL事务日志—redo日志介绍
MySQL事务日志—redo日志 事务有4种特性: 原子性、一致性、隔离性和持久性。 那么事务的四种特性到底是基于什么机制实现? 事务的原子性、一致性由事务的 undo 日志事务的隔离性由锁机制和MVCC实现。事务的持久性由redo 日志来保证。 两类日志概述:…...
告别音乐小白!字节跳动AI音乐创作工具,让你一键变作曲家!
还在羡慕别人能创作动听的音乐?五音不全的你,也梦想着谱写属于自己的乐章?现在,机会来了!字节跳动推出了一款AI音乐创作工具——抖音推出的海绵音乐,它能让你轻松一键创作音乐,即使是“音乐小白…...
空心正方形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的“空心”正方形图案。 输入描述: 多组输入,一个整数(3~20),表示输出的行数,也表示组成正方形边的“ * ”的数量。 输出描述…...
【EXCEL数据处理】000020 案例 保姆级教程,附多个操作案例。EXCEL使用表格。
前言:哈喽,大家好,今天给大家分享一篇文章!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【EXCEL数据处理】000020 案例 保姆级教程,附多个操作案例。…...
虾皮Shopee大数据面试题及参考答案
Cube 表性能优化,还有其他优化的方法吗? Cube 表性能优化可以从多个方面入手。 一方面,可以优化数据存储格式。选择合适的存储格式能够减少存储空间占用,提高数据读取速度。例如,Parquet 格式是一种高效的列式存储格式,它可以按列进行数据压缩,大大减少磁盘 I/O 和内存占…...
重学SpringBoot3-集成Redis(六)之消息队列
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(六)之消息队列 1. 什么是发布/订阅(Pub/Sub)?2. 场景应用3. Spring Boot 3 整合 R…...
LeetCode 134 Gas Station 解题思路和python代码
题目: There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i]. You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i 1)th station. You …...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...
EasyRTC音视频实时通话功能在WebRTC与智能硬件整合中的应用与优势
一、WebRTC与智能硬件整合趋势 随着物联网和实时通信需求的爆发式增长,WebRTC作为开源实时通信技术,为浏览器与移动应用提供免插件的音视频通信能力,在智能硬件领域的融合应用已成必然趋势。智能硬件不再局限于单一功能,对实时…...
