词汇库Plone. 中央,可插拔,TTW,支持IMS VDEX
项目描述
简介
ATVocabularyManager: Plone 的词汇管理门户工具
概述
ATVocabularyManager 通过 Plone 管理动态词汇表。
本产品基于 Archetypes 构建,旨在与 Archetypes 以及其他产品协同工作。它打算用于 Archetypes 字段中。将其用作 CMFMetadata 的词汇提供者也表现良好。与其他产品的集成也将顺利。
要使用受管理的词汇表,只需将术语 vocabulary = NamedVocabulary("myvocabulary") 添加到您的 Archetypes 架构字段中,从本产品导入 NamedVocabulary 并在 'portal_vocabularies' 工具中创建您的词汇(通过 Plone 网站设置获取)。NamedVocabulary 接受两个额外参数
empty_first_item,需要一个布尔值以在列表顶部获取空项,默认为 False;
custom_empty_first_item,需要一个包含自定义第一项的元组列表,默认为 None。
ATVocabularyManager 支持
- 简单平面键
值词汇表
- 树形
层次词汇表(见限制)
- IMS 词汇定义交换格式 (VDEX) 意识的词汇表
具有 XML 导入和导出。由于 VDEX 本身具有 i18n 意识,因此不需要 LinguaPlone!
- 词汇表是可插拔的类型。
ATVocabularyManager 为扩展您的特殊词汇类型做好了准备。ArchGenXML 将在此处帮助您。每个词汇项都需要是一个 CMF 意识的内容类型。将常规丰富内容作为词汇表重用。
ArchGenXML 1.4+ 代码生成器完全集成了 ATVocabularyManager:通过标记值定义的命名词汇透明注册,VDEX-XML 文件在安装时导入,在安装时创建占位符词汇表,并通过提供适当的类型来注册自定义类型。
ATVM与Linguaplone兼容(仅与SimpleVocabulary和TreeVocabulary进行了测试)。添加一些条目的简单词汇表,安装和配置Linguaplone,将词汇表翻译成您选择的语言,将每个条目翻译成您选择的语言。NamedVocabulary()将按常规返回词汇表,键将保持不变,不考虑语言设置,值将显示在当前选定的语言中。VDEX词汇表不使用LinguaPlone,但具有i18n意识(据我所知,比其他所有东西都好)。
您可以对treevocabularies进行具有层次感知的搜索(有关更多信息,请参阅doc/search_treevocabulary.txt)注意:目前,某些术语层次结构的变化需要重建目录(请参阅限制)。
安装
此插件可以像其他插件一样安装。请遵循官方文档
为了加快ATVocabularyManager的速度,您可能希望将其与Cache-Manager关联。
依赖关系
Products.Archetypes
imsvdex
[Products.Linguaplone] 可选
限制
- TreeVocabulary目录更新
如果您正在使用具有层次感知的目录搜索支持的tree-vocabularies,则在移动具有以下术语的vocabularyterm时,您需要重建uid_catalog和portal_catalog。
- VDEX TTW的创建/编辑很困难。
选择您喜欢的编辑器,创建词汇表并上传它或帮助编写UI。
已知错误
检查问题跟踪器:https://github.com/collective/Products.ATVocabularyManager/issues 欢迎在此处添加错误!
支持
通常,作者提供专业支持。经典的工作社区支持可以在plone.org上宣布的邮件列表和IRC频道中找到:http://plone.org
版权 / 许可证
Products.ATVocabularyManager受BSD类似许可证的保护。
Products.ATVocabularyManager的版权由
Jens Klein <jens.klein@bluedynamics.com> 和相应的作者
2010-2011年由BlueDynamics Alliance,奥地利,德国,瑞士
2007-2008年由BlueDynamics Alliance,Klein & Partner KEG,奥地利
2004-2009年由BlueDynamics Alliance,Klein & Partner KG,奥地利和部分eduplone Open Source Business Network EEIG,奥地利
版权所有。
在满足以下条件的情况下,允许重新分配和使用源代码和二进制代码,无论是否修改
源代码的重新分配必须保留上述版权声明、本条件列表和以下免责声明。
二进制形式的重新分配必须复制上述版权声明、本条件列表和以下免责声明在提供的文档和/或其他材料中。
未经事先书面许可,不得使用ATVocabularyManager或其贡献者的名称来认可或推广由此软件派生的产品。
本软件按“原样”提供,并且任何明示或暗示的保证,包括但不限于适销性和针对特定目的的适用性保证,均予以否认。在任何情况下,版权所有者或贡献者均不对任何直接、间接、偶然、特殊、示范性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;或业务中断)承担责任,无论何种原因和基于何种责任理论(合同、严格责任或侵权责任)(包括疏忽或其他),无论是否事先通知了此类损害的可能性。
致谢
部分代码是为ZUCCARO项目创建的。ZUCCARO(Zope-based Universally Configurable Classes for Academic Research Online)是由Bibliotheca Hertziana,Max Planck Institute for Art History开发的用于人文学科的数据库框架。更多信息请参阅:“zuccaro.biblhertz.it”:http://zuccaro.biblhertz.it/
人员
Jens Klein <jens@bluedynamics.com>(作者)
fRiSi <harald.webmeisterei.com>
gotcha <gotcha@bubblenet.be>
jenens <jens@bluedynamics.com>
naro <novotny.radim@gmail.com>
rocky <rocky@serverzen.com>
thet <raggam-nl@adm.at>
Wouter Vanden Hove, <wouter@wvhconsulting.org>
Paul J Stevens, <paul@nfg.nl>
JeanMichel FRANCOIS, <toutpt@gmail.com>
andrewburkhalter - <andrewb@onenw.org>
Mathieu Le Marec - Pasquet (kiorky), <kiorky@cryptelium.net>
待办事项
任务
创建一个问题:simplevocabs 不按字母顺序排序,也不使用 getObjectPositionInParent 定义的顺序(见问题 #4)
从 Products.Archetypes.interfaces.vocabulary 导入 IVocabularyTerm 的 try 中删除
我们应该在 IVocabularyTerm.getTermValue 中添加参数 'lang' [jenens] 同意,但我们应该将其设置为可选的(通常翻译应该是透明的)
将 getTermPath 移到单独的 hierarchicalvocabulary 接口?[hf] 这将允许我们通过接口区分层次词汇表,我们还需要让 namedvocbaulary.getKeyPathForTerms 也意识到这一点。
(在别名中缺失)将方法 getVocabularyValue 和 getVocabularyKey 标记为已弃用,并使用 getTermValue 和 getTermKey 方法代替 [jenens] XXX
使用 zope3 接口为术语,例如在 NamedVocabulary.getKeyPathForTerms 中有用(参见那里的注释)
解决代码中标记的 TODOs(XXX,FIXME)
功能想法
选择深度
- 基本思想
字段可以指定选择深度(0 无限制,1 第一级,2 第二级等),这将显示在 Displaylist 中。
- 为什么我们需要这样
如果某个字段不需要词汇表提供的细粒度选择可能性,则不需要定义新的词汇表。
可变显示列表
- 基本思想
字段可以指定用于显示列表的词汇项的哪个属性。
- 为什么我们需要那样
在某些情况下,需要相同的词汇表,但用于显示的选择应该使用另一个字段或字段组合。
- 风险/缺点
更复杂的缓存显示列表处理(需要处理不同的字典,而不仅仅是单个字典)
缓存显示列表
- 基本思想
使用 ZCacheable 缓存显示列表和词汇字典(我们唯一需要关心的是在术语移动或更改时使缓存无效)
- 为什么我们需要这样
获取词汇显示列表的成本很高。目前,每次编辑使用词汇的内容类型时,都会获取整个词汇的显示列表,甚至在查看时也是如此!
- [jenens] 将在不久的将来为 vdex 词汇实现此功能:已完成
- 待办事项:在上传 vdex 后使缓存无效。
(自动?)分配给 ram-cache-manager。
通用设置支持
- 基本思想
vdex 已经可以导出和导入 xml。我们也应该为 simple 和 term 实现 [jenens] 决策:使用 vdex,一些自己的 xml 或更好的 marshall 的 atxml,或者只是简单的可导入 CSV?Jens 的决策是:vdex(已实现导入)或 csv(待办)。
混入
vdex 和 tree 以及可能的其他类型的通用层次功能应该在一个 mixin 中编码。一次编码和测试,到处使用
目录更新
当前限制
对词汇结构(例如:将术语向上移动层次结构)的任何更改都必须触发不仅使缓存无效,而且重新索引层次结构中所有术语(uid_catalog 搜索 getTermUidPath,catalog.manage_reindexIndex(ids=('getTermUidPath',)))
目前这是 treevocabulary 的限制。vdex 不需要被编目
- 需要在 uid_catalog 和 portal_catalog 中重新索引对象
我们需要挂钩哪种方法?
- 在 portal_catalog 中,用于内容类型索引的索引
更糟糕的问题是重新索引那些在其路径-方法上定义自定义索引的对象。我们不知道它们使用的是哪个目录(可能是 portal_catalog,也可能是任何其他目录)
头脑风暴
将目录和索引存储在词汇表或 atvmtool 中
提供可以实现的某个地方的钩子
也许可以使用引用而不是文本行字段,以便能够找出使用了某个特定术语的内容。
简单词汇表
简单的词汇表是扁平的词汇表。
创建简单词汇表
SimpleVocabularies 可以在词汇库中创建
>>> portal = layer['portal'] >>> from Products.CMFCore.utils import getToolByName >>> atvm = getToolByName(portal, 'portal_vocabularies')>>> from plone.app.testing import TEST_USER_ID, setRoles >>> setRoles(layer['portal'], TEST_USER_ID, ['Manager']) >>> _ = atvm.invokeFactory('SimpleVocabulary', 'testvocab', title="test vocabulary")
您可以通过在词汇库上调用 getVocabularyByName 来获取词汇
>>> simple = atvm.getVocabularyByName('testvocab') >>> simple <SimpleVocabulary at /plone/portal_vocabularies/testvocab> >>> simple.Title() 'test vocabulary'
创建简单词汇表术语
简单的词汇表只能包含 SimpleVocabularyTerms。
>>> simple.allowedContentTypes() [<FactoryTypeInformation at /plone/portal_types/SimpleVocabularyTerm>]
您可以使用 invokeFactory 或 addTerm 方法添加术语
>>> _ = simple.invokeFactory('SimpleVocabularyTerm', 'term1') >>> simple.addTerm('term2', 'first time') True
addTerm 可以忽略重复的键,并返回添加是否成功。
>>> simple.addTerm('term2', 'second time', silentignore=True) False >>> simple.getDisplayList(portal) <DisplayList [('term1', ''), ('term2', 'first time')] at ...>
批量创建
对于在 Python 代码中创建简单的词汇表,您可以使用 atvm 为您提供的便利方法
>>> from Products.ATVocabularyManager.utils.vocabs import createSimpleVocabs
这需要以下格式的字典
>>> testvocabs = {} >>> testvocabs['sorting'] = ( ... ('c', u'Alpha'), ... ('a', u'Zeppelin'), ... ('y', u'Charly')) >>> createSimpleVocabs(atvm, testvocabs) >>> sorting = atvm.getVocabularyByName('sorting') >>> sorting.contentIds() ['c', 'a', 'y']
排序
您可以通过选择 排序方法 中的值来定义简单词汇表内词汇项的排序顺序。
默认排序顺序是按值(标题)的字母顺序排序
>>> sorting.getField('sortMethod').vocabulary.keys() ['getObjPositionInParent', 'lexicographic_values', 'lexicographic_keys'] >>> sorting.getSortMethod() 'lexicographic_values'
按值排序
>>> sorting.getDisplayList(portal) <DisplayList [('c', 'Alpha'), ('y', 'Charly'), ('a', 'Zeppelin')] at ...>
按键排序
>>> from Products.ATVocabularyManager.config import SORT_METHOD_LEXICO_KEYS >>> sorting.setSortMethod(SORT_METHOD_LEXICO_KEYS) >>> sorting.getDisplayList(portal) <DisplayList [('a', 'Zeppelin'), ('c', 'Alpha'), ('y', 'Charly')] at ...>
按文件夹位置排序
>>> sorting.listFolderContents() [<SimpleVocabularyTerm .../sorting/c>, <SimpleVocabularyTerm .../sorting/a>, <SimpleVocabularyTerm .../sorting/y>] >>> from Products.ATVocabularyManager.config import SORT_METHOD_FOLDER_ORDER >>> sorting.setSortMethod(SORT_METHOD_FOLDER_ORDER) >>> sorting.getDisplayList(portal) <DisplayList [('c', 'Alpha'), ('a', 'Zeppelin'), ('y', 'Charly')] ...>
Linguaplone 支持
简单的词汇表具有完整的 Linguaplone 支持,但即使没有安装 Linguaplone 也可以工作
>>> if portal.portal_quickinstaller.isProductInstalled('LinguaPlone'): ... portal.portal_quickinstaller.uninstallProducts(['LinguaPlone']) >>> portal.portal_quickinstaller.isProductInstalled('LinguaPlone') False
如果 Linguaplone 未安装,我们的词汇表可以正常工作而不会引起麻烦
>>> from plone import api >>> atvm = api.portal.get_tool(name='portal_vocabularies') >>> createTestVocabulary(atvm) >>> vocab = atvm.teststates >>> dict(vocab.getVocabularyDict(vocab)) {'ger': 'Germany', 'fin': 'Finland', 'aut': 'Austria', 'nor': 'Norway'}
如果 Linguaplone 已安装,简单的词汇表完全支持已翻译的词汇项
XXX 将测试 / testSimpleVocabulary / testTranslations 继续移植到这里
排序
此外,对已翻译的词汇表进行排序也按预期工作:XXX 编写以下测试的测试
键在每种语言中都是相同的,因此按键排序应在每种语言中产生相同的顺序
按标题排序可能产生完全不同的顺序
按文件夹中的位置排序可能不同,因为翻译有自己的顺序
对层次词汇表的搜索
这个测试演示了 ATVM 如何使您能够使用树状词汇字段使您的内容类型可搜索。
想象以下词汇
engine-type
electrical
mechanical
otto engine
diesel engine
搜索 engine==mechanical 应返回所有 otto 和 diesel 发动机的条目
如果您不是开发者而只想学习如何在内容类型上执行层次感知搜索,则可以跳过本教程。这在 Product ATVocabularyManagerExample 中演示
设置词汇表
让我们使用 ATVM 提供的实用方法创建我们的词汇表
>>> from Products.CMFCore.utils import getToolByName >>> portal = layer['portal'] >>> atvm = getToolByName(portal, 'portal_vocabularies') >>> from Products.ATVocabularyManager.utils.vocabs import createHierarchicalVocabs >>> dictionary = { ... ('electrical', 'electrical engines'): {}, ... ('mechanical', 'mechanial engines'): { ... ('otto', 'ottomotor'): {}, ... ('diesel', 'diesel engine'): {} ... } ... } >>> hierarchicalVocabs = {} >>> hierarchicalVocabs[('enginetypes', 'Diffetent types of engines')] = dictionary >>> from plone.app.testing import TEST_USER_ID, setRoles >>> setRoles(layer['portal'], TEST_USER_ID, ['Manager']) >>> createHierarchicalVocabs(atvm, hierarchicalVocabs)
现在我们的词汇表已经可用
>>> engines = atvm.getVocabularyByName('enginetypes') >>> engines <TreeVocabulary at /plone/portal_vocabularies/enginetypes>
背景信息
这个小部分告诉您 ATMV 如何实现将 otto 发动机识别为机械发动机。
词汇项的键是规范对象的 UID(如果词汇表翻译成不同的语言),可以使用 getTermKey 方法获取
>>> ottomotor = engines.mechanical.otto >>> ottomotor.getTermKey() == ottomotor.UID() True
TreeVocabularyTerm 实现了返回术语本身及其上方所有术语的词汇项键列表的 getTermKeyPath 方法。
>>> ottoPath = ottomotor.getTermKeyPath() >>> engines.mechanical.getTermKey() in ottoPath True
每个词汇项都使用 KeywordIndex 在 uid_catalog 中按 getTermKeyPath 进行索引。
键路径作为 uid_catalog 中的元数据列可用,因此可以通过目录查询获取,而无需调用实际对象。
我们可以通过搜索 otto 发动机的 UID 来找到我们的 otto 发动机术语
>>> uid_catalog = getToolByName(portal, 'uid_catalog') >>> uid_catalog(getTermKeyPath=ottomotor.UID())[0].getObject() <TreeVocabularyTerm at .../enginetypes/mechanical/otto>
搜索机械引擎返回 3 个词汇:奥托引擎、柴油引擎以及机械引擎的术语。
>>> result = uid_catalog(getTermKeyPath=engines.mechanical.UID()) >>> [brain.id for brain in result] ['mechanical', 'diesel', 'otto']
我们词汇的层次结构发生变化时,将重新索引所有更改术语以下的词汇。
XXX 在引擎下创建新术语“化石”,并将机械引擎移动到那里。之后,奥托和柴油引擎也应该可以在化石下使用。
使内容类型可搜索
为了能够搜索与术语相关的内容类型,不仅直接相关,还包括层次结构中的内容,我们需要在相关词汇术语的 TermKeyPath 下索引我们的对象。
ATVM 提供了一个快速实现的实用方法,该方法仅在工作目录上运行。
您可以在 NamedVocabulary 中使用 getKeyPathForTerms。
>>> from Products.ATVocabularyManager import NamedVocabulary >>> nv = NamedVocabulary('engines') >>> keyPath = nv.getKeyPathForTerms(portal, ottomotor.getTermKey()) >>> engines.mechanical.getTermKey() in keyPath True >>> ottomotor.getTermKey() in keyPath True
您需要做的就是实现一个使用 getKeyPathForTerms 方法的方法,并将其定义为索引方法。
# .. somewhere in the schemadefinition ReferenceField( name='myfield', widget=... vocabulary=NamedVocabulary("""myvocab"""), index="KeywordIndex", index_method="someIndexMethod" ), # .. somewhere in your content type definition define someIndexMethod(self): """used to index myfield """ # all we have to know is the field name of the field this # index method belongs to fieldName = 'myfield' # the following code need not be touched termUID = self.getField(fieldName).get(self) return self.getField(fieldName).vocabulary.getKeyPathForTerms(self, termUID)
有关如何在内容类型中使用 ATVocabularyManager 的更详细说明,请参阅 ATVocabularyManagerExample。
_ATVocabularyManagerExample: https://svn.plone.org/svn/archetypes/ATVocabularyManagerExample/
变更日志
1.6.7 (2015-07-30)
修复在编辑未翻译的规范内容时 SimpleVocabulary 的崩溃和清理 [pjstevns]
扩展对翻译 SimpleVocabulary 的测试并修复回归 [pjstevns]
如果 lp 和项目是语言中立的,则返回首选语言 [agitator]
Plone5 兼容性 [tomgross]
为所有词汇和术语添加了接口 [tomgross]
1.6.6 (2014-02-06)
尚未有任何更改。
1.6.5 (2014-02-06)
修复 simplevocabulary_view 文件夹操作,通过在表单中包含 p.protect.authenticator 来修复 [tmog]
修复 vocabularytool_view 文件夹操作,通过在表单中包含 p.protect.authenticator 来修复 [alecghica]
通过传递标题而不是名称来修复 vocabularytool_view 文件夹操作按钮显示 [ichim-david]
为了避免 Plone 4.x 的错误,将 nothing 追加到 tabsindex 表达式中 [ichim-david]
在 portal_vocabularies 的 __init__ 中添加一个可选的忽略 id,以便可以从 GenericSetup 导入它 [regebro]
修复 SimpleVocabulary 排序问题:有时文件夹中的顺序被忽略 [keul]
1.6.4 (2013-03-26)
修复 simplevocabulary_view 并将其设置为 SimpleVocabulary 和 SortedSimpleVocabulary 的默认视图 [petschki]
将“empty_first_item”和“custom_empty_first_item”额外参数添加到 NamedVocabulary 中,以在显示列表的顶部获取空项目 [simahawk]
与 plone 4.3 兼容 [kiorky]
1.6.3 (2013-01-16)
添加和更新一些文件以支持独立的构建 [pjstevns]
更新和清理测试代码以符合 PEP8 和 pyflakes,修复弃用警告,删除 ZopeTestCase。 [pjstevns]
更新内容类型以符合当前 Plone 实践(GS,FTI)。这可能仅使事物与 plone4+ 兼容。 [pjstevns]
将内容类型绑定到默认工作流。 [pjstevns]
从类型中删除了长期废弃的“属性”选项卡 [keul]
重构 i18n 结构(新翻译,不再需要 manual.pot 文件) [keul]
添加了意大利语翻译 [keul]
删除了旧的 Zope2 接口 [keul]
将旧的 i18n 文件夹移动到当前 locales [toutpt]
添加 fetchValuePathFromVDict 以在树状词汇中获取路径 [toutpt]
将 install_requires 提取为单独的变量 [pjstevns]
1.6.2 (2012-03-22)
避免在词汇不再存在但导入文件中仍存在实例化对象时破坏 *.zexp 文件的导入 [WouterVH]
为 vdex 词汇添加了字段“showTermPath”,以手动关闭术语路径 [jensens] [hpeteragitator]
为 vdex 词汇添加了字段“showLeafsOnly”,以更改是否只能选择词汇树的叶节点 [jensens] [hpeteragitator]
重构了 vdex 词汇的 getDisplayList [jensens] [hpeteragitator]
运行 i18ndude 并更新了德语翻译 [hpeteragitator]
让 createSimpleVocabs 接受字典键作为(id,标题)元组(就像 createHierarchicalVocabs 已经做到的那样),以便可以为词汇提供标题 [jcbrand]
1.6.1 (2011-05-02)
避免弃用警告 [WouterVH]
更新元数据文件和文件夹结构以符合当前约定 [WouterVH]
添加 z3c.autoinclude 入口以在 Plone 3.3+ 中自动加载 ZCML [WouterVH]
添加 MANIFEST.in 以包含顶层 *.txt 文件 [WouterVH]
1.6 - 2011-02-22
不要从metadata.xml中获取版本和shortdesc - 这是错误的。[jensens]
1.6.0a2 - 2011-02-18
更改了确定LinguaPlone是否安装的方法。在Plone4中询问QI不起作用。[naro]
添加了一些缺失的依赖项,并在setup.py中添加了一个新的额外部分。这有助于获取一个简单的针对plone4的测试buildout cfg。[do3cc]
在测试中添加了一些睡眠时间,否则genericsetup会两次创建ids,并失败。[do3cc]
临时禁用了测试中的两个检查。在Products.CMFQuickInstaller>=3.0.3中,门户词汇表在卸载期间不会被删除。[do3cc]
由于调用语义已更改,对测试设置进行了重构。[do3cc]
1.6.0a1 - 2010-07-16
修复了使用不带包名的registerType调用弃用的API。现在适用于Plone4。[thet]
将Products.LinguaPlone添加为测试依赖项到extras_require,并开始修复测试。[thet]
删除了旧的慢VDEX实现;添加了使用generixsetup导入/导出词汇的存根;添加了对generixsetup中vdex导入的支持。[jensens]
1.4.2 - 2008-06-04
添加了Diego Municio Cfr.提供的西班牙语翻译。http://plone.org/products/atvocabularymanager/issues/39。
合并了Duke为简单词汇的多语言csv导入修补程序。Cfr. http://plone.org/products/atvocabularymanager/issues/53。 [fRiSi]
修复了测试设置,以便使用naro添加的新GS配置文件设置ATVM。 (使用plone 3.1.1 buildout进行测试)这修复了 http://plone.org/products/atvocabularymanager/issues/52
去除了tests.framework。[fRiSi]
在setup.py中将imsvdex添加为必需依赖项,这使得使用buildout的人不再需要 easy_install imsvdex。[fRiSi]
添加了GenericSetup配置文件,删除了Install.py。[naro]
1.4 之前
解决#46的问题:从Windows/IE上传创建错误的ID。[jensens]
将新的VdexFileVocabulary作为上传表单的默认值。[jensens]
添加了替代vdex词汇,速度快得多。[jensens]
在词汇库(工具)中添加了便利方法,该方法返回一个字典,其中键=词汇表ID,值=词汇标题(语言感知。[jensens]
添加了便利函数,以便更容易地从词汇字典中获取值(utils.vocabs.fetchValueByKeyFromVocabularyDict)。[jensens]
为门户_vocabulary用户界面的各个元素添加了css处理程序,因此如果需要,可以轻松地将用户界面简化为对技术不敏感的客户,但不能覆盖模板 [andrewburkhalter]
语言协商以确保缓存具有语言感知能力。[jensens]
在types/simple/vocabulary.py中,应用了问题#4的补丁(简单词汇表的排序)[fRiSi]
在doc/simplevocabulary.txt中,添加了对simplevocabularies排序可能尚不适用于已翻译词汇的doctest测试。我添加了一个测试该内容的部分,但尚未在那里编写测试。[fRiSi]
event.py、configure.zcml、interfaces.py、types/simple/term.py。[rocky]
“重命名事件”现在在更新任何术语的标题时触发。[rocky]
“删除事件”现在在从词汇表中删除术语时触发;此特定功能仅在Zope 2.9或更高版本上运行时才会生效(注意:这不会使ATVM依赖于Zope 2.9)[rocky]
types/tree/vocabulary.py、types/simple/vocabulary.py用try-except替换了if not instance is None:。如果您正在使用未启用linguaplone的类型,并使用一个词汇表,则在创建此类型的对象时您会收到一个错误,因为getLanguage引发了AttributeError。[fRiSi]
types/tree/term.py修复http://plone.org/products/atvocabularymanager/issues/26。同时,我使用“hack解决方案”从扩展词汇的术语中移除了IVocabulary接口来解决这个问题。[fRiSi](有关更多信息,请参阅上面的问题。)
Makefile添加了一个新的目标clean,用于删除过时的pyc文件和-~备份文件[fRiSi]
namedvocabulary.py之前在uid-catalog返回多个值时不会添加术语的关键路径。直接取第一个结果比默默地忽略该项路径更好。[fRiSi]
在Extensions/Install.py中,对BadRequest错误进行了更清晰的检查,以防在安装时工具已经存在(还添加了安装/卸载/重新安装产品的基本测试。[fRiSi]
在Extensions/Install.py中,self.portal.portal_properties.navtree_properties.metaTypesNotToList默认为元组(在全新创建的plonesite上)。ATVM在安装时创建一个列表,并在卸载时从该列表中移除工具。如果在安装和卸载之间安装了其他产品,它们可能会将metaTypesNotToList重新更改为元组。修改了安装程序和卸载程序,使其在此处操作并返回元组。(应修复http://plone.org/products/atvocabularymanager/issues/10)[fRiSi]
tests/testATVocabularyManager.py测试了产品的安装和卸载。同意jens的意见,我们可以在卸载时对词汇进行zexp,以防不小心这样做。(http://plone.org/products/atvocabularymanager/issues/22/)[fRiSi]
types/simple/term.py: 移除了阻止我添加新术语的bug。[jensens]
在types/simple/term.py中,SimpleVocabularyTerms现在返回规范id作为键。这与当前行为不同,但对于翻译词汇是必要的。[fRiSi]
在types/simple/term.py中,getTermKeyPath现在返回包含术语键的列表,而不是它的uid。这与接口保持一致。[fRiSi]
types/simple/vocabulary.py,types/tree/vocabulary.py中的GetVocabularyDict现在使用instance.getLanguage而不是portal_lanuages.getPreferredLanguage(否则在大多数情况下传递实例将是无用的)
tests/testSimpleVocabulary.py: 添加了一个测试,检查翻译是否返回相同的键以及字典是否已翻译。
backports.py
改进了docstrings,使其更加明确。
getTermKey现在表明术语的所有翻译都有相同的键。
getTermValue:现在有一个可选的lang参数,使--kwargs在大多数情况下不再需要。
添加了排序简单的词汇表 [gotcha]
运行i18ndude并更新fr和nl [gotcha]
将支持对层次词汇表进行目录搜索的分支合并到trunk中(https://svn.plone.org/svn/archetypes/ATVocabularyManager/branches/treevocab-frisi)[fRiSi]
将当前trunk合并到这个分支。[fRiSi]
Utils/vocabs.py为批量创建词汇表提供了实用方法。[fRiSi]
types/simple/term.py,types/tree/term.py将getVocabularyValue和getVocabularyKey方法标记为已弃用,并使用IVocabularyTerm中定义的这些方法来使术语实现其接口。[fRiSi]
types/tree/vocabulary.py,types/simple/vocabulary.py改进了linguaplone支持,并添加了一个测试用例。[fRiSi]
tests/testTreeVocabulary.py 测试treevocabulary是否对linguaplone有意识。[fRiSi]
doc/search_treevocabulary.txt:一个doctest解释了ATVM如何对层次词汇表进行搜索,以及如何为您的内容类型启用它们。[fRiSi]
添加了荷兰语翻译,感谢Atopia。[jladage]
AllowedTypesByIface似乎损坏了,已在ATVM中添加了手动覆盖以修复此问题。[optilude]
在安装ATVM类型时删除了工作流。[ferri]
添加了巴西葡萄牙语翻译和portal_vocabularies标题的i18n支持。[ferri]
添加了i18n和捷克语翻译。[naro]
在Install.py中取消注释了代码,使portal_vocabularylib不在导航树中显示。[panjunyong]
对于简单词汇术语,使用StringWidget而不是IDWidget。[panjunyong]
项目详情
Products.ATVocabularyManager-1.6.7.tar.gz 的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | 4b675ee03ee4d8b51ca485fe163dcd174fb409197042670d1d9a0bb283a77426 |
|
MD5 | 5717360c71c4045af48802aad96494cf |
|
BLAKE2b-256 | 89ae661b19b077658ec0908f7161ce65ff3a8b7f77653eedb8baeec34a6daadb |