Giter VIP home page Giter VIP logo

Comments (2)

junwenwaynepeng avatar junwenwaynepeng commented on September 25, 2024

I try to fix it by naively add the following script after page loaded

  <script>
    // Wait for the DOM to be ready
    document.addEventListener("DOMContentLoaded", function () {
      // Get all forms with an ID starting with "martor-"
      var martorForms = document.querySelectorAll('[id^="martor-"]');
      console.log('I am runing')
      console.log(martorForms)
      // Loop through each form and add the specified classes
      martorForms.forEach(function (form) {
        form.classList.add("ace_editor", "ace_hidpi", "ace-github", "resizable");
        // Insert the specified content between div tags in the form
        if (form.innerHTML == null) {
          form.innerHTML = '<div style="position: absolute;"></div><textarea class="ace_text-input" wrap="off" autocorrect="off" autocapitalize="none" spellcheck="false" style="opacity: 0; font-size: 1px;" aria-haspopup="false" aria-autocomplete="both" role="textbox"></textarea><div class="ace_gutter" aria-hidden="true"><div class="ace_layer ace_gutter-layer ace_folding-enabled" style="height: 1000000px;"></div></div><div class="ace_scroller" style="line-height: 0px;"><div class="ace_content"><div class="ace_layer ace_print-margin-layer"><div class="ace_print-margin" style="left: 4px; visibility: hidden;"></div></div><div class="ace_layer ace_marker-layer"></div><div class="ace_layer ace_text-layer" style="height: 1000000px; margin: 0px 4px;"></div><div class="ace_layer ace_marker-layer"></div><div class="ace_layer ace_cursor-layer ace_hidden-cursors"><div class="ace_cursor"></div></div></div></div><div class="ace_scrollbar ace_scrollbar-v" style="display: none; width: 20px;"><div class="ace_scrollbar-inner" style="width: 20px;">&nbsp;</div></div><div class="ace_scrollbar ace_scrollbar-h" style="display: none; height: 20px;"><div class="ace_scrollbar-inner" style="height: 20px;">&nbsp;</div></div><div style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; font: inherit; overflow: hidden;"><div style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; font: inherit; overflow: visible;"></div><div style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; font: inherit; overflow: visible;">XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</div></div><div class="resizable-handle resizable-b"></div>' + form.innerHTML;
        }
      });
    });
  </script>

It didn't work of course. I also tried to change the line 33 of the templates/martor/editor.html from

          <div id="martor-{{ field_name }}" class="martor-field martor-field-{{ field_name }}"></div>

to

        <div id="martor-{{ field_name }}-test" class="martor-field martor-field-{{ field_name }}"></div>

And, everything goes wrong.

From these tests, I feel the process to render a proper markdown editor is controlled by some js in plugins, but without an overview of how an editor is generated, I am afraid that I am not able to solve this bug.

from django-markdown-editor.

junwenwaynepeng avatar junwenwaynepeng commented on September 25, 2024

I attempted two approaches to address this bug. The first one, which I considered more robust, unfortunately, did not succeed. Let me begin by presenting the code that was successful. If authors acknowledged this approach. I can push my version to brench.

Succesful way

class MartorWidget(forms.Textarea):
    def render(self, name, value, attrs=None, renderer=None, **kwargs):
        import random, string
        random_string = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(10))
        attrs['id'] = attrs['id'] + '-' + random_string
        # Make the settings the default attributes to pass
        attributes_to_pass = {
            "data-enable-configs": MARTOR_ENABLE_CONFIGS,
            "data-markdownfy-url": reverse("martor_markdownfy"),
        }

        if MARTOR_UPLOAD_URL:
            attributes_to_pass["data-upload-url"] = reverse("imgur_uploader")
        if MARTOR_SEARCH_USERS_URL:
            attributes_to_pass["data-search-users-url"] = reverse("search_user_json")
        if MARTOR_SEARCH_USERS_URL:
            attributes_to_pass["data-base-emoji-url"] = MARTOR_MARKDOWN_BASE_EMOJI_URL

        # Make sure that the martor value is in the class attr passed in
        if "class" in attrs:
            attrs["class"] += " martor"
        else:
            attrs["class"] = "martor"

        # Update and overwrite with the attributes passed in
        attributes_to_pass.update(attrs)

        # Update and overwrite with any attributes that are on the widget
        # itself. This is also the only way we can push something in without
        # being part of the render chain.
        attributes_to_pass.update(self.attrs)

        template = get_template("martor/%s/editor.html" % get_theme())
        emoji_enabled = MARTOR_ENABLE_CONFIGS.get("emoji") == "true"
        mentions_enabled = MARTOR_ENABLE_CONFIGS.get("mention") == "true"

        widget = super().render(name + '-' + random_string, value, attributes_to_pass)

        return template.render(
            {
                "martor": widget,
                "field_name": name,
                "random_string": random_string,
                "emoji_enabled": emoji_enabled,
                "mentions_enabled": mentions_enabled,
                "toolbar_buttons": MARTOR_TOOLBAR_BUTTONS,
            }
        )

Lines that I added and changed:

  1. Line 3 and 4: I add
        import random, string
        random_string = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(10))
  1. Line 37: I change widget = super().render(name, value, attributes_to_pass) to widget = super().render(name + '-' + random_string, value, attributes_to_pass)
  2. Line 43: I add "random_string": random_string,

Then, in editor.html, we have to put -{{ random_string }} after each {{ field_name }}.

{% load i18n %}
<div class="main-martor main-martor-{{ field_name }}-{{random_string}}" data-field-name="{{ field_name }}-{{random_string}}">
  <div class="section-martor">
    <nav class="tab-martor-menu" style="position:relative">
      <div class="nav nav-tabs" id="nav-tab" role="tablist">
        <a class="nav-link active" data-tab="editor-tab-{{ field_name }}-{{random_string}}" id="nav-editor-tab-{{ field_name }}-{{random_string}}" data-bs-toggle="tab" data-bs-target="#nav-editor-{{ field_name }}-{{random_string}}" type="button" role="tab" aria-controls="nav-editor-{{ field_name }}-{{random_string}}" aria-selected="true">
          <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pencil-square" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
            <path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
            <path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
          </svg>
          <span>{% trans "Editor" %}</span>
        </a>
        <a class="nav-link" data-tab="preview-tab-{{ field_name }}-{{random_string}}" id="nav-preview-tab-{{ field_name }}-{{random_string}}" data-bs-toggle="tab" data-bs-target="#nav-preview-{{ field_name }}-{{random_string}}" type="button" role="tab" aria-controls="nav-preview-{{ field_name }}-{{random_string}}" aria-selected="false">
          <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-eye-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
            <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/>
            <path fill-rule="evenodd" d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/>
          </svg>
          <span>{% trans "Preview" %}</span>
        </a>

        {% include "martor/bootstrap/toolbar.html" %}
      </div>
    </nav>

    <div class="tab-content" id="nav-tabContent">
      <div class="tab-pane fade show active" id="nav-editor-{{ field_name }}-{{random_string}}" role="tabpanel" aria-labelledby="nav-editor-tab-{{ field_name }}-{{random_string}}">
        <div class="text-center upload-progress" data-field-name="{{ field_name }}-{{random_string}}" style="display:none">
          <div class="spinner-border" role="status">
            <span class="visually-hidden">Loading...</span>
          </div>
          <div>{% trans "Uploading... please wait..." %}</div>
        </div>
        <div id="martor-{{ field_name }}-{{random_string}}" class="martor-field martor-field-{{ field_name }}"></div>
        {{ martor }}
        <span class="icon expand-editor">
          <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-arrows-expand" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
            <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13A.5.5 0 0 1 1 8zM7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708l2-2zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10z"/>
          </svg>
        </span>
      </div>

      <div class="tab-pane fade martor-preview" id="nav-preview-{{ field_name }}-{{random_string}}" role="tabpanel" aria-labelledby="nav-preview-tab-{{ field_name }}-{{random_string}}">
        <p>{% trans "Nothing to preview" %}</p>
      </div>
    </div>
  </div><!-- end  /.section-martor -->

  {% include 'martor/bootstrap/guide.html' %}
  {% include 'martor/bootstrap/emoji.html' %}
</div>

Unsuccesful way

My original plan is to change all {{ field_name }} to {{ model_name }}-{{ field_name }}-{{ instance_id }}. It means that I have to input model_name and instance_id into MartorWidget and let it render. There is no problem I can put model_name as a parameter of MartorWidget. However, the trouble is instance_id. It needs to be dynamic in Form's metaclass. After googling for hours, I found it was impossible to do so. Therefore, I discard this method.

from django-markdown-editor.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.