【问题标题】:Django CMS how to create nested plugins programaticallyDjango CMS 如何以编程方式创建嵌套插件
【发布时间】:2015-03-12 07:29:53
【问题描述】:

我正在编写一个迁移脚本来将一个旧的 html 网站解析为 Django CMS 页面。 我需要的是了解如何以编程方式嵌套插件。 在特殊情况下,我需要将 html 标签转换为 CMS LinkPlugin 对象,嵌套在由 Django-CMS 的标准 ckeditor TextPlugin 编辑的文本中。

如何以编程方式将插件嵌套在 Django CMS 的其他插件中。在我的情况下,我需要在文本中的 TextPlugin 内嵌套一个 CMS Link 插件。 我知道如何解析文本。我不明白如何从嵌套 CMS 插件的角度进行操作? 我无法互连我插入到祖先 TextPlugin 中的 Link CMS 插件对象实例和 CMSPlugin 对象实例。

更多上下文:

注意,从 UI 的角度来看,我真的知道如何做到这一点。我需要在脚本中模拟它。 我已将数据库转储为 JSON,并注意到其中有某些内容。

首先,我有一个放置在页面占位符中的 CMSPlugin 类实例。 (这部分来自CMS的placeholderadmin.py

            position = CMSPlugin.objects.filter(language=lang, parent=parent).count()
            plugin = CMSPlugin(
                language='en',
                position=position,
                plugin_type=plugin_type,
                placeholder=placeholder,
            )
            plugin.insert_at(parent, position='last-child', save=False)
            plugin.save()

            # ?????
            plugin.link = Link(
                name='Link text',
                page_link=target_page,
                placeholder=placeholder,
            )
            plugin.save()

这会在适当的占位符中创建一个嵌套插件并将其附加到一个文本插件中。但是,它添加了一个空白的 LinkPlugin 实例。我稍后会在 CMS 中创建一个链接插件的实例。 问题是我不知道如何正确地做到这一点。

从 UI 角度来看,CMS 插件是嵌套添加的,但不包含真正的插件实例。因此,该占位符的管理插件树使用空链接插件呈现。 添加了 CMSPlugins Link

我可以通过管理员编辑这个创建的链接插件并添加文本和目标链接。如何以编程方式执行此操作。例如。在脚本里面?脚本必须完成 1000 秒的页面,所以我不能手动完成

【问题讨论】:

    标签: python django hyperlink content-management-system ckeditor


    【解决方案1】:

    您是否尝试保存您创建的链接插件?

    plugin.link = Link(
                name='Link text',
                page_link=target_page,
                placeholder=placeholder,
            )
    

    也许可以尝试添加

    plugin.link.save()
    

    我希望是这样。

    【讨论】:

      【解决方案2】:

      对不起,只是在这方面保持一致。这在逻辑上比看起来要复杂得多。 我对此做了一篇文章。

      Django CMS Adding plugins inside plugins programmatically

      一般来说,解决方案是模仿 CMS 的做法。

          # Getting an site admin instance
          admin_site = AdminSite()
      
          instance, plugin_admin = plugin.get_plugin_instance(admin_site)
          plugin_admin.cms_plugin_instance = plugin
          plugin_admin.placeholder = plugin.placeholder
      
          # Triggering the Django Admin add view with our request.
          # That's how Django-CMS does this action itself.
          response = plugin_admin.add_view(request)
      

      在文章中查找完整的 sn-p。希望这对有类似问题的人有所帮助。

      【讨论】:

      • 我知道这是一个旧答案,但我想指出,从 djangoCMS 3.3.0 开始,该解决方案将不再有效。以编程方式添加插件的最佳方法是使用 cms api (cms.api)。
      【解决方案3】:

      要添加嵌套插件,您需要这样做:

              add_plugin(
                  placeholder=placeholder,
                  plugin_type='TextPlugin',
                  language=translation.get_language(),
              )
      
              target = placeholder.get_plugins().get(plugin_type='TextPlugin')
      
              add_plugin(
                  placeholder=placeholder, #same placeholder as the parent plugin
                  plugin_type='LinkPlugin',
                  language=translation.get_language(),
                  target=target, #the parent plugin
                  #here comes the params from the selected plugin
                  name='Google',
                  url='http://www.google.com'
              )
      

      这也适用于自定义插件。

      【讨论】:

        【解决方案4】:

        在您的 cms_plugins.py 文件中创建嵌套插件

            from .models import ParentPlugin, ChildPlugin
        
            @plugin_pool.register_plugin
            class ParentCMSPlugin(CMSPluginBase):
            render_template = 'parent.html'
            name = 'Parent'
            model = ParentPlugin
            allow_children = True  # This enables the parent plugin to accept child plugins
            # You can also specify a list of plugins that are accepted as children,
            # or leave it away completely to accept all
            # child_classes = ['ChildCMSPlugin']
        
            def render(self, context, instance, placeholder):
                context = super().render(context, instance, placeholder)
                return context
        
        
        @plugin_pool.register_plugin
        class ChildCMSPlugin(CMSPluginBase):
            render_template = 'child.html'
            name = 'Child'
            model = ChildPlugin
            require_parent = True  # Is it required that this plugin is a child of another plugin?
            # You can also specify a list of plugins that are accepted as parents,
            # or leave it away completely to accept all
            # parent_classes = ['ParentCMSPlugin']
        
            def render(self, context, instance, placeholder):
                context = super(ChildCMSPlugin, self).render(context, instance, placeholder)
                return context
        

        在你的父插件的插件模板文件中

        {% load cms_tags %}
        
        <div class="plugin parent">
            {% for plugin in instance.child_plugin_instances %}
                {% render_plugin plugin %}
            {% endfor %}
        </div>
        

        有关详细文档,请浏览

        https://docs.django-cms.org/en/latest/how_to/custom_plugins.html#nested-plugins

        【讨论】:

          猜你喜欢
          • 2018-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-09
          • 2018-10-13
          • 2014-09-26
          • 2018-09-07
          • 2018-09-28
          相关资源
          最近更新 更多