Integrating CKEditor in Django Admin and Rendering HTML in a template - Django Blog #4
Hello Internet People, today we integrate CKEditor in Django admin. CKEditor is a rich text editor. So, activate your virtual environment.
Install ckeditor django package
Just type following command to install,
pip3 install django-ckeditor
Now mention ckeditor in INSTALLED_APP in settings.py like following,
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
'ckeditor', #this
]
Settings for media upload
open settings.py and add following at last
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media/"
Add ckeditor uploader in the INSTALLED_APP
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
'ckeditor',
'ckeditor_uploader', #this
]
Now set the upload path for ckeditor in settings.py. add following code at last,
#ckeditor upload path
CKEDITOR_UPLOAD_PATH="uploads/"
This uploads directory will automatically create inside media directory of the root directory
Setup url
Open urls.py of awwblog and make look like following,
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls', namespace='blog')),
path('ckeditor/',include('ckeditor_uploader.urls')),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Change in model
We must change in model to get rich text editor in admin. Open models.py of blog application and make change like following,
make change in Post model like following,
from ckeditor_uploader.fields import RichTextUploadingField #import this
class Post(models.Model):
...
# body = models.TextField() # remove this
body=RichTextUploadingField() # add this
Now run migrations,
python3 manage.py makemigrations
and migrate,
python3 manage.py migrate
run development server using python3 manage.py runserver and open http://127.0.0.1:8000/admin and click on add post or open any other posts, you can notice, rich text editor now here in body field,
Now you can add headings, bullets, bold text, images, etc.
Let’s add post with headings and image.
Now open blog post which you added with ckeditor, here you can notice HTML tags are not rendering.
Filter and Tag in HTML template
To fix this we add safe filter in post_detail.html. So open post_detail.html and make following change,
<div class="article-body">
{{post.body|safe}} <!-- remove linebreaks -->
</div>
Now again go to that post and refresh the page,
But there is one problem too in home page,
Open post_list.html and make following change,
...
<p class="card-text mb-auto py-2">{{ post.body|safe|striptags|truncatechars:100 }}</p>
<div>
<a href="{{ post.get_absolute_url }}" class="btn btn-primary btn-sm">Read more</a>
</div>
...
Now you can see we get desire output,
Customizing CKEditor
As you can notice in the above CKEditor, there are enough functions to edit the content but we can add the function to it like source code highlighter. So let’s add more functionality,
open settings.py and add following code,
before that open this link and configure your CKEditor, add or remove whatever you want.
now open settings.py and add following code at last,
CKEDITOR_CONFIGS = {
'default': {
# 'skin': 'moono',
# # 'skin': 'office2013',
# 'toolbar_Basic': [
# ['Source', '-', 'Bold', 'Italic']
# ],
'toolbar_Custom': [
{'name': 'document', 'items': ['Source', '-', 'Save', 'NewPage', 'Preview', 'Print', '-', 'Templates']},
{'name': 'clipboard', 'items': ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo']},
{'name': 'editing', 'items': ['Find', 'Replace', '-', 'SelectAll']},
{'name': 'forms',
'items': ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton',
'HiddenField']},
'/',
{'name': 'basicstyles',
'items': ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']},
{'name': 'paragraph',
'items': ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-',
'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl',
'Language']},
{'name': 'links', 'items': ['Link', 'Unlink', 'Anchor']},
{'name': 'insert',
'items': ['Image', 'Youtube','Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe']},
'/',
{'name': 'styles', 'items': ['Styles', 'Format', 'Font', 'FontSize']},
{'name': 'colors', 'items': ['TextColor', 'BGColor']},
{'name': 'tools', 'items': ['Maximize', 'ShowBlocks']},
{'name': 'about', 'items': ['CodeSnippet']},
{'name': 'about', 'items': ['About']},
'/', # put this to force next toolbar on new line
{'name': 'yourcustomtools', 'items': [
# put the name of your editor.ui.addButton here
'Preview',
'Maximize',
]},
],
'toolbar': 'Custom', # put selected toolbar config here
'toolbarGroups': [{ 'name': 'document', 'groups': [ 'mode', 'document', 'doctools' ] }],
'height': 400,
# 'width': '100%',
'filebrowserWindowHeight': 725,
'filebrowserWindowWidth': 940,
'toolbarCanCollapse': True,
'mathJaxLib': '//cdn.mathjax.org/mathjax/2.2-latest/MathJax.js?config=TeX-AMS_HTML',
'tabSpaces': 4,
'extraPlugins': ','.join([
'uploadimage', # the upload image feature
# your extra plugins here
'div',
'autolink',
'autoembed',
'embedsemantic',
'autogrow',
'devtools',
'widget',
'lineutils',
'clipboard',
'dialog',
'dialogui',
'elementspath',
'codesnippet',
]),
}
}
Now open admin and you see following change,
You can now add more functions too in your content, one of them is code highlighter,
let’s see the example,
Now this working fine but let’s see in the post,
This not looks good right. So, let’s fix it.
We solve this with using highlight.js. Open base.html and add following CDN url and scripts in head tag,
<!-- highlight js -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/monokai-sublime.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
Now refresh the blog post page and you notice the change like following,
It’s looks good right. You can also add other code highlighter js library too according to your need.
add this css to make image responsive inside our post.
article img{
max-width: 100% !important;
height: auto !important;
border-radius: .25rem!important;
}
Note: You can also add bootstrap class using javascript. But I choose this way.
We learned many things today. Hope you are enjoying this series.
GitHub Link: https://github.com/SoniArpit/awwblog
Previous: Displaying List of Posts and Single Post on a Web page and Pagination – Django Blog #3