2016-03-02 103 views
0

我有一个使用基于Archetypes的内容的Plone网站家族。Plone,Archetypes:将文本字段从文本/纯文本更改为文本/ html

我有一些TextField s需要从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,就我而言)。但是,如果我简单地使用已更改的模式编辑对象,则可视编辑器看起来很好,但存储的文本被标签包围,并被解释为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中重新安装时。

缺什么? 这个升级步骤应该如何工作,即被触发?

回答

2

您可能需要现有对象的升级步骤。例如见eea。soercontent evolve19.pyconfigure.zcml

为了测试,如果是这样的话,写的升级步骤之前,请编辑保存在不改变任何东西。现在,如果再次进入编辑状态,则应该有适当的富文本编辑器。

+0

是的,我想我需要一个升级步骤;我会研究这个。我的主要问题不在于获取富文本编辑器,而是为了获取正确的内容类型。 – Tobias

+0

我通过创建升级步骤的努力更新了我的问题。这应该如何工作,即被触发? – Tobias

+0

将'1001'版本放入'profiles/default/metadata.xml'中,然后你的升级步骤应该出现在'Site Setup> Add-ons'或者通过ZMI:'portal_setup> manage_upgrades' – avoinea

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) 
+0

啊,有趣的(虽然也许不*完全*我需要什么)。对于可能包含“text/plain”或“text/html”的*每个字段,“text/x-html-safe”应该用作default_output_type吗? – Tobias

+0

对不起 - 我犹豫了太久,无法编辑以前的评论... 因此'text/x-html-safe'是关于剥离危险的HTML标签,并且建议用户提供的任何内容。 标准转换并非偶然将简单的'text/plain'(文本段落和项目符号列表)转换为HTML,对吗?我很抱歉 - 它是我的对象中的文本/纯文本,而不是文本/结构化文件或类似文件。 – Tobias

+0

Plone附带Products.PortalTransforms中的portal_transform工具。您可以使用它从一种MIME类型转换为另一种MIME类型。 – maurits