Cango
Cango

Reputation: 1

Replacing Words in TextField In Django

In django, in TextField, how to we replace,

[vimeo 123456]

with

<iframe src="http://player.vimeo.com/video/123456" width="400" height="225" frameborder="0"></iframe>

Thank you.

Upvotes: 0

Views: 1128

Answers (2)

Mike DeSimone
Mike DeSimone

Reputation: 42805

I don't think it's a good idea to have the HTML in the TextField. First, it would make editing a pain (you'd have to write code to translate back, which will be more difficult than forward); second, it would waste disk on storing a lot of HTML in the database; and finally, it would make it harder to fix bugs later (such as if Vimeo changed their URL format).

You have two options that I can see:

1. View Function

Do this translation in your view function. Your view function would have a line like:

context["commentText"] = process_markup(thePost.commentText)

Then, in your template file, you need to mark the field as safe since you've already filtered it:

{{ commentText|safe }}

2. Custom Filter

Do this translation in a custom filter tag, like the restructuredtext filter in django.contrib.markup. This is what sebpiq recommended, and is probably the better option.

from django.template.defaultfilters import stringfilter
import re

@stringfilter
def mymarkup(value):
    return process_markup(value)

Then, in your template file, you need to call your filter:

{{ commentText|mymarkup }}

In both cases, you would need to write process_markup(value), which would look something like:

import re

_TAGS = [
    # First, escape anything that might be misinterpreted.  Order is important.
    (r'&', r'&amp;'),
    (r'<', r'&lt;'),
    (r'>', r'&gt;'),
    (r'"', r'&quot;'),
    (r"'", r'&#39;'),

    # Simple tags
    (r'\[b\]', r'<b>'),
    (r'\[/b\]', r'</b>'),

    # Complex tags with parameters
    (r'\[vimeo +(\d+) *\]', r'<iframe src="http://player.vimeo.com/video/\g<1>"'
        r' width="400" height="225" frameborder="0"></iframe>'),
]

def process_markup(value):
    for pattern, repl in _TAGS:
        value = re.sub(pattern, repl, value)
    return value

There are probably better ways to write this function, but you get the idea.

Upvotes: 1

sebpiq
sebpiq

Reputation: 7802

Don't do this in your TextField. Rather in the templates. But then you have to parse the value, so I would suggest you write a simple template filter :

from django.template.defaultfilters import stringfilter
import re

@stringfilter
def textfieldtourl(value):
    #parsing of your '[vimeo <id>]'
    #return "http://player.vimeo.com/video/<id>"

And then in template :

<iframe src="{{ my_object.my_text_field|textfieldtourl }}" width="400" height="225" frameborder="0"></iframe>

Where my_object is the object on which your TextField is defined, my_text_field is the name of your TextField, and textfieldtourl is the name of the filter you'll define to replace a code like [vimeo 1235] by an actual url.

More infos on writing custom template fiters.

Upvotes: 0

Related Questions