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 ofCustomFlatPage
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 theContentImage
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 processedpre_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.
精彩评论