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

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

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

Сообщение #61 Sumanai » 05.10.2013, 21:04

factotum:откуда у Вас возьмется стандартный предпросмотр?

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

Сообщение #62 factotum » 05.10.2013, 21:08

Sumanai:И да, <hr> тоже надо удалять, а то плодится начинают.
Код: Выделить всё
!function ($) {
   /* Preview */
   $(function(){
      function preview() {
         var form = document.postform
         var formData = new FormData(form)
         formData.append("preview", "")
         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: "html",
            cache: false,
            contentType: false,
            processData: false,
            success:  function(data){
               // console.log("data:",data)
               $preview = $("#preview")
               $preview.next("hr").remove()
               $preview.remove()
               $(".post:last").after(data)
            }
         })
      }
       
      $(document).on('click', 'input[name=preview]', function(e) {
         e.preventDefault()
         e.stopPropagation()
         preview()
      })
   })
}(window.jQuery)
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #63 Sumanai » 05.10.2013, 21:19

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

Соврал. Нет там такого. Кодировка задаётся в корневом .htaccess как по умолчанию.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #64 factotum » 05.10.2013, 21:28

Sumanai:У пользователей без яваскрипта, к примеру.
Код: Выделить всё
.section-viewtopic #preview {
margin-top: 20px;
/* в общем все, что угодно */
}
а так?
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #65 Sumanai » 05.10.2013, 21:32

Собственно, никто не мешает в моём коде прописать заголовок:
Код: Выделить всё
//Проверяем заголовок, если запрос аякс- отдаём только сам пост, если нет- идём дальше
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) )
{
header('Content-Type: text/html; charset=utf-8');
$template->set_filenames(array(
   'body' => 'posting_preview.html')
);
$template->display('body');
garbage_collection();
exit_handler();
}}

Плюс ещё прописал более правильное определение заголовка и рекомендуемые функции выхода из скрипта при отправке содержимого.

factotum:а так?

А так нормально.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #66 factotum » 05.10.2013, 21:34

Sumanai:А так нормально.
раз нормально, можно двигаться дальше. Проиграть другие сценарии. Старт топика/Первое сообщение

Добавлено спустя 39 секунд:
Sumanai:Собственно, никто не мешает в моём коде прописать заголовок:
мне кажется так надежней. тем более, например, у меня, совсем другой код в htaccess

Добавлено спустя 3 минуты 55 секунд:
factotum:Старт топика/Первое сообщение
хехе, в этих случаях мы оказываемся сразу в posting.php
Смысла в ajax становиться очень мало
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #67 Sumanai » 05.10.2013, 21:51

factotum:раз нормально, можно двигаться дальше.

Ага.

factotum:мне кажется так надежней. тем более, например, у меня, совсем другой код в htaccess

Соглашаюсь.

factotum:хехе, в этих случаях мы оказываемся сразу в posting.php
Смысла в ajax становиться очень мало

Там тоже есть кнопка "Предпросмотр", и на неё тоже иногда нажимают, чтобы посмотреть, как будет выглядеть тема.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #68 factotum » 05.10.2013, 22:02

следующий сценарий - PM. Нужна поддержка PHP.
или отказаться от превью в других шаблонах еще в js:
Код: Выделить всё
$(document).on('click', '.section-viewtopic input[name=preview]', function(e) {
Sumanai:чтобы посмотреть, как будет выглядеть тема.
там терять нечего - один пост с быстрым редиректом на тот же пост. если очень нужно, то можно. имхо не обязательно.

Добавлено спустя 16 минут 9 секунд:
Код: Выделить всё
!function ($) {
   /* Preview viewtopic*/
   $(function(){
      function preview() {
         var form = document.getElementById("postform")
         var formData = new FormData(form)
         formData.append("preview", "")
         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: "html",
            cache: false,
            contentType: false,
            processData: false,
            success:  function(data){
               // console.log("data:",data)
               if ($("#preview").length){
                  $preview = $("#preview")
                  $preview.next("hr").remove()
                  $preview.remove()
               }
               $(".post:last").after(data)
            }
         })
      }
       
      $(document).on('click', '.section-viewtopic input[name=preview]', function(e) {
         e.preventDefault()
         e.stopPropagation()
         preview()
      })
   })
}(window.jQuery)
до этого форма ловилась по уникальному имени. а оно есть не везде. Скажем, в PM - только ID
так перехватываем клик по превью только на шаблоне viewtopic_body.html

Добавлено спустя 5 минут 54 секунды:
можно еще пощупать быстрое редактирование. но в этом случае нужно получать и саму форму
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #69 Sumanai » 05.10.2013, 22:41

factotum:следующий сценарий - PM. Нужна поддержка PHP.

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

Сообщение #70 factotum » 05.10.2013, 22:45

Sumanai:Никак не могу понять, как там работает шаблонизатор
не помогу. не хватает нервной системы.
предположу, что это:
Код: Выделить всё
/ Select the active module
$module->set_active($id, $mode);

Добавлено спустя 3 минуты 10 секунд:
У формы линк на исполнение: /ucp.php?i=pm&amp;mode=compose&amp;action=post&amp;sid=...
текущий JS ее ловит. подменить запрос без проблем:
Код: Выделить всё
var url = form.action
            .replace('posting.php', 'postingajax.php')
            .replace('ucp.php', 'ucpajax.php')
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #71 Sumanai » 05.10.2013, 22:58

factotum:предположу, что это:

Я дошёл до ucp_pm_compose. Там явно логика отправки личных сообщений. Но шаблон нигде не подключается.
Единственное, это
Код: Выделить всё
case 'compose':
//неинтересный нам код
include($phpbb_root_path . 'includes/ucp/ucp_pm_compose.' . $phpEx);
            compose_pm($id, $mode, $action, $user_folders);

$tpl_file = 'posting_body';
Посмотрю, куда девается этот $tpl_file

Добавлено спустя 55 минут 46 секунд:
В общем там всё сложно. Формирование ответа идёт немного по другому. Но нашёл, куда можно приткнуть наш код. В файле \includes\ucp\ucp_pm_compose.php ищем
Код: Выделить всё
unset($message_text);
И добавляем перед
Код: Выделить всё
      if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) )
      {
      header('Content-Type: text/html; charset=utf-8');
      $template->set_filenames(array(
         'body' => 'posting_preview.html')
      );
      $template->display('body');
      garbage_collection();
      exit_handler();
      }
Осталось придумать, куда это вставить, и в яваскрипте сделать разделение, куда что вставлять, в зависимости от текущего скрипта.

Добавлено спустя 29 минут 31 секунду:
Внимание! Предыдущий код всё рушит при незаполненном сообщении :sad:
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #72 factotum » 06.10.2013, 12:50

Sumanai:if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) )
добавить небольшой фоллбек:
Код: Выделить всё
// Output page ...
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   $template->set_filenames(array(
      'body' => 'posting_preview.html')
   );
   header('Content-Type: text/html; charset=utf-8', true);
   $template->display('body');
   garbage_collection();
   exit_handler();
}
PHP работает, но есть чувство не законченности.
Добавлено спустя 18 минут 6 секунд:
Нашел первую. Постинг от имени "Гость" требует Имени и кода капчи. Если их нет - превью не показывает и не показывает ошибки. Нужно добавлять

Добавлено спустя 29 минут 9 секунд:
Код: Выделить всё
garbage_collection();
exit_handler();
не совсем понятен такой метод. Почему не exit() или лучше die()?

Добавлено спустя 52 минуты 56 секунд:
получилось пока так:
Код: Выделить всё
// Output page ...
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   $template->set_filenames(array(
      'body' => 'posting_preview.html')
   );
   header('Content-Type: text/html; charset=utf-8', true);
   $template->display('body');
   die();
}

Добавлено спустя 35 минут 13 секунд:
отлавливаем ошибки:
Код: Выделить всё
// Output page ...
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   header('Content-Type: text/html; charset=utf-8', true);
   if (sizeof($error)) {
      echo '<div class="alert alert-danger"><p class="error">' .  implode('</p><p class="error">', $error) . '</p></div>';
   } else {
      $template->set_filenames(array(
         'body' => 'posting_preview.html')
      );
      $template->display('body');
   }
   die();
}

Добавлено спустя 19 минут 9 секунд:
далее:

в нынешней реализации ответ сервера растянут в процессах выполнения кода PHP
Выглядит это примерно так:
{время выполнения операции}[вывод]{время выполнения операции}[вывод]{время выполнения операции}[вывод].....[закрытие соединения]
Правильней было бы выводить через буфер.
Что-то вроде такого:
ob_start(); // открываем буфер вывода
echo("Hello there!"); // добавляем нужное
ob_end_clean(); //закрываем буфер.
С буфером передача данных выглядит примерно так:
{время выполнения всех операций}[вывод][закрытие соединения]

Добавлено спустя 24 минуты 40 секунд:
получилось так:
Код: Выделить всё
// Output page ...
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   header('Content-Type: text/html; charset=utf-8', true);
   ob_start();
   if (sizeof($error)) {
      echo '<div class="alert alert-danger"><p class="error">' .  implode('</p><p class="error">', $error) . '</p></div>';
   } else {
      $template->set_filenames(array(
         'body' => 'posting_preview.html')
      );
      $template->display('body');
   }
   $size = ob_get_length(); // Определяем длину контента
   header("Content-Length: $size"); // Помещаем длину в заголовок ответа
   ob_end_flush();     // Закрываем буфер
   flush();            // Отдаем содержимое буфера
   ob_end_clean(); // Сбрасываем буфер
   die();
}
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Предпросмотр AJAX RC1

Сообщение #73 factotum » 06.10.2013, 18:55

предлагаю зарелизить наработанное.

Предпросмотр сообщений без перезагрузки страницы.
Почему:
+ Снижение нагрузки на сервер
+ Снижение нагрузки для клиентов
+ Быстрое исполнение

RC1:
+ Добавлен коллбек ошибок
+ Добавлена прокрутка к получаемым блокам
+ Данные отдаются через буфер
+ Небольшие корректировки, направленные на увеличение производительности со стороны клиентов

Скорость работы на сервере:
preview-speed.png
preview-speed.png (4.82 КБ) Просмотров: 8647


Интеграция
открыть файл:
Код: Выделить всё
\styles\prosilver\template\overall_header.html
найти:
Код: Выделить всё
</head>
Добавить перед:
Код: Выделить всё
<script src="{ROOT_PATH}assets/js/preview.min.js"></script>

(c) factotum, Sumanai

Лицензия: GPL 3
Вложения
preview-13-10-06.zip
(16.18 КБ) Скачиваний: 485
Последний раз редактировалось factotum 06.10.2013, 19:26, всего редактировалось 1 раз.
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #74 Sumanai » 06.10.2013, 19:26

factotum:не совсем понятен такой метод. Почему не exit() или лучше die()?

Это рекомендуемый разработчиками phpBB метод. Вычитал когда- то в документации. garbage_collection(); - сборщик мусора, тоже пригодится. Он вызывается в стандартной функции page_footer(). Так как мы выводим страницу своими силами, то должны позаботится об этом сами.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #75 factotum » 06.10.2013, 19:31

Sumanai:garbage_collection(); - сборщик мусора
Closing the cache object and the database :smile:
согласен, правлю

Sumanai:Это рекомендуемый разработчиками phpBB метод
не нашел ничего по теме
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #76 Sumanai » 06.10.2013, 19:38

Главный минус- IE<10 не поддерживают объект FormData. В следующей версии надо бы собирать данные самому, чтобы вырезать мусор и заставить работать на ещё актуальных ИЕ9 и 8.

Добавлено спустя 49 секунд:
factotum:не нашел ничего по теме

Завершение работы

Ваша страница должна вызывать либо page_footer() в конце, чтобы обработать вывод шаблона и завершить работу скрипта, или, по крайней мере, вызывать exit_handler(). Этот вызов необходим потому, что он вызывает внешние приложения, присоединенные к phpBB, необходимые для выполнения в конце работы скрипта.

Добавлено спустя 6 минут 38 секунд:
Как починим ИЕ8-9- можно будет оформить культурный мод. Думаю, он должен пойти на стандартном phpBB без правок. Может выложить на phpbbguru, на радость местному населению? Автомоды я умею оформлять.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Сообщение #77 factotum » 06.10.2013, 19:58

Sumanai:культурный мод
я не против, но заниматься этим не буду.

пока Вам для размышления:
Код: Выделить всё
// Output page ...
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   if (@extension_loaded('zlib') && !headers_sent() && ob_get_level() <= 1 && ob_get_length() == 0) {
      ob_start('ob_gzhandler');
   } else {
      ob_start();
   }
   header('Content-type: text/html; charset=UTF-8');
   if (sizeof($error)) {
      echo '<div class="alert alert-danger"><p class="error">' .  implode('</p><p class="error">', $error) . '</p></div>';
   } else {
      $template->set_filenames(array(
         'body' => 'posting_preview.html')
      );
      $template->display('body');
   }
   $size = ob_get_length(); // Определяем длину контента
   header("Content-Length: $size"); // Помещаем длину в заголовок ответа
   ob_end_flush(); // Закрываем буфер
   flush(); // Отдаем содержимое
   ob_end_clean(); // Сбрасываем буфер
   garbage_collection(); // Сбрасываем кеш и закрываем соединения с базой
   exit_handler(); // Закрываем соединения с присоедененными приложениями
   die();
}
Мог чего и лишнего добавить. Проверить бы каждую команду. Есть мнение, что die() вполне достаточно
И у меня на серверах несколько особые отношения со сжатием, поэтому попрошу посмотреть на предмет сжатия ответа. Теоретически должно работать, если форум отдает сжатые страницы.

Пока гляну js.
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #78 Sumanai » 06.10.2013, 20:20

factotum:И у меня на серверах несколько особые отношения со сжатием, поэтому попрошу посмотреть на предмет сжатия ответа. Теоретически должно работать, если форум отдает сжатые страницы.

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

Сообщение #79 factotum » 06.10.2013, 20:30

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

Sumanai:Но у моего локалхоста так же несколько особые отношения со сжатием.
Может просто не подключена библиотека сжатия?
А так phpBB юзает устаревший метод сжатия средствами PHP. Если PHP подключено к Апачу как CGI/FastCGI, без танцев с бубном - прощай сжатие. Правильней сжимать Апачем

Добавлено спустя 11 минут 52 секунды:
Подправленный код с поддержкой IE < 10
Мусора нет
Код: Выделить всё
!function ($) {
   /* Preview viewtopic*/
   $(function(){
      function preview() {
         var form = document.getElementById("postform")
         var formData = $(form).serialize() + '&preview'
         var url = form.action
            .replace('posting.php', 'postingajax.php')
            .replace('ucp.php', 'ucpjax.php')
         console.log("form:",form,"formdata:",formData,"url:",url)
         $.ajax({
            global: false,
            type: "POST",
            url: url,
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            success:  function(data){
               // console.log("data:",data)
               if ($("#preview").length){
                  $preview = $("#preview")
                  $preview.next("hr").remove()
                  $preview.remove()
               }
               $(".alert").remove()
               $(".post:last").after(data)
               target = document.getElementById("preview") || document.getElementsByClassName("alert")[0]
               $('html, body').animate({
                  scrollTop: $(target).offset().top
               }, 200)
            }
         })
      }
       
      $(document).on('click', '.section-viewtopic input[name=preview]', function(e) {
         e.preventDefault()
         e.stopPropagation()
         preview()
      })
   })
}(window.jQuery)
factotum
Автор темы
Откуда: Люксембург
Репутация: 234
С нами: 11 лет 11 месяцев

Сообщение #80 Sumanai » 06.10.2013, 20:45

factotum:не все сервера поддерживают такие запросы.

Тогда смысла в проверке содержимого при том, что не поддерживается сам заголовок- тем более нет.
Для надёжности можно в пост добавлять AJAX=TRUE, это точно будет работать на кривых серверах.

factotum:Может просто не подключена библиотека сжатия?

В том то и дело что подключена. Но сжимает неохотно и далеко не всё, что надо. Но у меня в качестве локалхоста openserver на винде, так что тут всё может быть.

Вот ещё- гостями так и не отправляется. Я кажется знаю почему- мешает код VEG, который от ботов защищает, капчи не причём.
Sumanai M
Аватара
Репутация: 1677
С нами: 11 лет 2 месяца

Пред.След.

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