views:

54

answers:

3

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.

A: 

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/&lt;id&gt;"

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.

sebpiq
Think a blog system and when i add a content, maybe i will want to use [vimeo 123456] combination. So, we should solve this out of templates i think. Because maybe i won't use this. What do you think?
Cango
"and when i add a content, maybe i will want to use [vimeo 123456] combination" do you mean that the user that actually add the content would write "[vimeo 123456]" in some form field ??? If it's not what you meant I think I didn't get it ...
sebpiq
Sorry for my low level English. In my blog system i will use this code, maybe in first line, or end of the content, or somewhere in the content. So this sould happen in textfield. Thank you for your help.
Cango
Your level of English is fine, it is just that your explanation is not very clear ! "this code" what code (do you mean "<iframe> ...") ? "content" which content (do you mean your html page) ? Anyways, you should not store html in your models, so whatever you want to do, I advise you to store "[vimeo 123456]" in your TextField, and to format this in your template into a url (like I told you in the answer).
sebpiq
I am newbie in django also. If you understand me, ok, i will try your suggestion in the evening. I will write your first code in templatetags folder? And second code, in the template file. If i write [vimeo 123456], it will replace with iframe code. Thank you again.
Cango
+1  A: 

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&lt;1&gt;"'
        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.

Mike DeSimone
A: 

Thanks for the information, i added django.contrib.markup in settings.py, i installed doc-utils, i added {% load markup %} and i am getting this error.

Invalid filter: 'markup'. It is in templatetags/markup.py and in it, it is def markup(value):

What shoud i do?

Cango
Edit your question or leave a comment, do not post a new answer.
Török Gábor
I couldn't do it, because there is no edit link on my first message. Thank you.
Cango