Пример #1
0
class SourceDisplayNode(GenericNode):
    def __init__(self, obj, display, *args, **kwargs):
        self.obj = Variable(obj)
        self.display = Variable(display)
        super(SourceDisplayNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            obj = self.obj.resolve(context)
            display = self.display.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        sep = kwargs.get("sep", None)
        sep = args[1] if not sep and len(args) > 1 else sep

        kwargs = {}
        if sep:
            kwargs.update({"sep": sep})
        if not (obj.__class__ is Content or hasattr(obj, "content_ptr")):
            raise TemplateSyntaxError("'source_display' only renders "
                                      "Content instances")

        html = get_content_source(obj, display, context=context, **kwargs)

        return self.render_output(context, html)
Пример #2
0
class VoteFormNode(GenericNode):

    template = "voting/form.html"

    def __init__(self, obj, vote, *args, **kwargs):
        self.obj = Variable(obj)
        self.vote = Variable(vote)
        super(VoteFormNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            ctx = {
                "object": self.obj.resolve(context),
                "vote": self.vote.resolve(context)
            }
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        next = kwargs.get("next", None)
        next = args[0] if not next and len(args) > 0 else next

        if next:
            ctx.update({"next": next})

        html = render_to_string(self.template, ctx, context_instance=context)

        return self.render_output(context, html)
Пример #3
0
class ObjectDisplayNode(GenericNode):
    def __init__(self, obj, display, *args, **kwargs):
        self.obj = Variable(obj)
        self.display = Variable(display)
        super(ObjectDisplayNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            obj = self.obj.resolve(context)
            display = self.display.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        ctx = {"object": obj, "display": display}

        color = kwargs.get("color", None)
        color = args[0] if not color and len(args) > 0 else color
        if color:
            ctx.update({"color": color})

        if obj.__class__ is Item:
            template = "items/_product_display.html"
        elif obj.__class__ is User:
            template = "profiles/_profile_display.html"
            skills = obj.get_profile().skills
            ctx.update({"username": user_display(obj)})
            if skills.count():
                ctx.update({"skills": skills})
        else:
            raise TemplateSyntaxError("'object_display' only renders Item "
                                      "and User instances")
        html = render_to_string(template, ctx, context_instance=context)

        return self.render_output(context, html)
Пример #4
0
class MDCTNode(Node):
    def __init__(self,var_name,fmt_name=settings.DEFAULT_TIME_FORMAT,
                    tz_var=None):
        self.var_name = Variable(var_name)
        if tz_var is None:
            self.tz_var = None
        else:
            self.tz_var = Variable(tz_var)
        self.fmt_name = fmt_name

    def render(self, context):
        tz_name = settings.DEFAULT_TZ
        if self.tz_var is None:
            user = Variable('user').resolve(context)
            if user.is_authenticated():
                tz_name = user.profile.time_zone
        else:
            tz_name = self.tz_var.resolve(context)
            
        dt = self.var_name.resolve(context)
        
        utc = pytz.timezone('UTC')
        tz = pytz.timezone(tz_name)
        dt = utc.localize(dt)
        dt = dt.astimezone(tz)
        return dt.strftime(settings.TIME_FORMATS[self.fmt_name])
Пример #5
0
class FormPartNode(Node):
    """
    Named piece of HTML layout.
    """
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "%r accepts at most 4 arguments (part_id, section, asvar, varname), got: {}" %
                (bits[0], ','.join(bits[1:])))

        self.part_id = Variable(bits[1])
        self.section = bits[2] if len(bits) >= 3 else None

        self.varname = None
        if len(bits) > 3:
            if bits[3] != 'asvar':
                raise TemplateSyntaxError('Forth argument should be asvar, got {}', format(bits[3]))
            if len(bits) < 4:
                raise TemplateSyntaxError('Variable name not provided')
            else:
                self.varname = Variable(bits[4])

        self.nodelist = parser.parse(('end{}'.format(bits[0]),))
        parser.delete_first_token()

    def resolve_part(self, context):
        part = self.part_id.resolve(context)
        if isinstance(part, BoundField):
            part = part.field
        return part

    def render(self, context):
        part = self.resolve_part(context)
        parts = context['form_parts']

        if self.section in parts[part]:
            # already rendered
            if self.varname is not None:
                context[self.varname.resolve(context)] = parts[part][self.section]
                return ""
            else:
                return parts[part][self.section]

        # child parts
        children = (node for node in self.nodelist if isinstance(node, FormPartNode))
        _render_parts(context, children)

        # render own content
        value = self.nodelist.render(context).strip()
        if self.varname is not None:
            context[self.varname.resolve(context)] = value
            return ''
        else:
            if not value:
                return ''
            return value
Пример #6
0
class ContentInfoNode(GenericNode):
    def __init__(self, content, display, *args, **kwargs):
        self.content = Variable(content)
        self.display = Variable(display)
        super(ContentInfoNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            content = self.content.resolve(context)
            display = self.display.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        pic_size = kwargs.get("pic_size", None)
        pic_size = args[0] if not pic_size and len(args) > 0 else pic_size

        template, author = ["content/info.html", content.author]
        ctx = {"created": content.created}
        if "signature" in display or display == "detail":
            ctx.update({"case": "signature"})
            if display in ["signature", "detail"]:
                ctx.update({
                    "signature_author": True,
                    "signature_pic": True,
                    "author_name": user_display(author),
                    "reputation": author.reputation.reputation_incremented,
                    "author_url": author.get_absolute_url(),
                    "profile_pic": profile_pic(author, size=pic_size)
                })
            elif display == "signature-author":
                ctx.update({
                    "signature_author": True,
                    "author_name": user_display(author),
                    "reputation": author.reputation.reputation_incremented,
                    "author_url": author.get_absolute_url()
                })
            elif display == "signature-pic":
                ctx.update({
                    "signature_pic": True,
                    "profile_pic": profile_pic(author, size=pic_size)
                })
            else:
                raise TemplateSyntaxError("'content_info': wrong display.")
        elif display == "header":
            ctx.update({
                "case": "header",
                # "author_name": user_display(author),
                # "author_url": author.get_absolute_url(),
                "author": author,
                "reputation": author.reputation.reputation_incremented,
                "about": author.get_profile().about
            })
        elif display in ["date", "list"]:
            ctx.update({"case": "date"})
        else:
            raise TemplateSyntaxError("'content_info': wrong display value.")
        return render_to_string(template, ctx, context_instance=context)
Пример #7
0
class FormPartNode(Node):
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "%r accepts at most 4 arguments (part_id, section, asvar, varname), got: {}"
                % (bits[0], ','.join(bits[1:])))

        self.part_id = Variable(bits[1])
        self.section = bits[2] if len(bits) >= 3 else None

        self.varname = None
        if len(bits) > 3:
            if bits[3] != 'asvar':
                raise TemplateSyntaxError(
                    'Forth argument should be as var, got {}', format(bits[3]))
            if len(bits) < 4:
                raise TemplateSyntaxError('Variable name not provided')
            else:
                self.varname = Variable(bits[4])

        self.nodelist = parser.parse(('end{}'.format(bits[0]), ))
        parser.delete_first_token()

    def resolve_part(self, context):
        part = self.part_id.resolve(context)
        if isinstance(part, BoundField):
            part = part.field
        return part

    def render(self, context):
        part = self.resolve_part(context)
        parts = context['form_parts']

        if self.section in parts[part]:
            # already rendered
            if self.varname is not None:
                context[self.varname.resolve(context)] = parts[part][
                    self.section]
                return ""
            else:
                return parts[part][self.section]

        # child parts
        children = (node for node in self.nodelist
                    if isinstance(node, FormPartNode))
        _render_parts(context, children)

        # render own content
        value = self.nodelist.render(context).strip()
        if self.varname is not None:
            context[self.varname.resolve(context)] = value
            return ''
        else:
            if not value:
                return ''
            return value
Пример #8
0
class RepeatNode(Node):
    def __init__(self, nodelist, count_from, count_to):
        self.nodelist = nodelist
        self.count_from = Variable(count_from)
        self.count_to = Variable(count_to)

    def render(self, context):
        output = self.nodelist.render(context)
        return output * (int(self.count_from.resolve(context)) -
                         int(self.count_to.resolve(context)))
Пример #9
0
class WidgetAttrNode(Node):
    """
    {% attr form.email 'widget' 'data-validate' %}email{% endattr %}
    {% attr form.email 'widget' 'class' append %}green{%  endattr %}
    {% attr form.email 'widget' 'required' %}True{%  endattr %}
    """
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) < 4:
            raise TemplateSyntaxError(
                "{} accepts at least 3 arguments (bound_field, 'groupname' 'attr_name'), got: {}"
                .format((bits[0], ','.join(bits[1:]))))

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "{} accepts at mast 4 arguments (bound_field, 'groupname' 'attr_name' action ), got: {}"
                .format((bits[0], ','.join(bits[1:]))))

        if len(bits) >= 5 and bits[4] not in ['append', 'override']:
            raise TemplateSyntaxError(
                "{} unknown action {}  should be 'append' of 'override'".
                format((bits[0], ','.join(bits[4]))))

        self.field = Variable(bits[1])
        self.group = Variable(bits[2])
        self.attr = bits[3]
        self.action = bits[4] if len(bits) >= 5 else 'override'
        self.nodelist = parser.parse(('end{}'.format(bits[0]), ))
        parser.delete_first_token()

    def resolve_field(self, context):
        field = self.field.resolve(context)
        if isinstance(field, BoundField):
            field = field.field
        return field

    def render(self, context):
        field = self.resolve_field(context)
        group = self.group.resolve(context)
        form_widget_attrs = context['form_widget_attrs']
        value = self.nodelist.render(context)

        if group not in form_widget_attrs[field]:
            form_widget_attrs[field][group] = {}
        attrs = form_widget_attrs[field][group]

        if self.attr not in attrs or self.action == 'override':
            attrs[self.attr] = (value, self.action)
        else:
            old_value, old_action = attrs[self.attr]
            if old_action != 'override':
                attrs[self.attr] = ('{} {}'.format(old_value,
                                                   value), self.action)
Пример #10
0
class WidgetAttrNode(Node):
    """
    {% attr form.email 'widget' 'data-validate' %}email{% endattr %}
    {% attr form.email 'widget' 'class' append %}green{%  endattr %}
    {% attr form.email 'widget' 'required' %}True{%  endattr %}
    """
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) < 4:
            raise TemplateSyntaxError(
                "{} accepts at least 3 arguments (bound_field, 'groupname' 'attr_name'), got: {}".format(
                    (bits[0], ','.join(bits[1:]))))

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "{} accepts at mast 4 arguments (bound_field, 'groupname' 'attr_name' action ), got: {}".format(
                    (bits[0], ','.join(bits[1:]))))

        if len(bits) >= 5 and bits[4] not in ['append', 'override']:
            raise TemplateSyntaxError(
                "{} unknown action {}  should be 'append' of 'override'".format(
                    (bits[0], ','.join(bits[4]))))

        self.field = Variable(bits[1])
        self.group = Variable(bits[2])
        self.attr = bits[3]
        self.action = bits[4] if len(bits) >= 5 else 'override'
        self.nodelist = parser.parse(('end{}'.format(bits[0]),))
        parser.delete_first_token()

    def resolve_field(self, context):
        field = self.field.resolve(context)
        if isinstance(field, BoundField):
            field = field.field
        return field

    def render(self, context):
        field = self.resolve_field(context)
        group = self.group.resolve(context)
        form_widget_attrs = context['form_widget_attrs']
        value = self.nodelist.render(context)

        if group not in form_widget_attrs[field]:
            form_widget_attrs[field][group] = {}
        attrs = form_widget_attrs[field][group]

        if self.attr not in attrs or self.action == 'override':
            attrs[self.attr] = (value, self.action)
        else:
            old_value, old_action = attrs[self.attr]
            if old_action != 'override':
                attrs[self.attr] = ('{} {}'.format(old_value, value), self.action)
Пример #11
0
class FollowFormNode(GenericNode):

    template = "follow/follow_form.html"

    def __init__(self, user, obj, *args, **kwargs):
        self.user = Variable(user)
        self.obj = Variable(obj)
        super(FollowFormNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            user = self.user.resolve(context)
            obj = self.obj.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        fields = ["next", "base_class", "success_class", "extra_class",
                  "tooltip_class", "quote_type"]
        for index, field in enumerate(fields):
            value = kwargs.get(field, None)
            value = args[index] if not value and len(args) > index else value
            setattr(self, field, value)

        is_following = Follow.objects.is_following(user, obj)
        buttons = copy.deepcopy(DEFAULT_CONF)
        for key in buttons.keys():
            if user == obj:
                buttons[key].update({"disabled": "disabled"})
            if self.base_class:
                buttons[key].update({"class": self.base_class})
            if self.extra_class:
                buttons[key].update({"extra_class": self.extra_class})
            tooltip_class = self.tooltip_class if self.tooltip_class else \
                buttons[key]["tooltip_class"]
            buttons[key].update({
                "class": buttons[key]["class"] + " " + tooltip_class})
            if key == "following" and self.success_class:
                buttons[key]["class"] += " " + self.success_class

        key = "follow" if is_following else "following"
        buttons[key]["class"] = buttons[key]["class"] + " hidden"

        ctx = {"object": obj, "buttons": buttons}
        if self.next:
            ctx.update({"next": self.next})

        html = render_to_string(self.template, ctx, context_instance=context)

        return self.render_output(context, html)
Пример #12
0
class _ABTestNode(Node):

    def __init__(self, ab_test_name, variant_a_content, variant_b_content):
        self.ab_test_name = Variable(ab_test_name)
        self.variant_a_content = variant_a_content
        self.variant_b_content = variant_b_content

    def render(self, context):
        ab_test_name = self.ab_test_name.resolve(context)
        ab_test = ABTest.objects.get_or_create(name=ab_test_name)[0]

        block_context = context.copy()
        block_context["ab_test"] = ab_test

        if self._is_variant_a_applicable(context["request"]):
            block_context["ab_test_variant"] = VARIANT_A
            content = self.variant_a_content.render(block_context)
            ab_test.times_a_presented += 1
        else:
            block_context["ab_test_variant"] = VARIANT_B
            content = self.variant_b_content.render(block_context)
            ab_test.times_b_presented += 1

        ab_test.save()

        return content

    @staticmethod
    def _is_variant_a_applicable(request):
        raise NotImplementedError("Determine whether A or B is applicable!")
Пример #13
0
class TagDisplayNode(GenericNode):
    def __init__(self, tag, *args, **kwargs):
        self.tag = Variable(tag)
        super(TagDisplayNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            tag = self.tag.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        template, ctx = ["tags/_tag_display.html", {"tag": tag}]
        fields = ["quote_type", "extra_class"]
        for index, field in enumerate(fields):
            value = kwargs.get(field, None)
            value = args[index] if not value and len(args) > index else value
            if not value:
                continue
            if field == "quote_type":
                setattr(self, field, value)
            elif field == "extra_class":
                ctx.update({field: value})

        html = render_to_string(template, ctx, context_instance=context)
        html = hyphenate(html)

        return self.render_output(context, html)
Пример #14
0
class RangeNode(Node):
    def __init__(self, num, context_name):
        self.num, self.context_name = Variable(num), context_name

    def render(self, context):
        context[self.context_name] = range(int(self.num.resolve(context)))
        return ""
Пример #15
0
class IncludeHandlebarsNode(Node):
    def __init__(self, name):
        self.name = Variable(name)

    def render(self, context):
        name = self.name.resolve(context)
        template = get_template(name)

        return template.render(context)
Пример #16
0
class URINode(GenericNode):
    def __init__(self, obj, request, *args, **kwargs):
        self.obj = Variable(obj)
        self.request = Variable(request)
        super(URINode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            obj = self.obj.resolve(context)
            request = self.request.resolve(context)
        except:
            return ""
        if obj.__class__ is not Tag:
            url = obj.get_absolute_url()
        else:
            # Dirty. Check coop-tag
            url = reverse("tagged_items", args=[obj.slug])
        return self.render_output(context, request.build_absolute_uri(url))
Пример #17
0
class UserCommentCountNode(Node):
    def __init__(self, user, context_name):
        self.user = Variable(user)
        self.context_name = context_name

    def render(self, context):
        user = self.user.resolve(context)
        context[self.context_name] = user.jcomment_set.all().count()
        return ''
Пример #18
0
class FormRenderNode(Node):
    """Sugar for element in template rendering."""
    def __init__(self, parser, token):  # noqa D102
        bits = token.split_contents()

        if len(bits) == 0:
            raise TemplateSyntaxError(
                "%r received invalid args, expected one element for render."
                " Got: %r".format(bits[0], bits[1:]))

        remaining_bits = bits[2:]

        self.kwargs = token_kwargs(remaining_bits, parser)

        if remaining_bits:
            raise TemplateSyntaxError("%r received an invalid token: %r" %
                                      (bits[0], remaining_bits[0]))

        for key in self.kwargs:
            if key not in ('template', 'widget'):
                raise TemplateSyntaxError("%r received an invalid key: %r" %
                                          (bits[0], key))

            self.kwargs[key] = self.kwargs[key]

        self.nodelist = parser.parse(('end{}'.format(bits[0]), ))
        parser.delete_first_token()

        self.element = Variable(bits[1])

    def render(self, context):  # noqa D102
        element = self.element.resolve(context)

        options = {}
        for key, value in self.kwargs.items():
            options[key] = value.resolve(context)

        # render inner parts
        children = (node for node in self.nodelist
                    if isinstance(node, FormPartNode))
        _render_parts(context, children)

        attrs = (node for node in self.nodelist
                 if isinstance(node, WidgetAttrNode))
        for attr in attrs:
            attr.render(context)

        # render element
        if isinstance(element, BoundField):
            return Field(element.name).render(context, **options)
        elif hasattr(element, 'render'):
            with context.push(parent=element):
                return element.render(context, **options)
        else:
            raise TemplateSyntaxError(
                "form_render can't render %r".format(element))
Пример #19
0
class NnmcommentCountNode(Node):
    def __init__(self, content_object, context_name):
        self.content_object = Variable(content_object)
        self.context_name = context_name

    def render(self, context):
        content_object = self.content_object.resolve(context)
        context[self.context_name] = Nnmcomment.public.all_for_object(
            content_object).count()
        return ''
class FormRenderNode(Node):
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) == 0:
            raise TemplateSyntaxError(
                "%r received invalid args, expected one element for render. Got: %r" %
                (bits[0], bits[1:]))

        remaining_bits = bits[2:]

        self.kwargs = token_kwargs(remaining_bits, parser)

        if remaining_bits:
            raise TemplateSyntaxError("%r received an invalid token: %r" %
                                      (bits[0], remaining_bits[0]))

        for key in self.kwargs:
            if key not in ('template', 'widget'):
                raise TemplateSyntaxError("%r received an invalid key: %r" %
                                          (bits[0], key))

            self.kwargs[key] = self.kwargs[key]

        self.nodelist = parser.parse(('end{}'.format(bits[0]),))
        parser.delete_first_token()

        self.element = Variable(bits[1])

    def render(self, context):
        element = self.element.resolve(context)

        options = {}
        for key, value in self.kwargs.items():
            options[key] = value.resolve(context)

        # render inner parts
        children = (node for node in self.nodelist if isinstance(node, FormPartNode))
        _render_parts(context, children)

        attrs = (node for node in self.nodelist if isinstance(node, WidgetAttrNode))
        for attr in attrs:
            attr.render(context)

        # render element
        if isinstance(element, BoundField):
            return Field(element.name).render(context, **options)
        elif hasattr(element, 'render'):
            with context.push(parent=element):
                return element.render(context, **options)
        else:
            raise TemplateSyntaxError("form_render can't render %r" % (element, ))
Пример #21
0
class IncludeNode(Node):
    def __init__(self, template_name):
        self.template_name = Variable(template_name)

    def render(self, context):
        try:
            template_name = self.template_name.resolve(context)
            t = get_template(template_name)
            return t.render(context)
        except TemplateSyntaxError, e:
            if settings.TEMPLATE_DEBUG:
                raise
            return ''
        except:
Пример #22
0
class EditButtonsNode(GenericNode):

    template = "items/_edit_buttons.html"

    def __init__(self, user, obj, *args, **kwargs):
        self.user = Variable(user)
        self.obj = Variable(obj)
        super(EditButtonsNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            user = self.user.resolve(context)
            obj = self.obj.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        #TODO: More generically, implement a 'can_manage' permission
        if not (user.is_superuser or getattr(obj, "author", None) == user):
            return ""
        url_args = [obj._meta.module_name, obj.id]
        ctx = {
            "edit_url": reverse("item_edit", args=url_args),
            "delete_url": reverse("item_delete", args=url_args)
        }

        fields = ["edit_next", "delete_next"]
        for index, field in enumerate(fields):
            value = kwargs.get(field, None)
            value = args[index] if not value and len(args) > index else value
            if value:
                key = string.replace(field, "next", "url")
                ctx.update({key: "%s?next=%s" % (ctx.get(key), value)})

        html = render_to_string(self.template, ctx, context_instance=context)

        return self.render_output(context, html)
Пример #23
0
class IncludeThingTemplateNode(Node):
    def __init__(self, template_name, context_thing):
        self.template_name = template_name
        self.context_thing = Variable(context_thing)

    def render(self, context):
        thing = self.context_thing.resolve(context)
        try:
            template = loader.get_template(self.template_name % (thing.type,))
        except TemplateDoesNotExist:
            template = loader.get_template(self.template_name % ("default",))
        template_context = Context(dict_=context)
        template_context.update({
            'thing': thing
        })
        return template.render(template_context)
Пример #24
0
class PriceNode(GenericNode):
    def __init__(self, value, *args, **kwargs):
        self.value = Variable(value)
        super(PriceNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            value = self.value.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        fields = ["currency", "language_code"]
        for index, field in enumerate(fields):
            val = kwargs.get(field, None)
            val = args[index] if not val and len(args) > index else val
            setattr(self, field, val)

        return self.render_output(
            context, format_price(value, self.currency, self.language_code))
Пример #25
0
class FormPartNode(Node):
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) > 3:
            raise TemplateSyntaxError(
                "%r accepts at most 2 arguments (part_id, section), got: {}" %
                (bits[0], bits[1:]))

        self.part_id = Variable(bits[1])
        self.section = bits[2] if len(bits) == 3 else None

        self.nodelist = parser.parse(('end{}'.format(bits[0]), ))
        parser.delete_first_token()

    def resolve_part(self, context):
        part = self.part_id.resolve(context)
        if isinstance(part, BoundField):
            part = part.field
        return part

    def render(self, context):
        part = self.resolve_part(context)
        parts = context['form_parts']

        if self.section in parts[part]:
            # already rendered
            return parts[part][self.section]

        # child parts
        children = (node for node in self.nodelist
                    if isinstance(node, FormPartNode))
        _render_parts(context, children)

        # render own content
        value = self.nodelist.render(context).strip()
        if not value:
            return ''
        return value
Пример #26
0
class FormPartNode(Node):
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) > 3:
            raise TemplateSyntaxError(
                "%r accepts at most 2 arguments (part_id, section), got: {}" %
                (bits[0], bits[1:]))

        self.part_id = Variable(bits[1])
        self.section = bits[2] if len(bits) == 3 else None

        self.nodelist = parser.parse(('end{}'.format(bits[0]),))
        parser.delete_first_token()

    def resolve_part(self, context):
        part = self.part_id.resolve(context)
        if isinstance(part, BoundField):
            part = part.field
        return part

    def render(self, context):
        part = self.resolve_part(context)
        parts = context['form_parts']

        if self.section in parts[part]:
            # already rendered
            return parts[part][self.section]

        # child parts
        children = (node for node in self.nodelist if isinstance(node, FormPartNode))
        _render_parts(context, children)

        # render own content
        value = self.nodelist.render(context)
        if not value.strip():
            return ''
        return value
Пример #27
0
class UpdateQueryNode(template.Node):
    def __init__(self, query, parts):
        self.query = Variable(query)
        self.parts = self.query_update(parts)

    def query_update(self, query_parts):
        parts = []
        for part in query_parts:
            parts.append(part.split('='))
        return parts

    def render(self, context):
        query = self.query.resolve(context).copy()
        for var, value in self.parts:
            if (value[0] == value[-1] and value[0] in ('\'', '"')
                    and len(value[0]) > 2):
                query[var] = value[1:-1]
            else:
                query[var] = Variable(value).resolve(context)
        query_str = query.urlencode()
        if query_str:
            return '?%s' % query_str
        else:
            return ''
Пример #28
0
class TagsDisplayNode(GenericNode):
    def __init__(self, tags, *args, **kwargs):
        self.tags = Variable(tags)
        super(TagsDisplayNode, self).__init__(*args, **kwargs)

    def render(self, context):
        try:
            tags = self.tags.resolve(context)
            args, kwargs = self.resolve_template_args(context)
        except:
            return ""

        f_kwargs = {
            "queryset": tags.all(),
            "object_name": "tag",
            "template": "tags/_tag_display.html",
            "context": context,
            "container": "tags"
        }
        fields = ["max_nb", "quote_type", "sep", "extra_class"]
        for index, field in enumerate(fields):
            value = kwargs.get(field, None)
            value = args[index] if not value and len(args) > index else value
            if not value:
                continue
            if field == "extra_class":
                f_kwargs.update({"template_context": {field: value}})
            elif field == "quote_type":
                setattr(self, field, value)
            else:
                f_kwargs.update({field: value})

        html = generate_objs_sentence(**f_kwargs)
        # html = hyphenate(html)

        return self.render_output(context, html)
Пример #29
0
class WidgetAttrsNode(Node):
    def __init__(self, parser, token):
        bits = token.split_contents()

        if len(bits) < 3:
            raise TemplateSyntaxError(
                "%r accepts at least 2 arguments (bound_field, 'groupname'), got: {}"
                % (bits[0], ','.join(bits[1:])))

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "%r accepts at mast 4 arguments (bound_field, 'groupname' default attrs_dict ), got: {}"
                % (bits[0], ','.join(bits[1:])))

        if len(bits) > 3 and bits[3] != 'default':
            raise TemplateSyntaxError(
                "%r 3d argument should be 'default' (bound_field, 'groupname' default attrs_dict ), got: {}"
                % (bits[0], ','.join(bits[1:])))

        self.field = Variable(bits[1])
        self.group = Variable(bits[2])
        self.widget_attrs = Variable(bits[4]) if len(bits) >= 5 else None
        self.nodelist = parser.parse(('end{}'.format(bits[0]), ))
        parser.delete_first_token()

    def resolve_field(self, context):
        field = self.field.resolve(context)
        if isinstance(field, BoundField):
            field = field.field
        return field

    def render(self, context):
        field = self.resolve_field(context)
        group = self.group.resolve(context)
        form_widget_attrs = context['form_widget_attrs']

        override = {}
        if group in form_widget_attrs[field]:
            override = form_widget_attrs[field][group]

        build_in_attrs, tag_content = {}, self.nodelist.render(context)
        for attr, _, value in ATTRS_RE.findall(tag_content):
            build_in_attrs[attr] = mark_safe(value) if value != '' else True

        widget_attrs = {}
        if self.widget_attrs is not None:
            widget_attrs = self.widget_attrs.resolve(context)

        result = build_in_attrs.copy()

        if 'class' in result and 'class' in widget_attrs:
            result['class'] += ' ' + widget_attrs.pop('class')
        result.update(widget_attrs)

        for attr, (value, action) in override.items():
            if action == 'override':
                result[attr] = value
            elif action == 'append':
                if attr in result:
                    result[attr] += " " + value
                else:
                    result[attr] = value

        return flatatt(result)
Пример #30
0
class TableNode(Node):
    """
    Allows easy construction of complex tables.

    {% table 'object_list' %}
        {% tableheader attr='attribute' text='Display Name' %}
        {% tableheader attr='attribute2' sortable=True %}
        {% if some_condition %}
        {% tableheader attr='conditional_header' %}
        {% endif %}
    {% endtable %}
    """
    def __init__(self, parser, token):
        bits = token.split_contents()
        bits.pop(0)
        if len(bits) == 0:
            raise TemplateSyntaxError("'table' statement takes one argument")

        self.data = Variable(bits.pop(0))

        self.kwargs = token_kwargs(bits, parser)
        for key in self.kwargs:
            if key not in ('collapseclass', 'templatename',
                           'subtabletoggletext'):
                raise TemplateSyntaxError("'table' received invalid key: %s" %
                                          key)

        self.nodelist = parser.parse(('endtable', ))
        parser.delete_first_token()

    def render(self, context):
        request = context.get("request")

        data = self.data.resolve(context)

        collapseclass = self.kwargs.get('collapseclass')
        if collapseclass:
            collapseclass = collapseclass.resolve(context)

        template_name = self.kwargs.get('templatename')
        if template_name:
            template_name = template_name.resolve(context)
        else:
            template_name = 'dj_tables/bootstrap4.html'
        template = get_template(template_name)

        subtable_toggle_text = self.kwargs.get('subtabletoggletext')
        if subtable_toggle_text:
            subtable_toggle_text = subtable_toggle_text.resolve(context)
        else:
            subtable_toggle_text = 'View Details'

        with context.push(
                tableid=uuid.uuid4(
                ),  # just some unique id for the table, useful for bootstrap collapsibles ie.
                tabledata=data,
                tableheaders=[],
                tablerowactions=[],
                subtabletoggletext=subtable_toggle_text,
                subtables=[]):
            self._render_nodelist(self.nodelist, context)

            context['collapseclass'] = collapseclass

            tablecolspan = len(context['tableheaders'])
            if context['tablerowactions']:
                tablecolspan += 1
            if context['subtables']:
                tablecolspan += 1
            context['tablecolspan'] = tablecolspan

            return template.render(context.flatten())

    def _render_nodelist(self, nodelist, context):
        for node in nodelist:
            if self._can_render_node(node):
                node.render(context)
            elif hasattr(node, 'conditions_nodelists'):
                node.conditions_nodelists = [
                    (condition,
                     NodeList([
                         node for node in nodelist
                         if self._can_render_node(node)
                     ])) for condition, nodelist in node.conditions_nodelists
                ]
                node.render(context)
            elif hasattr(node, 'nodelist'):
                node.nodelist = NodeList([
                    node for node in node.nodelist
                    if self._can_render_node(node)
                ])
                node.render(context)

    def _can_render_node(self, node):
        return isinstance(node, TableHeaderNode) or\
            isinstance(node, TableRowActionNode) or\
            isinstance(node, SubtableNode)
Пример #31
0
class WidgetAttrNode(Node):
    """The tag allows to add or override specific attribute in the rendered HTML.

    The first argumnent is the attribute group name, second is the
    attribute name.  The third optional flag shows to override (by
    default) or `append` the value.

    Usage::

        {% attr form.email 'widget' 'data-validate' %}email{% endattr %}
        {% attr form.email 'widget' 'class' append %}green{%  endattr %}
        {% attr form.email 'widget' 'required' %}True{%  endattr %}

    """
    def __init__(self, parser, token):  # noqa D102
        bits = token.split_contents()

        if len(bits) < 4:
            raise TemplateSyntaxError(
                "{} accepts at least 3 arguments (bound_field, 'groupname'"
                " 'attr_name'), got: {}".format(bits[0], ','.join(bits[1:])))

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "{} accepts at mast 4 arguments (bound_field, 'groupname'"
                " 'attr_name' action ), got: {}".format(
                    bits[0], ','.join(bits[1:])))

        if len(bits) >= 5 and bits[4] not in ['append', 'override']:
            raise TemplateSyntaxError(
                "{} unknown action {}  should be 'append'"
                " of 'override'".format(bits[0], ','.join(bits[4])))

        self.field = Variable(bits[1])
        self.group = Variable(bits[2])
        self.attr = bits[3]
        self.action = bits[4] if len(bits) >= 5 else 'override'
        self.nodelist = parser.parse(('end{}'.format(bits[0])))
        parser.delete_first_token()

    def resolve_field(self, context):
        """Resolve field reference form context."""
        field = self.field.resolve(context)
        if isinstance(field, BoundField):
            field = field.field
        return field

    def render(self, context):  # noqa D102
        field = self.resolve_field(context)
        group = self.group.resolve(context)
        form_widget_attrs = context['form_widget_attrs']
        value = self.nodelist.render(context)

        if group not in form_widget_attrs[field]:
            form_widget_attrs[field][group] = {}
        attrs = form_widget_attrs[field][group]

        if self.attr not in attrs or self.action == 'override':
            attrs[self.attr] = (value, self.action)
        else:
            old_value, old_action = attrs[self.attr]
            if old_action != 'override':
                attrs[self.attr] = ('{} {}'.format(old_value,
                                                   value), self.action)
Пример #32
0
class RangeNode(Node):
    def __init__(self, num, context_name):
        self.num, self.context_name = Variable(num), context_name
    def render(self, context):
        context[self.context_name] = range(int(self.num.resolve(context)))
        return ""
class WidgetAttrNode(Node):
    """The tag allows to add or override specific attribute in the rendered HTML.

    The first argumnent is the attribute group name, second is the
    attribute name.  The third optional flag shows to override (by
    default) or `append` the value.

    Usage::

        {% attr form.email 'widget' 'data-validate' %}email{% endattr %}
        {% attr form.email 'widget' 'class' append %}green{%  endattr %}
        {% attr form.email 'widget' 'required' %}True{%  endattr %}

    """

    def __init__(self, parser, token):  # noqa D102
        bits = token.split_contents()

        if len(bits) < 4:
            raise TemplateSyntaxError(
                "{} accepts at least 3 arguments (bound_field, 'groupname'"
                " 'attr_name'), got: {}".format(bits[0], ','.join(bits[1:]))
            )

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "{} accepts at mast 4 arguments (bound_field, 'groupname'"
                " 'attr_name' action ), got: {}".format(
                    bits[0], ','.join(bits[1:]))
            )

        if len(bits) >= 5 and bits[4] not in ['append', 'override']:
            raise TemplateSyntaxError(
                "{} unknown action {}  should be 'append'"
                " of 'override'".format(bits[0], ','.join(bits[4]))
            )

        self.field = Variable(bits[1])
        self.group = Variable(bits[2])
        self.attr = bits[3]
        self.action = bits[4] if len(bits) >= 5 else 'override'
        self.nodelist = parser.parse(('end{}'.format(bits[0])))
        parser.delete_first_token()

    def resolve_field(self, context):
        """Resolve field reference form context."""
        field = self.field.resolve(context)
        if isinstance(field, BoundField):
            field = field.field
        return field

    def render(self, context):  # noqa D102
        field = self.resolve_field(context)
        group = self.group.resolve(context)
        form_widget_attrs = context['form_widget_attrs']
        value = self.nodelist.render(context)

        if group not in form_widget_attrs[field]:
            form_widget_attrs[field][group] = {}
        attrs = form_widget_attrs[field][group]

        if self.attr not in attrs or self.action == 'override':
            attrs[self.attr] = (value, self.action)
        else:
            old_value, old_action = attrs[self.attr]
            if old_action != 'override':
                attrs[self.attr] = (
                    '{} {}'.format(old_value, value),
                    self.action
                )
class WidgetAttrsNode(Node):
    """
    Renders attrs for the html tag.

    <input{% attrs boundfield 'widget' default field.widget.attrs %}
        id="id_{{ bound_field.name }}"
        class="{% if bound_field.errors %}invalid{% endif %}"
    {% endattrs %}>
    """

    def __init__(self, parser, token):  # noqa D102
        bits = token.split_contents()

        if len(bits) < 3:
            raise TemplateSyntaxError(
                "%r accepts at least 2 arguments (bound_field,"
                " 'groupname'), got: {}".format(bits[0], ','.join(bits[1:]))
            )

        if len(bits) > 5:
            raise TemplateSyntaxError(
                "%r accepts at mast 4 arguments (bound_field, 'groupname'"
                " default attrs_dict ), got: {}".format(
                    bits[0], ','.join(bits[1:]))
            )

        if len(bits) > 3 and bits[3] != 'default':
            raise TemplateSyntaxError(
                "%r 3d argument should be 'default' (bound_field, 'groupname'"
                " default attrs_dict ), got: {}".format(
                    bits[0], ','.join(bits[1:]))
            )

        self.field = Variable(bits[1])
        self.group = Variable(bits[2])
        self.widget_attrs = Variable(bits[4]) if len(bits) >= 5 else None
        self.nodelist = parser.parse(('end{}'.format(bits[0])))
        parser.delete_first_token()

    def resolve_field(self, context):
        """Resolve field reference form context."""
        field = self.field.resolve(context)
        if isinstance(field, BoundField):
            field = field.field
        return field

    def render(self, context):  # noqa D102
        field = self.resolve_field(context)
        group = self.group.resolve(context)
        form_widget_attrs = context['form_widget_attrs']

        override = {}
        if group in form_widget_attrs[field]:
            override = form_widget_attrs[field][group]

        build_in_attrs, tag_content = {}, self.nodelist.render(context)
        for attr, _, value in ATTRS_RE.findall(tag_content):
            build_in_attrs[attr] = mark_safe(value) if value != '' else True

        widget_attrs = {}
        if self.widget_attrs is not None:
            widget_attrs = self.widget_attrs.resolve(context)

        result = build_in_attrs.copy()

        if 'class' in result and 'class' in widget_attrs:
            result['class'] += ' ' + widget_attrs.pop('class')
        result.update(widget_attrs)

        for attr, (value, action) in override.items():
            if action == 'override':
                result[attr] = value
            elif action == 'append':
                if attr in result:
                    result[attr] += " " + value
                else:
                    result[attr] = value

        return flatatt(result)