Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display_modifier function for GroupByCriteratie is not dynamic, issue with Vocabularies #110

Open
fredvd opened this issue Jul 16, 2020 · 0 comments

Comments

@fredvd
Copy link
Member

fredvd commented Jul 16, 2020

This is very similar to the use case in issue #41 , but I'd like to focus on one specific problem. The similarity is that one of my filter items is a vocabulary and the value is used in display instead of the vocabulary its Title.

So I have added both a filter and a sorting function encapsulated in an object.

The problem: The GroupByCriteria adapter is run once on startup and the only parameter passed to both functions only contains the keys. When the Vocabulary is dynamic and can be changed because it is build up out of registry settings or content in the Plone site, the display and sorting functions will not be updated. In my use case they are coming from collective.classifiers themes and categories.

When you instantiate a vocabulary you always pass in the context. Because context is not available or relevant in my particular use case I'm using zope.component.hooks.getSite to use the portal_root as context to instantiate the Vocabulary, but it still stays a one shot at startup :-(

As one commeng in #1 already mentions, performance will be an issue. Ideally the display_modifier and sort_key_functions are instantiated once per request and it's freshness can be tuned using memoize.

Is my reasoning so far sound, or am I missing something how the integration with vocabularies can be fixed?

Here's the code for my GroupByCriteria I'm using now. clean_title and flatten have to do with collective.classifiers supporting 2 levels like a mini-taxonomy).

from collective.collectionfilter.interfaces import IGroupByCriteria
from collective.collectionfilter.interfaces import IGroupByModifier
from zope.component import adapter, getUtility
from zope.interface import implementer, provider
from zope.schema.interfaces import IVocabularyFactory
from zope.schema.interfaces import IContextAwareDefaultFactory
from zope.component.hooks import getSite

import logging

logger = logging.getLogger("sgbp.content")


class VocabularyLookup(object):

    vocabulary = None
    flatten = False

    dummy = "▼→"

    def clean_title(self, term):
        result = term.title.split(" > ", 1)
        if len(result) > 1:
            return "-  " + result[-1]
        elif len(result) == 1:
            return term.title + ": ▼"

    def __init__(self, vocab, flatten=False):
        factory = getUtility(IVocabularyFactory, vocab)
        self.vocabulary = factory(getSite())
        self.flatten = flatten
        self.terms = [
            self.clean_title(term) if flatten else term.title
            for term in self.vocabulary._terms
        ]
        self.sort_map = dict([(term[1], term[0]) for term in enumerate(self.terms)])
        logger.info(
            "initialised collectionfilter for vocab {0}".format(self.vocabulary)
        )

    def display(self, value):
        term = self.vocabulary.getTerm(value)
        if self.flatten:
            return self.clean_title(term)
        return term.title

    def sortmap(self, value):
        val = value["title"]
        return self.sort_map.get(val, 0)


@implementer(IGroupByModifier)
@adapter(IGroupByCriteria)
def groupby_modifier(groupby):

    themes_label = VocabularyLookup("collective.classifiers.themes", flatten=True)
    categories_label = VocabularyLookup(
        "collective.classifiers.categories", flatten=False
    )

    groupby._groupby["classifiers_themes"] = {
        "index": "classifiers_themes",
        "metadata": "classifiers_themes",
        "display_modifier": themes_label.display,
        "sort_key_function": themes_label.sortmap,
        # "value_blacklist": ["bekkens", "grondwatersystemen"],
    }

    groupby._groupby["classifiers_categories"] = {
        "index": "classifiers_categories",
        "metadata": "classifiers_categories",
        "display_modifier": categories_label.display,
        "sort_key_function": categories_label.sortmap,
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant