tated
tated

Reputation: 661

django-cms: how to get the Page from an app associated with it

Given this apphook:

class NewsHook(CMSApp):
    name = _("News")
    urls = ["apps.news.urls"]

apphook_pool.register(NewsHook)

and this model inside apps.news.models:

class Article(models.Model):
    title = models.CharField(max_length=255)
    ...

Is it possible to reference the page associated by apphook in, say, a method on Article?

From the model side I've gotten as far as article._meta.app_label or article._meta.app_config.verbose_name, but that only yields 'news' and 'News', respectively.

And I know from https://github.com/divio/django-cms/blob/7888ab8421bb836c8f7a1127d9a2bf4d4bbdf23e/cms/models/pagemodel.py#L82 that a page's apphook is accessible with page.application_urls, which gives me 'u'NewsHook'.

But I'm missing a link.

I suppose I could filter Pages by the application_urls field and look for a match with my article._meta.app_config.verbose_name, but that would be neither neither failsafe nor pretty.

Any ideas for a better way?

Upvotes: 4

Views: 508

Answers (1)

Mærcos
Mærcos

Reputation: 373

I know this question is a year old and probably OP have figured it out, but I had a similar problem, which I solved by referencing the apphook directly on the method.

from applications.cms_apps import ApplicationAppHook
from cms.models.pagemodel import Page

class Application(models.Model):
    def related_cms_page(self):
        return Page.objects.filter(application_namespace=ApplicationAppHook.app_name).public().first()

I've gone somewhat further and created a templatetag that uses the application_namespace value to retrieve the page

from cms.models.pagemodel import Page

@register.assignment_tag()
def get_page_by_namespace(application_namespace_str):
    try:
        return Page.objects.filter(application_namespace=application_namespace_str).public().first()
    except AttributeError:
        # EAFP ;)
        return None

And on the template:

{% get_page_by_namespace 'applications_apphook' as page %}
{% if page %}
    {{ page.get_menu_title }}
    {# Official Django CMS templatetags also works in this instance, i.e. {% page_attribute "page_title" page %} but it seems a bit redundant to me #}
{% endif %}

Upvotes: 2

Related Questions