Автоматическое создание содержания статьи из тегов заголовков H2-H6 less * @link https://sandev.pro/ */ class HeadersMenu { /** * Шаблон строки в содержании. БЕЗ закрывающего тега li * %1$d - ID группы * %2$s - номер строки. Например: 2.2.3 * %3$s - имя группы, тега H* * @var string */ private static $tpl_list = '
  • %2$s %3$s'; /** * Шаблон формируемый для заголовка в теле статьи * %1$d - индекс тега h[1], h[2], h[3] ... * %2$d - ID группы * %3$s - имя группы * @var string */ private static $tpl_header = ' %3$s'; /** * Временная переменная для формирования списка и иерархии * @var array */ private static $menu = []; /** * Инициализация * @param mixed &$story текст полной новости * @return mixed сформированный шаблон списка содержания */ public static function init(&$story = '') { if (empty($story)) { return false; } preg_match_all("#(.*?)#is", $story, $hmenu); if (count($hmenu[2]) < 2) { return false; } self::$menu = []; foreach ($hmenu[2] as $k => $v) { $menu_id = $k + 1; $v = strip_tags($v); $v = trim($v); $h_tag = intval($hmenu[1][$k]); self::$menu[] = [ 'id' => $k+1, 'tag' => $h_tag, 'h' => $v ]; $tag = preg_quote($hmenu[0][$k]); $tag = str_replace('#', '\#', $tag); $story = preg_replace( "#{$tag}#", sprintf(self::$tpl_header, $h_tag, $menu_id, $v), $story, 1 ); } return self::buildSubMenu(self::$menu[0]['tag']); } /** * Создание списка с рекурсией для подпунктов * @param integer $prev номер первого, корневого тега H[?] * @param array $number номер строки * @param integer $sub уровень вложенности * @return mixed сформированный шаблон */ private static function buildSubMenu($prev = 0, $number = [1], $sub = 0) { $list = ''; while (self::$menu) { if (self::$menu[0]['tag'] == $prev) { $v = array_shift(self::$menu); $num = join('.', $number); $list .= sprintf(self::$tpl_list, $v['id'], $num, $v['h']); if (self::$menu[0]['tag'] > $v['tag'] ) { $temp = $number; array_push($number, 1); $list .= self::buildSubMenu(self::$menu[0]['tag'], $number, $sub + 1); $number = $temp; } $list .= '
  • '; $number[$sub]++; } else { break; } } if ($sub) { $list = '
      ' . $list . '
    '; } return $list; } } if (isset($row['full_story']) && $tpl instanceof dle_template) { $menulist = HeadersMenu::init($row['full_story']); $tpl->set('{hmenu}', $menulist); $tpl->set_block("#\[hmenu\](.*?)\[/hmenu\]#is", $menulist ? "\\1" : ''); $tpl->set_block("#\[not-hmenu\](.*?)\[/not-hmenu\]#is", $menulist ? '' : "\\1"); } ]]>
    set( '{navigation}', "" );]]> set( '{static}', $template );]]>