BBcode как добавить свой код (SMF 2.017)

Автор Ulibka, 18 мая 2020, 18:32:28

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Ulibka

Нужно добавить собственный BB код  вида: [smg id=79335]
Данную конструкцию мне надо преобразовать в html img и по номеру извлечь атрибут src из базы

Как это сделать я примерно представляю.
В файле
./Sources/Subs.php
надо найти функцию parse_bbc

Туда добавить новый тег используя конструкцию вида:

array(
   'tag' => 'smg',
   'type' => '
closed',
   'before' => '<img src="$1">',

   'parameters' => array(


        'id' => array('optional' => true, 'value' => ' src="$1"', 'match' => '(\d+)'),

)
),

Скажите пожалуйста, для чего служат конструкции disabled? Я так и не смог понять их предназначения?


disabled_content: used in place of content when the tag is
  disabled.  For closed, default is '', otherwise it is '$1' if
  block_level is false, '<div>$1</div>' elsewise.

disabled_before: used in place of before when disabled.  Defaults
  to '<div>' if block_level, '' if not.

disabled_after: used in place of after when disabled.  Defaults
  to '</div>' if block_level, '' if not.




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

validate: except when type is missing or 'closed', a callback to
  validate the data as $data.  Depending on the tag's type, $data
  may be a string or an array of strings (corresponding to the
  replacement.)



Скажите пожалуйста, надо ли для одиночного тега описывать parameters ?

В какое место parse_bbc мне надо вставить преобразование моего параметра в ссылку?

digger®

Конструкции disabled нужны чтобы можно было показывать свои заглушки, когда этот бб-код выключен.
Насчет остального, посмотрите пример https://github.com/realdigger/SMF-Redirector/blob/master/Sources/Mod-Redirector.php
Я там через хук переопределял коды url и iurl, так же можете и свои коды добавить в массив $codes

Ulibka

Большое спасибо за пример!

Но в моем пример тип тега получается closed ( [smg id=79335])
А в примечании написано что для типа closed функция validate не вызывается:

validate: except when type is missing or 'closed', a callback to
  validate the data as $data.  Depending on the tag's type, $data
  may be a string or an array of strings (corresponding to the
  replacement.)

У Вас основная работа идет как раз в validate и завершающая часть идет уже в buffer, а я получается validate не смогу воспользоваться?

digger®

#3
Как-то так

$codes[] = [
    'tag' => 'smg',
    'type' => 'closed',
    'content' => '<img src="{id}">',
    'parameters' => ['id' => ['validate' => 'findSmgSrc']]
];

function findSmgSrc($id)
{
    $src = doSomething($id);
    return $src;
}

Ulibka

Огромное спасибо еще раз!!!
 :D   smitten 
Но я никак не могу понять - как Вы смогли найти это решение ???

'parameters'
=> ['id' => ['validate' => 'findSmgSrc']]



Да, посмотрев Subs.php в строке 2095 я нашел две строчки кода:

elseif
(isset($possible['parameters'][$key]['validate']))
   $params['{' . $key . '}'] = $possible['parameters'][$key]['validate']($matches[$i + 1]);



Неужели Вы внимательно изучали все 3000 строк кода функции parce_bbc ?
Преклоняюсь перед Вашим мастерством!!!

Дайте пожалуйста еще один совет. В моей реализации findSmgSrc посылает запрос к базе и по id извлекает ссылку. Получается что запросов будет столько же - сколько и тегов smg.

Если изображения хранятся в attachments, то SMF делает по другому - определяет все имеющиеся attachments на странице и извлекает их за один запрос к базе.

Нет ли возможности как то обрабатывать теги за два прохода?
В первом проходе определить теги и их параметры, а во втором проходе уже слать запрос к базе ?

digger®

Найти решение помогло вот это
parameters: an optional array of parameters, for the form
  [tag abc=123]content[/tag].  The array is an associative array
  where the keys are the parameter names, and the values are an
  array which may contain the following:
- match: a regular expression to validate and match the value.
- quoted: true if the value should be quoted.
- validate: callback to evaluate on the data, which is $data.
- value: a string in which to replace $1 with the data.
  either it or validate may be used, not both.
- optional: true if the parameter is optional.
array(
'tag' => 'quote',
'parameters' => array(
'author' => array('match' => '([^<>]{1,192}?)'),
'link' => array('match' => '(?:board=\d+;)?((?:topic|threadid)=[\dmsg#\./]{1,40}(?:;start=[\dmsg#\./]{1,40})?|action=profile;u=\d+)'),
'date' => array('match' => '(\d+)', 'validate' => 'timeformat'),
),

ЦитироватьНет ли возможности как то обрабатывать теги за два прохода?
В первом проходе определить теги и их параметры, а во втором проходе уже слать запрос к базе ?

Можно в парсере бб-кодов  не делать выборку из базы, а в src ставить плейсхолдеры с id типа src="[[[1]]]" и все id записать в глобальный массив $context.
Потом навесить свою функцию на хук буфера и в ней по массиву id сделать выборку из базы одним запросом и в цикле перебрать id заменяя через str_replace в содержимом буфера плейсхолдеры на реальные значения.