El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Creant un tag per Django

Una de les coses que fa Django potent com a bastiment és la seva extensibilitat, és força senzill extendre el llenguatge de plantilles amb nous filtres i nous tags.

Avui tenia la necessitat de generar un nombre aleatori, semblant a l'exemple d'Ajax d'un post anterior, pero aquesta vegada volia que no fos necessari cridar a cap vista.

Això seria molt senzill de fer passant el valor com a paràmetre, però pot servir com un exemple més de com crear els nostres propis tags.

Crear un tag en Django requereix de dues passes: crear la funció de compilació i crear la classe que renderitzarà el trag mostrant el text que volem.

Una vegada fet això basta registrar el tag i per això el mateix Django ja ens facilita un decorador.

La randomCode és la que agafa el tag i els paràmetres del tag i en far el parseig. En aquest punt hem de caçar els errors de sintaxi del tag i informar a l'usuari de com es fa server.

La classe randomCodeNode agafa el valor que li passa la funció anterior i fa les operacions necessàries per a tonar-nos una cadena de text presentable en una plana web.

L'esquelet ens pot servir com a base de tags molt més complexos, per exemple tags que incloguin automàticament llibreries javascript , o que facin més senzilla la seva utilització, ...

Per fer servir aquest tag n'haurem de carregar l'arxiu dins la nostra plantilla, com en el cas del filtres això se fa amb un {% load arx %} on arx és el nom de l'arxiu que conté el tag que acabam de crear.

   from django import template
   import string
   import random
   CODE_CHARS = string.ascii_uppercase+string.digitsregister = template.Library()

@register.tag(name="randomCode")

  def randomCode(parser, token):
    try:
       # split_contents() knows not to split quoted strings.
       tag_name, num = token.split_contents()
    except ValueError:
       raise template.TemplateSyntaxError, "%r tag requires an integer as a single argument" % token.contents.split()[0]
    if not (num[0] == num[-1] and num[0] in ('"', "'")):
       raise template.TemplateSyntaxError, "%r tag's argument should be in quotes and be a positive integer" % tag_name
    try:
       value = int(num[1:-1])
       if value <0:
           raise template.TemplateSyntaxError, "%r tag's argument must be a positive integer"
    except:
       raise template.TemplateSyntaxError, "%r tag's argument must be a positive integer" % tag_name
    return randomCodeNode(value)

  class randomCodeNode(template.Node):    def init(self, num):
       self.num = num
       def render(self, context):
       try:
           codi = random.sample(CODE_CHARS,self.num)
       except ValueError, e:
           raise template.TemplateSyntaxError, "tag's argument must be a lower than %i" % len(CODE_CHARS)
       s = ''
       return s.join(codi)

El Wordpress no és gaire bo amb el codi, podeu trobar-ho millor colorejat a Djangosnippets

blog comments powered by Disqus