我有一系列Plone网站,它们使用基于Archetypes的内容。
我有一些TextField
需要从text/plain
更改为text/html
;说,架构剪断了
TextField(
name='summary',
default='',
read_permission=Access_contents_information,
default_content_type='text/plain',
allowable_content_types=('text/plain',),
storage=AnnotationStorage(migrate=True),
widget=TextAreaWidget(
label=_('my_label_summary',
default='Summary'),
i18n_domain='plone',
),
),
应该改为
TextField(
name='summary',
default='',
read_permission=Access_contents_information,
default_content_type='text/html',
default_output_type='text/html',
allowable_content_types=('text/html',),
storage=AnnotationStorage(migrate=True),
widget=RichWidget(
label=_('my_label_summary',
default='Summary'),
i18n_domain='plone',
),
),
由于物品的数量很少,我愿意接受受影响区域的临时丑陋外观(例如折叠的线路断裂);更重要的是拥有可视化编辑器(使用可切换的内容类型对我不起作用)。
最好的解决方案当然是将当前text/plain
字段原样使用,并且在即将编辑对象时,将它们转换为合理的text/html
等效字符,然后可以用可视化编辑器编辑(CKEditor,在我的例子中)。
但是,如果我只是使用更改的架构编辑对象,则可视编辑器看起来很好,但存储的文本被<p>
/ </p>
标记包围并解释为text/plain
。
我找到了/archetype_tool/manage_updateSchemaForm
,但更新了我班级的架构并没有帮助。
我找到https://plone.org/products/archetypes/documentation/old/ArchetypesDeveloperGuide/,但这看起来既不完整又过时。
任何指针?谢谢!
更新
因为这不符合评论:
我现在创建了一个upgrades
子包; configure.zcml
:
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
i18n_domain="plone">
<genericsetup:upgradeStep
source="*"
destination="1001"
title="text/html fields for MyType"
profile="Products.myproduct:default"
handler=".to_1001.fix_mimetypes"/>
</configure>
模块代码(to_1001.py
):
import logging
from Products.CMFCore.utils import getToolByName
from ..tools.log import getLogSupport
logger, debug_active, DEBUG = getLogSupport(fn=__file__)
def htmlify_attribute(o, attr_name, brain=None, default=u''):
"""
Change MIME type of a TextField to text/html
"""
attr = getattr(o, attr_name, None)
changed = False
brain_url = (brain is not None
and brain.getURL()
or None)
if not attr:
mutator = o.getField(attr_name).getMutator(o)
mutator(default)
attr = getattr(o, attr_name, None)
changed = True
convert = False
mimetype = getattr(attr, 'mimetype', 'text/plain')
if mimetype != 'text/html':
if brain_url is not None:
logger.info('Fixing MIME type of %(attr_name)s'
' for %(brain_url)s', locals())
setattr(attr, 'mimetype', 'text/html')
changed = True
return changed
def fix_mimetypes(context):
"""
text/plain --> text/html for some MyType fields
"""
pc = getToolByName(context, 'portal_catalog')
TYPES = ['MyType']
brains = pc.unrestrictedSearchResults(portal_type=TYPES)
total = len(brains)
MASK = 'Fixing MIME types for %(total)d %(TYPES)s objects'
logger.info(MASK + ' ...', locals())
cnt = 0
import pdb; pdb.set_trace()
for brain in brains:
obj = brain.getObject()
if htmlify_attribute(obj, 'summary', brain):
cnt += 1
if cnt or True:
logger.info('%(cnt)d objects changed', locals())
logger.info(MASK + ': DONE', locals())
return ('Done '+MASK) % locals()
由于我的产品缺少special profile version,因此我创建了一个.../profiles/default/metadata.xml
文件,并将值设置为1000
;因为在启动时没有发生任何事情,并且在QuickInstaller中没有发现任何特殊情况,我重新安装,然后将数字增加一个。
我的to_1001
模块是在启动时导入的,正如我可以通过注册记录器看到的那样
(已记录);但它不是使用(因为我知道因为
pdb.set_trace()
),既没有使用增加的版本号启动(bin/instance fg
),也没有在QuickInstaller中重新安装时。
缺少什么? 这个升级步骤应该如何工作,即被触发?
答案 0 :(得分:2)
您可能需要现有对象的升级步骤。例如,请参阅eea.soercontent evolve19.py和configure.zcml
要测试是否是这种情况,请在编写升级步骤之前,转到修改和保存,而不进行任何更改。现在,如果再次进入“编辑”,则应该使用富文本编辑器。
答案 1 :(得分:1)
我现在已经将这个代码用于两个客户端,以初始化新的富文本字段。我想如果他们是旧的或新的领域并不重要。此函数将内容实例作为输入。因此,您可以遍历目录大脑并传递此函数brain.getObject()
。
def initialize_rich_text_fields(instance):
"""New rich text fields should have mimetype text/html.
Adapted from setDefaults in Archetypes BasicSchema.
"""
default_output_type = 'text/x-html-safe'
mimetype = 'text/html'
schema = instance.Schema()
for field in schema.values():
# We only need to do this for fields with one specific mimetype.
if not shasattr(field, 'default_output_type'):
continue
if field.default_output_type != default_output_type:
continue
# only touch writable fields
mutator = field.getMutator(instance)
if mutator is None:
continue
base_unit = field.getBaseUnit(instance)
if base_unit.mimetype == mimetype:
continue
# If content has already been set, we respect it.
if base_unit:
continue
default = field.getDefault(instance)
args = (default,)
kw = {'field': field.__name__,
'_initializing_': True}
kw['mimetype'] = mimetype
mapply(mutator, *args, **kw)