From 2485c9b620245cbdcbfad649307a62678e9a0f6e Mon Sep 17 00:00:00 2001 From: Grey Li Date: Mon, 9 Sep 2024 08:46:56 +0800 Subject: [PATCH] Add flask-ckeditor example --- examples/ckeditor/.flaskenv | 1 + examples/ckeditor/app.py | 37 ++++++++++ examples/ckeditor/static/favicon.ico | Bin 0 -> 5558 bytes examples/ckeditor/static/style.css | 88 +++++++++++++++++++++++ examples/ckeditor/templates/article.html | 8 +++ examples/ckeditor/templates/base.html | 38 ++++++++++ examples/ckeditor/templates/index.html | 18 +++++ examples/ckeditor/templates/macros.html | 9 +++ pdm.lock | 35 +++++++-- pyproject.toml | 1 + requirements/v2.txt | 12 +++- 11 files changed, 239 insertions(+), 8 deletions(-) create mode 100644 examples/ckeditor/.flaskenv create mode 100644 examples/ckeditor/app.py create mode 100644 examples/ckeditor/static/favicon.ico create mode 100644 examples/ckeditor/static/style.css create mode 100644 examples/ckeditor/templates/article.html create mode 100644 examples/ckeditor/templates/base.html create mode 100644 examples/ckeditor/templates/index.html create mode 100644 examples/ckeditor/templates/macros.html diff --git a/examples/ckeditor/.flaskenv b/examples/ckeditor/.flaskenv new file mode 100644 index 00000000..068d27fd --- /dev/null +++ b/examples/ckeditor/.flaskenv @@ -0,0 +1 @@ +FLASK_DEBUG=1 diff --git a/examples/ckeditor/app.py b/examples/ckeditor/app.py new file mode 100644 index 00000000..69c4e8b8 --- /dev/null +++ b/examples/ckeditor/app.py @@ -0,0 +1,37 @@ +import os + +from flask_ckeditor import CKEditor +from flask import Flask, render_template, flash +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField +from wtforms.validators import DataRequired, Length +from flask_ckeditor import CKEditorField +from bleach import clean + +app = Flask(__name__) +app.secret_key = os.getenv('SECRET_KEY', 'secret string') +ckeditor = CKEditor(app) + +def clean_html(html): + allowed_tags = ['a', 'abbr', 'b', 'br', 'blockquote', 'code', + 'del', 'div', 'em', 'img', 'p', 'pre', 'strong', + 'span', 'ul', 'li', 'ol'] + allowed_attributes = ['src', 'title', 'alt', 'href', 'class'] + return clean(html, tags=allowed_tags, attributes=allowed_attributes) + + +class ArticleForm(FlaskForm): + title = StringField('Title', validators=[DataRequired(), Length(1, 50)]) + body = CKEditorField('Body', validators=[DataRequired()]) + submit = SubmitField('Publish') + + +@app.route('/', methods=['GET', 'POST']) +def index(): + form = ArticleForm() + if form.validate_on_submit(): + title = form.title.data + body = clean_html(form.body.data) + flash('Your article is published!') + return render_template('article.html', title=title, body=body) + return render_template('index.html', form=form) diff --git a/examples/ckeditor/static/favicon.ico b/examples/ckeditor/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..096f17960c5157d6194ab4f8f9d31f73e370ccd8 GIT binary patch literal 5558 zcmd^DTPSr~6kZ!eZf&{Ww@cb73ArnhL@2xxUYH!GJl61$<#)Az5BtCSZ?`kEFA+6KhCRR1}$+nITV4Pvqt0g{-Zuu^eF0 z-Q3(LJ~A?r^4PWJvt^`I&Teb(zG+#l=zl z$;k=X-`}Ucy}eDqcXoDYuBWHRBtAJgnbu@xW=d)-EiGxTx3^c4gRz6Br>E1J+}vDA zjh&qx%?%6;NOFkJ&d#Pa1qB6?8u$-_4G#}Xa){5%%cC_F6&1w7!s1_b9v&VvH$6Q~ z;93xaab#qK+}zyI8u*x>pJz3dm6ZhkJ7~AJx5V7s9P{+qv$wY=dcB^xm6a9diM6#g z>xUX!TU*Qlwn_A#d45Is*A3U1)87@_vyR!O!0&E z-~XY$MBCfjo0OE4nDm^S98=dq;Q3a<`uX{p#Ns`GXZ-#B9Ulovgn8cI-(QwzcXwA( z&vy(C4$9(C8>5$(7bz_*C6kkr3=VVT`T057+S(%V@$s@e@cbtxCX&|HR&sWBMzL@$ z@LV4r9xBc;sLe;5_kpOqyj)h3ujkvdv$ItH`ubWEj^_vu52qaP0dpUp`>egVxJa@0 z_xGA`Ja0@)4AZZws?x->w6sLA4-XHTaJ)YJmT1-0)tY$L*VifZ_4QQ~j@M61OG9~5 zTU)D%2i9gZGcz+ySR4bco4`|7SEq^N;NSq|W!FX2P>T8a`HVwpehnJ&!VupWH$(a})?dpzF9#>N;98UX(Ms6UO4;;J|RufOYKS7}b35?(SwhaG%v+ zpvKkJmEoWf78a%&%WL%Y^)a5QsVUVQu!rIe&Z#`F+V;@U5Tk)}u3B7RU?9Um!_h#@D6~_DYfDE<}EcfRW+99otv9uG<$n{ z#M9H0p0{*5ogyE+C*TeC#4au_s@6exM*;iC)zwwP&!IdY{|*Gl3+Ke5q9QUeF+umK zd_A_`-rk6fjg8{iH#Rn~++<8iNs(}5Wo4PH$HdCYiUfz_#|ZCg;60F%%iVuC7b{^P s2lEo@aPe23J3s1!_8;6>KIXss`=6pVoPmEA{rne>gFkw*UYD literal 0 HcmV?d00001 diff --git a/examples/ckeditor/static/style.css b/examples/ckeditor/static/style.css new file mode 100644 index 00000000..9bcb52e0 --- /dev/null +++ b/examples/ckeditor/static/style.css @@ -0,0 +1,88 @@ +body { + margin: auto; + width: 750px; +} + +nav ul { + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; + background-color: #333; +} + +nav li { + float: left; +} + +nav li a { + display: block; + color: white; + text-align: center; + padding: 14px 16px; + text-decoration: none; +} + +nav li a:hover { + background-color: #111; +} + +main { + padding: 10px 20px; +} + +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; +} + +.error { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} + +.note { + padding: 5px 10px 10px; + border-left: solid 2px #bbb; + margin-bottom: 20px; +} + +.note form { + display: inline; +} + +.info { + color: grey; +} + +.btn { + font-family: Arial; + font-size: 12px; + padding: 5px 8px; + text-decoration: none; + cursor: pointer; + background-color: white; + color: black; + border: 1px solid #999999; +} + +.btn:hover { + text-decoration: none; + border: 1px solid black; +} + +footer { + font-size: 13px; + color: #888; + border-top: 1px solid #eee; + margin-top: 25px; + text-align: center; + padding: 20px; +} diff --git a/examples/ckeditor/templates/article.html b/examples/ckeditor/templates/article.html new file mode 100644 index 00000000..4b75d1ef --- /dev/null +++ b/examples/ckeditor/templates/article.html @@ -0,0 +1,8 @@ +{% extends 'base.html' %} + +{% block title %}{{ title }}{% endblock %} + +{% block content %} +

{{ title }}

+

{{ body|safe }}

+{% endblock %} diff --git a/examples/ckeditor/templates/base.html b/examples/ckeditor/templates/base.html new file mode 100644 index 00000000..292ec78b --- /dev/null +++ b/examples/ckeditor/templates/base.html @@ -0,0 +1,38 @@ + + + + + {% block head %} + + {% block title %}HelloFlask - CKEditor Example{% endblock %} + + {% block styles %} + + {% endblock %} + {% endblock %} + + + + +
+ {% for message in get_flashed_messages() %} +
{{ message }}
+ {% endfor %} + {% block content %}{% endblock %} +
+ + {% block scripts %}{% endblock %} + + + diff --git a/examples/ckeditor/templates/index.html b/examples/ckeditor/templates/index.html new file mode 100644 index 00000000..33c500a2 --- /dev/null +++ b/examples/ckeditor/templates/index.html @@ -0,0 +1,18 @@ +{% extends 'base.html' %} +{% from 'macros.html' import form_field %} + +{% block content %} +

New Article

+
+ {{ form.csrf_token }} + {{ form_field(form.title) }} + {{ form_field(form.body) }} + {{ form.submit }} +
+{% endblock %} + +{% block scripts %} +{{ super() }} +{{ ckeditor.load() }} +{{ ckeditor.config(name='body') }} +{% endblock %} diff --git a/examples/ckeditor/templates/macros.html b/examples/ckeditor/templates/macros.html new file mode 100644 index 00000000..ae7da4b2 --- /dev/null +++ b/examples/ckeditor/templates/macros.html @@ -0,0 +1,9 @@ +{% macro form_field(field) %} +{{ field.label }}
+{{ field(**kwargs) }}
+{% if field.errors -%} +{% for error in field.errors -%} +{{ error }}
+{%- endfor %} +{%- endif %} +{% endmacro %} diff --git a/pdm.lock b/pdm.lock index 01f60f06..576e9e67 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev", "docs"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:9b4b0579d68835b9f6f7a3a3d70ff9f13d8a937e986b8fc71df342a574a6419d" +content_hash = "sha256:e2f616c368c07d18f35529a2062a89308fa941d969a147a91d3d34ea1fa89714" [[package]] name = "babel" @@ -21,6 +21,21 @@ files = [ {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] +[[package]] +name = "bleach" +version = "6.1.0" +requires_python = ">=3.8" +summary = "An easy safelist-based HTML-sanitizing tool." +groups = ["default"] +dependencies = [ + "six>=1.9.0", + "webencodings", +] +files = [ + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, +] + [[package]] name = "blinker" version = "1.8.2" @@ -408,15 +423,15 @@ files = [ [[package]] name = "flask-ckeditor" -version = "0.5.1" +version = "1.0.0" summary = "CKEditor integration for Flask." groups = ["default"] dependencies = [ "Flask", ] files = [ - {file = "Flask-CKEditor-0.5.1.tar.gz", hash = "sha256:15c8a54a0967cc51b6fa8191ab5fa042e7ee486d6d420c4d5f509a357557c278"}, - {file = "Flask_CKEditor-0.5.1-py2.py3-none-any.whl", hash = "sha256:330b10f1364a5ef990fd1de72429bb03e4a1ab6ee3aec85f7b38656315dd07fd"}, + {file = "Flask_CKEditor-1.0.0-py2.py3-none-any.whl", hash = "sha256:1a4aa871b510100df7bb8401b71cdcddfe1fd6d860649bc3760d0d43df485d72"}, + {file = "flask_ckeditor-1.0.0.tar.gz", hash = "sha256:e1737ca180ea0d46d53226f888f4786589f2e8ed810694aaff2aa68dfad15a98"}, ] [[package]] @@ -1124,7 +1139,7 @@ name = "six" version = "1.16.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" summary = "Python 2 and 3 compatibility utilities" -groups = ["dev", "docs"] +groups = ["default", "dev", "docs"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1270,6 +1285,16 @@ files = [ {file = "webassets-2.0.tar.gz", hash = "sha256:167132337677c8cedc9705090f6d48da3fb262c8e0b2773b29f3352f050181cd"}, ] +[[package]] +name = "webencodings" +version = "0.5.1" +summary = "Character encoding aliases for legacy web content" +groups = ["default"] +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + [[package]] name = "werkzeug" version = "3.0.3" diff --git a/pyproject.toml b/pyproject.toml index 82e9df48..00caca01 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ dependencies = [ "flask-mailman>=1.1.0", "flask-caching>=2.3.0", "flask-assets>=2.1.0", + "bleach>=6.1.0", ] requires-python = ">=3.8" readme = "README.md" diff --git a/requirements/v2.txt b/requirements/v2.txt index ee3aa30a..373033bd 100644 --- a/requirements/v2.txt +++ b/requirements/v2.txt @@ -1,6 +1,9 @@ # This file is @generated by PDM. # Please do not edit it manually. +bleach==6.1.0 \ + --hash=sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe \ + --hash=sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6 blinker==1.8.2 \ --hash=sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01 \ --hash=sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83 @@ -90,9 +93,9 @@ flask-assets==2.1.0 \ flask-caching==2.3.0 \ --hash=sha256:51771c75682e5abc1483b78b96d9131d7941dc669b073852edfa319dd4e29b6e \ --hash=sha256:d7e4ca64a33b49feb339fcdd17e6ba25f5e01168cf885e53790e885f83a4d2cf -flask-ckeditor==0.5.1 \ - --hash=sha256:15c8a54a0967cc51b6fa8191ab5fa042e7ee486d6d420c4d5f509a357557c278 \ - --hash=sha256:330b10f1364a5ef990fd1de72429bb03e4a1ab6ee3aec85f7b38656315dd07fd +flask-ckeditor==1.0.0 \ + --hash=sha256:1a4aa871b510100df7bb8401b71cdcddfe1fd6d860649bc3760d0d43df485d72 \ + --hash=sha256:e1737ca180ea0d46d53226f888f4786589f2e8ed810694aaff2aa68dfad15a98 flask-mailman==1.1.0 \ --hash=sha256:1bb2b701cb332cf888962fd9d9155714f84b7f2c0d75a4d596548cae5d479bff \ --hash=sha256:538c94334f211f29d18fab5f5870c3711f8ded08d6fe93ca488b10d3e7c107e6 @@ -342,6 +345,9 @@ watchdog==4.0.1 \ webassets==2.0 \ --hash=sha256:167132337677c8cedc9705090f6d48da3fb262c8e0b2773b29f3352f050181cd \ --hash=sha256:a31a55147752ba1b3dc07dee0ad8c8efff274464e08bbdb88c1fd59ffd552724 +webencodings==0.5.1 \ + --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ + --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 werkzeug==3.0.3 \ --hash=sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18 \ --hash=sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8