django-visual-editor 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_visual_editor-0.1.1/LICENSE +21 -0
- django_visual_editor-0.1.1/MANIFEST.in +16 -0
- django_visual_editor-0.1.1/PKG-INFO +314 -0
- django_visual_editor-0.1.1/QUICKSTART.md +140 -0
- django_visual_editor-0.1.1/README.md +281 -0
- django_visual_editor-0.1.1/django_visual_editor/__init__.py +13 -0
- django_visual_editor-0.1.1/django_visual_editor/apps.py +7 -0
- django_visual_editor-0.1.1/django_visual_editor/fields.py +42 -0
- django_visual_editor-0.1.1/django_visual_editor/migrations/0001_initial.py +54 -0
- django_visual_editor-0.1.1/django_visual_editor/migrations/__init__.py +1 -0
- django_visual_editor-0.1.1/django_visual_editor/models.py +33 -0
- django_visual_editor-0.1.1/django_visual_editor/static/django_visual_editor/css/editor.css +2 -0
- django_visual_editor-0.1.1/django_visual_editor/static/django_visual_editor/js/editor.bundle.js +1 -0
- django_visual_editor-0.1.1/django_visual_editor/templates/django_visual_editor/widget.html +6 -0
- django_visual_editor-0.1.1/django_visual_editor/urls.py +8 -0
- django_visual_editor-0.1.1/django_visual_editor/views.py +45 -0
- django_visual_editor-0.1.1/django_visual_editor/widgets.py +39 -0
- django_visual_editor-0.1.1/django_visual_editor.egg-info/PKG-INFO +314 -0
- django_visual_editor-0.1.1/django_visual_editor.egg-info/SOURCES.txt +22 -0
- django_visual_editor-0.1.1/django_visual_editor.egg-info/dependency_links.txt +1 -0
- django_visual_editor-0.1.1/django_visual_editor.egg-info/requires.txt +2 -0
- django_visual_editor-0.1.1/django_visual_editor.egg-info/top_level.txt +1 -0
- django_visual_editor-0.1.1/pyproject.toml +77 -0
- django_visual_editor-0.1.1/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vladislav Khoboko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Include documentation
|
|
2
|
+
include README.md
|
|
3
|
+
include LICENSE
|
|
4
|
+
include QUICKSTART.md
|
|
5
|
+
|
|
6
|
+
# Include static files
|
|
7
|
+
recursive-include django_visual_editor/static *
|
|
8
|
+
recursive-include django_visual_editor/templates *
|
|
9
|
+
|
|
10
|
+
# Include migrations
|
|
11
|
+
recursive-include django_visual_editor/migrations *.py
|
|
12
|
+
|
|
13
|
+
# Exclude Python cache files
|
|
14
|
+
global-exclude __pycache__
|
|
15
|
+
global-exclude *.py[co]
|
|
16
|
+
global-exclude .DS_Store
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-visual-editor
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Visual text editor for Django with image upload, formatting and HTML compression
|
|
5
|
+
Author-email: Vladislav Khoboko <vladislah@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/hvlads/django-visual-editor
|
|
8
|
+
Project-URL: Repository, https://github.com/hvlads/django-visual-editor
|
|
9
|
+
Project-URL: Issues, https://github.com/hvlads/django-visual-editor/issues
|
|
10
|
+
Keywords: django,editor,wysiwyg,visual-editor,rich-text,html-editor
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Web Environment
|
|
13
|
+
Classifier: Framework :: Django
|
|
14
|
+
Classifier: Framework :: Django :: 5.2
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: django>=4.2
|
|
31
|
+
Requires-Dist: pillow>=10.0.0
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Django Visual Editor
|
|
35
|
+
|
|
36
|
+
A visual text editor for Django with image upload support, text formatting, and HTML compression.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- **Visual Editing**: Intuitive WYSIWYG editor
|
|
41
|
+
- **Text Formatting**:
|
|
42
|
+
- Bold, Italic, Underline, Strikethrough
|
|
43
|
+
- Font family selection (Arial, Times New Roman, Georgia, Courier New, etc.)
|
|
44
|
+
- Font size selection (10px - 24px)
|
|
45
|
+
- Clear formatting
|
|
46
|
+
- **Headings**: H1, H2, H3
|
|
47
|
+
- **Lists**: Numbered and bulleted lists
|
|
48
|
+
- **Code**:
|
|
49
|
+
- Inline code (`<code>` tag) with toggle support
|
|
50
|
+
- Code blocks (pre+code) for multi-line code
|
|
51
|
+
- **Images**: Upload via drag-and-drop, paste, or file picker
|
|
52
|
+
- Resize images by dragging or using preset sizes (S, M, L, XL)
|
|
53
|
+
- Align images (left, center, right)
|
|
54
|
+
- Delete images
|
|
55
|
+
- **Links**: Create hyperlinks
|
|
56
|
+
- **Undo/Redo**: Full history support (Ctrl+Z, Ctrl+Y)
|
|
57
|
+
- **HTML Source Mode**: Toggle between visual and HTML code editing
|
|
58
|
+
- **HTML Compression**: Automatic conversion to compact HTML with inline styles
|
|
59
|
+
- **Keyboard Shortcuts**: Ctrl+B (Bold), Ctrl+I (Italic), Ctrl+U (Underline), Ctrl+Z (Undo), Ctrl+Y (Redo)
|
|
60
|
+
- **Auto Cleanup**: Command to remove unused images
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
### 1. Install Dependencies
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Install Python dependencies
|
|
68
|
+
pip install django Pillow
|
|
69
|
+
|
|
70
|
+
# Install Node.js dependencies for frontend build
|
|
71
|
+
cd frontend
|
|
72
|
+
npm install
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Build Frontend
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cd frontend
|
|
79
|
+
npm run build
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
For development with automatic rebuild:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm run dev
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Configure Django
|
|
89
|
+
|
|
90
|
+
Add to `settings.py`:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
INSTALLED_APPS = [
|
|
94
|
+
...
|
|
95
|
+
'django_visual_editor',
|
|
96
|
+
...
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
# Media files settings
|
|
100
|
+
MEDIA_URL = 'media/'
|
|
101
|
+
MEDIA_ROOT = BASE_DIR / 'media'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Add URL to `urls.py`:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from django.conf import settings
|
|
108
|
+
from django.conf.urls.static import static
|
|
109
|
+
|
|
110
|
+
urlpatterns = [
|
|
111
|
+
...
|
|
112
|
+
path('editor/', include('django_visual_editor.urls')),
|
|
113
|
+
...
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
if settings.DEBUG:
|
|
117
|
+
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 4. Run Migrations
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
python manage.py migrate
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Usage
|
|
127
|
+
|
|
128
|
+
### Option 1: Using VisualEditorField (Recommended)
|
|
129
|
+
|
|
130
|
+
The simplest way - just use the field in your model:
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from django.db import models
|
|
134
|
+
from django_visual_editor import VisualEditorField
|
|
135
|
+
|
|
136
|
+
class BlogPost(models.Model):
|
|
137
|
+
title = models.CharField(max_length=200)
|
|
138
|
+
content = VisualEditorField(
|
|
139
|
+
config={
|
|
140
|
+
'min_height': 400,
|
|
141
|
+
'max_height': 800,
|
|
142
|
+
'placeholder': 'Start typing...',
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then use it in forms and admin - no additional configuration needed:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# forms.py
|
|
151
|
+
from django import forms
|
|
152
|
+
from .models import BlogPost
|
|
153
|
+
|
|
154
|
+
class BlogPostForm(forms.ModelForm):
|
|
155
|
+
class Meta:
|
|
156
|
+
model = BlogPost
|
|
157
|
+
fields = ['title', 'content']
|
|
158
|
+
# Widget is automatically set from the field!
|
|
159
|
+
|
|
160
|
+
# admin.py
|
|
161
|
+
from django.contrib import admin
|
|
162
|
+
from .models import BlogPost
|
|
163
|
+
|
|
164
|
+
@admin.register(BlogPost)
|
|
165
|
+
class BlogPostAdmin(admin.ModelAdmin):
|
|
166
|
+
pass # Widget is automatically set from the field!
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Option 2: Using VisualEditorWidget Manually
|
|
170
|
+
|
|
171
|
+
If you prefer to use a regular TextField and configure the widget in forms:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
# models.py
|
|
175
|
+
from django.db import models
|
|
176
|
+
|
|
177
|
+
class BlogPost(models.Model):
|
|
178
|
+
title = models.CharField(max_length=200)
|
|
179
|
+
content = models.TextField() # Regular TextField
|
|
180
|
+
|
|
181
|
+
# forms.py
|
|
182
|
+
from django import forms
|
|
183
|
+
from django_visual_editor import VisualEditorWidget
|
|
184
|
+
from .models import BlogPost
|
|
185
|
+
|
|
186
|
+
class BlogPostForm(forms.ModelForm):
|
|
187
|
+
class Meta:
|
|
188
|
+
model = BlogPost
|
|
189
|
+
fields = ['title', 'content']
|
|
190
|
+
widgets = {
|
|
191
|
+
'content': VisualEditorWidget(
|
|
192
|
+
config={
|
|
193
|
+
'min_height': 400,
|
|
194
|
+
'max_height': 800,
|
|
195
|
+
'placeholder': 'Start typing...',
|
|
196
|
+
}
|
|
197
|
+
),
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# admin.py
|
|
201
|
+
from django.contrib import admin
|
|
202
|
+
from django_visual_editor import VisualEditorWidget
|
|
203
|
+
from .models import BlogPost
|
|
204
|
+
from django import forms
|
|
205
|
+
|
|
206
|
+
class BlogPostAdminForm(forms.ModelForm):
|
|
207
|
+
class Meta:
|
|
208
|
+
model = BlogPost
|
|
209
|
+
fields = '__all__'
|
|
210
|
+
widgets = {
|
|
211
|
+
'content': VisualEditorWidget(),
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@admin.register(BlogPost)
|
|
215
|
+
class BlogPostAdmin(admin.ModelAdmin):
|
|
216
|
+
form = BlogPostAdminForm
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### In Templates
|
|
220
|
+
|
|
221
|
+
```django
|
|
222
|
+
<!-- Display content -->
|
|
223
|
+
<div class="blog-content">
|
|
224
|
+
{{ post.content|safe }}
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<!-- Form -->
|
|
228
|
+
<form method="post">
|
|
229
|
+
{% csrf_token %}
|
|
230
|
+
{{ form.as_p }}
|
|
231
|
+
{{ form.media }} <!-- Important! Loads CSS and JS -->
|
|
232
|
+
<button type="submit">Save</button>
|
|
233
|
+
</form>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Configuration
|
|
237
|
+
|
|
238
|
+
Available configuration parameters for `VisualEditorWidget`:
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
VisualEditorWidget(
|
|
242
|
+
config={
|
|
243
|
+
'min_height': 300, # Minimum editor height (px)
|
|
244
|
+
'max_height': 600, # Maximum editor height (px)
|
|
245
|
+
'placeholder': 'Text...', # Placeholder text
|
|
246
|
+
}
|
|
247
|
+
)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Cleanup Unused Images
|
|
251
|
+
|
|
252
|
+
Run the management command to remove unused images:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Show what will be deleted (dry run)
|
|
256
|
+
python manage.py cleanup_editor_images --dry-run
|
|
257
|
+
|
|
258
|
+
# Delete unused images
|
|
259
|
+
python manage.py cleanup_editor_images
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
It's recommended to set up this command in cron for periodic cleanup.
|
|
263
|
+
|
|
264
|
+
## Example Project
|
|
265
|
+
|
|
266
|
+
Run the example blog:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
cd example_project
|
|
270
|
+
python manage.py migrate
|
|
271
|
+
python manage.py createsuperuser
|
|
272
|
+
python manage.py runserver
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Then open:
|
|
276
|
+
- http://localhost:8000/ - Post list
|
|
277
|
+
- http://localhost:8000/post/new/ - Create new post
|
|
278
|
+
- http://localhost:8000/admin/ - Django Admin
|
|
279
|
+
|
|
280
|
+
## Project Structure
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
django-visual-editor/
|
|
284
|
+
├── django_visual_editor/ # Django application
|
|
285
|
+
│ ├── models.py # Model for uploaded images
|
|
286
|
+
│ ├── widgets.py # Django widget
|
|
287
|
+
│ ├── views.py # View for image upload
|
|
288
|
+
│ ├── urls.py # URL configuration
|
|
289
|
+
│ ├── management/ # Management commands
|
|
290
|
+
│ ├── static/ # Static files (compiled)
|
|
291
|
+
│ └── templates/ # Templates
|
|
292
|
+
├── frontend/ # TypeScript sources
|
|
293
|
+
│ ├── src/
|
|
294
|
+
│ │ ├── editor/ # Main editor
|
|
295
|
+
│ │ ├── utils/ # Utils (upload, compression)
|
|
296
|
+
│ │ ├── types/ # TypeScript types
|
|
297
|
+
│ │ └── styles/ # CSS styles
|
|
298
|
+
│ ├── package.json
|
|
299
|
+
│ ├── tsconfig.json
|
|
300
|
+
│ └── webpack.config.js
|
|
301
|
+
└── example_project/ # Usage example
|
|
302
|
+
└── blog/ # Demo blog application
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Technologies
|
|
306
|
+
|
|
307
|
+
- **Backend**: Django 5.2+
|
|
308
|
+
- **Frontend**: TypeScript, Webpack
|
|
309
|
+
- **Editor**: Custom implementation using ContentEditable API
|
|
310
|
+
- **Styles**: Vanilla CSS
|
|
311
|
+
|
|
312
|
+
## License
|
|
313
|
+
|
|
314
|
+
MIT
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Quick Start
|
|
2
|
+
|
|
3
|
+
Quick start guide for Django Visual Editor.
|
|
4
|
+
|
|
5
|
+
## 1. Install Dependencies
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install Python dependencies
|
|
9
|
+
uv sync
|
|
10
|
+
|
|
11
|
+
# Go to frontend directory
|
|
12
|
+
cd frontend
|
|
13
|
+
|
|
14
|
+
# Install Node.js dependencies
|
|
15
|
+
npm install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 2. Build Frontend
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# From the frontend directory
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
After building, files will appear in `django_visual_editor/static/django_visual_editor/js/`
|
|
26
|
+
|
|
27
|
+
## 3. Run Example Project
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Go back to project root
|
|
31
|
+
cd ..
|
|
32
|
+
|
|
33
|
+
# Go to example_project
|
|
34
|
+
cd example_project
|
|
35
|
+
|
|
36
|
+
# Run migrations
|
|
37
|
+
python manage.py migrate
|
|
38
|
+
|
|
39
|
+
# Create superuser
|
|
40
|
+
python manage.py createsuperuser
|
|
41
|
+
|
|
42
|
+
# Run server
|
|
43
|
+
python manage.py runserver
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 4. Open in Browser
|
|
47
|
+
|
|
48
|
+
- **Blog homepage**: http://localhost:8000/
|
|
49
|
+
- **Create post**: http://localhost:8000/post/new/ (login required)
|
|
50
|
+
- **Django Admin**: http://localhost:8000/admin/
|
|
51
|
+
|
|
52
|
+
## 5. Test the Editor
|
|
53
|
+
|
|
54
|
+
1. Login through the admin panel
|
|
55
|
+
2. Create a new post at http://localhost:8000/post/new/
|
|
56
|
+
3. Try:
|
|
57
|
+
- Font selection (dropdown in toolbar)
|
|
58
|
+
- Font size selection (dropdown in toolbar)
|
|
59
|
+
- Text formatting (Bold, Italic, Underline, Strikethrough)
|
|
60
|
+
- Creating headings (H1, H2, H3)
|
|
61
|
+
- Lists (bulleted and numbered)
|
|
62
|
+
- Code:
|
|
63
|
+
- Inline code (click `<code>` button) - toggle on/off
|
|
64
|
+
- Code blocks (click `{ }` button) for multi-line code
|
|
65
|
+
- Image upload (drag-and-drop or button)
|
|
66
|
+
- Click on uploaded images to resize and align them
|
|
67
|
+
- Use preset sizes: S (25%), M (50%), L (75%), XL (100%)
|
|
68
|
+
- Align images: left, center, or right
|
|
69
|
+
- Drag the resize handle to custom size
|
|
70
|
+
- Creating links
|
|
71
|
+
- Clear formatting (✕ button)
|
|
72
|
+
- Undo/Redo (↶ ↷ buttons)
|
|
73
|
+
- HTML Source mode (click </> button)
|
|
74
|
+
- Keyboard shortcuts: Ctrl+B, Ctrl+I, Ctrl+U, Ctrl+Z, Ctrl+Y
|
|
75
|
+
|
|
76
|
+
## Frontend Development
|
|
77
|
+
|
|
78
|
+
For development with automatic rebuild:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd frontend
|
|
82
|
+
npm run dev
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Webpack will watch for changes and automatically rebuild files.
|
|
86
|
+
|
|
87
|
+
## Cleanup Unused Images
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
cd example_project
|
|
91
|
+
|
|
92
|
+
# Show what will be deleted
|
|
93
|
+
python manage.py cleanup_editor_images --dry-run
|
|
94
|
+
|
|
95
|
+
# Delete unused images
|
|
96
|
+
python manage.py cleanup_editor_images
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## File Structure
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
django-visual-editor/
|
|
103
|
+
├── django_visual_editor/ # Main Django application
|
|
104
|
+
│ ├── models.py # EditorImage model
|
|
105
|
+
│ ├── widgets.py # VisualEditorWidget
|
|
106
|
+
│ ├── views.py # View for uploads
|
|
107
|
+
│ └── static/ # Compiled JS/CSS
|
|
108
|
+
├── frontend/ # TypeScript sources
|
|
109
|
+
│ ├── src/
|
|
110
|
+
│ │ ├── editor/ # Editor and toolbar
|
|
111
|
+
│ │ ├── utils/ # Upload and HTML compression
|
|
112
|
+
│ │ └── styles/ # CSS
|
|
113
|
+
│ └── package.json
|
|
114
|
+
└── example_project/ # Usage example
|
|
115
|
+
└── blog/ # Blog with VisualEditor
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Troubleshooting
|
|
119
|
+
|
|
120
|
+
### Error uploading images
|
|
121
|
+
|
|
122
|
+
Check:
|
|
123
|
+
1. Is Pillow installed: `pip install Pillow`
|
|
124
|
+
2. Are MEDIA_ROOT and MEDIA_URL configured in settings.py
|
|
125
|
+
3. Are media URLs added to urls.py for DEBUG mode
|
|
126
|
+
|
|
127
|
+
### Editor not displaying
|
|
128
|
+
|
|
129
|
+
Check:
|
|
130
|
+
1. Is frontend built: `cd frontend && npm run build`
|
|
131
|
+
2. Does file `django_visual_editor/static/django_visual_editor/js/editor.bundle.js` exist
|
|
132
|
+
3. Is `{{ form.media }}` added to the template
|
|
133
|
+
|
|
134
|
+
### TypeScript errors during build
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
cd frontend
|
|
138
|
+
npm install
|
|
139
|
+
npm run type-check
|
|
140
|
+
```
|