Подтвердить что ты не робот

Частично запускать код как html и как текст

Введение

В настоящее время я создаю шаблон, в котором пользователи могут создавать шаблон для приложения. Пользователь может перетаскивать несколько блоков, таких как текстовые блоки и блоки "настраиваемого кода". Шаблон будет анализироваться в приложении. Сейчас шаблон может выглядеть так:

<section>
    <div class="row">
        <div class="col-sm-12">
            <section data-type="code">
                <#code></#code>
            </section>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-12" data-type="container-content">
            <section data-type="text">
                <u>Lorem</u> ipsum
            </section>
        </div>
    </div>
</section>

Итак, этот шаблон содержит два элемента (см. атрибут data-type): одна часть - это пользовательский письменный код. Здесь пользователь написал собственный код, включая код Apache Freemarker. Вторая часть - это индивидуальный письменный текст.

Ситуация

Приведенный выше код будет использоваться двумя разными способами.

  • Именно этот код будет использоваться внутри приложения, используя шаблон (так что почему они должны иметь возможность писать код Freemarker, потому что это будет проанализировано).
  • На моем веб-сайте пользователь должен уметь для редактирования этого шаблона. Поскольку код хранится в базе данных как написано выше, есть проблема:

Проблема

Когда я непосредственно обрабатываю шаблон в веб-интерфейсе, часть text будет правильно отображаться с тегами <u></u>, но часть code будет отображаться как html, что может вызвать странное поведение (например, так как обозначение freemarker </#list> автоматически преобразуется в <!--#list-->).

Но если я сделаю полный шаблон только текстовым, часть text с тегами <u></u> также не будет отображаться.

Ожидаемый результат

Я хочу прочитать переменную шаблона с помощью JavaScript/jQuery, а затем проанализировать каждый data-type с помощью text как html и code как текст.

Как я могу пропустить шаблон и сделать это?

4b9b3361

Ответ 1

Рекомендация

Для анализа HTML в javascript обычно используется объект DOMParser (поддерживается IE10 +).

Как вы сказали, синтаксический анализ не выполняется внутри раздела data-type="code", потому что он не знает, как обрабатывать теги </#...>...

const templ = `<section><div class="row"><div class="col-sm-12"><section data-type="code"><#code></#code></section></div></div><div class="row"><div class="col-sm-12" data-type="container-content"><section data-type="text"><u>Lorem</u> ipsum</section></div></div></section>`;
const parser = new DOMParser();
const doc = parser.parseFromString(templ, "text/html");

console.log(
  "Wrongly parsed </#code> tag:\n",
  doc.querySelector("[data-type='code']").innerHTML
);

Ответ 2

Существует альтернативный синтаксис, который использует квадратные скобки вместо угловых скобок.

Проверьте, разрешает ли он проблему идентификации вашего тега, не испортив никакую другую функцию.

https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html

EDIT 1

Чтобы показать исходный код внутри тегов < #code при анализе HTML, вы можете избежать его в своей базе данных (выделите html специальные символы, такие как <, > и & to & lt; & gt; и &). Таким образом, когда он визуализируется, в содержимом кода не создаются теги html, и документ не будет испорчен.

Затем вы можете отобразить все содержимое базы данных напрямую как HTML: текст будет содержать разметку, а код будет текстовым.

Чтобы сделать эту модификацию, вы можете использовать регулярные выражения, чтобы найти то, что заключено в теги < #code > , и заменить эквивалент, экранированный HTML. Точный способ сделать это зависит от языка, который вы будете использовать для задания, так как есть некоторые отличия в RegExes и доступных функциях escape-функций.

EDIT 2

Если вы загружаете контент с помощью AJAX, у вас есть возможность применить замену в javascript, ПОСЛЕ того, как контент был получен с сервера, сохраняя вашу базу данных как есть.

Ответ 3

Вы можете использовать коды кодировки, поэтому он не выполняется перед выводом. ссылка HTML charset

Они могут редактировать его, поскольку он выглядит нормально и отправляет его вам или серверу. Убедитесь, что вы включили ссылку на кодировку в голове.

<meta charset="UTF-8"> // HTML5 
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"> // HTML4

<!-- @CHARSET / No execute -->
&#60;section&#62;
    &#60;div class="row"&#62;
        &#60;div class="col-sm-12"&#62;
            &#60;section data-type="code"&#62;
                <#code> <!-- Run this --> </#code>
            &#60;/section&#62;
        &#60;/div&#62;
    &#60;/div&#62;
    &#60;div class="row"&#62;
        &#60;div class="col-sm-12" data-type="container-content"&#62;
            &#60;section data-type="text"&#62;
                &#60;u&#62; <!-- Don't run --> &#60;/u&#62; 
            &#60;/section&#62;
        &#60;/div&#62;
    &#60;/div&#62;
&#60;/section&#62;

Ответ 4

Если я не понял это неправильно, вы можете использовать тег <plaintext> для отображения блока как текст на странице.

<plaintext>
    <#code></#code>
</plaintext>

Ответ 5

Как насчет этого?

// https://stackoverflow.com/info/7477/autosizing-textarea-using-prototype
function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if (!text)
      return;

   /* Accounts for rows being deleted, pixel value may need adjusting */
   if (text.clientHeight == text.scrollHeight) {
      text.style.height = "30px";
   }

   var adjustedHeight = text.clientHeight;
   if (!maxHeight || maxHeight > adjustedHeight)
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if (maxHeight)
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if (adjustedHeight > text.clientHeight)
         text.style.height = adjustedHeight + "px";
   }
}

$('textarea').each(function(i,v){
  FitToContent($(v)[0], document.documentElement.clientHeight)
});
textarea {
  background: transparent;
  border: 0;
  font-family: 'Times New Roman';
  font-size: 1em;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
    <div class="row">
        <div class="col-sm-12">
            <h4>First code block</h4>
            <section data-type="code">
                <textarea class='code'><#code>
    <h2>FreeMarker Spring MVC Hello World</h2>
    <table class="datatable">
        <tr>
            <th>Make</th><th>Model</th>
        </tr>
        <#list model["carList"] as car>
        <tr>
            <td>${car.make}</td>
            <td>${car.model}</td>
        </tr>
        </#list>
    </table>
</#code></textarea>
            </section>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-12" data-type="container-content">
            <h4>Regular HTML section</h4>
            <section data-type="text">
                <u>Lorem</u> ipsum
            </section>
        </div>
    </div>
      <div class="row">
        <div class="col-sm-12">
            <h4>Second code block</h4>
            <section data-type="code">
                <textarea class='code'><#code>
    <table class="datatable">
        <tr>
            <th>Name</th><th>Email</th>
        </tr>
        <#list model["personList"] as person>
        <tr>
            <td>${person.name}</td>
            <td>${person.email}</td>
        </tr>
        </#list>
    </table>
</#code></textarea>
            </section>
        </div>
    </div>
</section>