Commit 628023e9 authored by PJ Janse van Rensburg's avatar PJ Janse van Rensburg

Merge 'wysiwyg' example into 'forms-files-images'.

parent 6572d0e0
This example shows how you can define your own custom forms by using form rendering rules. It also demonstrates general file handling as well as the handling of image files specifically.
This example shows how you can::
* define your own custom forms by using form
rendering rules
* handle generic static file uploads
* handle image uploads
* turn a TextArea field into a rich WYSIWYG editor using WTForms and CKEditor
To run this example:
......
......@@ -3,6 +3,7 @@ import os.path as op
from flask import Flask, url_for
from flask_sqlalchemy import SQLAlchemy
from wtforms import fields, widgets
from sqlalchemy.event import listens_for
from jinja2 import Markup
......@@ -66,6 +67,15 @@ class User(db.Model):
notes = db.Column(db.UnicodeText)
class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64))
text = db.Column(db.UnicodeText)
def __unicode__(self):
return self.name
# Delete hooks for models, delete files if models are getting deleted
@listens_for(File, 'after_delete')
def del_file(mapper, connection, target):
......@@ -94,7 +104,28 @@ def del_image(mapper, connection, target):
pass
# define a custom wtforms widget and field.
# see https://wtforms.readthedocs.io/en/latest/widgets.html#custom-widgets
class CKTextAreaWidget(widgets.TextArea):
def __call__(self, field, **kwargs):
# add WYSIWYG class to existing classes
existing_classes = kwargs.pop('class', '') or kwargs.pop('class_', '')
kwargs['class'] = '{} {}'.format(existing_classes, "ckeditor")
return super(CKTextAreaWidget, self).__call__(field, **kwargs)
class CKTextAreaField(fields.TextAreaField):
widget = CKTextAreaWidget()
# Administrative views
class PageView(sqla.ModelView):
form_overrides = {
'text': CKTextAreaField
}
create_template = 'create_page.html'
edit_template = 'edit_page.html'
class FileView(sqla.ModelView):
# Override form field to use Flask-Admin FileUploadField
form_overrides = {
......@@ -144,15 +175,15 @@ class UserView(sqla.ModelView):
rules.Field('city'),
# String is resolved to form field, so there's no need to explicitly use `rules.Field`
'country',
# Show macro from Flask-Admin lib.html (it is included with 'lib' prefix)
# Show macro that's included in the templates
rules.Container('rule_demo.wrap', rules.Field('notes'))
]
# Use same rule set for edit page
form_edit_rules = form_create_rules
create_template = 'rule_create.html'
edit_template = 'rule_edit.html'
create_template = 'create_user.html'
edit_template = 'edit_user.html'
# Flask views
......@@ -166,7 +197,8 @@ admin = Admin(app, 'Example: Forms', template_mode='bootstrap3')
# Add views
admin.add_view(FileView(File, db.session))
admin.add_view(ImageView(Image, db.session))
admin.add_view(UserView(User, db.session, name='User'))
admin.add_view(UserView(User, db.session))
admin.add_view(PageView(Page, db.session))
def build_sample_db():
......@@ -242,6 +274,10 @@ def build_sample_db():
file.path = "example_" + str(i) + ".pdf"
db.session.add(file)
sample_text = "<h2>This is a test</h2>" + \
"<p>Create HTML content in a text area field with the help of <i>WTForms</i> and <i>CKEditor</i>.</p>"
db.session.add(Page(name="Test Page", text=sample_text))
db.session.commit()
return
......
Flask
Flask-Admin
Flask-SQLAlchemy
pillow==2.9.0
pillow
{% extends 'admin/model/create.html' %}
{% import 'rule_demo.html' as rule_demo %}
\ No newline at end of file
{% import 'macros.html' as rule_demo %}
{% extends 'admin/model/edit.html' %}
{% import 'rule_demo.html' as rule_demo %}
{% import 'macros.html' as rule_demo %}
This example shows how you can turn a TextArea field into a rich WYSIWYG editor using WTForms and CKEditor.
To run this example:
1. Clone the repository::
git clone https://github.com/flask-admin/flask-admin.git
cd flask-admin
2. Create and activate a virtual environment::
virtualenv env
source env/bin/activate
3. Install requirements::
pip install -r 'examples/wysiwyg/requirements.txt'
4. Run the application::
python examples/wysiwyg/app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from wtforms import fields, widgets
import flask_admin as admin
from flask_admin.contrib import sqla
# Create application
app = Flask(__name__)
# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'
# Create in-memory database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sample_db.sqlite'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
''' Define a wtforms widget and field.
WTForms documentation on custom widgets:
https://wtforms.readthedocs.io/en/latest/widgets.html#custom-widgets
'''
class CKTextAreaWidget(widgets.TextArea):
def __call__(self, field, **kwargs):
# add WYSIWYG class to existing classes
existing_classes = kwargs.pop('class', '') or kwargs.pop('class_', '')
kwargs['class'] = u'%s %s' % (existing_classes, "ckeditor")
return super(CKTextAreaWidget, self).__call__(field, **kwargs)
class CKTextAreaField(fields.TextAreaField):
widget = CKTextAreaWidget()
# Model
class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64))
text = db.Column(db.UnicodeText)
def __unicode__(self):
return self.name
# Customized admin interface
class PageAdmin(sqla.ModelView):
form_overrides = dict(text=CKTextAreaField)
create_template = 'create.html'
edit_template = 'edit.html'
# Flask views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
if __name__ == '__main__':
# Create admin
admin = admin.Admin(app, name="Example: WYSIWYG")
# Add views
admin.add_view(PageAdmin(Page, db.session))
# Create DB
db.create_all()
# Start app
app.run(debug=True)
Flask
Flask-Admin
Flask-SQLAlchemy
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment