kronoszx
3/15/2018 - 10:11 PM

Django Custom Filters

import re

from django import template
from django.utils.timezone import now as timezone_now
from django.utils.translation import ugettext as _


register = template.Library()


@register.filter
def replace(string):
    match = re.search(r'(?!www)([A-Za-z0-9]{3,13}\.[a-z]+(\.[a-z]+)?)', string)
    return(match.group() + ('/..'))
    

@register.filter(name='offset', is_safe=False)
def offset(hex_color, brightness_offset=1):
    """ takes a color like #87c95f and produces a lighter or darker variant """
    if len(hex_color) != 7:
        raise Exception("Passed %s into color_variant(), needs to be in #87c95f format." % hex_color)
    rgb_hex = [hex_color[x:x+2] for x in [1, 3, 5]]
    new_rgb_int = [int(hex_value, 16) + brightness_offset for hex_value in rgb_hex]
    new_rgb_int = [min([255, max([0, i])]) for i in new_rgb_int] # make sure new values are between 0 and 255
    # hex() produces "0x88", we want just "88"
    return "#" + "".join([hex(i)[2:] for i in new_rgb_int])


@register.filter(name='get_type', is_safe=False)
def get_type(value):
    t = type(value)
    return t.__module__ + "." + t.__name__


@register.filter(name='humanreadable', is_safe=True)
def human_readable_timedelta(value, complete=False):

    theDateAndTime = value
    fromDate = timezone_now()

    if value.__class__.__name__ != "timedelta":
        if theDateAndTime > fromDate:
            return None
        elif theDateAndTime == fromDate:
            return _('now')
        delta = fromDate - theDateAndTime
    else:
        delta = value

    deltaMinutes = delta.seconds // 60
    deltaHours = delta.seconds // 3600
    deltaYears = delta.days // 365
    deltaMonths = delta.days // 30
    deltaMinutes -= deltaHours * 60
    deltaWeeks = delta.days // 7
    deltaSeconds = delta.seconds - deltaMinutes * 60 - deltaHours * 3600
    deltaDays = delta.days - deltaWeeks * 7

    valuesAndNames = [
        (deltaYears, _('year')),
        (deltaMonths, _('month')),
        (deltaWeeks, _('week')),
        (deltaDays, _('day')),
        (deltaHours, _('hour')),
        (deltaMinutes, _('minute')),
        (deltaSeconds, _('second'))
    ]

    text = ""
    for value, name in valuesAndNames:
        if complete:
            if value > 0:
                text += len(text) and ", " or ""
                text += "%d %s" % (value, name)
                text += (value > 1) and "s" or ""
        else:
            if value > 0:
                text += "%d %s" % (value, name)
                text += (value > 1) and "s" or ""
                break

    # replacing last occurrence of a comma by an 'and'
    if text.find(",") > 0:
        text = " and ".join(text.rsplit(", ", 1))

    return text
    
    
# <li{% if request.path|startswith:'/settings/' %} class="active"{% endif %}>
@register.filter('startswith')
def startswith(text, starts):
    if isinstance(text, basestring):
        return text.startswith(starts)
    return False
    

#  {% if field|fieldtype == 'CheckboxInput' %}    
@register.filter('fieldtype')
def fieldtype(field):
    return field.field.widget.__class__.__name__