我想制作功能性 HTML 元素,我的意思是在页面渲染之前返回其中的 HTML 函数的元素,这样 HTML 就变得像 LISP 一样。例如,如果 HTML 是这样写的:
<setf>
<var-name>X</var-name>
<list>
<li>a large red box</li>
<li>an iron key</li>
<li>a mangy cat</li>
</list>
</setf>
You see
<foreach> <var-name>EL</var> <var-val>X</var-val>
<div><var-val>EL</var-val>,</div>
</foreach>
我希望“setf”是一个自定义标签,它执行将名为“X”的变量的值设置为给定列表的功能,并且我希望“foreach”是一个自定义标签,它评估其中的HTML代码,依次输出列表 X 中每个值 EL 的函数结果:
You see a large red box, an iron key, a mangy cat,
然后呈现为 HTML。 (为了使示例简单,我没有修复最后一个逗号的错误。)
当然,我希望能够动态定义或重新定义标签,就像在 LISP 中一样:
<defun>
<var-name>reverse</var-name> <!-- reverse a list -->
<list> <var-name>X</varname> </list> <!-- the argument list, which is a single list -->
<if> <null> <var-val>X</var-val> </null>
<then> <nil /> </then>
<else>
<cons> <reverse> <cdr> <var-val>X</var-val> </cdr> </reverse> <car> <var-val>X</var-val> </car> </cons>
</else>
</if>
</defun>
...这不会像写的那样工作,因为评估是从下往上完成的,所以代码的
<reverse> ... </reverse>
位将在评估“reverse”的封闭函数定义之前评估。能够定义递归函数很重要,但我不知道如何定义。
我还希望能够为每个标签指定评估是在服务器端还是客户端执行。不过,如果只能在其中之一上完成,我可以接受。
我已经阅读了有关 HTML 自定义元素的新的且未最终确定的规范的文档,但我无法判断它们是否允许我使元素对其内部内容执行函数评估。我想找到一些方法来做到这一点,也许使用自定义元素、Javascript、浏览器插件或服务器端预处理器。我想用 HTML 编写类似 LISP 的代码。这将使在 HTML 中的单个位置中进行简单计算变得更加容易,而不是将其分割到不同的页面和用不同语言编写的脚本中。
如果您认为这是一个坏主意,请给出具体原因。
如果你想在服务器端进行评估,那么你不妨实际使用 Common Lisp 编写页面,并且借助 cl-who 或 Spinneret 可以直接以相当友好的方式编写 HTML:
CL-USER> (spinneret:with-html
(:doctype)
(:html
(:div
(:h1 "My features")
(:ol
(dolist (s (subseq *features* 0 6))
(:li (:pre (string s))))))))
上面的调用写入以下文本:
<!DOCTYPE html>
<html lang=en>
<div>
<h1>My features</h1>
<ol>
<li>
<pre>CLOSER-MOP</pre>
<li>
<pre>PARENSCRIPT</pre>
<li>
<pre>NAMED-READTABLES</pre>
<li>
<pre>HTML-TEMPLATE</pre>
<li>
<pre>CL-FAD</pre>
<li>
<pre>OSICAT-FD-STREAMS</pre>
</ol>
</div>
</html>
NIL
为了将您的 HTML 代码评估为 Lisp,您需要做更多的工作,例如 Mozilla 开发人员文档中的§使用自定义元素,其中有一个在 JS 中声明自定义元素的示例:
customElements.define("popup-info", PopupInfo);
然后你可以在 HTML 中编写这样的元素:
<popup-info>
...
</popup-info>
这样的Web组件是从外到内执行的,即。首先调用外部组件类的构造函数,然后创建其内部的组件(自定义元素执行顺序)。
你可以像这样定义一整套模仿 Lisp 语言的组件,但我认为对于可以直接在 JS 中或通过服务器完成的事情来说,这将是大量工作。但我认为至少可以实施概念验证。