Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-cms "summary view" aggregating content from multiple pages

Django==1.5.1 django-cms==2.4.1

I'd like to make something like a summary view from all the child pages of a selected page in django-cms, pulling out title, truncated content etc with a more... link for each listed child. I've managed to get titles and paths just fine, but im struggling to get content from the placeholders.

I have a templatetag like this:

from cms.models import Page
from cms.utils.page_resolver import get_page_from_path

from django import template


register = template.Library()


@register.inclusion_tag('news_summary_item.html')
def get_news_items():
    news_root = get_page_from_path('news')
    newsitems = news_root.children.filter(published=True)
    return {'newsitems':newsitems}

and here is the template its using:

{% load cms_tags menu_tags %}
<ul>
{% for item in newsitems %}
    <li><a href="/{{ item.get_path }}">{{ item.get_title }}</a>
        {% for placeholder in item.placeholders.all %}
            # {% show_placeholder placeholder.slot item current_language %} #
        {% endfor %}
    </li>
{% endfor %}
</ul>

Can anyone help with getting the placeholder content here? Ideally, id like to be able to pass it through truncatewords_html to just get a summary, but open to other ways to get the same effect.

Thanks for any tips/pointers!

like image 240
captainmish Avatar asked May 09 '13 09:05

captainmish


1 Answers

I had to index CMS content in one project and I get the content of each placeholder, and the content of a placeholder is stored in the plugins attached to it

How te get the content of a CMSPlugin in a view?

from cms.models import CMSPlugin

plugin = CMSPlugin.objects.filter(plugin_type='TextPlugin')[0]  # Get first text plugin
# This return the body/content of the plugin:
plugin_content = plugin.get_plugin_instance()[0].body 

If you would like to manage other plugins like PicturePlugin you could get the "alt" text like:

plugin_picture_content = plugin.get_plugin_instance()[0].alt

How to get the content of CMSPlugin in a template?

# plugin_object containing a CMSPlugin
{{plugin_object.get_plugin_instance.0.body}}

I supose when you want to get the content, we are talking about TextPlugin, you have to be carefull here because only the plugin type TextPlugin has the attribute body, the PicturePlugin has the attribute alt and the LinkPlugin has the attribute href etc...

Solution adapted for your problem

You are doing a loop over placeholders, so you need to get all the plugins for each placeholder and get the content of each plugin, because the content of the placeholders as I mentioned before are stored in the plugins attached to it (TextPlugin, PicturePlugin, LinkPlugin...).

...    ...    ...
{% for placeholder in item.placeholders.all %}  # Loop over placeholders
    {% for plugin in placeholder.get_plugin_list %}  # Get plugins for each placeholder
        {{plugin.get_plugin_instance.0.body|striptags}}
    {% endfor %}
{% endfor %}
...    ...    ...

And to ensure that you only show the content of TextPlugin and not from other plugins you could do:

...    ...    ...
{% for placeholder in item.placeholders.all %}  # Loop over placeholders
    {% for plugin in placeholder.get_plugin_list %}  # Get plugins for each placeholder
        {% if 'TextPlugin' in plugin.plugin_type %}
            {{plugin.get_plugin_instance.0.body|striptags}}
        {% endif %}
    {% endfor %}
{% endfor %}
...    ...    ...
like image 147
AlvaroAV Avatar answered Nov 12 '22 09:11

AlvaroAV