什么是Archetypes?
Archetypes是Plone内容扩展开发的一个开发框架,只需要用python语言对内容类型提供描述信息,便可自动完成一些逻辑和内容编
辑展现界面。它分离了内容的数据字段(field)、显示器件(widget)、存储(storage)。
Archetypes能做什么?
能自动生成内容的编辑和显示页面,因此你不用写任何的页面模版代码
为每个内容自动维护一个用户不能更改的、内部唯一代号(UID)。这样即便内容被移动了,仍然可以通过UID来找到
支持内容的关联引用。每种内容,可和其他的内容建立多种关系。比如,一个新闻可能附加了几个其他的参考文档的链接
默认就包括一套安全设置,能够满足大多数的应用场合
支持多种存储方式,除了保存在ZODB对象数据库外,还可保存在文件系统,或者关系数据库中
提供大量的显示器件(控件),可构造丰富的界面,如网格表格、富文本输入等
提供了数据格式转换的功能,比如,可以将微软的Word文档转换为html格式,直接在浏览器上显示
在Archetypes中,最重要的就是schema(语义)
一旦内容的底层语义(schema)发生变化,相关的用户界面会随之改变,这正是Archetypes的强大所在
+--------------+
| 语义(Schema) |
+--------------+
| +--------------+
|-->| 字段(Field) |
| +--------------+
| | +------------------+
| `--------->| 显示器件(Widget) |
| +------------------+
| +--------------+
`-->| 字段(Field) |
+--------------+
| +------------------+
`--------->| 显示器件(Widget) |
+------------------+
这就是语义,字段和显示器件的关系
怎么创建语义?
将各个字段(Field)以按照元组(tuple)的方式传入Schema对象,即可创建一个新的语义(schema)。
如ArchExample的Article.py文件中
StringField( ' group ' ,
vocabulary = ARTICLE_GROUPS,
widget = SelectionWidget(),
),
StringField( ' blurb ' ,
searchable = 1 ,
widget = TextAreaWidget(),
),
TextField( ' body ' ,
searchable = 1 ,
required = 1 ,
primary = 1 ,
default_output_type = ' text/html ' ,
allowable_content_types = ( ' text/plain ' ,
' text/structured ' ,
' text/restructured ' ,
' text/html ' ,
' application/msword ' ),
widget = RichWidget(label = ' Body ' ),
),
),
marshall = PrimaryFieldMarshaller(),
)
多个语义(Schema)累加,是可以组装为一个新的语义(Schema)的。ArchExample也是这样做的,它累加了一个叫做 BaseSchema 的语义。
注意:在界面上各个输入项显示的次序,和Schema定义中字段(Field)的添加次序是一致的。这意味着,移动Schema中各个字段
(Field)在语义(Schema)中的位置,便可调整这些元素在界面上的显示次序。
什么是字段(Filed)?
字段就如果数据库中定义表结构中的字段一样,它是组成语义的基本单元。每一个字段有一个默认使用的显示器件(Widget),你也可以单独指定。
下面是Archetypes中可用字段的列表
名字 | 类型 | 默认显示器件 | 描述 |
BooleanField | 布尔类型 | ComputedWidget | 用于存放真/假的简单字段 |
DateTimeField | 日期和时间对象 | CalendarWidget | 用于存放日期和时间 |
FileField | 文件类型 | FileWidget | 用于存放大段的数据,比如文本文件,微软的Word文档,等等 |
FixedPointField | 定点数值 | DecimalWidget | 用于存放定点的数值数据 |
FloatField | 浮点数 | DecimalWidget | 用于存放浮点数值数据 |
ImageField | 图片 | ImageWidget | 存放图片,允许动态的调整图片的大小 |
IntegerField | 整数 | StringWidget | 存放整数数值类型 |
LinesField | 列表 | LinesWidget | 数据的列表(list),比如关键字 |
ReferenceField | 引用 | ReferenceWidget | 指向这个对象和其他对象的引用 |
StringField | 字符串 | StringWidget | 针对存放比较小的字符串优化的字段,比如小于100个字符的字符串 |
TextField | 字符串 | TextWidget | 针对存放较大的字符串优化的字段,比如大于100个字符. 这个字符串可被转化为多种格式 |
所有的这些字段,可在Archetypes的public模块中导入,比如:
from Products.Archetypes.public import BooleanField
每个字段都有一组可设置的属性,name 属性是字段唯一必需的参数,而且必须唯一,并使用不包含空格和点号的小写英文字母。
所有的其他属性都是可选的。下表描述了其他的所有的属性。
名字 | 描述 | 可能的值 |
accessor | 获取字段值(用于显示的值)的方法名 | 可以指定任何方法名(如specialGetMethod) |
default | 字段默认值 | 为字段设置一个合适的默认值 |
default_method | 参数是一个方法名的字符串,调用该方法得到字段默认值,如果不设置则系统将自动生成一个 | 任何一个方法的名称字符串 |
edit_accessor | 获取字段原始值(比如rst中的原始代码)的方法名 | 任何方法名(如rawGetMethod) |
enforceVocabulary | 如果被设置则不接受vocabulary之外的任何值 | True或False |
vocabulary | 字段的可能的值的列表,常用于下拉列表中的可选项 | 字符串列表,如 ['Green', 'Red', 'Blue'] |
index | 如果你希望这个字段被用在它自己的索引名中,可以在这里设置一个索引类型字符串。如果再加上:schema后缀,则它还会作为metadata信息被存储 | 任何索引名,如KeywordIndex 或 KeywordIndex:schema. |
name | 字段的唯一命名(必须的属性) | 任何小写的字符串并遵守Python变量命名规则,(如 description, user_name, 或 coffee_bag_6). |
mode | 字段的读写模式,使用一个字符串形式表示,默认值是读写模式 | 只读模式是 'r', 只写模式是 'w', 读写模式是 'rw' |
multiValued | 表示字段是否可以有多个值,这对于下拉列表形式的多选项很有用 | True 或 False. |
mutator | 改变字段值的方法名,由此可以改变这个字段怎样被设置 | 任何方法名(如 specialSetMethod) |
primary | 如果设置为真,则这个字段将被作为FTP和WebDAV协议的响应。只能有一个字段设置这个值,如果有多个字段设置了primary则只有第一个被使用。通常只为主body属性设置这个字段 | True 或 False. |
required | 指定这个字段是否必需 | True 或 False. |
schemata | 相当于分组 | 分类的字符串 |
metadata | 指示这个值是否会被放入到metadata信息中 | 默认值是False |
searchable | 指定该字段是否加入到可搜索文本中以被搜索到 | True 或 False. |
validators | 为字段设置校验,可以在这里设置校验方法的字符串的元组,它会顺序执行这个校验方法 | 任何校验器 |
storage | 在哪里存放数据;默认是 AttributeStorage ,将数据存放为对象的一个属性 | 任何一个有效的storage对象,比如 AttributeStorage 或者 SQLStorage |
widget | 用于显示字段的器件名称 | 任何器件对象 |
read_permission | 用于读取时的权限设置 | 如CMFCore的permissions中定义的View权限 |
write_permission | 修改这个字段所需要的权限 | 如CMFCorer的permissions中定义的ModifyPortalContent权限 |
什么是显示器件(Widget)?
显示器件(Widget)包含了如何显示对象的一些信息。可从Archetypes的 public 模块中导入显示器件,如:
from Products.Archetypes.public import BooleanWidget
可以为Widget的构造函数中的每个参数添加以"_msgid"为后缀的关键字式参数,为它提供一个msgid,并且使用i18n_domain参数指定翻译域,如:
StringField( " blurb " ,
required = 1 ,
searchable = 1 ,
widget = TextAreaWidget(label = " Article Blurb " ,
label_msgid = " label_blurb " ,
description = " Please input a short blurb for this article. " ,
description_msgid = " help_blurb " ,
i18n_domain = " archexample " ),
)
Plone中的内容,每个内容都包括很多属性。但是FTP或者WebDAV只能传递单个的文件。这样,通过FTP/WebDAV下载内容的时候,需要将内容转换单个的文件。上面的例子中, body字段被设置为内容的主字段(primary),在FTP/WebDAV下载的时候,会直接传递这个字段的内容,而不是整个内容。
Archetypes将这种内容到单个文件的转换,叫做Marshall。相应的,从文件转换到内容的过程,则叫做DeMarshall。Archetypes内容的Schema定义中,可指定一个Marshaller,来负责Marshall和DeMarshall的过程: marshall=some_marshaller() 。Archetypes默认包括2种Marshaller:
- PrimaryFieldMarshaller: 仅仅将主字段转换为文件,Plone的文件和页面,均采用这个Marshaller。
- RFC822Marshaller: 将内容采用RFC822的标准格式存储,也就是邮件的存储格式。这个格式采用 "关键字: 值" 的方式,能够传递内容的各种属性。
Validator校验器:
要实现这个功能,可在字段(Field)定义中增加一个检验参数。比如,为了测试你的 IntegerField 是否真的是一个整数,你可这样完成:
from Products.Archetypes.public import IntegerWidget
# 一个简单的年龄字段
age = IntegerField( ' age ' ,
validators = ( " isInt " ),
widget = IntegerWidget(label = " 你的年龄 " )
)
而像isInt这样的validators是事先plone定义好的。常用的validators有如下:
名字 | 说明 |
isDecimal | 是10进制数,包括正负号、指数等 |
isInt | 是整数 |
isPrintable | 是否可打印,只能是字母和数字 |
isSSN | 是9个数字(也就是美国的社会安全号) |
isUSPhoneNumber | 长度为10个数字 |
inNumericRange | 位于某个范围的数值 |
isURL | 是URL,起始为http://,ftp://,或者https:// |
isEmail | 是邮件地址格式 |
isEmpty | 为空 |
isValidDate | 是有效的日期 |
isMaxSize | 上传文件的大小限制 |
自己也可以注册自己写的校验器,前提是自己写的Python类实现了IValidator接口。像这样:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)