O webu
Automatické generování obsahu

Obsah stránky (anglicky: table of contents, zkráceně TOC) může zpřehlednit čtení delšího článku na obsahovém webu.

Takový obsah například běžně používá Wikipedie, kdy se na začátku stránky zobrazuje seznam obsahující odkazy na jednotlivé části dané stránky.

Jak na to

Prvním předpokladem pro automatickou tvorbu Obsahu je důsledné používání kotev/záložek u nadpisů. Tj. u každého nadpisu mít identifikátor.

<h1 id="nadpis">
  Text nadpisu
</h1>

Chybí-li identifikátory, není nic ztraceno. I identifikátor je možné automaticky vygenerovat. Stačí projít nadpisy a v jejich textu převést mezery na spojovníky a odstranit diakritiku (více v článku Vytvoření přátelského URL).

TOC (table of contents) umí generovat i nástroje typu Texy!.

Generování obsahu stránky

Z nadpisů (nebo obecně z elementů, které mají atirbut id) je potom celkem jednoduché sestavit výsledný seznam.

Sestavování obsahu

V zásadě existují dvě možnosti, jak výsledný obsah sestavit.

  1. Použít HTML seznam (<ul>/<ol>) a různé úrovně nadpisů do sebe zanořovat.
  2. Zanoření znázornit jen CSS styly.

Druhů způsob vypsání obsahů značně zjednodušuje. Stačí v podsatě ke každé položce s id přiřadit CSS třídu odpovídajícího názvu. A zbytek zařídit kaskádovými styly.

<ul>
  <li class="uroven-h1"></li>
  <li class="uroven-h2"></li>
</ul>

JavaScript

Na straně klienta v JS je to asi nejsnazší. Zvlášť za pomoci querySelectoru (od IE 8) je vybrání potřebných elementů hodně elegantní.

var polozky = document.querySelectorAll("[id]");

Tyto položky projedeme cyklem:

var obsah = "<h2>Obsah</h2><ul>";
for (var i = 0; i < polozky.length; i++) {
  var uroven = polozky[i].tagName.toLowerCase();
  obsah += "<li class='level-" + 
            uroven + 
            "'><a href='#" + 
            polozky[i].id + "'>" + 
            polozky[i].innerHTML + "</a>";    
}
obsah += "</ul>";

Nyní stačí obsah proměnné vypsat do nějakého <div>u.

<div class="obsah"></div>
<script>
  document.querySelector(".obsah").innerHTML = obsah;
</script>

V případě, že se na stránce používají identifikátory i pro stylování, je vhodné některé značky buď přeskočit (<div> a <span>), nebo napak vytvářet odkazy jen pro nadpisy (<h1>, <h2>, …). Stačí k tomu kontrolovat vlastnost tagName (v ukázce hodnotu proměnné uroven).

if (uroven == "div" || uroven == "span") continue;

PHP

Podobný seznam může vyzobat z HTML i PHP.

function tableOfContents($html) {
  $pattern = '/<h([2-5]) id=["\'](.*?)["\'].*?>(.*?)<\/h\1>/';
  preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);

  $output = "";
  foreach ($matches as $item) {
    $output .= '
      <li class="level-' . $item[1] . '">
        <a href="#' . $item[2] . '">' . $item[3] . '</a>
      </li>';
  }
  
  return (!empty($output)) ? 
    "<ul class='summary'>" . $output . "</ul>" : 
    "";
}

Funkční ukázka na GitHubu.

Zvýraznění aktuální části

Zajímavé vylepšení může být zvýraznění aktivní části, pokud je na ní odrolováno. Pochopitelně v případě, že je prostor pro fixní umístění seznamu nadpisů.