简体   繁体   English

扩展Plone-Controlpanel表格

[英]Extend Plone-Controlpanel Form

Is it possible to extend the Controlpanel-View with each addon? 是否可以使用每个插件扩展Controlpanel-View?

For Example 例如
ca.db.core -> Makes basic fieldset/tab for DB Connection Settings ca.db.core - >为数据库连接设置创建基本字段集 /选项卡
ca.db.person -> If installed, Adds to the "core" settings a new fieldset/tab for Person specific fields/settings ca.db.person - >如果已安装,则向“核心”设置添加人员特定字段/设置的新字段集/选项卡
ca.db.schema -> If installed, also adds an new fieldset/tab for schema.org Fields ca.db.schema - >如果已安装,还会为schema.org字段添加新的字段集/选项卡

Yes it's possible, I once discussed this problem with a guy, who wrote the bda.plone.shop addon. 是的,有可能,我曾经和一个写过bda.plone.shop插件的人讨论过这个问题。

They faced the same problem, and solved it by using a ContextProxy object, which puts the different schema definitions together in one proxy object. 他们遇到了同样的问题,并通过使用ContextProxy对象解决了这个问题,该对象将不同的模式定义放在一个代理对象中。

Using a proxy is IMHO a hack, but I don't know a better solution. 使用代理是恕我直言,但我不知道更好的解决方案。

The proxy, tries to get/set a attribute from a list of schemas. 代理,尝试从模式列表中获取/设置属性。 Be aware, you need to handle conflicting names, means if you have the same field name in more than one schema. 请注意,您需要处理冲突的名称,这意味着如果您在多个架构中具有相同的字段名称。

class ContextProxy(object):

    def __init__(self, interfaces):
        self.__interfaces = interfaces
        alsoProvides(self, *interfaces)

    def __setattr__(self, name, value):
        if name.startswith('__') or name.startswith('_ContextProxy__'):
            return object.__setattr__(self, name, value)

        registry = getUtility(IRegistry)
        for interface in self.__interfaces:
            proxy = registry.forInterface(interface)
            try:
                getattr(proxy, name)
            except AttributeError:
                pass
            else:
                return setattr(proxy, name, value)
        raise AttributeError(name)

    def __getattr__(self, name):
        if name.startswith('__') or name.startswith('_ContextProxy__'):
            return object.__getattr__(self, name)

        registry = getUtility(IRegistry)
        for interface in self.__interfaces:
            proxy = registry.forInterface(interface)
            try:
                return getattr(proxy, name)
            except AttributeError:
                pass

        raise AttributeError(name)

Now you need to use the proxy in your ControlPanel form. 现在,您需要在ControlPanel表单中使用代理。 I assume you're using the RegistryEditForm from plone.registry : 我假设你正在使用plone.registryRegistryEditForm

class SettingsEditForm(controlpanel.RegistryEditForm):
    schema = ISettings
    label = _(u"Settings")
    description = _(u"")

    # IMPORTANT Note 1 - This is where you hook in your proxy    
    def getContent(self):
        interfaces = [self.schema]  # Base schema from ca.db.core
        interfaces.extend(self.additionalSchemata) # List of additional schemas
        return ContextProxy(interfaces)

    # IMPORTANT Note 2 - You may get the additional schemas dynamically to extend the Settings Form. For example by name (startswith...)
    # In this case they have a separate interface, which marks the relevant interfaces.
    @property
    def additionalSchemata(self):
        registry = getUtility(IRegistry)
        interface_names = set(record.interfaceName for record
                              in registry.records.values())

        for name in interface_names:
            if not name:
                continue

            interface = None
            try:
                interface = resolve(name)
            except ImportError:
                # In case of leftover registry entries of uninstalled Products
                continue

            if ISettingsProvider.providedBy(interface):
                yield interface

     ...

You can find the full code here 你可以在这里找到完整的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM