Awesome Django Markdown Editor, supported for Bootstrap & Semantic-UI

Overview

martor pypi version paypal donation

license python version django version build

Martor is a Markdown Editor plugin for Django, supported for Bootstrap & Semantic-UI.

Features

  • Live Preview
  • Integrated with Ace Editor
  • Supported with Bootstrap and Semantic-UI
  • Supported Multiple Fields fixed this issue
  • Upload Images to imgur.com (via API) and custom uploader
  • Direct Mention users @[username] - (requires user to logged in).
  • Supports embed/iframe video from (Youtube, Vimeo, Dailymotion, Yahoo, Veoh, & Metacafe)
  • Spellchecking (only supports US English at this time)
  • Emoji :emoji_name: + Cheat sheets
  • Martor Commands Reference
  • Supports Django Admin
  • Toolbar Buttons
  • Highlight pre

Preview

editor

preview

Requirements

  • Django>=2.0
  • Markdown>=3.0
  • requests>=2.12.4

Installation

Martor is available directly from PyPI:

1. Installing the package.

$ pip install martor

2. Don't forget to add 'martor' to your 'INSTALLED_APPS' setting (without migrations).

# settings.py
INSTALLED_APPS = [
    ....
    'martor',
]

3. Add url pattern to your urls.py.

# urls.py
# django >= 2.0
urlpatterns = [
    ...
    path('martor/', include('martor.urls')),
]

# django <= 1.9
urlpatterns = [
    ...
    url(r'^martor/', include('martor.urls')),
]

4. Collect martor's static files in your STATIC_ROOT folder.

./manage.py collectstatic

Setting Configurations settings.py

Please register your application at https://api.imgur.com/oauth2/addclient to get IMGUR_CLIENT_ID and IMGUR_API_KEY.

# Choices are: "semantic", "bootstrap"
MARTOR_THEME = 'bootstrap'

# Global martor settings
# Input: string boolean, `true/false`
MARTOR_ENABLE_CONFIGS = {
    'emoji': 'true',        # to enable/disable emoji icons.
    'imgur': 'true',        # to enable/disable imgur/custom uploader.
    'mention': 'false',     # to enable/disable mention
    'jquery': 'true',       # to include/revoke jquery (require for admin default django)
    'living': 'false',      # to enable/disable live updates in preview
    'spellcheck': 'false',  # to enable/disable spellcheck in form textareas
    'hljs': 'true',         # to enable/disable hljs highlighting in preview
}

# To show the toolbar buttons
MARTOR_TOOLBAR_BUTTONS = [
    'bold', 'italic', 'horizontal', 'heading', 'pre-code',
    'blockquote', 'unordered-list', 'ordered-list',
    'link', 'image-link', 'image-upload', 'emoji',
    'direct-mention', 'toggle-maximize', 'help'
]

# To setup the martor editor with title label or not (default is False)
MARTOR_ENABLE_LABEL = False

# Imgur API Keys
MARTOR_IMGUR_CLIENT_ID = 'your-client-id'
MARTOR_IMGUR_API_KEY   = 'your-api-key'

# Markdownify
MARTOR_MARKDOWNIFY_FUNCTION = 'martor.utils.markdownify' # default
MARTOR_MARKDOWNIFY_URL = '/martor/markdownify/' # default

# Markdown extensions (default)
MARTOR_MARKDOWN_EXTENSIONS = [
    'markdown.extensions.extra',
    'markdown.extensions.nl2br',
    'markdown.extensions.smarty',
    'markdown.extensions.fenced_code',

    # Custom markdown extensions.
    'martor.extensions.urlize',
    'martor.extensions.del_ins',      # ~~strikethrough~~ and ++underscores++
    'martor.extensions.mention',      # to parse markdown mention
    'martor.extensions.emoji',        # to parse markdown emoji
    'martor.extensions.mdx_video',    # to parse embed/iframe video
    'martor.extensions.escape_html',  # to handle the XSS vulnerabilities
]

# Markdown Extensions Configs
MARTOR_MARKDOWN_EXTENSION_CONFIGS = {}

# Markdown urls
MARTOR_UPLOAD_URL = '/martor/uploader/' # default
MARTOR_SEARCH_USERS_URL = '/martor/search-user/' # default

# Markdown Extensions
# MARTOR_MARKDOWN_BASE_EMOJI_URL = 'https://www.webfx.com/tools/emoji-cheat-sheet/graphics/emojis/'     # from webfx
MARTOR_MARKDOWN_BASE_EMOJI_URL = 'https://github.githubassets.com/images/icons/emoji/'                  # default from github
MARTOR_MARKDOWN_BASE_MENTION_URL = 'https://python.web.id/author/'                                      # please change this to your domain

# If you need to use your own themed "bootstrap" or "semantic ui" dependency
# replace the values with the file in your static files dir
MARTOR_ALTERNATIVE_JS_FILE_THEME = "semantic-themed/semantic.min.js"   # default None
MARTOR_ALTERNATIVE_CSS_FILE_THEME = "semantic-themed/semantic.min.css" # default None
MARTOR_ALTERNATIVE_JQUERY_JS_FILE = "jquery/dist/jquery.min.js"        # default None

Check this setting is not set else csrf will not be sent over ajax calls:

CSRF_COOKIE_HTTPONLY = False

Usage

Model

from django.db import models
from martor.models import MartorField

class Post(models.Model):
    description = MartorField()

Form

from django import forms
from martor.fields import MartorFormField

class PostForm(forms.Form):
    description = MartorFormField()

Admin

from django.db import models
from django.contrib import admin

from martor.widgets import AdminMartorWidget

from yourapp.models import YourModel

class YourModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': AdminMartorWidget},
    }

admin.site.register(YourModel, YourModelAdmin)

Template Renderer

Simply safely parse markdown content as html ouput by loading templatetags from martor/templatetags/martortags.py.

{% load martortags %}
{{ field_name|safe_markdown }}

# example
{{ post.description|safe_markdown }}

Don't miss to include the required css & js files before use. You can take a look at this folder martor_demo/app/templates for more details. The below example is a one of the way to implement it when you choose the MARTOR_THEME = 'bootstrap':

{% extends "bootstrap/base.html" %}
{% load static %}
{% load martortags %}

{% block css %}
  <link href="{% static 'plugins/css/ace.min.css' %}" type="text/css" media="all" rel="stylesheet" />
  <link href="{% static 'martor/css/martor.bootstrap.min.css' %}" type="text/css" media="all" rel="stylesheet" />
{% endblock %}

{% block content %}
  <div class="martor-preview">
    <h1>Title: {{ post.title }}</h1>
    <p><b>Description:</b></p>
    <hr />
    {{ post.description|safe_markdown }}
  </div>
{% endblock %}

{% block js %}
  <script type="text/javascript" src="{% static 'plugins/js/highlight.min.js' %}"></script>
  <script>
    $('.martor-preview pre').each(function(i, block){
        hljs.highlightBlock(block);
    });
  </script>
{% endblock %}

Template Editor Form

Different with Template Renderer, the Template Editor Form have more css & javascript dependencies.

{% extends "bootstrap/base.html" %}
{% load static %}

{% block css %}
  <link href="{% static 'plugins/css/ace.min.css' %}" type="text/css" media="all" rel="stylesheet" />
  <link href="{% static 'plugins/css/resizable.min.css' %}" type="text/css" media="all" rel="stylesheet" />
  <link href="{% static 'martor/css/martor.bootstrap.min.css' %}" type="text/css" media="all" rel="stylesheet" />
{% endblock %}

{% block content %}
  <form class="form" method="post">{% csrf_token %}
    <div class="form-group">
      {{ form.title }}
    </div>
    <div class="form-group">
      {{ form.description }}
    </div>
    <div class="form-group">
      <button class="btn btn-success">
        <i class="save icon"></i> Save Post
      </button>
    </div>
  </form>
{% endblock %}

{% block js %}
  <script type="text/javascript" src="{% static 'plugins/js/ace.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/mode-markdown.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/ext-language_tools.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/theme-github.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/typo.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/spellcheck.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/highlight.min.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/resizable.min.js' %}"></script>
  <script type="text/javascript" src="{% static 'plugins/js/emojis.min.js' %}"></script>
  <script type="text/javascript" src="{% static 'martor/js/martor.bootstrap.min.js' %}"></script>
{% endblock %}

Custom Uploader

If you want to save the images uploaded to your storage, Martor also provides a way to handle this. Please checkout this WIKI

Test Martor from this Repository

Assuming you are already setup with a virtual enviroment (virtualenv):

$ git clone https://github.com/agusmakmun/django-markdown-editor.git
$ cd django-markdown-editor/ && python setup.py install
$ cd martor_demo/
$ python manage.py makemigrations && python manage.py migrate
$ python manage.py runserver

Checkout at http://127.0.0.1:8000/simple-form/ on your browser.

Martor Commands Reference

command refference

Notes

Martor was inspired by these great projects: django-markdownx, Python Markdown and Online reStructuredText editor.

Comments
  • Semantic conflicts with bootstrap

    Semantic conflicts with bootstrap

    This uses semantic.js if you install on a site with bootstrap it breaks dialog boxes becuase they have the same .dialog js methods and similar styles.

    Is there a way to fix this with out changing an entire site to use bootstraps no conflict mode ?

    currently i have had to remove semantic.js to make dialogs work on my site any better solution ?

    I am currently trying to integrate this into django wiki i have a PR with my current progress if interested.

    https://github.com/django-wiki/django-wiki/pull/709

    enhancement help wanted 
    opened by olymk2 16
  • Martor crashes with Markdown 3

    Martor crashes with Markdown 3

    Log:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
        response = get_response(request)
      File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 158, in _get_response
        response = self.process_exception_by_middleware(e, request)
      File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 156, in _get_response
        response = response.render()
      File "/usr/local/lib/python3.6/site-packages/django/template/response.py", line 106, in render
        self.content = self.rendered_content
      File "/usr/local/lib/python3.6/site-packages/django/template/response.py", line 83, in rendered_content
        content = template.render(context, self._request)
      File "/usr/local/lib/python3.6/site-packages/django/template/backends/django.py", line 61, in render
        return self.template.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 175, in render
        return self._render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 167, in _render
        return self.nodelist.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 943, in render
        bit = node.render_annotated(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 910, in render_annotated
        return self.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py", line 155, in render
        return compiled_parent._render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 167, in _render
        return self.nodelist.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 943, in render
        bit = node.render_annotated(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 910, in render_annotated
        return self.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py", line 155, in render
        return compiled_parent._render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 167, in _render
        return self.nodelist.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 943, in render
        bit = node.render_annotated(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 910, in render_annotated
        return self.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/defaulttags.py", line 517, in render
        return self.nodelist.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 943, in render
        bit = node.render_annotated(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 910, in render_annotated
        return self.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py", line 67, in render
        result = block.nodelist.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 943, in render
        bit = node.render_annotated(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 910, in render_annotated
        return self.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py", line 67, in render
        result = block.nodelist.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 943, in render
        bit = node.render_annotated(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 910, in render_annotated
        return self.render(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 993, in render
        output = self.filter_expression.resolve(context)
      File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 703, in resolve
        new_obj = func(obj, *arg_vals)
      File "/usr/local/lib/python3.6/site-packages/martor/templatetags/martortags.py", line 21, in safe_markdown
        return mark_safe(markdownify(field_name))
      File "/usr/local/lib/python3.6/site-packages/martor/utils.py", line 28, in markdownify
        extension_configs=MARTOR_MARKDOWN_EXTENSION_CONFIGS
      File "/usr/local/lib/python3.6/site-packages/markdown/core.py", line 390, in markdown
        md = Markdown(**kwargs)
      File "/usr/local/lib/python3.6/site-packages/markdown/core.py", line 100, in __init__
        configs=kwargs.get('extension_configs', {}))
      File "/usr/local/lib/python3.6/site-packages/markdown/core.py", line 126, in registerExtensions
        ext = self.build_extension(ext, configs.get(ext, {}))
      File "/usr/local/lib/python3.6/site-packages/markdown/core.py", line 181, in build_extension
        return module.makeExtension(**configs)
      File "/usr/local/lib/python3.6/site-packages/martor/extensions/del_ins.py", line 48, in makeExtension
        return DelInsExtension(configs=dict(configs))
      File "/usr/local/lib/python3.6/site-packages/markdown/extensions/__init__.py", line 42, in __init__
        self.setConfigs(kwargs)
      File "/usr/local/lib/python3.6/site-packages/markdown/extensions/__init__.py", line 73, in setConfigs
        self.setConfig(key, value)
      File "/usr/local/lib/python3.6/site-packages/markdown/extensions/__init__.py", line 61, in setConfig
        if isinstance(self.config[key][0], bool):
    KeyError: 'configs'
    

    Downgrading to Markdown 2.6.11 fixed the problem for me.

    opened by lubo 10
  • HTML Code getting removed.

    HTML Code getting removed.

    Whenever any HTML Code is written inside the editor it is being removed as [HTML_REMOVED]. Ideally, this should not happen. Can you please have a look into it.

    opened by astikanand 10
  • Markdown widget becomes unresponsive when a model has multiple DraceditorField

    Markdown widget becomes unresponsive when a model has multiple DraceditorField

    Hello,

    I just found this plugin and it is just what I need -congratulations for the good work ;)-, after installing and setting up some fields to DraceditorField() I entered the django admin panel and found the following error.

    While in a model if you have only just 1 DraceditorField, the widget works as expected

    1field markdown

    But in the moment that in a same model two DraceditorFields are added when entering admin panel one of the widgets become unresponsive and duplicated with information of the previous field, and of course it is impossible to edit its content also. Try it by yourself, declare a model with two DraceditorField.

    See how 2nd Markdown editor looks weird in the following image:

    2 fields

    Do you have a guess on why this is happening? Could be easy for you to fix it?

    bug help wanted 
    opened by gomezjdaniel 9
  • Preview not working

    Preview not working

    Instead of getting a preview, it just looks exactly like the raw text in the editor box.

    models.py:

    class Question(models.Model, HitCountMixin):
        title = models.CharField(max_length=200, blank=False)
        description = MartorField()
    

    forms.py

    class QuestionForm(forms.ModelForm):
        class Meta:
            model = Question
            fields = ['title', 'description']
            widgets = {
                'description': AdminMartorWidget,
            }
        def __init__(self, *args, **kwargs):
            self.user = kwargs.pop('user')
            super(QuestionForm, self).__init__(*args, **kwargs)
            self.fields['description'] = MartorFormField()
    

    EDIT My new form looks like this:

    class QuestionForm(forms.ModelForm):
        class Meta:
            model = Question
            fields = ['title', 'description']
    
        def __init__(self, *args, **kwargs):
            self.user = kwargs.pop('user')
            super(QuestionForm, self).__init__(*args, **kwargs)
            self.fields['description'] = MartorFormField()
    

    image

    opened by jdhurwitz 7
  • XSS via href content

    XSS via href content

    The bug reported here https://github.com/agusmakmun/django-markdown-editor/issues/173 can be extended to an href content with small syntax changes.

    Steps to reproduce

    1. editor insert: [testlinkxss](" onmouseover=alert(document.domain) l)
    2. preview will result in:

      <a href="" onmouseover="alert(document.domain)" l"="">testlinkxss

    3. go with the mouse over will trigger the payload.
    Screenshot 2022-05-23 at 16 25 26 Screenshot 2022-05-23 at 16 25 15
    opened by Arkango 6
  • Semantic css is missing its image assets

    Semantic css is missing its image assets

    when trying to run collectstatic with the gzip storage engine, it errors when processing semantic.min.css.

    because the flags.png file is not present so it fails to compress and stops the collect static process.

    Its looking for a child path of the below in the css file.

    themes/default/assets/images/flags.png

    opened by olymk2 6
  • XSS using javascript: URLs

    XSS using javascript: URLs

    javascript: urls can cause cross site scripting

    Steps to reproduce

    1. paste this in your editor [aaaa](javascript:alert(1))
    2. preview it
    3. click on aaaa

    The fix would be only allowing https?:// urls or maybe a small whitelist.

    opened by wfinn 5
  •  i cant display fields with inline - django admin

    i cant display fields with inline - django admin

    the bug has not been fixed yet, i cant display fields with inline. #148

    fieldsets = (
            (
                None,
                {
                    'fields': (
                        (
                            'status',
                            'published_at',
                        ),
                        'title'
                    ),
                },
            ),
            # (
            #     'Content',
            #     {'fields': ('content',)},       # martor
            # ),
        )
    

    does not work when martor editor is active.

    Details

    • OS (Operating System) version: MacOS
    • Browser and browser version: Chrome 89
    • Django version: 3.1.7
    • Martor version: 1.6.0
    bug help wanted 
    opened by niturk 5
  • live preview not showing up in django admin

    live preview not showing up in django admin

    Hi, i found a problem here.

    during production (i deployed on pythonanywhere), the preview editor doesn't appear in django admin, but it works fine if i run it on local. I've already collect martor's static and i've convinced that the path to static martor directory is correct but, still the preview editor doesnt work.

    opened by sodrooome 5
  • Demo application - martor_demo not working!

    Demo application - martor_demo not working!

    Here's the complete trace on running the command python manage.py check:

    Traceback (most recent call last):
      File "manage.py", line 15, in <module>
        execute_from_command_line(sys.argv)
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/Django-3.0b1-py3.7.egg/django/core/management/__init__.py", line 401, in execute_from_command_line
        utility.execute()
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/Django-3.0b1-py3.7.egg/django/core/management/__init__.py", line 377, in execute
        django.setup()
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/Django-3.0b1-py3.7.egg/django/__init__.py", line 24, in setup
        apps.populate(settings.INSTALLED_APPS)
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/Django-3.0b1-py3.7.egg/django/apps/registry.py", line 114, in populate
        app_config.import_models()
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/Django-3.0b1-py3.7.egg/django/apps/config.py", line 211, in import_models
        self.models_module = import_module(models_module_name)
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/importlib/__init__.py", line 127, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
      File "<frozen importlib._bootstrap>", line 983, in _find_and_load
      File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 728, in exec_module
      File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/martor-1.4.4-py3.7.egg/martor/models.py", line 3, in <module>
        from .fields import MartorFormField
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/martor-1.4.4-py3.7.egg/martor/fields.py", line 4, in <module>
        from .widgets import (MartorWidget, AdminMartorWidget)
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/martor-1.4.4-py3.7.egg/martor/widgets.py", line 14, in <module>
        class MartorWidget(forms.Textarea):
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/martor-1.4.4-py3.7.egg/martor/widgets.py", line 51, in MartorWidget
        class Media:
      File "/home/alfarhanzahedi/Projects/django/django-markdown-editor/venv/lib/python3.7/site-packages/martor-1.4.4-py3.7.egg/martor/widgets.py", line 73, in Media
        if MARTOR_ENABLE_CONFIGS['spellcheck'] == 'true':
    KeyError: 'spellcheck'
    
    opened by alfarhanzahedi 5
  • safe_markdown throw KeyError exception

    safe_markdown throw KeyError exception

    This content throws a KeyError exception when template using safe_markdown

    int[] values = new int[] { 0, 12, 44, 36, 92, 54, 13, 8 };
    IEnumerable<int> result =
        from v in values
        where v < 37
        orderby -v
        select v;
    

    <div>{{ object.content|safe_markdown }}</div>

    Details

    • OS (Operating System) version: macOS Monterey 12.6.1
    • Browser and browser version: 107.0.5304.110 (正式版本) (x86_64)
    • Django version: 4.0.2
    • Martor version & theme: 1.6.15 bootstrap

    Steps to reproduce

    1. Write markdown content as shown above
    2. Template output content with safe_markdown filter
    3. Browse url with markdown template
    截圖 2022-11-25 上午5 52 29
    opened by enjoy-software 0
  • Youtube embed not rendering in Safari

    Youtube embed not rendering in Safari

    Details

    • OS (Operating System) version: macOS 12.5.1 (Monterey)
    • Browser and browser version: Safari 16.0
    • Django version: 4.1.2
    • Martor version & theme: 1.6.14 with Bootstrap theme

    Steps to reproduce

    1. In Safari: In the Simple Form demo, just pasting a Youtube url in the markdown editor, renders an empty iframe.
    Screen Shot 2022-10-12 at 3 23 49 PM
    1. As you can see, the the src parameter is set without the protocol string (https).

    2. This works fine in Chrome (106.0.5249.103) and Firefox (v 105.0.3)

    I know this is a bug report, but in case it helps, I made the following changes to the mdx_video.py file

    1. In the extendMarkdown function, I changed the regular expression to capture the protocol along with the youtubeid parameter. So the code was change from r"([^(]|^)https?://www\.youtube\.com/watch\?\S*v=(?P<youtubeid>\S[^&/]+)" TO r"([^(]|^)(?P<protocol>(https?))://www\.youtube\.com/watch\?\S*v=(?P<youtubeid>\S[^&/]+)"

    2. In the Youtube class, I changed the code from

    class Youtube(markdown.inlinepatterns.Pattern):
        def handleMatch(self, m):
            if self.ext.config["youtube_nocookie"][0]:
                url = "//www.youtube-nocookie.com/embed/%s" % m.group("youtubeid")
            else:
                url = "//www.youtube.com/embed/%s" % m.group("youtubeid")
            width = self.ext.config["youtube_width"][0]
            height = self.ext.config["youtube_height"][0]
            return render_iframe(url, width, height)
    

    TO the version below that just uses the protocol parameter

    class Youtube(markdown.inlinepatterns.Pattern):
        def handleMatch(self, m):
            if self.ext.config["youtube_nocookie"][0]:
                url = "{0}://www.youtube-nocookie.com/embed/{1}".format(m.group("protocol"), m.group("youtubeid"))
            else:
                url = "{0}://www.youtube.com/embed/{1}".format(m.group("protocol"), m.group("youtubeid"))
    

    Finally, thank you so much for your work/plugin. It has been incredibly helpful. If you take pull requests, I'd be happy to make the changes for your review.

    opened by Amartya 1
  • CSS styles are conflicting with Django Admin

    CSS styles are conflicting with Django Admin

    When loading martor in the admin, it loads CSS rules which overrides many admin styles. For example, when using bootstrap theme, it causes collapsible fieldsets to be completely hidden:

    .collapse:not(.show) {
        display: none;
    }
    

    Even when using the "semantic" theme, there are many style definitions that are not namespaced, and causes default admin styles to be overriden, for example, h2 headings look way to big because of this rule in martor-admin.css:

    h2 {
        font-size: 16px!important;
        margin: 1em 0 0.5em 0!important;
    }
    

    I'm assuming these style definitions are only meant for the preview. If that's the case, then they should be namespaced to the preview box.

    opened by bendavis78 3
  • Preview fails due to missing CSRF token

    Preview fails due to missing CSRF token

    When selecting preview tab in admin, it says "Nothing to preview". The console output shows the following::

    WARNING django.security.csrf: Forbidden (CSRF token missing or incorrect.): /martor/markdownify/ 
    
    • Django version: 2.2.12
    • Martor version: 1.6.13
    opened by bendavis78 1
  • Bootstrap collapse class overrides Django class

    Bootstrap collapse class overrides Django class

    Details

    • OS (Operating System) version: Debian Bullseye
    • Browser and browser version: Chrome 100
    • Django version: 3.2
    • Martor version & theme: 1.6.13

    Steps to reproduce

    1. Define inline class class ObjectInline(GenericTabularInline): model = Object classes = ("collapse",)

    2. Bootstrap rule overrides Django css and Inline becomes not colapsed but invisible.

    .collapse:not(.show) {
        display: none;
    }
    
    opened by 13hakta 0
  • Newer Django dark mode looks horrible when combined with Martor

    Newer Django dark mode looks horrible when combined with Martor

    The newer version of Django where the admin supports auto dark mode, it looks quite bad when dark mode is initiated on admin pages that have martor fields.

    It looks like everything still functions, it just looks bad.

    opened by yatahaze 1
Releases(v1.6.15)
Owner
Linux, Python & Django Enthusiast past @titipbeliin @doaai
Wagtail - Vue - Django : The initial environment of full-stack local dev web app with wagtail and vue

Wagtail - Vue - Django : The initial environment of full-stack local dev web app with wagtail and vue. A demo to show how to use .vue files inside django app.

Quang PHAM 2 Oct 20, 2022
Simple tagging for django

django-taggit This is a Jazzband project. By contributing you agree to abide by the Contributor Code of Conduct and follow the guidelines. django-tagg

Jazzband 3k Jan 02, 2023
Django Login Api With Python

How to run this project Download and extract this project Create an environment and install all the libraries from requiements.txt pip freeze -r requi

Vikash Kisku 1 Dec 10, 2021
Plug and play continuous integration with django and jenkins

django-jenkins Plug and play continuous integration with Django and Jenkins Installation From PyPI: $ pip install django-jenkins Or by downloading th

Mikhail Podgurskiy 941 Oct 22, 2022
Full control of form rendering in the templates.

django-floppyforms Full control of form rendering in the templates. Authors: Gregor Müllegger and many many contributors Original creator: Bruno Renié

Jazzband 811 Dec 01, 2022
An extremely fast JavaScript and CSS bundler and minifier

Website | Getting started | Documentation | Plugins | FAQ Why? Our current build tools for the web are 10-100x slower than they could be: The main goa

Evan Wallace 34.2k Jan 04, 2023
Store model history and view/revert changes from admin site.

django-simple-history django-simple-history stores Django model state on every create/update/delete. This app supports the following combinations of D

Jazzband 1.8k Jan 06, 2023
Social Media Network Focuses On Data Security And Being Community Driven Web App

privalise Social Media Network Focuses On Data Security And Being Community Driven Web App The Main Idea: We`ve seen social media web apps that focuse

Privalise 8 Jun 25, 2021
Zendesk Assignment - Django Based Ticket Viewer

Zendesk-Coding-Challenge Django Based Ticket Viewer The assignment has been made using Django. Important methods have been scripted in views.py. Excep

Akash Sampurnanand Pandey 0 Dec 23, 2021
Log and View requests made on Django

Django Request Viewer Log and view requests made on your Django App Introduction Recently, @ichtrojan and @toniastro released horus, a request logger

Akere Mukhtar 26 May 29, 2022
A reusable Django model field for storing ad-hoc JSON data

jsonfield jsonfield is a reusable model field that allows you to store validated JSON, automatically handling serialization to and from the database.

Ryan P Kilby 1.1k Jan 03, 2023
Fast / fuzzy PostgreSQL counts for Django

Created by Stephen McDonald Introduction Up until PostgreSQL 9.2, COUNT queries generally required scanning every row in a database table. With millio

stephenmcd 85 Oct 25, 2021
Django + Next.js integration

Django Next.js Django + Next.js integration From a comment on StackOverflow: Run 2 ports on the same server. One for django (public facing) and one fo

Quera 162 Jan 03, 2023
Django app for building dashboards using raw SQL queries

django-sql-dashboard Django app for building dashboards using raw SQL queries Brings a useful subset of Datasette to Django. Currently only works with

Simon Willison 383 Jan 06, 2023
A BitField extension for Django Models

django-bitfield Provides a BitField like class (using a BigIntegerField) for your Django models. (If you're upgrading from a version before 1.2 the AP

DISQUS 361 Dec 22, 2022
Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB.

djangoProject Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB. packages utiliz

Sofia Rocha 1 Feb 22, 2022
Django models and endpoints for working with large images -- tile serving

Django Large Image Models and endpoints for working with large images in Django -- specifically geared towards geospatial tile serving. DISCLAIMER: th

Resonant GeoData 42 Dec 17, 2022
Sistema de tratamento e análise de grandes volumes de dados através de técnicas de Data Science

Sistema de tratamento e análise de grandes volumes de dados através de técnicas de data science Todos os scripts, gráficos e relatórios de todas as at

Arthur Quintanilha Neto 1 Sep 05, 2022
Modular search for Django

Haystack author: Daniel Lindsley date: 2013/07/28 Haystack provides modular search for Django. It features a unified, familiar API that allows you to

Daniel Lindsley 4 Dec 23, 2022
Fully reponsive Chat Application built with django, javascript, materialUi, bootstrap4, html and css.

Chat app (Full Stack Frameworks with Django Project) Fully reponsive Chat Application built with django, javascript, materialUi, bootstrap4, html and

1 Jan 19, 2022