aboutsummaryrefslogtreecommitdiff
path: root/apps/utils/widgets.py
blob: 6dc28bf5247d77c1e8d425fc2cfef8f6c3ae4468 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import os
from django import forms
from django.contrib import admin
from django.contrib.admin.widgets import AdminFileWidget
from django.utils.safestring import mark_safe
from django.forms import widgets
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.template.loader import render_to_string
from django.template import Context
from django.forms.widgets import SelectMultiple
from django.conf import settings

import markdown

from bs4 import BeautifulSoup
from django.utils.module_loading import import_string


class CustomSelectMultiple(SelectMultiple):
    def render_options(self, choices, selected_choices):
        if not selected_choices:
            # there is CreatView and we have no selected choices - render all selected
            render_option = self.render_option
        else:
            # there is UpdateView and we have selected choices - render as default
            render_option = super(CustomSelectMultiple, self).render_option

        selected_choices = set(force_text(v) for v in selected_choices)
        output = []
        for option_value, option_label in chain(self.choices, choices):
            if isinstance(option_label, (list, tuple)):
                output.append(format_html('<optgroup label="{0}">', force_text(option_value)))
                for option in option_label:
                    output.append(render_option(selected_choices, *option))
                output.append('</optgroup>')
            else:

                output.append(render_option(selected_choices, option_value, option_label))
        return '\n'.join(output)

    def render_option(self, selected_choices, option_value, option_label):
        option_value = force_text(option_value)
        selected_html = mark_safe(' selected="selected"')

        return format_html('<option value="{0}"{1}>{2}</option>',
                           option_value,
                           selected_html,
                           force_text(option_label))


class TagListFilter(admin.SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('tag')

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'tag'

    def lookups(self, request, model_admin):
        """
        Returns a list of tuples. The first element in each
        tuple is the coded value for the option that will
        appear in the URL query. The second element is the
        human-readable name for the option that will appear
        in the right sidebar.
        """
        tl = []
        self.model_to_use = model_admin.model
        for t in self.model_to_use.tags.all().order_by('name'):
            tl += (t.name, t.name),
        return tl

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        qs = self.model_to_use.objects.all()
        try:
            request.GET['tag']
            return qs.filter(tags__name=self.value())
        except:
            return qs


def thumbnail(image_path):
    absolute_url = os.path.join(settings.IMAGES_URL, image_path[7:])
    print(absolute_url)
    return '<img style="max-width: 400px" src="%s" alt="%s" />' % (absolute_url, image_path)


class ImageRadioSelect(forms.RadioSelect):
    template_name = 'horizontal_select.html'


class AdminImageWidget(AdminFileWidget):
    """
    A FileField Widget that displays an image instead of a file path
    if the current file is an image.
    """
    def render(self, name, value, attrs=None):
        output = []
        file_name = str(value)
        help_text = ''
        if file_name:
            file_path = '%s' % (file_name)
            if attrs['id'] == 'id_thumbnail':
                help_text = '160 wide'
            if attrs['id'] == 'id_image':
                help_text = '205px high'
            output.append('<span>%s</span><a target="_blank" href="%s">%s</a>' % (help_text, file_path, thumbnail(file_name)))

        output.append(super(AdminFileWidget, self).render(name, value, attrs))
        return mark_safe(''.join(output))


class LGEntryForm(forms.ModelForm):
    class Meta:
        widgets = {
            'body_markdown': forms.Textarea(attrs={'rows': 40, 'cols': 100}),
            'featured_image': ImageRadioSelect,
        }


class LGEntryFormSmall(forms.ModelForm):
    class Meta:
        widgets = {
            'body_markdown': forms.Textarea(attrs={'rows': 12, 'cols': 100}),
        }


class RelatedFieldWidgetCanAdd(widgets.Select):
    """
    Modifies standard django Select widget to add link after to add new instance
    of related model (doesn't check permissions, that's for the form instance)
    """
    def __init__(self, related_model, related_url=None, *args, **kw):
        super(RelatedFieldWidgetCanAdd, self).__init__(*args, **kw)
        if not related_url:
            rel_to = related_model
            info = (rel_to._meta.app_label, rel_to._meta.object_name.lower())
            related_url = 'admin:%s_%s_add' % info
        print(related_url)
        self.related_url = related_url

    def render(self, name, value, *args, **kwargs):
        self.related_url = reverse(self.related_url)
        print(self.related_url)
        output = [super(RelatedFieldWidgetCanAdd, self).render(name, value, *args, **kwargs)]
        output.append('<a class="circle plus small-circle modal-open" href="%s" id="add_id_%s" data-modal-hed-class="%s" data-modal-hed="Add a New %s">New</a>' % (self.related_url, name, name, name.capitalize()))
        return mark_safe(u''.join(output))