Example #1
0
 def import_member(self, obj, member, value):
     if member.translated:
         for lang, translated_value in value.iteritems():
             translated_value = self.import_value(member, translated_value)
             schema.set(obj, member, translated_value, lang)
     else:
         value = self.import_value(member, value)
         schema.set(obj, member, value)
Example #2
0
    def _read_schema(self, member, target, languages, path):

        if target is None:
            if isinstance(member, type):
                target = member()
            else:
                target = {}

        path.append(member)

        try:
            for child_member in member.members().values():

                if child_member.editable != schema.EDITABLE:
                    continue

                if self._is_schema(child_member):
                    nested_target = schema.get(target, child_member, None)
                    if nested_target is None:
                        nested_target = self.create_nested_target(
                            member, child_member, target)
                        schema.set(target, child_member.name, nested_target)
                else:
                    nested_target = target

                value = self.read(
                    child_member, nested_target,
                    languages if child_member.translated else None, path)

            # Validate child members *after* all members have read their values
            # (this allows conditional validations based on other members in
            # the schema)
            if self.errors != "ignore":
                invalid_members = set()

                for error in member.get_errors(target):
                    error_member = error.member
                    if (error_member not in invalid_members
                            and error_member.editable == schema.EDITABLE):
                        invalid_members.add(error_member)
                        error_target = error.context.get_object()
                        fixed_value = self._fix_value(error_target,
                                                      error_member,
                                                      error.value, error)
                        if error_member.name:
                            schema.set(error_target, error_member.name,
                                       fixed_value)
        finally:
            path.pop()

        return target
Example #3
0
    def unrelate(self, member, item):
        """Breaks the relation between the edited item and one of its related
        items.
        
        @param member: The member describing the relation between the two
            items. It should be the end nearer to the edited item.
        @type member: L{RelationMember<cocktail.schema.RelationMember>}

        @param item: The item to unrelate.
        @type item: L{Item<woost.models.item.Item>}
        """
        if isinstance(member, schema.Collection):
            collection = schema.get(self.form_data, member)
            schema.remove(collection, item)
        else:
            schema.set(self.form_data, member, None)
Example #4
0
    def _read_value(self, member, target, language, path):

        if member.read_request_value:
            value = member.read_request_value(self)
        else:
            key = self.get_parameter_name(member, language)
            value = self.source(key)

        if not (value is None and self.undefined == "skip"):
            value = self.process_value(member, value)

            if not path and self.errors != "ignore":
                value = self._fix_value(target, member, value)

            if target is not None and member.editable == schema.EDITABLE:
                schema.set(target, member.name, value, language)

        return value
Example #5
0
    def relate(self, member, item):
        """Adds a relation between the edited item and another item.
        
        @param member: The member describing the relation between the two
            items. It should be the end nearer to the edited item.
        @type member: L{RelationMember<cocktail.schema.RelationMember>}

        @param item: The item to relate.
        @type item: L{Item<woost.models.item.Item>}
        """
        if isinstance(member, schema.Collection):

            collection = schema.get(self.form_data, member)

            # Editing collections with duplicate entries is not allowed
            if item in collection:
                raise ValueError(
                    "Collections with duplicate entries are not allowed")

            schema.add(collection, item)
        else:
            schema.set(self.form_data, member, item)
    def _handle_form_data(self):

        stack_node = self.stack_node
        form_data = stack_node.form_data
        translations = stack_node.translations

        section = self.params.read(schema.String("section", default="fields"))

        added_translation = self.params.read(
            schema.String("add_translation",
                          enumeration=self.available_languages))

        deleted_translation = self.params.read(
            schema.String("delete_translation", enumeration=translations))

        # Remove translations
        if deleted_translation:
            translations.remove(deleted_translation)
            for key, member in self.fields_schema.members().iteritems():
                if member.translated:
                    values = form_data.get(key)
                    if values:
                        values.pop(deleted_translation, None)

        get_method = cherrypy.request.method.upper() == "GET"

        # Load form data from the request
        get_parameter(self.fields_schema,
                      target=form_data,
                      languages=translations,
                      prefix=self.form_prefix,
                      errors="ignore",
                      implicit_booleans=not get_method,
                      undefined="skip" if get_method else "set_none")

        # Add translations
        if added_translation and added_translation not in translations:
            translations.append(added_translation)

            # Try to copy an existing fallback translation
            for fallback_language in iter_language_chain(added_translation,
                                                         include_self=False):
                if fallback_language in translations:
                    for key, member in self.fields_schema.members().iteritems(
                    ):
                        if member.translated:
                            value = schema.get(form_data,
                                               key,
                                               language=fallback_language)
                            schema.set(form_data,
                                       key,
                                       value,
                                       language=added_translation)
                    break
            # If there's no fallback translation to use, create a new
            # translation from scratch
            else:
                translation_data = {}
                stack_node.content_type.translation.init_instance(
                    translation_data)
                for key, value in translation_data.iteritems():
                    schema.set(form_data,
                               key,
                               value,
                               language=added_translation)

        # Drop references
        unlink = cherrypy.request.params.get("relation-unlink")

        if unlink:
            form_data[unlink] = None

        return form_data