Search code examples
pythonflaskblogs

Flask blog post extensive controls - How to control text formating, ability to add links, pictures etc


I am building a website-blog using the Flask python web-framework. I can create a blog post, wherein the content field is where all the text of my post goes. The problem is it is just a TextAreaField, with raw unformatted text. In every major forum I've seen (or even this stack-overflow post) while you're assembling your post you're given the ability to have bold text, italicized text, add links, add code-styled text, add pictures, add numbered lists, headings and more.

How can I add any of that to my post? Visually what I'm going for are these controls:

enter image description here

There's the ability to make a section of the text bold, another to make it italic, underline it, add a picture, add a link, add a code section, add a heading (these would be enough for my needs; also embedding a video would be nice). I understand that an image is possibly a more difficult matter as I run into the problem of where to save the images. Save them all per-post, save them independently in another table in the database and link them to an individual post (one-post to many-pictures relationship), store them to an external service (say Imgur)?

In short my PostModel table (using flask_sqlalchemy) contains these columns: title, content, author, datePosted and tags. My PostForm form contains the fields: title (StringField), content (TextAreaField) and tags (FieldList(FormField())) and a button submitField.

How do I accomondate these functions in my flask web-app? Is it maybe possible that I can format the text in the content TextAreaField such that it is displayed a certain way? Hopefully I made myself clear. Thanks in advance.


Solution

  • What I needed was a WYSIWYG (What You See Is What You Get) editor. There are many freely available with popular ones being TinyMCE, Summernote, CKEditor and others.

    Your current code requires few modifications. It is not that hard to integrate it with your code. You specify the required libraries and the initialization code.

    Typically you have a content field of type textarea which will require a class attribute as specified for the library (for Summernote say class="summernoteClass") such that the textarea element can be targeted by the library's javascript code.

    Then you simply store this content to the database as before. Note that this may require cleaning the content in case the user types any malicious <script>s (if so I recommend the bleach python module and then bleach.clean(str)).

    Finally to display the html back (and not the html entities) using Jinja2 template framework you can do so by simply appending |safe in the html code, like so: <p class="article-content">{{ post.content | safe }}</p>. Maybe this will help others.