My dear reader, how are you? السلام عليكم

Greatness is what happens when you aren’t afraid to relentlessly push yourself to tear down all your walls of limitations ― Edmond Mbiaka

This post explains the integration of Ace code editor with Django.


Few useful links to practically follow the project:

  1. Django-Ace-Integration GitHub repository — DirectMe
  2. Clone the application from GitHub using
git clone https://github.com/ArsalanShahid116/Django-Ace-Integration

SETTING-UP DJANGO PROJECT

Django-Ace-Integration$ virtualenv aceenv 
Django-Ace-Integration$ source aceenv/bin/activate
(aceenv)Django-Ace-Integration$ pip3 install django
(aceenv)Django-Ace-Integration$ pip3 freeze > requirements.txt

# Create a Django project
(aceenv)Django-Ace-Integration$ django-admin startproject config 

# Change project name
(aceenv)Django-Ace-Integration$ mv config DjangoAce
(aceenv)Django-Ace-Integration$ cd DjangoAce  
(aceenv)Django-Ace-Integration/DjangoAce$ django-admin startapp coder

# list the qanda application in the list of installed apps in settings.py of project in config directory as shown below

INSTALLED_APPS = [
'coder', # add this
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

# Configure Django project to use PostgreSQL. 
# open DjangoAce/config/settings.py and update the following DATABASE variable as follows

DATABASES = {
        'default':
            {
                'ENGINE': 'django.db.backends.postgresql',
                'NAME': 'mymdb',
                'USER': 'mymdb',
                'PASSWORD': 'development',
                'HOST': '127.0.0.1',
                'PORT': '5432',
            }
}

# Configure Django project-wide templates and static files.  
# open DjangoAce/config/settings.py and update the following DATABASE variable as follows 

STATISFILES_DIR = [os.path.join(BASE_DIR, 'static'),]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'),], # add this
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
(aceenv)Django-Ace-Integration/DjangoAce$ pip3 install psycopg2
(aceenv)Django-Ace-Integration/DjangoAce$ python3 manage.py makemigrations
(aceenv)Django-Ace-Integration/DjangoAce$ python3 manage.py migrate
(aceenv)Django-Ace-Integration/DjangoAce$ python3 manage.py runserver


Check if development server is working by entering the following URL in browser http://127.0.0.1:8000/. It should be giving you something as shown in Figure 1. If it does, you are doing great. cheers!

A detail on individual Django project files is given in one of my earlier posts at DirectMe

Image result for django welcome page

Fig 1: Django Welcome Page


Follow the steps below to integrate Ace Code Editor into your Django Projects.

1) First of all, we will create a model as shown below

# open coder/models.py and add the following program

from django.db import models
from django.conf import settings

class Code(models.Model):
    title = models.CharField(max_length=250)
    program = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title

2) Register model in Django admin

# open coder/admin.py and add the following program

from django.contrib import admin
from .models import Code

admin.site.register(Code)

3) Create a form to submit programs as shown below

# Create coder/forms.py and add the following program

from django import forms
from .models import Code

class CodeForm(forms.ModelForm):
    class Meta:
        model = Code
        fields = ('program', 'title')
        widgets = {
                "program": forms.Textarea(),
            }

4) Add a view for the forms as shown below

# Create coder/views.py and add the following program

from django.shortcuts import render
from django.http import HttpResponse
from .forms import CodeForm
from .models import Code

def add_code(request):
    if request.method == 'POST':
        form = CodeForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponse('Program added to database')
        else:
            return HttpResponse('not valid')
    else:  # display empty form
        form = CodeForm()

    return render(request, 'coder/add_code.html', {'code_form': form})

5) Let us now add a template

# Create coder/templates/coder/add_code.html and add the following program

{% extends "base.html" %}

<title>{% block title %}DjangoAce{% endblock %}</title>

{% block content %}

<form id="coder_form" class="form" method="post">
        {% csrf_token %}

        <div>
                Program title: <input type="text" name="title" required id="id_program"> <br> <br>
        </div>

        <div id="mydiv">
                <textarea data-editor="twilight" name="program" cols="200" rows="20" required id="id_program">
        </textarea>
        </div>

        <div>
        <input type="Submit" name="Submit" value="Submit"/>
        </div>
</form>

{% endblock %}

6) Let us now add a base template as shown below

# create coder/base.html and add the following program

{% load static %}
<!DOCTYPE html>
<html>
<head>
        <title>{% block title %}{% endblock %}</title>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"
        integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
        rel="stylesheet" crossorigin="anonymous">

<style>
textarea{
        height: 100%;
        width: 100%;
        -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
        -moz-box-sizing: border-box;    /* Firefox, other Gecko */
        box-sizing: border-box;         /* Opera/IE 8+ */
}

#mydiv{
        height: 500px;
        width: 1000px;
}
</style>

</head>

<body>
        <header>
        <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
        <div class="navbar-brand">DjangoAce</div>
        </nav>
        </header>
        <br />
        <br />
        <br />
        <br />

        <div class="container">
        <div id="content">
                {% block content %}
                {% endblock %}
        </div>

<script src="{% static "ace/ace.js" %}"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

        <script>
                $(function () {
                    $('textarea[data-editor]').each(function () {
                var textarea = $(this);
                var theme = textarea.data('editor');
                var editDiv = $('<div>', {
                    position: 'absolute',
                    width: textarea.width(),
                    height: textarea.height(),
                   'class': textarea.attr('class')
                 }).insertBefore(textarea);

                textarea.css('visibility', 'hidden');
                ace.require("ace/ext/language_tools");
                var editor = ace.edit(editDiv[0]);

                editor.setOptions({enableLiveAutocompletion: true, cursorStyle: 'ace', showGutter: true, showLineNumbers: true});
                editor.setFontSize(16);
                editor.getSession().setValue(textarea.val());
                editor.getSession().setMode("ace/mode/python");
                editor.setTheme("ace/theme/" + theme);

                textarea.closest('form').submit(function () {
                textarea.val(editor.getSession().getValue());
            })
          });
        });
</script>

</body>
</html>

7) Add statis files. Create a directory in coder/static, name it as ace and add the ace source files from the following link DirectMe into it.

8) Add a route to the application and views as shown below

# Open coder/urls.py and add the following program 

from django.urls import path
from . import views
from django.contrib.auth import views as auth_views

urlpatterns = [
        path('add', views.add_code, name='add_code'),
        ]

# open config/urls.py and add the following program 

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

import coder.urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('coder/', include('coder.urls')),
]

If you run the development server at this point in time you should be able to see the added functionalities at http://127.0.0.1:8000/coder/add


I hope you find this tutorial useful. If you find any errors or feel any need for improvement, let me know in your comments below.

Signing off for today. Stay tuned and I will see you next week! Happy learning.

LEAVE A REPLY

Please enter your comment!
Please enter your name here