DEFAULT_VOCABULARY_CONTAINER = 'SimpleVocabulary'
DEFAULT_VOCABULARY_ITEM = 'SimpleVocabularyTerm'

VDEX_EXPORT_NEWL = '\n'
VDEX_EXPORT_INDENT = '\t'

# encoding of files in flat-file csv import
IMPORT_ENCODING = 'latin-1'


SORT_METHOD_FOLDER_ORDER = "getObjPositionInParent"
SORT_METHOD_LEXICO_VALUES = "lexicographic_values"
SORT_METHOD_LEXICO_KEYS = "lexicographic_keys"

VOCABULARY_SORT_ORDERS = DisplayList((
    ('getObjPositionInParent', _('Vocabulary Folder Order'),
     'sort_method_folder_order'),
    ('lexicographic_values', _('Lexicographic sort by values'),
     'sort_method_lexi_value'),
    ('lexicographic_keys', _('Lexicographic sort by keys'),
     'sort_method_lexi_keys'),
    ))

# LinguaPlone addon?
import pkg_resources
try:
    pkg_resources.get_distribution("Products.LinguaPlone")
except DistributionNotFound:
    HAS_LINGUA_PLONE = False
else:
    HAS_LINGUA_PLONE = True
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.utils import base_hasattr
from Products.Archetypes.utils import OrderedDict
try:
    from Products.Archetypes.lib.vocabulary import DisplayList
except ImportError:
    from Products.Archetypes.utils import DisplayList

from Products.ATVocabularyManager.types.simple import SimpleVocabulary
from Products.ATVocabularyManager.config import PROJECTNAME
from Products.ATVocabularyManager import messageFactory as _

schema = SimpleVocabulary.schema + Schema((
    BooleanField('ShowLeavesOnly',
        widget = BooleanWidget(
            label = _("label_show_leaves_only",
                      default=u"Show leaves only"),
            description = _("help_show_leaves_only",
                            default=u"Check to show only leaves in this vocabulary."),
        ),
    ),
))


class TreeVocabulary(SimpleVocabulary):
    security = ClassSecurityInfo()

    schema = schema

    meta_type = 'TreeVocabulary'

    def getDisplayList(self, instance, display_parents='tree'):
Esempio n. 3
0
class SimpleVocabularyTerm(BaseContent):
    security = ClassSecurityInfo()
    portal_type = meta_type = 'SimpleVocabularyTerm'
    archetype_name = 'Simple Vocabulary Term'
    _at_rename_after_creation = True
    implements(ISimpleVocabularyTerm)

    schema = BaseSchema + Schema((
        StringField(
            'id',
            required=0,  ## Still actually required, but
            ## the widget will supply the missing value
            ## on non-submits
            mode="rw",
            accessor="getId",
            mutator="setId",
            default='',
            size=50,
            widget=StringWidget(
                label=_("label_key", default="Key"),
                description=_(
                    "help_vocab_name",
                    default=
                    "Should not contain spaces, underscores or mixed case."),
            ),
        ),
        StringField(
            'title',
            required=1,
            searchable=0,
            default='',
            accessor='Title',
            widget=StringWidget(label=_("label_value", default="Value"), ),
        )))

    aliases = {
        '(Default)': 'base_view',
        'view': 'base_view',
        'edit': 'base_edit',
    }

    # Methods
    # methods from Interface IVocabularTerm

    def getTermKey(self):
        """
        """
        if not HAS_LINGUA_PLONE or self.isCanonical():
            return self.getId()
        else:
            return self.getCanonical().getId()

    def getTermValue(self, lang=None):
        """
        """
        if not lang is None:
            # if we ask for a specific language, we try to
            # provide it
            trans = self.getTranslation(lang)
            # if not found, we return the title of the current term
            return trans and trans.Title() or self.Title()
        return self.Title()

    def getTermKeyPath(self):
        # terms of flat vocabularies can savely return their key
        return [
            self.getTermKey(),
        ]

    def getVocabularyKey(self):
        ''' returns the key of the field '''
        deprecated(
            "please use the IVocabularyTerm compatible method 'getTermKey'")
        return self.getTermKey()

    def getVocabularyValue(self, **kwargs):
        ''' returns the value of the field. The value is a processed value '''
        deprecated(
            "please use the IVocabularyTerm compatible method 'getTermValue'")
        return self.getTermValue()

    def processForm(self, data=1, metadata=0, REQUEST=None, values=None):
        request = REQUEST or self.REQUEST
        values = request.form

        if 'title' in values:
            orig_title = self.Title()

        BaseContent.processForm(self, data, metadata, REQUEST, values)

        if 'title' in values:
            new_title = values['title']
            vocab = find_toplevel_vocab(self)
            event.notify(TermRenamedEvent(orig_title, new_title, self, vocab))

    def update(self, *args, **kwargs):
        if 'title' in kwargs:
            orig_title = self.Title()

        BaseContent.update(self, *args, **kwargs)

        if 'title' in kwargs:
            new_title = kwargs['title']
            vocab = find_toplevel_vocab(self)
            event.notify(TermRenamedEvent(orig_title, new_title, self, vocab))

    edit = update

    # uncomment lines below when you need
    factory_type_information = {
        'allowed_content_types': (),
        'allow_discussion': 0,
        'immediate_view': 'simplevocabulary_view',
        'global_allow': 0,
        'filter_content_types': 1,
    }

    actions = ()
Esempio n. 4
0
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.utils import base_hasattr
from Products.Archetypes.utils import OrderedDict
from Products.Archetypes.utils import DisplayList
from Products.ATVocabularyManager.interfaces import ITreeVocabulary

from Products.ATVocabularyManager.types.simple import SimpleVocabulary
from Products.ATVocabularyManager.config import PROJECTNAME
from Products.ATVocabularyManager import messageFactory as _

from zope.interface import implements

schema = SimpleVocabulary.schema + Schema((
    BooleanField('ShowLeavesOnly',
        widget = BooleanWidget(
            label = _("label_show_leaves_only",
                      default=u"Show leaves only"),
            description = _("help_show_leaves_only",
                            default=u"Check to show only leaves in this vocabulary."),
        ),
    ),
))


class TreeVocabulary(SimpleVocabulary):
    """ A tree vocabulary
    """

    security = ClassSecurityInfo()
    schema = schema
    meta_type = 'TreeVocabulary'
    implements(ITreeVocabulary)
Esempio n. 5
0
class SimpleVocabulary(OrderedBaseFolder):

    implements(ISimpleVocabulary)

    security = ClassSecurityInfo()
    meta_type = 'SimpleVocabulary'

    schema = BaseFolderSchema.copy() + Schema((
        StringField('id',
                    required = 1, ## Still actually required, but
                    ## the widget will supply the missing value
                    ## on non-submits
                    mode = "rw",
                    accessor = "getId",
                    mutator = "setId",
                    default = '',
                    widget = StringWidget(
                        label=_("label_vocab_name",
                                default="Vocabulary Name"),
                        description=_("help_vocab_name",
                                      default="Should not contain spaces, underscores or mixed case."),
                        size=50,
                        ),
                    ),

        TextField('description',
                  default = '',
                  required = 0,
                  searchable = 0,
                  accessor = "Description",
                  storage = MetadataStorage(),
                  widget = TextAreaWidget(label=PMF("label_description",
                                                    default="Description"),
                                          description=PMF("help_description",
                                                          default="Enter a brief description"),
                                          rows = 5,
                                          ),
                  ),

        StringField("sortMethod",
                    default = SORT_METHOD_LEXICO_VALUES,
                    required = 0, # smooth upgrades from 1.0.0-beta2
                    searchable = 0,
                    widget = SelectionWidget(
                        label = _("label_sort_method",
                                  default="Sort method"),
                        description = _("help_sort_method",
                                        default="Sort method used for displaying vocabulary terms"),
                    ),
                    vocabulary = VOCABULARY_SORT_ORDERS,
        ),
    ))

    def isLinguaPloneInstalled(self):
        """ checks if LinguaPlone is installed """
        return ILinguaPloneProductLayer in registered_layers() \
               or self.portal_quickinstaller.isProductInstalled('LinguaPlone')

    # Methods from Interface IVocabulary
    def getDisplayList(self, instance):
        """Returns a object of class DisplayList as defined in
        Products.Archetypes.utils.

        The instance of the content class is given as parameter.
        The list is sorted accordingly to the sortMethod chosen.
        """
        dl = DisplayList()
        vdict = self.getVocabularyDict(instance)
        for key in self.getSortedKeys(instance):
            dl.add(key, vdict[key])
        return dl

    def getVocabularyLines(self, instance=None):
        """Returns a List of Key-Value tuples.
        The list is sorted accordingly to the sortMethod chosen.
        """
        termlist = []
        vdict = self.getVocabularyDict(instance)

        for key in self.getSortedKeys():
            termlist.append((key, vdict[key]))
        return termlist

    def getVocabularyDict(self, instance=None):
        """Returns a vocabulary dictionary as defined in the interface
        """

        if self.isLinguaPloneInstalled():
            # if lp is installed
            # obtain language and return translated dict
            try:
                # we use the language of instance for this dictionary
                lang = instance.getLanguage()
            except AttributeError:
                # we retrieve the current language
                langtool = getToolByName(self, 'portal_languages')
                lang = langtool.getPreferredLanguage()
            return self._getTranslatedVocabularyDict(lang)
        else:
            # just return all terms
            vdict = OrderedDict()
            for obj in self.contentValues():
                vdict[obj.getTermKey()] = obj.getTermValue()
            return vdict

    def _getTranslatedVocabularyDict(self, lang):
        vdict = OrderedDict()
        for obj in self.contentValues():
            vdict[obj.getTermKey()] = obj.getTermValue(lang)
        return vdict

    def isFlat(self):
        """ returns true for a flat vocabulary """
        return 1

    def showLeafsOnly(self):
        """ indicates if only leafs should be shown """
        return 1

    # some supporting methods

    def getSortedKeys(self, instance=None):
        """ returns a list of keys sorted accordingly to the

        selected sort method (may be unsorted if method = no sort)
        """
        sortMethod = self.getSortMethod()
        context = self
        if self.isLinguaPloneInstalled():
            from Products.LinguaPlone.interfaces import ITranslatable
            langtool = getToolByName(self, 'portal_languages')
            if instance and ITranslatable.providedBy(instance):
                lang = instance.getLanguage() or langtool.getPreferredLanguage()
            else:
                lang = langtool.getPreferredLanguage()
            context = context.getTranslation(lang) or self

        keys = [term.getVocabularyKey() for term in context.contentValues()]

        if not hasattr(self, 'sortMethod'):
            # smooth upgrade from previous releases
            return keys

        if sortMethod == SORT_METHOD_LEXICO_KEYS:
            keys.sort()
            return keys

        if sortMethod == SORT_METHOD_LEXICO_VALUES:
            # returns keys sorted by lexicogarphic order of VALUES
            terms = context.contentValues()
            terms.sort(lambda x, y: cmp(x.getTermValue(), y.getTermValue()))
            return [term.getVocabularyKey() for term in terms]

        if sortMethod == SORT_METHOD_FOLDER_ORDER:
            try:
                contentListing = getMultiAdapter(
                    (context, context.REQUEST), name='folderListing')()
            except ComponentLookupError:
                # still Plone 3 compatible
                contentListing = context.getFolderContents()
            return [term.getObject().getTermKey() for term in contentListing]

        # fallback
        return keys

    security.declareProtected(AddPortalContent, 'addTerm')
    def addTerm(self, key, value, language=None, termtype=DEFAULT_VOCABULARY_ITEM,
                silentignore=False, **kwargs):
        """ add a new key/value pair to the container

            termtype is the portal_type of the term

            language is for future use with LinguaPlone

            with silentignore duplicate keys are silently skipped

            returns True if addition worked
        """

        if key in self.getVocabularyDict():
            if silentignore:
                return False
            raise KeyError('key %s already exist in vocabulary %s ' % (
                key, self.title_or_id()))

        allowed = [fti.content_meta_type for fti in self.allowedContentTypes()]
        if not termtype in allowed:
            if termtype == DEFAULT_VOCABULARY_ITEM and len(allowed) == 1:
                termtype = allowed[0].meta_type
            else:
                raise ValueError('type %s is not allowed as vocabularyterm in this context' % termtype)


        self.invokeFactory(termtype, key)
        self[key].setTitle(value)
        return True

    security.declareProtected(AddPortalContent, 'importCSV')
    def importCSV(self, csvdata,
                  termtype=DEFAULT_VOCABULARY_ITEM,
                  titlerow=False,
                  silentignore=False):
        """ imports given csv data as the given vocabularytype

            csv is a string or a file-like object in the style:

                "Data 1.1", "Data 1.2"
                "Data 2.1", "Data 2.2"
                "Data 3.1", "Data 3.2"

            vocabularytype is the terms portal-type, like SimpleVocabularyTerm
            which is also the default.

            It uses column 1 as key=id and column 2 as value=title.

            If titlerow is True the first line will be skipped.
        """

        qi = getToolByName(self, 'portal_quickinstaller')
        lp = qi.isProductInstalled('LinguaPlone')

        if type(csvdata) == type(''):
            csvdata = StringIO(csvdata)

        csvreader = csv.reader(csvdata)
        languages = []
        for row in csvreader:

            if titlerow:

                # If LinguaPlone is installed, it's assumed the title row is
                # used to define language columns
                if lp:
                    for n in range(1, len(row)):
                        languages.append(row[n])

                titlerow = False

            else:
                value = str(row[1], IMPORT_ENCODING)
                key = row[0] or make_uuid(value)
                self.addTerm(key, value, termtype=termtype, silentignore=silentignore)

                if len(languages) > 0:
                    self[key].setLanguage(languages[0])
                    if len(row) > 2:
                        for col in range(2, len(row)):
                            self[key].addTranslation(languages[col-1], title=row[col])
class TreeVocabularyTerm(TreeVocabulary, SimpleVocabularyTerm):
    """ Term inside of a TreeVocabulary or as an subterm
    """

    security = ClassSecurityInfo()
    meta_type = 'TreeVocabularyTerm'
    implements(ITreeVocabularyTerm)

    schema = BaseSchema + Schema(
        (
            StringField(
                'id',
                required=0,  ## Still actually required, but
                ## the widget will supply the missing value
                ## on non-submits
                mode="rw",
                accessor="getId",
                mutator="setId",
                default='',
                size=50,
                widget=IdWidget(
                    label=_("label_key", default=u"Key"),
                    description=_(
                        "help_vocab_name",
                        default=
                        "Should not contain spaces, underscores or mixed case."
                    ),
                ),
            ),
            StringField(
                'title',
                required=1,
                searchable=0,
                default='',
                accessor='Title',
                widget=StringWidget(label=_("label_value",
                                            default=u"Value"), ),
            )), )

    # Methods
    # methods from Interface IVocabularyTerm

    def getTermKey(self):
        """
        """
        if not HAS_LINGUA_PLONE or self.isCanonical():
            return self.UID()
        else:
            return self.getCanonical().UID()

    def getTermValue(self, lang=None):
        """
        """
        if (not HAS_LINGUA_PLONE) or (lang is None):
            return self.Title()
        else:
            trans = self.getTranslation(lang)
            return trans and trans.Title() or self.Title()

    def getTermKeyPath(self):
        path = [
            self.getTermKey(),
        ]
        actTerm = self
        while actTerm.aq_parent.portal_type != 'TreeVocabulary' \
                  and hasattr(actTerm.aq_parent, 'getTermKey'):
            path.append(actTerm.aq_parent.getTermKey())
            actTerm = actTerm.aq_parent

        path.reverse()
        return path

    def getVocabularyKey(self):
        ''' returns the key of the field '''
        deprecated(
            "please use the IVocabularyTerm compatible method 'getTermKey'")
        return self.getTermKey()

    def getVocabularyValue(self, lang=None, **kwargs):
        ''' returns the value of the field. The value is a processed value '''
        deprecated(
            "please use the IVocabularyTerm compatible method 'getTermValue'")
        return self.getTermValue(lang=lang, **kwargs)

    # these should be inherited from SimpleVocabularyTerm
    processForm = SimpleVocabularyTerm.processForm
    edit = SimpleVocabularyTerm.edit
    update = SimpleVocabularyTerm.update
Esempio n. 7
0
DEFAULT_VOCABULARY_CONTAINER = 'SimpleVocabulary'
DEFAULT_VOCABULARY_ITEM = 'SimpleVocabularyTerm'

VDEX_EXPORT_NEWL = '\n'
VDEX_EXPORT_INDENT = '\t'

# encoding of files in flat-file csv import
IMPORT_ENCODING = 'latin-1'

SORT_METHOD_FOLDER_ORDER = "getObjPositionInParent"
SORT_METHOD_LEXICO_VALUES = "lexicographic_values"
SORT_METHOD_LEXICO_KEYS = "lexicographic_keys"

VOCABULARY_SORT_ORDERS = DisplayList((
    ('getObjPositionInParent', _('Vocabulary Folder Order'),
     'sort_method_folder_order'),
    ('lexicographic_values', _('Lexicographic sort by values'),
     'sort_method_lexi_value'),
    ('lexicographic_keys', _('Lexicographic sort by keys'),
     'sort_method_lexi_keys'),
))

# LinguaPlone addon?
import pkg_resources
try:
    pkg_resources.get_distribution("Products.LinguaPlone")
except DistributionNotFound:
    HAS_LINGUA_PLONE = False
else:
    HAS_LINGUA_PLONE = True
DEFAULT_VOCABULARY_CONTAINER = 'SimpleVocabulary'
DEFAULT_VOCABULARY_ITEM = 'SimpleVocabularyTerm'

VDEX_EXPORT_NEWL = '\n'
VDEX_EXPORT_INDENT = '\t'

# encoding of files in flat-file csv import
IMPORT_ENCODING = 'latin-1'


SORT_METHOD_FOLDER_ORDER = "getObjPositionInParent"
SORT_METHOD_LEXICO_VALUES = "lexicographic_values"
SORT_METHOD_LEXICO_KEYS = "lexicographic_keys"

VOCABULARY_SORT_ORDERS = DisplayList((
    ('getObjPositionInParent', _('Vocabulary Folder Order'), 'sort_method_folder_order'),
    ('lexicographic_values', _('Lexicographic sort by values'), 'sort_method_lexi_value'),
    ('lexicographic_keys', _('Lexicographic sort by keys'), 'sort_method_lexi_keys'),
    ))

# LinguaPlone addon?
try:
    import Products.LinguaPlone
except ImportError:
    HAS_LINGUA_PLONE = False
else:
    HAS_LINGUA_PLONE = True

GLOBALS = globals()