neutronX / django-markdownx

Comprehensive Markdown plugin built for Django
https://neutronx.github.io/django-markdownx/
Other
854 stars 153 forks source link

Template tag that renders markdown #74

Open dyve opened 7 years ago

dyve commented 7 years ago

Hi, looking at the code it would be easy to add a custom template tag that calls markdownify.

The use case is that when you use a Markdown editor, you'd probably want to show rendered Markdown text somewhere in your app. MArkdownX provides a utils function (markdownify) to convert Markdown to HTML in a view, but not i na template. The benefit of adding this would be that a project using MarkdownX would not require a Markdown renderer such as django-markdown-deux to show the rendered markdown in templates.

Would a PR that implements this be appreciated, or is this project aimed at being a MD editor only?

adi- commented 7 years ago

This is fairly easy task to add template tag. But, as you suggested, it would be nice to support it for wider audience.

If you got a PR already, please push it.

dyve commented 7 years ago

I don't have a PR ready, but willin gto submit it.

The instructions how to run the tests seem to be missing from the docs. travis is instricted to python runtests.py but that file is not in the project root?

davideghz commented 7 years ago

It would be great to have it

dyve commented 7 years ago

PR #77

xenatisch commented 7 years ago

Tags are good, and they're easy to use. But we need to discuss the scope, and their functionality. I'm not sure a filter is what we're looking for. I think something along the lines of editor and preview are useful. But then it brings about the project policy of not turning into a WYSIWYG editor. We need to balance this right.

Also, the mark_safe command is a little too much for my taste. It needs to be done explicitly by the end-of-line programmer as and when necessary. It opens a can of worms re security that we really wanna avoid, specially if the editor is used by unregistered users.

Any thoughts are welcome!

davideghz commented 7 years ago

It opens a can of worms re security that we really wanna avoid

Django beginner here; at the moment I'm rendering html with something like:

{{ thread.content|truncatechars:140|show_markdown|safe }}

being show_markdown my custom templatetag.

@register.filter
def show_markdown(text):
    return markdownify(text)

I don't think this is safe either. It would be great if the rendering of formatted html would be managed by the markdownx app as well, so that security concerns can be addressed in the right way and not left to the end-of-line programmer.

dyve commented 7 years ago

Thanks for the feedback folks. Looks like we're on different tracks here. I'd use bleach or django-bleach to sanitize untrusted output. Markdown to HTML might or might not be automatically safe.

I noticed (and tested) that markdownify respect Markdown's "HTML is allowed and will be rendered" settings. That makes being wary of output even more important.

For my use case, it looks like I'm better off using django-markdown-deux and django-bleach, since and editor is not my primary concern.

I hop my small PR is of some use in the future, but I'll leave that up to other contributors.

xenatisch commented 7 years ago

@dyve Thank you for your contribution.

As a matter of fact, I use the template tags from django-markdown-deux too (of with some minor modifications to incorporate specific needs to display maths). Which is why I think it's not necessary to have a markdown conversion filter when it comes to trans-compilation (there are plenty of choices out there). I think a good tutorial in our docs would probably go a long way.

I'm not familiar with django-bleach, though I shall have a look at that, and perhaps make recommendations in the docs.

Finally, on your contribution, I'm sure we can, and will use it in some shape or form in the project.

xenatisch commented 7 years ago

@davideghz

You're truncating. That's not a typical thing to do with Markdown.

It would be great if the rendering of formatted html would be managed by the markdownx app as well, so that security concerns can be addressed in the right way and not left to the end-of-line programmer.

We cannot address the security concerns unless we know the circumstances. And believe me, we already do address a lot of security issues (CSRF and JavaScript injection in SVG files) as well as we practically can.

Additionally, if we do that, we're essentially telling the API users to not worry about security, and that's not a good idea. What we can do, again, is to have tutorials.

Further on that point, I don't think it is in general a good idea for us to take care of Markdown interpretation. On reason is that Markdown is not an absolute standard (that versatility is what makes it so interesting). You can write your own interpreter, or use an interpreter that incorporates specific extensions you're looking for, or whatever.

Imposing an interpreter would simply turn MarkdownX into just another Django Markdown package. It we were to do that, could easily achieve it through JavaScript Markdown packages, which would have more security (existing HTML could be filtered out), and not calls to the server would be necessary for trans-compilation. But that's what a lot of other packages do, and it doesn't seem to be what MarkdownX fans and users are after. At the moment, MarkdownX is the most popular Django Markdown package; and if I were to speculate the reason why, I would say it's precisely because of the level of versatility it offers.

davideghz commented 7 years ago

I see your point. Btw, I truncate it since I need to show a small part of the whole text in a box. Is there a better way to achieve it? I think this issue is not the right place to discuss it, but a quick tutorial about it would be great!

StanleyDerLurch commented 6 years ago

You can do this right in your model...

# models.py
@property
def formatted_markdown(self):
    return markdownify(self.text)

in your template just add {{ object.formatted_markdown|safe }}

I think it's the easiest way :)

pickfire commented 2 years ago
from django import template  
from django.utils.safestring import mark_safe   
from markdownx.utils import markdownify  

register = template.Library()

@register.filter  
def markdown(text):
    return mark_safe(markdownify(text))   
{{ text|markdown }}