Skip to content

Commit d592605

Browse files
authored
Merge pull request #137 from agusmakmun/development
Development
2 parents f236d06 + 2e74b89 commit d592605

31 files changed

+831
-765
lines changed

.github/FUNDING.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
github: [agusmakmun]
2+
patreon:
3+
ko_fi:
4+
liberapay:
5+
issuehunt:
6+
custom: ['https://www.paypal.me/summonagus']

README.md

Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
## martor [![pypi version][1]][2] [![paypal donation][3]][4]
2+
3+
[![license][5]][6] [![python version][7]][8] [![django version][9]][10] [![build][11]][12]
4+
5+
**Martor** is a Markdown Editor plugin for Django, supported for _Bootstrap_ & _Semantic-UI_.
6+
7+
8+
### Features
9+
10+
* Live Preview
11+
* Integrated with [_Ace Editor_](https://ace.c9.io)
12+
* Supported with [_Bootstrap_](https://getbootstrap.com) and [_Semantic-UI_](https://semantic-ui.com)
13+
* Supported Multiple Fields [_fixed this issue_](https://github.com/agusmakmun/django-markdown-editor/issues/3)
14+
* Upload Images to imgur.com _(via API)_ and [custom uploader][13]
15+
* Direct Mention users `@[username]` - _(requires user to logged in)_.
16+
* Supports embed/iframe video from (Youtube, Vimeo, Dailymotion, Yahoo, Veoh, & Metacafe)
17+
* Spellchecking (only supports US English at this time)
18+
* Emoji `:emoji_name:` + Cheat sheets
19+
* Martor Commands Reference
20+
* Supports Django Admin
21+
* Toolbar Buttons
22+
* Highlight `pre`
23+
24+
25+
### Preview
26+
27+
![editor](https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/.etc/images/bootstrap/martor-editor.png)
28+
29+
![preview](https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/.etc/images/bootstrap/martor-preview.png)
30+
31+
32+
### Requirements
33+
34+
* `Django>=2.0`
35+
* `Markdown>=3.0`
36+
* `requests>=2.12.4`
37+
38+
39+
### Installation
40+
41+
Martor is available directly from [PyPI][2]:
42+
43+
1. Installing the package.
44+
45+
```
46+
$ pip install martor
47+
```
48+
49+
50+
2. Don't forget to add `'martor'` to your `'INSTALLED_APPS'` setting _(without migrations)_.
51+
52+
```
53+
# settings.py
54+
INSTALLED_APPS = [
55+
....
56+
'martor',
57+
]
58+
```
59+
60+
61+
3. Add url pattern to your `urls.py.`
62+
63+
```
64+
# urls.py
65+
# django >= 2.0
66+
urlpatterns = [
67+
...
68+
path('martor/', include('martor.urls')),
69+
]
70+
71+
# django <= 1.9
72+
urlpatterns = [
73+
...
74+
url(r'^martor/', include('martor.urls')),
75+
]
76+
```
77+
78+
79+
4. Collect martor's static files in your `STATIC_ROOT` folder.
80+
81+
```
82+
./manage.py collectstatic
83+
```
84+
85+
86+
Setting Configurations `settings.py`
87+
---------------------------------------
88+
89+
Please register your application at https://api.imgur.com/oauth2/addclient
90+
to get `IMGUR_CLIENT_ID` and `IMGUR_API_KEY`.
91+
92+
```
93+
# Choices are: "semantic", "bootstrap"
94+
MARTOR_THEME = 'bootstrap'
95+
96+
# Global martor settings
97+
# Input: string boolean, `true/false`
98+
MARTOR_ENABLE_CONFIGS = {
99+
'emoji': 'true', # to enable/disable emoji icons.
100+
'imgur': 'true', # to enable/disable imgur/custom uploader.
101+
'mention': 'false', # to enable/disable mention
102+
'jquery': 'true', # to include/revoke jquery (require for admin default django)
103+
'living': 'false', # to enable/disable live updates in preview
104+
'spellcheck': 'false', # to enable/disable spellcheck in form textareas
105+
'hljs': 'true', # to enable/disable hljs highlighting in preview
106+
}
107+
108+
# To show the toolbar buttons
109+
MARTOR_TOOLBAR_BUTTONS = [
110+
'bold', 'italic', 'horizontal', 'heading', 'pre-code',
111+
'blockquote', 'unordered-list', 'ordered-list',
112+
'link', 'image-link', 'image-upload', 'emoji',
113+
'direct-mention', 'toggle-maximize', 'help'
114+
]
115+
116+
# To setup the martor editor with title label or not (default is False)
117+
MARTOR_ENABLE_LABEL = False
118+
119+
# Imgur API Keys
120+
MARTOR_IMGUR_CLIENT_ID = 'your-client-id'
121+
MARTOR_IMGUR_API_KEY = 'your-api-key'
122+
123+
# Markdownify
124+
MARTOR_MARKDOWNIFY_FUNCTION = 'martor.utils.markdownify' # default
125+
MARTOR_MARKDOWNIFY_URL = '/martor/markdownify/' # default
126+
127+
# Markdown extensions (default)
128+
MARTOR_MARKDOWN_EXTENSIONS = [
129+
'markdown.extensions.extra',
130+
'markdown.extensions.nl2br',
131+
'markdown.extensions.smarty',
132+
'markdown.extensions.fenced_code',
133+
134+
# Custom markdown extensions.
135+
'martor.extensions.urlize',
136+
'martor.extensions.del_ins', # ~~strikethrough~~ and ++underscores++
137+
'martor.extensions.mention', # to parse markdown mention
138+
'martor.extensions.emoji', # to parse markdown emoji
139+
'martor.extensions.mdx_video', # to parse embed/iframe video
140+
'martor.extensions.escape_html', # to handle the XSS vulnerabilities
141+
]
142+
143+
# Markdown Extensions Configs
144+
MARTOR_MARKDOWN_EXTENSION_CONFIGS = {}
145+
146+
# Markdown urls
147+
MARTOR_UPLOAD_URL = '/martor/uploader/' # default
148+
MARTOR_SEARCH_USERS_URL = '/martor/search-user/' # default
149+
150+
# Markdown Extensions
151+
# MARTOR_MARKDOWN_BASE_EMOJI_URL = 'https://www.webfx.com/tools/emoji-cheat-sheet/graphics/emojis/' # from webfx
152+
MARTOR_MARKDOWN_BASE_EMOJI_URL = 'https://github.githubassets.com/images/icons/emoji/' # default from github
153+
MARTOR_MARKDOWN_BASE_MENTION_URL = 'https://python.web.id/author/' # please change this to your domain
154+
155+
# If you need to use your own themed "bootstrap" or "semantic ui" dependency
156+
# replace the values with the file in your static files dir
157+
MARTOR_ALTERNATIVE_JS_FILE_THEME = "semantic-themed/semantic.min.js" # default None
158+
MARTOR_ALTERNATIVE_CSS_FILE_THEME = "semantic-themed/semantic.min.css" # default None
159+
MARTOR_ALTERNATIVE_JQUERY_JS_FILE = "jquery/dist/jquery.min.js" # default None
160+
```
161+
162+
Check this setting is not set else csrf will not be sent over ajax calls:
163+
164+
```
165+
CSRF_COOKIE_HTTPONLY = False
166+
```
167+
168+
169+
### Usage
170+
171+
172+
#### Model
173+
174+
```
175+
from django.db import models
176+
from martor.models import MartorField
177+
178+
class Post(models.Model):
179+
description = MartorField()
180+
```
181+
182+
183+
#### Form
184+
185+
```
186+
from django import forms
187+
from martor.fields import MartorFormField
188+
189+
class PostForm(forms.Form):
190+
description = MartorFormField()
191+
```
192+
193+
194+
#### Admin
195+
196+
```
197+
from django.db import models
198+
from django.contrib import admin
199+
200+
from martor.widgets import AdminMartorWidget
201+
202+
from yourapp.models import YourModel
203+
204+
class YourModelAdmin(admin.ModelAdmin):
205+
formfield_overrides = {
206+
models.TextField: {'widget': AdminMartorWidget},
207+
}
208+
209+
admin.site.register(YourModel, YourModelAdmin)
210+
```
211+
212+
213+
#### Template Renderer
214+
215+
Simply safely parse markdown content as html ouput by loading templatetags from `martor/templatetags/martortags.py`.
216+
217+
```
218+
{% load martortags %}
219+
{{ field_name|safe_markdown }}
220+
221+
# example
222+
{{ post.description|safe_markdown }}
223+
```
224+
225+
226+
Don't miss to include the required css & js files before use.
227+
You can take a look at this folder [martor_demo/app/templates][14] for more details.
228+
The below example is a one of the way to implement it when you choose the `MARTOR_THEME = 'bootstrap'`:
229+
230+
```
231+
{% extends "bootstrap/base.html" %}
232+
{% load static %}
233+
{% load martortags %}
234+
235+
{% block css %}
236+
<link href="{% static 'plugins/css/ace.min.css' %}" type="text/css" media="all" rel="stylesheet" />
237+
<link href="{% static 'martor/css/martor.bootstrap.min.css' %}" type="text/css" media="all" rel="stylesheet" />
238+
{% endblock %}
239+
240+
{% block content %}
241+
<div class="martor-preview">
242+
<h1>Title: {{ post.title }}</h1>
243+
<p><b>Description:</b></p>
244+
<hr />
245+
{{ post.description|safe_markdown }}
246+
</div>
247+
{% endblock %}
248+
249+
{% block js %}
250+
<script type="text/javascript" src="{% static 'plugins/js/highlight.min.js' %}"></script>
251+
<script>
252+
$('.martor-preview pre').each(function(i, block){
253+
hljs.highlightBlock(block);
254+
});
255+
</script>
256+
{% endblock %}
257+
```
258+
259+
260+
#### Template Editor Form
261+
262+
Different with *Template Renderer*, the *Template Editor Form* have more css & javascript dependencies.
263+
264+
```
265+
{% extends "bootstrap/base.html" %}
266+
{% load static %}
267+
268+
{% block css %}
269+
<link href="{% static 'plugins/css/ace.min.css' %}" type="text/css" media="all" rel="stylesheet" />
270+
<link href="{% static 'plugins/css/resizable.min.css' %}" type="text/css" media="all" rel="stylesheet" />
271+
<link href="{% static 'martor/css/martor.bootstrap.min.css' %}" type="text/css" media="all" rel="stylesheet" />
272+
{% endblock %}
273+
274+
{% block content %}
275+
<form class="form" method="post">{% csrf_token %}
276+
<div class="form-group">
277+
{{ form.title }}
278+
</div>
279+
<div class="form-group">
280+
{{ form.description }}
281+
</div>
282+
<div class="form-group">
283+
<button class="btn btn-success">
284+
<i class="save icon"></i> Save Post
285+
</button>
286+
</div>
287+
</form>
288+
{% endblock %}
289+
290+
{% block js %}
291+
<script type="text/javascript" src="{% static 'plugins/js/ace.js' %}"></script>
292+
<script type="text/javascript" src="{% static 'plugins/js/mode-markdown.js' %}"></script>
293+
<script type="text/javascript" src="{% static 'plugins/js/ext-language_tools.js' %}"></script>
294+
<script type="text/javascript" src="{% static 'plugins/js/theme-github.js' %}"></script>
295+
<script type="text/javascript" src="{% static 'plugins/js/typo.js' %}"></script>
296+
<script type="text/javascript" src="{% static 'plugins/js/spellcheck.js' %}"></script>
297+
<script type="text/javascript" src="{% static 'plugins/js/highlight.min.js' %}"></script>
298+
<script type="text/javascript" src="{% static 'plugins/js/resizable.min.js' %}"></script>
299+
<script type="text/javascript" src="{% static 'plugins/js/emojis.min.js' %}"></script>
300+
<script type="text/javascript" src="{% static 'martor/js/martor.bootstrap.min.js' %}"></script>
301+
{% endblock %}
302+
```
303+
304+
305+
### Custom Uploader
306+
307+
If you want to save the images uploaded to your storage,
308+
**Martor** also provides a way to handle this. Please checkout this [WIKI][13]
309+
310+
311+
### Test Martor from this Repository
312+
313+
Assuming you are already setup with a virtual enviroment (virtualenv):
314+
315+
```
316+
$ git clone https://github.com/agusmakmun/django-markdown-editor.git
317+
$ cd django-markdown-editor/ && python setup.py install
318+
$ cd martor_demo/
319+
$ python manage.py makemigrations && python manage.py migrate
320+
$ python manage.py runserver
321+
```
322+
323+
324+
Checkout at http://127.0.0.1:8000/simple-form/ on your browser.
325+
326+
327+
### Martor Commands Reference
328+
329+
![command refference](https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/.etc/images/bootstrap/martor-guide.png)
330+
331+
332+
### Notes
333+
334+
**Martor** was inspired by these great projects: [django-markdownx][15], [Python Markdown][16] and [Online reStructuredText editor][17].
335+
336+
337+
[1]: https://img.shields.io/pypi/v/martor.svg
338+
[2]: https://pypi.python.org/pypi/martor
339+
340+
[3]: https://img.shields.io/badge/donate-paypal-blue
341+
[4]: https://www.paypal.com/paypalme/summonagus
342+
343+
[5]: https://img.shields.io/badge/license-GNUGPLv3-blue.svg
344+
[6]: https://raw.githubusercontent.com/agusmakmun/django-markdown-editor/master/LICENSE
345+
346+
[7]: https://img.shields.io/pypi/pyversions/martor.svg
347+
[8]: https://pypi.python.org/pypi/martor
348+
349+
[9]: https://img.shields.io/badge/Django-1.8%20%3E=%203.1-green.svg
350+
[10]: https://www.djangoproject.com
351+
352+
[11]: https://travis-ci.org/agusmakmun/django-markdown-editor.svg?branch=master
353+
[12]: https://travis-ci.org/agusmakmun/django-markdown-editor
354+
355+
[13]: https://github.com/agusmakmun/django-markdown-editor/wiki
356+
[14]: https://github.com/agusmakmun/django-markdown-editor/tree/master/martor_demo/app/templates
357+
[15]: https://github.com/adi-/django-markdownx
358+
[16]: https://github.com/waylan/Python-Markdown
359+
[17]: http://rst.ninjs.org

0 commit comments

Comments
 (0)