研究Archetype框架

来源:互联网 发布:淘宝定制规则 编辑:程序博客网 时间:2024/06/18 16:02

  什么是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文件中

schema = BaseSchema +  Schema((
    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或Falsevocabulary字段的可能的值的列表,常用于下拉列表中的可选项字符串列表,如 ['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信息中默认值是Falsesearchable指定该字段是否加入到可搜索文本中以被搜索到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 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接口。像这样:

from validation.validators import RangeValidator
from validation import validation

# RangeValidator 需要传入校验器的名字、起始和结束值
validAge = RangeValidator("validAge", 0, 150)
validation.register(validAge)
原创粉丝点击