[Django]-Django CMS how to create nested plugins programatically

3👍

Sorry just to be consistent on this. This is far more complicated in logic then it seems.
I did an article on this.

Django CMS Adding plugins inside plugins programmatically

In general the solution is to mimic the CMS way of doing this.

    # 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)

Look for the full snippet in article. Hope this helps someone with similar problems.

2👍

To add nested plugins you need to do this:

        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'
        )

This also works with custom plugins.

1👍

Did you tried to save Link plugin that you’ve created?

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

maybe try to add

plugin.link.save()

I hope that is the case.

0👍

To create nested plugins in your cms_plugins.py file

    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

In your plugin template file of parent plugin

{% load cms_tags %}

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

For detailed documentation, go through

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

👤Gopika

Leave a comment