Парсинг BBCode через AJAX

Список разделов phpBBex 1.x (поддерживается) Пожелания 1.x

Описание: В phpBBex 1.x чего-то не хватает? Напишите об этом здесь, и мы постараемся исправиться.
Правила раздела: Одна тема — один запрос новой возможности. Обязательно формируйте внятный заголовок, максимально отражающий суть вашей идеи. Также приведите примеры, где предлагаемая вами возможность будет актуальна.
Модератор: Поддержка

Сообщение #21 Sumanai » 28.09.2013, 21:03

factotum:тут рабочий пример Livepreview. Довести до ума и будет счастье

Ну да, минипрофиля нет. Да и отправка по каждому символу раз в секунду :eek: завалит любой сервер, кроме разве что вконтакта и круче.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #22 VEG » 28.09.2013, 21:07

factotum:ну и лайвпревью не совсем подойдет при использовании бб-медиа/ajax-based бб-тегов.
Если загружать предпросмотр во фрейм, то будет работать.
VEG M
Администратор
Аватара
Откуда: Finland
Репутация: 1653
С нами: 12 лет

Сообщение #23 factotum » 28.09.2013, 21:30

VEG:Если загружать предпросмотр во фрейм, то будет работать.
если честно, задачи предосмотра в реалтайм не ставил. думаю, пока остановлюсь на предосмотре по клику на "предосмотр". если станет тесно, будем двигаться дальше

Добавлено спустя 3 минуты 52 секунды:
Sumanai:завалит любой сервер, кроме разве что вконтакта и круче.
не завалит. но сетевые пакеты да, сыплются как из ведра. По другому нужно делать обработчик на js или обновлять по требованию. В последнем случае уже не лайв, но без редиректов.
Sumanai:минипрофиля нет
там реализация без заморочек. плагин определяет активность и отсылает содержимое формы в парсер. После пересылает полученный контент в условленный ноуд. Определить ид автора не составит труда. Думаю, можно сделать красиво.
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #24 Sumanai » 28.09.2013, 21:38

factotum:думаю, пока остановлюсь на предосмотре по клику на "предосмотр".

Это лучший вариант, просто и со вкусом.

factotum:плагин определяет активность и отсылает содержимое формы в парсер.

Не похоже. В файрбаге запросы каждую секунду.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #25 factotum » 28.09.2013, 21:42

и да, если VEG вынесет инициализацию bbcode в формате <div id="data-bbcode">JSON data</div>, то парсер на JS допишу :ill:

Добавлено спустя 4 минуты 1 секунду:
Sumanai:Не похоже. В файрбаге запросы каждую секунду.
есть вариант еще один. но это в моем случае с markitup. При вставке bbcode текстовый процессор создает индивидуальное событие. К нему и можно привязать обновление. Либо дописывать события в дефолтные скрипты phpBB, чтобы в итоге получить markitup...
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #26 Sumanai » 28.09.2013, 21:48

По кнопке проще и лучше. Нечего долбить сервер по пустякам.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #27 factotum » 28.09.2013, 23:56

заработало как хотелось бы.
в корень форума кидаем обработчик "preview.php":
Код: Выделить всё
<?php
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
include($phpbb_root_path . 'includes/message_parser.' . $phpEx);

$user->session_begin();
$auth->acl($user->data);
$user->setup();

$parser = new parse_message(utf8_normalize_nfc(request_var('text', '', true)));
$parser->parse(true, true, true);
$output    = $parser->format_display(true, true, true, false);

echo $output;
?>
тут следует обратить внимание на строку "$parser = new parse_message(utf8_normalize_nfc(request_var('text', '', true)));" переменная "text" определяет запрос. С такой же переменной нам нужно обращаться к обработчику.

В viewtopic_body.html находим подходящее место в конце листинга постов и маркируем его, скажем, <div id="preview"></div>

В принципе можно использовать разметку полноценного поста с данными текущего пользователя. То есть по сути там будет пустой пост, но с аватарой, подписью и прочими регалиями. Скрываем его по ID.

В форме быстрого ответа убиваем текущую кнопку и меняем что-нибудь вроде такого:
Код: Выделить всё
<span id="btn-preview" class="btn btn-link">{L_PREVIEW}</span>

Остается все это связать запросом ajax:
Код: Выделить всё
!function ($) {
   /* Preview */
   $(function(){
      function preview() {
         // Получаем содержимое панели ответа и помещаем его в переменную text, объявленную в парсере
         var text = "text="+encodeURIComponent(document.getElementById("message").value)
         //Техническая строка - выводит содержимое, которое получили. можно удалить
         console.log('text:',text)
         // Выполняем сам запрос
         $.ajax({
            type: 'POST',
            dataType: 'text',
            global: false,
            //Выше отменяем ненужную глобальность объектов. Ниже в url указываем адрес, по которому будем стучаться
            url: 'preview.php',
               data: text,
               success: function(data) {
                  // отладочная строка - выводим в консоль что нам прислал парсер
                  console.log('data:',data)
                  // ломим место, где нам нужно показать превью и подставляем туда полученное от парсера содержимое
                  $('#preview').html(data)
               },
               // На всякий случай для ошибки. Можно сообщить что-нибудь стоящее, пока отладочный код
               error: function(xhr, status, error) {
                  var err = eval("(" + xhr.responseText + ")");
                  alert(err.Message);
               }
            })
      }
      // ждем клика на кнопку превью
      $(document).on('click', '#btn-preview', function(e) {
         e.preventDefault()
         preview()
      })
   })
}(window.jQuery)

Работает достаточно быстро. Нужно поразмыслить о безопасности таких запросов. Скорее всего код немного обрастет
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #28 factotum » 29.09.2013, 00:35

возник вопрос. нужно ли обрабатывать bbcode_uid?

Добавлено спустя 6 минут 35 секунд:
и есть ли возможность проверить form_token или еще что-нибудь, чтобы избежать недружелюбных запросов к preview.php?
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #29 Sumanai » 29.09.2013, 01:16

factotum:В принципе можно использовать разметку полноценного поста с данными текущего пользователя.

Лучше их передавать во время постинга, чтобы иметь актуальные счётчики пузомерок.

factotum:В форме быстрого ответа убиваем текущую кнопку

Лучше просто повесить обработчик с return false, на всякий.

factotum:возник вопрос. нужно ли обрабатывать bbcode_uid?

message_parser должен его обрабатывать. Он нужен, иначе ббкоды не признаются.
Пошёл пробовать.

Добавлено спустя 25 минут 38 секунд:
factotum:<div id="preview"></preview>

То есть вы хотели написать <div id="preview"></div>.

Добавлено спустя 5 минут 12 секунд:
Sumanai:message_parser должен его обрабатывать. Он нужен, иначе ббкоды не признаются.

Понял, я не о том. При отправке нужно обрабатывать, при записи в БД. В предпросмотре он не нужен.

Вот, сваял за 5 минут:
пост.png
пост.png (5.28 КБ) Просмотров: 8769
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #30 factotum » 29.09.2013, 11:32

Sumanai:То есть вы хотели написать <div id="preview"></div>.
да :ill: Поправьте, пожалуйста, в посте. У меня редактирование уже закрыто.
Sumanai:Вот, сваял за 5 минут:
разбухает из-за конвертации символов. По другому никак. Это не критично.
Приснил полный список вопросов:
1. Безопасность. К запросу нужно прикручивать тоукен. А это критично.
2. Проверка разрешенных бб-кодов
3. Проверка длины сообщения
4. Проверка цензора
5. Проверка мейджик урлов
Может и еще чего. С этим будет полноценный предосмотр

Добавлено спустя 52 минуты 46 секунд:
немного пруфов по теме.
Начальная инициализация: https://wiki.phpbb.com/Practical.Add_custom_page
Проверка тоукена: https://wiki.phpbb.com/Check_form_key
Парсинг текста: https://wiki.phpbb.com/Tutorial.Parsing_text
Генерация текста для вывода: https://wiki.phpbb.com/Generate_text_for_display
Вывод на внешних страницах: https://wiki.phpbb.com/Practical.Displaying_posts_and_topics_on_external_pages

Добавлено спустя 3 часа 10 минут:
factotum:разбухает из-за конвертации символов. По другому никак. Это не критично.
строку:
Код: Выделить всё
var text = "text="+encodeURIComponent(document.getElementById("message").value)
заменить на:
Код: Выделить всё
var text = $('#message').val()
В хроме работает корректно. Нужно тестировать в других браузерах

Добавлено спустя 1 минуту 39 секунд:
добавил сообщение, а редактирование то закрыто. О как!

Забыл строчку:
Код: Выделить всё
var text = $('#message').val()
text = "text=" + text
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #31 Sumanai » 29.09.2013, 18:52

factotum:В хроме работает корректно. Нужно тестировать в других браузерах

В файрфоксе урлы не проскакивают, запарывается на &. В принципе нужно кодировать только несколько символов, остальное прекрасно отправляется, так как UTF-8.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #32 factotum » 29.09.2013, 19:44

Sumanai, есть у меня другая идея. Надеюсь, правильная.
Что дописать в запрос, чтобы попасть на страницу с превью?
чет не могу поймать этот параметр тут
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #33 Sumanai » 29.09.2013, 19:50

factotum:Sumanai, есть у меня другая идея. Надеюсь, правильная.

Озвучите?

factotum:Что дописать в запрос, чтобы попасть на страницу с превью?
чет не могу поймать этот параметр тут

Я тоже.
Разве что
/posting.php?mode=reply
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #34 factotum » 29.09.2013, 20:10

Sumanai:Озвучите?
phpbb нужно жить, чтобы понимать все нюансы джунглей кода.
Показалось, что проще сделать запрос аджакс к странице с превью, вытянуть оттуда превью и показать на странице.
Не быстро, побольше ресурсов. Но надежно, правильно и безопасно.
Sumanai:Я тоже.
уже поймал. Content-Disposition: form-data; name="preview"

Добавлено спустя 15 минут 52 секунды:
Для желающих побаловаться с отладочным кодом:
Код: Выделить всё
!function ($) {
   /* Preview */
   $(function(){
      function preview() {
         var form = document.postform
         var formData = new FormData(form)
         formData.append("preview", "")
         var url = form.action
         console.log("form:",form,"formdata:",formData,"url:",url)
         $.ajax({
            type: "POST",
            url: url,
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            success:  function(data){
               //alert("---"+data);
               console.log("data:",data)
            }
         })
      }
       
      $(document).on('click', '#btn-preview', function(e) {
         e.preventDefault()
         e.stopPropagation()
         preview()
      })
   })
}(window.jQuery)
по запросу ловим страницу, на которую должны были перейти.
Там уже ловим нужное. Этот же метод можно использовать для всего остального, в том числе загрузки файлов.
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #35 Sumanai » 29.09.2013, 21:31

Последнюю строчку забыли :smile:
Исправил.
Добавлено спустя 1 минуту 49 секунд:
И да, посылает всю страницу целиком. Ну нафиг такой аджакс.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #36 factotum » 29.09.2013, 21:44

Sumanai:И да, посылает всю страницу целиком. Ну нафиг такой аджакс.
как минимум - не нужно парится с php. Для меня код phpBB дремучий лес, повернутый к фронд-энд разработчикам нифига не лицом. А вот из формы ответа сделать шлюз для работы через ajax - почему бы и нет?
Получаем:
+ безопасные запросы
+ корректная поддержка всего функционала
+ избавляемся от редиректов
+ минимум кода

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


В противном случае нужен не один модуль на php. Кто это напишет?
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #37 Sumanai » 29.09.2013, 21:59

factotum:Для меня код phpBB дремучий лес, повернутый к фронд-энд разработчикам нифига не лицом.

ХЗ, я достаточно легко читаю код при необходимости. Он весьма простой. Хотя опыта у меня нет, в блокноте открыт код, а во вкладке браузера- php.net со страницей описания IF, ибо я забываю, что это такое :toothless: (утрирую).

factotum:Самом собой, в итоге нужно подменить все операции с формой быстрого ответа на запросы к шлюзу через аджакс.

По мне так просто немного модифицировать, распихав обработчики в нужных местах, типа если это аджакс- то не нужно поднимать код выдачи например списка последних 20 сообщений в обратном порядке. Во многих случаях даже условие писать не надо- только дополнить.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #38 factotum » 29.09.2013, 22:21

Sumanai:Во многих случаях даже условие писать не надо- только дополнить.
допилить можно то, где железно понимаешь как это работает и последствия. Если не уверен, чем это обернется - не трогать!

Пока попробую сделать зеркало формы ответа, чтобы стучаться только через аджакс
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #39 factotum » 30.09.2013, 09:04

Вопрос скорее к VEG. Где лучше смотреть, чтобы posting.php отдавал данные в JSON?
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Сообщение #40 factotum » 30.09.2013, 20:04

factotum:Где лучше смотреть, чтобы posting.php отдавал данные в JSON?
разобрался немного.

Собственно идея в черновике.
копируем posting.php с условным названием, скажем, postingajax.php
получаем точную копию обработчика событий форума, в которой не нужна генерация страницы:
строка 1567 : // Output page ...
тут комментируем строки исходной генерацию страницы.
в конце добавляем вывод данных в формате JSON, что-то вроде этого:
Код: Выделить всё
header('Content-type: application/json'); /* добавляем ревалентый заголовок при ответе страницы*/
/* Небольшой пример отправки данных превью */
$previewrow = array('message' => $preview_message, 'signature' => $preview_signature, 'signature_uid' => $preview_signature_uid, 'signature_bitfield' => $preview_signature_bitfield );
echo json_encode($previewrow);
Получаем шлюз, обрабатывающий данные. После отдает данные в формате JSON
добавляем скрипт:
Код: Выделить всё
!function ($) {
   /* Preview */
   $(function(){
      function preview() {
         // Собираем данные формы. Пока так, но в этом виде отсылает кучу не нужных данных. Правильней собрать значения полей input
         var form = document.postform
         var formData = new FormData(form)
         // добавляем событие предосмотра
         formData.append("preview", "")
         // Обрабатываем линк на парсер формы, подменяя posting.php на свой обработчик
         var url = form.action.replace('posting.php', 'postingajax.php');
         // Поглядываем в консоли на полученные данные
         console.log("form:",form,"formdata:",formData,"url:",url)
         // Отправляем запрос
         $.ajax({
            type: "POST",
            url: url,
            data: formData,
            dataType: "json",
            cache: false,
            contentType: false,
            processData: false,
            success:  function(data){
               console.log("data:",data)
            }
         })
      }
       // Слушаем клик по кнопке предосмотра
      $(document).on('click', 'input[name=preview]', function(e) {
         e.preventDefault()
         // Останавливаем действие по умолчанию
         e.stopPropagation()
         // Отправляем данные формы и получаем обработанные события
         preview()
      })
   })
}(window.jQuery)
Плюсы концепции:
+ Полноценный обработчик событий постинга с вытекающими
+ Безопасность в рамках безопасности форума
+ Возможность использовать любые события через запросы AJAX без редиректа на полную форму ответа
+ Нет откровенной необходимости в правках шаблона/ядра
+ Корректная обработка событий с поддержкой функциональности форума
+ Свобода обработки информации с помощью js
+ Пользователи без JS смогут пользоваться исходным функционалом

Интересны мнения других. Может найдутся минисы
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 12 лет

Пред.След.

Вернуться в Пожелания 1.x



cron