H2Menu

Es war im Juni 2013, als ich einige längere Seiten überarbeitet hatte und mich gefragt habe, ob ich die Seiten nun in mehrere unterseiden aufgliedern sollte oder sonst wie die Wortschlange von ca. 5-15 DIN-A4-Seiten gliedern kann. Ich halte mich ja schon bei jeder Seite an die Nutzung der Überschriften <h1>, <h2> und <h3>. Es gibt auf jeder Seite immer nur genau eine Überschrift der ersten Ebene (<h1>) und in der Regel mehrere Überschriften <h2> und eher selten auch <h3>. Dann bin ich auf die Idee gekommen unter der H1 Überschrift einfach eine Aufzählung zu erstellen, die die H2-Überschriften als kleines Inhaltsverzeichnis anzeigt.

Update. Diese Funktion wurde mittlerweile mit HTML5 umgesetzt. Siehe auch MSXFAQ Besucher umfrage

VBA-Skript

Nun kann und will ich meine Zeit nicht damit verbringen, bei allen Seiten manuell so eine Liste zu pflegen. Also habe ich den Code um die Funktion "PageWork" einfach um weitere Zeilen ergänzt.

Der Code prüft zuerst, ob es eine "index.htm"-Seite ist. Die möchte ich nicht um das H2menu bereichern, da diese schon eine Inhaltsseite ist.

If (LCase(Right(pw.Document.URL, 9)) = "index.htm") Then
            Call Logging(2, "Pagework h2menu: skip index.htm-page at " & MakeRel(ActiveWeb.URL & "/", pw.Document.URL))

Dann prüfe ich, ob es überhaupt eine "h1"-Überschrift gibt. Seiten ohne Überschrift werden übersprungen. Da kann nur unsinn raus kommen.

ElseIf (pw.Document.templateRegions.Item("content").all.tags("h1").Length = 0) Then
   Call Logging(2, "Pagework h2menu: no H1 entries. at " & MakeRel(ActiveWeb.URL & "/", pw.Document.URL))

Dann wird geprüft, ob es "genügend" h2-Überschriften gibt. Eine Auflistung macht keinen Sinn, wenn es keine oder nur eine H2-Überschrift gibt. Sollte eine Auflistung dann nicht erforderlich sein, dann schaue ich aber nach, ob es vielleicht noch eine frühere Auflistung gibt die ich entfernen muss. Weiterhin entferne ich alle Anchors bei den Überschriften, deren Klasse "linkh2" ist.

ElseIf (pw.Document.templateRegions.Item("content").all.tags("h2").Length < 2) Then
   Call Logging(3, "Pagework h2menu: Number of H2 entries 0 or 1. at " & MakeRel(ActiveWeb.URL & "/", pw.Document.URL))
   If Not (pw.Document.templateRegions.Item("content").all.Item("h2menu") Is Nothing) Then
       Call Logging(3, "Pagework h2menu: removing h2menu section at " & MakeRel(ActiveWeb.URL & "/", pw.Document.URL))
       ' Entfernen des h2menu-Blocks
       pw.Document.templateRegions.Item("content").all.Item("h2menu").outerHTML = ""
       ' Rueckbau der eventuell nochvorhandenn Textmarken für Each h2anchor In pw.Document.templateRegions.Item("content").all.tags("a")
         If (h2anchor.className = "linkh2") Then
             h2anchor.outerHTML = h2anchor.innerHTML
         End If
      Next
       'pw.Document.templateRegions.Item("content").all.Item("h2menu").outerHTML = ""
   End If

Für den Fall, dass genug Überschriften gefunden wurden und es keinen DIV-Block mit der ID "h2menu" gibt, wird er angelegt. er wird später gefüllt bzw. ein bestehender Block einfach stumpf überschrieben.

Else
   If (pw.Document.templateRegions.Item("content").all.Item("h2menu") Is Nothing) Then
       Call Logging(4, "Pagework h2menu Adding entry after H1")
       Dim h1
       Set h1 = pw.Document.templateRegions.Item("content").all.tags("h1").Item(0)
       h1.outerHTML = h1.outerHTML + "<div id=""h2menu""></div>"
   End If

Und dann läuft das Skript nacheinander jede H2-Überschrift ab, versieht Sie mit einem Anchor bzw. aktualisiert ihn und addiert die Überschrift samt Link als HTML-Code in eine temporäre Variable.

   Dim h2, h2count, h2menuhtml
   h2count = 0
   h2menuhtml = "" für Each h2 In pw.Document.templateRegions.Item("content").all.tags("h2")
       h2count = h2count + 1
       If (h2.innerHTML <> ("<a name=""h2." + Trim(Str(h2count)) + """ class=""linkh2"">" + h2.innerText + "</a>")) Then
  h2.innerHTML = "<a name=""h2." + Trim(Str(h2count)) + """ class=""linkh2"">" + h2.innerText + "</a>"
       End If
       
       h2menuhtml = h2menuhtml + "<li><a href=""#h2." + Trim(Str(h2count)) + """ class=""linkh2"" title=""h2"">" 
 + h2.innerText + "</a></li>" + vbCrLf
   Next

Am Ende wird der Inhalt der Variable zusammen mit dem dem Tag "<ol>" als nummerierte Liste eingefügt

   h2menuhtml = "<p>Inhalt</p><ol>" + vbCrLf + h2menuhtml + vbCrLf + "</ol>" + vbCrLf
   ' Writing H2menu
   If Trim(pw.Document.templateRegions.Item("content").all.Item("h2menu").innerHTML <> Trim(h2menuhtml)) Then
       pw.Document.templateRegions.Item("content").all.Item("h2menu").innerHTML = h2menuhtml
   End If

Über die Abfrage mit TRIM sorge ich dass die Seite nur dann geändert wird, wenn sich wirklich etwas geändert hat. Würde ich jede Änderung stumpf schreiben, würde die Datei später als "geändert" dastehen und müsste auf die Webseite hochgeladen werden. Sharepoint Designer erkennt leider nicht selbst, wenn sich gar nichts ändern würde.

Für eine einfachere "Erkennung" und Formatierung habe ich den Blick in einer eigenen DIV-Klasse zusammen gefasst:

So kann ich im nächsten Schritt die Formate gezielt anwenden aber auch bei folgenden "PageGen"-Läufen den Textbereich immer wieder zuverlässig finden.

Formatierung mit CSS

Die Formatierung erfolgt wieder per CSS-Formate, wobei ich hier etwas tricksen musste, um vererbte Formate wieder außer Kraft zu setzen und mit dem ":hover" die Höhe anzupassen.

Den "SPAN"-Teil nutze ich, um den Text "Aufklappen" zu verbergen, wenn das Element von der Maus berührt wird.

Formatierung mit JavaScript

Die Funktion mit der Maus über ein Element zu fahren und es damit durch das "Hover"-Attribut sichtbar zu machen, ist auf Tablets (IOS, Android etc.) nicht zu nutzen. Daher habe ich den Teil "Aufklappen" mit einem JavaScript-Code hinterlegt. Ein Klick auf das "Aufklappen" zeigt das Menü an und ein weiterer Klick macht es wieder zu.

<a href="#" onclick="h2minmax('h2menu');">Aufklappen</a>

Der Code dazu habe ich in einer eigenen Datei hinterlegt und im Source mit eingebunden:

<script type="text/javascript" src="../h2minmax.js"></script>

Die Funktion selbst ist sehr übersichtlich. 

Damit gibt es nun aber auch die Möglichkeit auf Tablets und anderen Geräte über einen Klick auf die Überschrift das Menü aufzuklappen und offen zu lassen. Ein weiterer Klick stellt wieder das Standardverhalten her. nur das kleine Dreieck habe ich nicht passend "gedreht".

PageGen

Ich habe zuerst ca. 20 Seiten einzeln mit dem Skript bearbeitet um mögliche Fehler zu erkennen. In der Zeit habe ich das Skript optimiert, z.B. indem ich eine Seiten ohne H1 oder mit wenigen H2-Einträgen nun überspringe. Am 29. Jun 2013 habe ich dann mittels des normalen PageGen-Laufes alle Seiten bearbeiten lassen.

Die MSXFAQ besteht aktuell aus über 2000 HTML-Dateien. Ich denke dass das Skript ausreichend getestet ist aber wenn Sie eine verunstaltete Seite finden sollten, dann können Sie mir gerne die URL nennen und ich kümmere mich darum.
Ebenso kann es sein, dass ich das Layout noch etwas anpasse.

Nebeneffekt

Die Verlinkung der H2-Überschrifte als Link in der Seite führt nun auch dazu, dass Sie auf einen Abschnitt einer Seite ganz gezielt verlinken können. Die Überschriften sind einfach durchnummeriert und über "#h2.x" am Ende der URL können Sie direkt die Überschrift anspringen, wie das folgende Beispiel zeigt.:

Dieser Links springt zur zweiten Überschrift auf dieser Seite.

Weitere Links