Beispiel #1
0
    def other_fields(link: Link, field_name: str) -> dict:
        """ All fields (except the type fields) that need to get rendered in the template. """
        label = CharField()
        target = BooleanField()
        no_follow = BooleanField()
        link_type = ChoiceField(
            choices=type_manager.type_choices(link.config('types')))

        fields = {
            'label':
            label.widget.render(
                '{}_link_label'.format(field_name),
                link.data('label'),
                attrs={'id': 'id_{}_link_label'.format(field_name)}),
            'target':
            target.widget.render(
                '{}_link_target'.format(field_name),
                link.data('target') is not None,
                attrs={'id': 'id_{}_link_target'.format(field_name)}),
            'link_type':
            link_type.widget.render(
                '{}_link_type'.format(field_name),
                link.data('type'),
                attrs={'id': 'id_{}_link_type'.format(field_name)}),
            'no_follow':
            no_follow.widget.render(
                '{}_link_no_follow'.format(field_name),
                link.data('no_follow'),
                attrs={'id': 'id_{}_link_no_follow'.format(field_name)})
        }

        return fields
Beispiel #2
0
 def get_context(self, name: str, value: Link, attrs: dict):
     context = {
         'widget': {
             'name': name,
             'link': value,
             'type_fields': self.type_fields(value),
             'other_fields': self.other_fields(value, name),
             'allow_target': value.config('allow_target'),
             'allow_label': value.config('allow_label'),
             'allowed_types': value.config('types'),
             'allow_no_follow': value.config('allow_no_follow'),
         }
     }
     return context
Beispiel #3
0
    def _parse_link(self, value: Optional[str]) -> Link:
        """ Map given json string to Link object. """
        data = {}

        if value:
            data = json.loads(value)

        return Link(config=self.config, data=data, name=self.name)
Beispiel #4
0
    def type_fields(link: Link) -> dict:
        """ Generate all fields for the different link types that are allowed in this link instance. """
        types = {}
        for link_type in link.config('types'):
            instance = type_manager.instance(link_type, link)
            types[link_type] = {
                'markup': instance.render(),
                'instance': instance,
            }

        return types
Beispiel #5
0
    def render(self,
               name: str,
               value: Optional[Link],
               attrs: dict = None,
               renderer: DjangoTemplates = None):
        # On initial init value can be None
        if not value:
            value = Link(config=self.config, name=name)

        context = self.get_context(name, value, attrs)
        return self._render(self.template_name, context, renderer)
Beispiel #6
0
    def clean(self, value: Link) -> Link:
        """
        Validate given Link object. We do this by get a form instance of the link type and grab the
        first error (if one) and raise it.
        """
        form = value.link_type.form(required=self.required)
        if not form.is_valid():
            for key, error in form.errors.as_data().items():
                raise error[0]
        else:
            value._data['value'] = form.cleaned_data

        return value
Beispiel #7
0
    def value_from_datadict(self, data, files, name) -> Link:
        """
        Get the selected type and initialise a Link object with all the data that got submitted in the POST.
        For now we'll just assign all the submitted data to the links value property and basically just
        use it as a DTO. In the LinkFormField's clean method this data will be validated and cleaned.
        """
        link_type = type_manager.get(data.get(f'{name}_link_type', None))
        link_data = {
            'type':
            link_type.identifier,
            'target':
            '_blank'
            if data.get('{}_link_target'.format(name), None) else None,
            'label':
            data.get('{}_link_label'.format(name), None),
            'no_follow':
            True
            if data.get('{}_link_no_follow'.format(name), None) else False,
            'value':
            data
        }

        return Link(config=self.config, data=link_data, name=name)