Skip to content
Snippets Groups Projects
Select Git revision
0 results

django-markdownx

  • Clone with SSH
  • Clone with HTTPS
  • Pablo Ricco's avatar
    Pablo Ricco authored
    6cb26f50
    History

    django-markdownx Version

    Status Travis Format Python Versions Django Versions License

    Key features

    • raw editing
    • live preview
    • drag&drop image uploads (stored locally in MEDIA folder)
    • customizable image insertion tag
    • image filtering using content types and max file size
    • image manipulations (compression, size, cropping, upscaling)
    • pre-&post- text altering
    • easy template customization for layout purposes
    • multiple editors on one page
    • Django Admin support

    Preview

    Preview

    (using Bootstrap for layout and styling)

    Menu

    Quick Start

    1. Install django-markdownx package.

      pip install django-markdownx
    2. Add markdownx to your INSTALLED_APPS.

      #settings.py
      INSTALLED_APPS = (
          [...]
          'markdownx',
      )
    3. Add url pattern to your urls.py.

      #urls.py
      urlpatterns = [
          [...]
          url(r'^markdownx/', include('markdownx.urls')),
      ]
    4. Collect included markdownx.js and markdownx.css (for django admin styling) to your STATIC_ROOT folder.

      python manage.py collectstatic
    5. ...and don't forget to include jQuery in your html file.

      <head>
          [...]
          <script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
      </head>

    Usage

    Model

    #models.py
    from markdownx.models import MarkdownxField
    
    class MyModel(models.Model):
    
        myfield = MarkdownxField()

    ...and then, include a form's required media in the template using {{ form.media }}:

    <form method="POST" action="">{% csrf_token %}
        {{ form }}
    </form>
    {{ form.media }}

    Form

    #forms.py
    from markdownx.fields import MarkdownxFormField
    
    class MyForm(forms.Form):
    
        myfield = MarkdownxFormField()

    ...and then, include a form's required media in the template using {{ form.media }}:

    <form method="POST" action="">{% csrf_token %}
        {{ form }}
    </form>
    {{ form.media }}

    Django Admin

    When using included MarkdowxModel class in your models, just use MarkdownxModelAdmin as follows:

    #admin.py
    from django.contrib import admin
    
    from markdownx.admin import MarkdownxModelAdmin
    
    from .models import MyModel
    
    admin.site.register(MyModel, MarkdownxModelAdmin)

    However, when you want to use markdownx with other classes – lets say TextField – than override default widget as follows:

    #admin.py
    from django.db import models
    from django.contrib import admin
    
    from markdownx.widgets import AdminMarkdownxWidget
    
    from .models import MyModel
    
    class MyModelAdmin(admin.ModelAdmin):
        formfield_overrides = {
            models.TextField: {'widget': AdminMarkdownxWidget},
        }
    
    admin.site.register(MyModel, MyModelAdmin)

    Customization

    Settings

    Place settings in your settings.py to override default values:

    #settings.py
    
    # Markdownify
    MARKDOWNX_MARKDOWNIFY_FUNCTION = 'markdownx.utils.markdownify' # Default function that compiles markdown using defined extensions. Using custom function can allow you to pre-process or post-process markdown text. See below for more info.
    
    # Markdown extensions
    MARKDOWNX_MARKDOWN_EXTENSIONS = [] # List of used markdown extensions. See below for more info.
    MARKDOWNX_MARKDOWN_EXTENSION_CONFIGS = {} # Configuration object for used markdown extensions
    
    # Markdown urls
    MARKDOWNX_URLS_PATH = '/markdownx/markdownify/' # URL that returns compiled markdown text.
    MARKDOWNX_UPLOAD_URLS_PATH = '/markdownx/upload/' # URL that accepts file uploads, returns markdown notation of the image.
    
    # Media path
    MARKDOWNX_MEDIA_PATH = 'markdownx/' # Path, where images will be stored in MEDIA_ROOT folder
    
    # Image
    MARKDOWNX_UPLOAD_MAX_SIZE = 52428800 # 50MB - maximum file size
    MARKDOWNX_UPLOAD_CONTENT_TYPES = ['image/jpeg', 'image/png'] # Acceptable file content types
    MARKDOWNX_IMAGE_MAX_SIZE = {'size': (500, 500), 'quality': 90,} # Different options describing final image processing: size, compression etc. See below for more info.
    
    # Editor
    MARKDOWNX_EDITOR_RESIZABLE = True # Update editor's height to inner content height while typing

    MARKDOWNX_MARKDOWNIFY_FUNCTION

    Default function that compiles markdown looks like:

    # utils.py
    import markdown
    
    from .settings import MARKDOWNX_MARKDOWN_EXTENSIONS, MARKDOWNX_MARKDOWN_EXTENSION_CONFIGS
    
    def markdownify(content):
        return markdown.markdown(content, extensions=MARKDOWNX_MARKDOWN_EXTENSIONS, extension_configs=MARKDOWNX_MARKDOWN_EXTENSION_CONFIGS)

    MARKDOWNX_MARKDOWN_EXTENSIONS

    #settings.py
    MARKDOWNX_MARKDOWN_EXTENSIONS = [
        'markdown.extensions.extra',
        'markdown.extensions.nl2br',
        'markdown.extensions.smarty',
    ]

    Visit https://pythonhosted.org/Markdown/extensions/index.html to read more about markdown extensions.

    MARKDOWNX_IMAGE_MAX_SIZE

    Dict properties:

    • size – (width, height). When 0 used, i.e.: (500,0), property will figure out proper height by itself
    • quality – default: 90 – image quality, from 0 (full compression) to 100 (no compression)
    • crop – default: False – if True, use size to crop final image
    • upscale – default: False – if image dimensions are smaller than those in size, upscale image to size dimensions

    Widget's custom template

    Default widget's template looks like:

    <div class="markdownx">
        {{ markdownx_editor }}
        <div class="markdownx-preview"></div>
    </div>

    When you want to use Bootstrap 3 and side-by-side panes (as in preview image above), just place markdownx/widget.html file in your project's 'TEMPLATE_DIRS' folder with:

    <div class="markdownx row">
        <div class="col-md-6">
            {{ markdownx_editor }}
        </div>
        <div class="col-md-6">
            <div class="markdownx-preview"></div>
        </div>
    </div>

    Custom image insertion tag

    Markdown uses ![]() syntax to insert uploaded image file. This generates very simple html <image> tag. When you want to have more control and use your own html tags just create custom form_valid() function in ImageUploadView class.

    Default ImageUploadView class looks like:

    #views.py
    from django.http import JsonResponse
    from django.views.generic.edit import FormView
    
    from .forms import ImageForm
    
    class ImageUploadView(FormView):
    
        template_name = "dummy.html"
        form_class = ImageForm
        success_url = '/'
    
        def form_invalid(self, form):
            response = super(ImageUploadView, self).form_invalid(form)
            if self.request.is_ajax():
                return JsonResponse(form.errors, status=400)
            else:
                return response
    
        def form_valid(self, form):
            image_path = form.save()
            response = super(ImageUploadView, self).form_valid(form)
    
            if self.request.is_ajax():
                image_code = '![]({})'.format(image_path)
                return JsonResponse({'image_code': image_code})
            else:
                return response

    JS events

    Each markdownx jQuery object triggers two basic events:

    • 'markdownx.init'
    • 'markdownx.update' – also returns 'response' variable containing markdownified text
    $('.markdownx').on('markdownx.init', function() {
    	console.log("INIT");
    });
    
    $('.markdownx').on('markdownx.update', function(e, response) {
    	console.log("UPDATE" + response);
    });

    Dependencies

    • Markdown
    • Pillow
    • Django
    • jQuery

    Changelog

    v1.6.3
    • Corrupted image upload exception
    v1.6.2
    • Runtest template fix
    v1.6.1
    • Template render syntax fix
    v1.6
    • Support for Django's default_storage
    • Fix for missing MARKDOWNX_MARKDOWNIFY_FUNCTION in settings
    v1.5
    • Possibility to customize image insertion code
    v1.4.3
    • Markdown abstractable function fix
    v1.4.2
    • Maintenance release
    v1.4.1
    • Make rendering the markdown abstractable
    v1.4
    • Added JS (jQuery) events
    • Custom upload url path
    • Fix when subclassing MarkdownxWidget
    v1.3
    • Added Markdown extension configuration setting
    v1.2.1
    • Fix by Eduard Sukharev: Fix accessing file length in python3
    v1.2
    • Added custom url path setting MARKDOWNX_URLS_PATH to compile markdown with custom view (i.e. for pre/post altering markdown text)
    v1.1.3
    • Setup tools fix
    v1.1.2
    • Critical fix for image upload
    v1.1.1
    • Package fix
    v1.1
    • Python 3.3+ support
    • Very simple test added just to test python 3 support
    v1.0.1
    • Moved html logic from FormField to Widget to be able to override model objects other than included MarkdownxModel
    • Fixed default value for MARKDOWNX_EDITOR_RESIZABLE
    v1.0.0
    • Warning: no backward compatibility
    • Admin, Model and Form custom objects
    • Django admin styles for compiled markdown
    • Settings variables changed:
      • MARKDOWNX_MAX_SIZE => MARKDOWNX_IMAGE_MAX_SIZE
      • MARKDOWNX_MARKDOWN_KWARGS => MARKDOWNX_MARKDOWN_EXTENSIONS
      • MARKDOWNX_MAX_UPLOADSIZE => MARKDOWNX_UPLOAD_MAX_SIZE
      • MARKDOWNX_CONTENT_TYPES => MARKDOWNX_UPLOAD_CONTENT_TYPES
    v0.4.2
    • Path fix by argaen
    v0.4.1
    • Better editor height updates
    • Refresh preview on image upload
    • Small JS code fixes
    v0.4.0
    • editor auto height
    v0.3.1
    • JS event fix
    v0.3.0
    • version bump
    v0.2.9
    • Removed any inlcuded css
    • Removed JS markdown compiler (full python support now with Markdown lib)
    v0.2.0
    • Allow to paste tabs using Tab button
    v0.1.4
    • package data fix
    v0.1.3
    • README.md fix on PyPi
    v0.1.2
    • critical setuptools fix
    v0.1.1
    • change context name editor to markdownx_editor for better consistency
    v0.1.0
    • init

    License

    django-markdown is licensed under the open source BSD license. Read LICENSE file for details.

    Package requests

    It would be nice if anyone could support this project by adding missing functionality:

    • tests
    • JS intelligent auto-scrolling when side-by-side panes used

    Notes

    django-markdownx was inspired by great django-images and django-bootstrap-markdown packages.