from fasthtml.common import NotStr,Div, to_xml自定义组件
大多数情况下,默认的 ft 组件(例如 Div、P、H1 等)就足以满足您的所有需求。
如果您不了解 ft 组件是什么,应首先阅读关于 ft 组件的说明。
然而,在许多情况下,您需要一个自定义的 ft 组件来创建独特的 HTML 标签(例如 <zero-md></zero-md>)。FastHTML 提供了多种方法来实现这一点,本节将逐一介绍。通常,您应该选择能满足需求的最高级选项。
这篇外部教程通过一个实际场景,讲解了您可能需要使用自定义 ft 组件创建自定义 HTML 标签的情况。通过真实世界的示例,可以很好地理解本指南内容的用处。
NotStr
第一种方法是使用 NotStr 类将 HTML 标签作为字符串使用。这种方法适用于一次性使用,但随着复杂度的增加,会变得难以处理。不过,我们可以看到,使用 NotStr 和使用开箱即用的组件可以生成相同的 XML。
div_NotStr = NotStr('<div></div>')
print(div_NotStr)<div></div>
自动创建
下一个(也是更好的)方法是让 FastHTML 为您生成组件函数。正如您在我们的 assert 中所见,这将创建一个函数,该函数会生成我们想要的 HTML。尽管在 fasthtml.components 源代码中并没有一个名为 Some_never_before_used_tag 的函数,但这依然有效(您可以通过查看源代码自行验证)。
通常,需要这些标签是因为某个 CSS 或 Javascript 库创建了一个新的 XML 标签,而这个标签并非标准的 HTML。例如,zero-md Javascript 库会寻找 <zero-md></zero-md> 标签,以便知道在哪个元素上运行其 Javascript 代码。大多数 CSS 库通过基于 class 属性创建样式来工作,但它们也可以将样式应用于它们自己定义的任意 HTML 标签。
from fasthtml.components import Some_never_before_used_tag
Some_never_before_used_tag()<some-never-before-used-tag></some-never-before-used-tag>手动创建
自动创建并非魔法。它只是调用了一个 Python 函数 __getattr__,您也可以自己调用它来获得相同的结果。
import fasthtml
auto_called = fasthtml.components.Some_never_before_used_tag()
manual_called = fasthtml.components.__getattr__('Some_never_before_used_tag')()
# Proving they generate the same xml
assert to_xml(auto_called) == to_xml(manual_called)知道了这一点,我们便明白,通过修改 __getattr__ 函数创建组件的方式,可以创建一个与 FastHTML 默认行为不同的函数!这只需要几行代码,阅读这些代码是更深入地理解组件的好方法。
双下划线(Dunder)方法和函数是名称前后都有双下划线的特殊函数。它们在 Python 的特定时刻被调用,因此您可以使用它们来实现符合特定用例的自定义行为。如果您不了解 Python 的工作原理,它们可能看起来像魔法,但它们在修改 Python 默认行为方面非常常用(__init__ 可能是最常见的一个)。
在一个模块中,__getattr__ 被调用以获取一个属性。在 fasthtml.components 中,它被定义为为您自动创建组件。
例如,如果您想要一个创建 <path></path> 的组件,并且不与 pathlib.Path 的名称冲突,您可以做到这一点。FastHTML 会自动创建具有一对一映射和一致名称的新组件,这几乎总是您想要的。但在某些情况下,您可能希望自定义这种行为,您可以使用 ft_hx 函数来实现与默认方式不同的操作。
from fasthtml.common import ft_hx
def ft_path(*c, target_id=None, **kwargs):
return ft_hx('path', *c, target_id=target_id, **kwargs)
ft_path()<path></path>我们可以在该函数中添加任何我们需要的行为,因此,让我们来看一些您在项目中可能需要的、逐步复杂的示例。
标签属性中的符号(如 @)
也可能出现 HTML 标签中的某个参数使用了 Python 参数中不能使用的字符。为了处理这些情况,您可以使用字典来定义这些参数。
Div(normal_arg='normal stuff',**{'notNormal:arg:with_varing@symbols!':'123'})<div normal-arg="normal stuff" notnormal:arg:with_varing@symbols!="123"></div>