开发者

Performing text processing on flatpage content to include handling of custom tag

I'm using flatpages app in my project to manage some html content. That content w开发者_运维问答ill include images, so I've made a ContentImage model allowing user to upload images using admin panel. The user should then be able to include those images in content of the flatpages. He can of course do that by manually typing image url into <img> tag, but that's not what I'm looking for.

To make including images more convenient, I'm thinking about something like this:

  • User edits an additional, let's say pre_content field of CustomFlatPage model (I'm using custom flatpage model already)
  • instead of defining <img> tags directly, he uses a custom tag, something like [img=...] where ... is name of the ContentImage instance
  • now the hardest part: before CustomFlatPage is saved, pre_content field is checked for all [img=...] occurences and they are processed like this:
  • ContentImage model is searched if there's image instance with given name and if so, [img=...] is replaced with proper <img> tag.
  • flatpage actual content is filled with processed pre_content and then flatpage is saved (pre_content is leaved unchanged, as edited by user)

The part that I can't cope with is text processing. Should I use regular expressions? Apparently they can be slow for large strings. And how to organize logic? I assume it's rather algorithmic question, but I'm not familliar with text processing in Python enough, to do it myself.

Can somebody give me any clues?


I finally imlemented this using regular expressions. I decided, that spaces are not allowed inside the custom tag. Main text processing function looks like this:

import re
from django.utils.translation import ugettext as _

def process_image_tags(text, ImageModel):
    '''image tag usage:
        ... some text ... [img=image_name:image_class(optional)] ... some text ...
    '''
    t1 = re.split(r'(\[img=[a-z0-9\-_\:]+\])', text)
    t2 = []
    for i in t1:
        if i[:5] == '[img=':
            attrs = i[5:-1].split(':')
            name_attr = attrs[0] #name attribute
            error = None
            try:
                image = ImageModel.objects.get(name=name_attr)
            except ImageModel.DoesNotExist:
                error = '<span class="image_tag_error">%s</span>' % _('Image with given name not found')
            except ImageModel.MultipleObjectsReturned:
                error = '<span class="image_tag_error">%s</span>' % _('More than one image found')
            if not error:
                p = ['<img']
                p.append('src="%s"' % image.image.url) 
                if len(attrs) > 1:
                    p.append('class="%s"' % attrs[1]) #class attribute
                if image.description:
                    p.append('title="%s"' % image.description)
                p.append('alt="%s"' % image.name)
                p.append('/>')                   
                t2.append(' '.join(p))
            else:
                t2.append(error)
        else:
            t2.append(i)
    return ''.join(t2)

Above function is then used in save method of CustomFlatPage model, like this:

def save(self, *args, **kwargs):           
    self.content = process_image_tags(self.pre_content, ContentImage)        
    super(CustomFlatPage, self).save(*args, **kwargs)

It seems to work, so I'll probably end up using that solution. Maybe I'll add some javascript for user to insert image tags by picking images from generated list of images, but even now it's better than manually typing urls, I think.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜