Выполнение обработки текста для содержимого плоской страницы с включением обработки пользовательского тега - PullRequest
3 голосов
/ 20 февраля 2011

Я использую приложение flatpages в своем проекте для управления HTML-контентом.Этот контент будет включать изображения, поэтому я сделал модель ContentImage, позволяющую пользователю загружать изображения с помощью панели администратора.Затем пользователь должен иметь возможность включать эти изображения в содержимое плоских страниц.Конечно, он может сделать это, вручную введя URL-адрес изображения в тег <img>, но это не то, что я ищу.

Чтобы сделать включение изображений более удобным, я думаю о чем-то вроде этого:

  • Пользователь редактирует дополнительное, скажем, поле pre_content модели CustomFlatPage (я уже использую собственную модель плоской страницы)
  • вместо непосредственного определения тегов <img>, ониспользует пользовательский тег, например, [img=...], где ... - это имя ContentImage экземпляра
  • , теперь самая сложная часть: перед сохранением CustomFlatPage поле pre_content проверяется для всех [img=...] вхождения и они обрабатываются следующим образом:
  • ContentImage модель ищется, если есть экземпляр изображения с данным именем, и если это так, [img=...] заменяется соответствующим тегом <img>.
  • фактическая плоская страница content заполняется обработанной pre_content, а затем сохраняется плоская страница (pre_content остается без изменений, как отредактировано пользователем)

Часть, с которой я не могу справиться, это текстобработка.Должен ли я использовать регулярные выражения?Очевидно, они могут быть медленными для больших строк.А как организовать логику?Я предполагаю, что это довольно алгоритмический вопрос, но я недостаточно знаком с обработкой текста в Python, чтобы сделать это сам.

Может кто-нибудь дать мне какие-нибудь подсказки?

1 Ответ

1 голос
/ 21 февраля 2011

Я наконец-то реализовал это, используя регулярные выражения. Я решил, что пробелы не допускаются внутри пользовательского тега. Основная функция обработки текста выглядит так:

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)

Приведенная выше функция затем используется в методе сохранения модели CustomFlatPage, например:

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

Кажется, это работает, поэтому я, вероятно, в конечном итоге воспользуюсь этим решением. Возможно, я добавлю javascript для пользователя, чтобы вставить теги изображений, выбирая изображения из сгенерированного списка изображений, но я думаю, что даже сейчас это лучше, чем вводить URL-адреса вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...