Создание содержания для статьи с помощью PHP 


Создание содержания для статьи с помощью PHP

Опубликовано

 

Введение

Содержание предлагает краткое представление посетителю сайта об излагаемой статье. Если посетителя интересует только определенная тема статьи, кликнув на соответствующем заголовке содержания, он непосредственно переходит к ней. Обычно в содержание выносят все заголовки статьи, и структурируют их в иерархическом порядке. Далее будет описана технология автоматической генерации “содержания” с помощью PHP.

Требования к статье

Работа PHP скрипта заключается в поиске заголовков различных уровней <H> в статье, и на их основе конструируется “содержание”. Поэтому в первую очередь необходимо подготовить статью таким образом, чтобы в ней присутствовали заголовки хотя бы первого уровня <H1>. На рисунке 1 приведен фрагмент HTML кода, в котором иллюстрировано правильное оформление текста, с учетом стандартов. А на рисунке 2 показано, как браузер отобразит этот фрагмент.

 HTML верстка

Рис. 1. HTML верстка.

 

 Фрагмент текста в браузере

Рис. 2. Фрагмент текста в браузере.

 

Поиск заголовков в статье с помощью регулярных выражений

Для начала необходимо создать строковую переменную и присвоить ей содержимое статьи. К примеру, можно создать переменную $content.

<?php
  $content="
    <h1>Язык программирования PHP</h1>
    <h2>Типы</h2>
    <h3>Целые числа</h3>
    ….
    ….
  ";
?>

Для поиска заголовков в статье воспользуемся функцией preg_match_all.

preg_match_all("/<[hH]([1-6])>(.*?)</[hH][1-6]>/",$content,$matches);

Действия функции состоят в следующем: из содержимого переменной $content, будут найдены все заголовки с первого по шестой уровень. Шаблон, по которому будет осуществляться поиск, составлен на основе регулярного выражения "/<[hH]([1-6])>(.*?)</[hH][1-6]>/". Результат выполнения функции будет присвоен массиву $matches. Для текущего примера содержимое $matches показано на рисунке 3.

 Содержимое массива $matches

Рис 3. Содержимое массива $matches

Как видно из рисунка 3, массив $matches - двумерный, со следующим содержимым:

  • [0][0-9] –названия заголовков статьи заключенных в HTML теги;
  • [1][0-9] –уровень вложенности заголовка;
  • [2][0-9] –названия заголовков статьи;

 

Создание “содержания”

На основе данных представленных в массиве $matches сгенерируем “содержание”, которое поместим в новую строковую переменную $soderjanie.

<?php
$soderjanie="<div id="soderjanie"><h1>Содержание</h1><ul class="header1">";
for ($i=0;$i<count($matches[0]);$i++){

  if ($i<>0 and $matches[1][$i]>$matches[1][$i-1]){
    $soderjanie.="<ul class="header{$matches[1][$i]}">";
  }elseif ($i<>0 and $matches[1][$i]<$matches[1][$i-1]){
    $quantity=$matches[1][$i-1]-$matches[1][$i];
    for ($j=1;$j<=$quantity;$j++)$soderjanie.="</ul>";
  }
  $soderjanie.="<li>{$matches[2][$i]}</li>";

}
$soderjanie.="</ul>";
?>

Итак “содержание” готово, и храниться в переменной $soderjanie. Если его вывести в браузере, выглядеть оно будет, как показано на рисунке 4.

 Содержание в виде текста

Рис. 4. Содержание в виде списка с обычным текстом.

Однако на данном этапе “содержание” представляет собой вложенный список с обычным текстом. Следующим этапом будет небольшое усовершенствование содержания, путем превращения обычного текста в якоря, при нажатии на которые можно напрямую переходить к интересующей теме. Для этого в уже описанный выше код добавим пару дополнительных строк:

<?php
$quantityanchor=0;//Счетчик для якоря
$soderjanie="<div id="soderjanie"><h1>Содержание</h1><ul class="header1">";
for ($i=0;$i<count($matches[0]);$i++){

  if ($i<>0 and $matches[1][$i]>$matches[1][$i-1]){
    $soderjanie.="<ul class="header{$matches[1][$i]}">";
  }elseif ($i<>0 and $matches[1][$i]<$matches[1][$i-1]){
    $quantity=$matches[1][$i-1]-$matches[1][$i];
    for ($j=1;$j<=$quantity;$j++)$soderjanie.="</ul>";
  }

  //Создание якорей в “содержании”, на заголовки в статье
  $quantityanchor++;
  $soderjanie.="<a href="#HAnch{$quantityanchor}"><li>{$matches[2][$i]}</li></a>";

  //Изменение заголовков статьи, путем добавления для каждого уникального ID
  $content=str_replace($matches[0][$i],"<H{$matches[1][$i]} id="HAnch{$quantityanchor}">{$matches[2][$i]}</H{$matches[1][$i]}>",$content);

}
$soderjanie.="</ul></div>";
?>

 

Теперь “содержание” состоит из якорей ссылающихся на заголовки статьи как показано на рисунке 5. 

 Содержание состоящее из ссылок на заголовки статьи

Рис. 5. Содержание состоящее из ссылок на заголовки статьи.

Осталось оформить содержание с помощью CSS

 

Оформление “содержания”

Применим к содержанию следующие стили:

<style>
  #soderjanie h1{
    margin:0;text-align:center;
    font:20px "Tahoma";text-decoration:underline;
    letter-spacing:5px;color:#004099;
  }

  #soderjanie a {color:#000000;text-decoration:none;}
  #soderjanie a:hover {color:#000000;text-decoration:underline;}

  #soderjanie {border-bottom:1px dotted black}
  #soderjanie li{list-style:circle;}

  #soderjanie .header1{font:small-caps 15px "Tahoma";}
  #soderjanie .header1 > a li{line-height:2;list-style:none;}

  #soderjanie .header2{font:normal 14px "Tahoma"}
  #soderjanie .header2 > a li{line-height:1.7;}

  #soderjanie .header3{font:normal 13px "Tahoma"}
  #soderjanie .header3 > a li{line-height:1.3;}
</style>