Wikipedia Diskussion:Lua/Modul/PageTree

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch English

Modul: Dokumentation

Ist es machbar, das Erscheinungsbild des Trees dahingehend zu erweitern, dass - analog zum Directory-Baum eines Dateimanagers - Subtrees zugeklappt und wieder aufgeklappt werden können? Wie könnten die Grundzüge einer Realisierung aussehen? Für das Inhaltsverzeichnis eines Wikibooks wäre das ausgesprochen hilfreich. --Kelti (Diskussion) 18:50, 29. Apr. 2015 (CEST)[Beantworten]

Einige Infos:
  1. Lua produziert wie auch jede Vorlage statischen Code. Das heißt: das Aussehen jeder einzelnen Seite ist fest vereinbart.
  2. Um dynamische Effekte zu erzielen, müsste zusätzlich ein JavaScript eingesetzt werden.
    • Das ist prinzipiell möglich. Sowas habe ich auch schon längst im Hinterkopf.
    • Dazu müsste jede Seite den vollständigen Baum erhalten, aber die Felder, die momentan noch eingeklappt sind, müssten über ein vom Seitenlink gesondertes Schaltelement sichtbar gemacht werden; oder könnten unsichtbar gemacht werden.
  3. Ein Unterseitensystem wie für Wikibooks ist jetzt schon durchaus möglich.
  4. Es lässt sich auch von einem Bot generieren; Wikipedia:Technik/Sitemap kommt von diesem Bot.
VG --PerfektesChaos 19:25, 29. Apr. 2015 (CEST)[Beantworten]

Hier eine Beispiel-Seite, die mittels eines Javascriptes das gewünschte Erscheinungsbild erzeugt. Solche Seiten können vom Modul PageTree oder von einem Template erzeugt und dann in diversen Seiten eingebunden werden. Es fehlt allerdings noch ein wichtiges Detail: wie kann der aktuelle Zustand des Baums (also: welche Subtrees sind eingeklappt und welche nicht) von einer Seite zur nächsten weitergereicht werden? Kann mir jemand auf die Sprünge helfen?


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>

<body>

<!--

  Purpose: Create a look-and-feel which is similar to that of a file manager.

HEAD and BOY elements are not accessible (in our case). Therefore CSS and JavaScript
resides within the BODY. Additionally a dummy-image is loaded to trigger an onload() event.

Hint: CSS shall be known and JavaScript MUST be known to browers (Chrome) 
before loading the visual HTML elements.
--> 

<style type="text/css">

tree {
  display: block;
  /* 'relative' is neccessary to get an anchor for the 'a'-elements */
  position: relative;
}
tree tree {
  /* indentation per level */
  margin-left: .9em;
}
tree div {
  /* re-size the icon */
  font-size: medium;
}
tree div a {
  position: absolute;
  /* indentation per level */
  left: .7em;
  /* some space between icon and text of a-element (with or without link) */
  margin-left: .3em;
  /* no underscore for links */
  text-decoration: none;
  color:inherit;
}
</style>

<script type="text/javascript">
//<![CDATA[

/*
The functions toggle the visibility of subtrees by toggling the 'display' property.
They expect a fix recursive structure of HTML-elements, where subtrees belong to their
preceding 'div' element:

<tree>
  <div>..<a href="...">..</a></div>
  <div>..<a href="...">..</a></div>
  <tree>
    <div>..<a href="...">..</a></div>
    ...
  </tree>
  <div>..<a href="...">..</a></div>
</tree>

Non-leaf-nodes are marked with a toggling symbol before the link text. This symbol
is part of the HTML, not of a CSS 'before' rule. CSS 'before' rules are not part of JavaScript.
Hence they cannot be chanced dynamically or stored in JavaScript's localStorage.

The functions don't use XPath as the xpath support and syntax differs from browser to browser.

*/

// -----------------  global variables  --------------------------------------------------------

// global var to store whether it is possible to save the state of the tree from one
// HTML-page to the next
var g_saveTreeState = false;

/*
U+25aa 	BLACK SMALL SQUARE (smaller than the following two)
U+25b8 	BLACK RIGHT-POINTING SMALL TRIANGLE
U+25be 	BLACK DOWN-POINTING SMALL TRIANGLE

U+25b9  WHITE RIGHT-POINTING SMALL TRIANGLE
U+25ff  LOWER RIGHT TRIANGLE
U+25c7  WHITE DIAMOND
*/
var g_opened  = "\u25b9";
var g_closed  = "\u25be";
var g_nothing = "\u00a0";
var g_nbsp    = "\u00a0";

// Chrome has no glyph for some of the above codepoints.
g_opened  = "-";
g_closed  = "+";


// ------------------------  functions  ---------------------------------------

// is this node defined and has he a certain name?
function checkNodeName(p_node, p_text) {
  if (typeof p_node === undefined || p_node === null || p_node.tagName != p_text) {
    return false;
  } else {
    return true;
  }
}


// window.localStorage and window.sessionStorage are not always available, eg: outdated
// browser, IE with local HTML-files, ... .
function isLocalStorageAvailable() {

  // perform the check only once
  if (g_saveTreeState) return true;

  // is the JavaScript-object 'localStorage' available? (in IE it is not available, if
  // displaying a local HTML file)
  try {
    if ('localStorage' in window &&
         window['localStorage'] !== null &&
         window['localStorage'] !== undefined) {
      return true;
    } else {
      return false;
    }
  } catch (e) {
    return false;
  }
}

// what was the former visibility?
function getOldVisibility(p_div, p_subTree) {

  var ret = null;

  // if localStorage is available, there may be an old value for the visibility
  if (g_saveTreeState) {
    ret = window.localStorage.getItem(p_div.id);
    if (ret != null) return ret;
  }

  // no localStorage or first time
  switch (p_subTree.style.display) {
    case "none":
      return "f";
    case "block", "":  // default CSS definition
      return "t";
    default:
      return "t";
  }
}

// toggle visibility of trees and save the actual value: t(rue) and f(alse)
function toggleSubtree(p_event) {
  // process nothing but click events (mouse and touchscreen)
  if (p_event.type != "click" && p_event.type != "dblclick" && p_event.type != "touchenter") return;

  // click event has 'bubbled up' to its parent TREE element. Get dispatcher of the event.
  var div = p_event.target;

  //  it should be the DIV element
  if (!checkNodeName(div, "DIV")) return; 

  // navigate to the FOLLOWING 'tree' element
  var subTree = div.nextElementSibling;
  if (!checkNodeName(subTree, "TREE")) return; 

  // is there a value from a previous 'click'?
  var display = getOldVisibility(div, subTree);
  switch (display) {
    case "n":
      // leaf nodes cannot toggle
      break;
    case "t":
      div.firstChild.nodeValue = g_closed;
      subTree.style.display = "none";
      if (g_saveTreeState) window.localStorage.setItem(div.id, "f");
      break;
    case "f":
      div.firstChild.nodeValue = g_opened;
      subTree.style.display = "block";
      if (g_saveTreeState) window.localStorage.setItem(div.id, "t");
      break;
  }
}

// create the initial tree according to its last state
function initTree() {

  // is it possible to restore the tree's state?
  g_saveTreeState = isLocalStorageAvailable();
  if (!g_saveTreeState) {
    if (window.console && window.console.log) {
      console.log("window.localStorage is not available.");
    }
  }

  // get the root node and start traversing
  var treeRoot = document.getElementById("treeRoot");
  if (!checkNodeName(treeRoot, "TREE")) return;

  traverseTree(treeRoot);
}

// helper function for 'initTree()'. The function calls itself.
function traverseTree(p_tree) {

  var childList = p_tree.childNodes;
  for (var i = 0; i < childList.length; i++) {
    var node = childList[i];
    if (checkNodeName(node, "TREE")) {
      // next level
      traverseTree(node);
    }
    if (checkNodeName(node, "DIV")) {

      // get CData from DIV element
      var text = node.firstChild;
      if (typeof text == undefined || text == null || text.nodeType != Node.TEXT_NODE) {
        // the CData is missing: create it as  
        node.insertBefore(document.createTextNode(g_nbsp), node.firstChild); 
        text = node.firstChild;
      }

      // The DIV element remains unchanged. Navigate to the following TREE element.
      var subTree = node.nextElementSibling;
      if (checkNodeName(subTree, "TREE")) {

        // open tree according to its last state
        var display = getOldVisibility(node, subTree);

        switch (display) {
          // do nothing, if undefined or "n"
          case "t":
            node.firstChild.nodeValue = g_opened;
            subTree.style.display = "block";
            break;
          case "f":
            node.firstChild.nodeValue = g_closed;
            subTree.style.display = "none";
            break;
        }
      }
    }
  }
}

//]]>
</script>

  <!-- dummy element to throw onload-event -->
  <img onload="initTree();" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Wikimedia-logo.svg/40px-Wikimedia-logo.svg.png" height="0" width="0" />
  <tree id="treeRoot" onclick="toggleSubtree(event);" ondblclick="toggleSubtree(event);">
    <div id="tree_1"> <a href="www.1.com">Chapter 1, no sub-chapter</a></div>
    <div id="tree_2"> <a href="www.2.com">Chapter 2</a></div>
    <tree>
      <div id="tree_2.1"> <a href="www.2_1.com">Chapter 2.1</a></div>
      <tree>
        <div id="tree_2.1.1"> <a href="www.2_1_1.com">Chapter 2.1.1</a></div>
      </tree>
      <div id="tree_2.2"> <a href="www.2_2.com">Chapter 2.2</a></div>
      <div id="tree_2.3"> <a href="www.2_3.com">Chapter 2.3</a></div>
      <div id="tree_2.4"> <a href="www.2_4.com">Chapter 2.4</a></div>
      <tree>
        <div id="tree_2.4.1"> <a href="www.2_4_1.com">Chapter 2.4.1</a></div>
        <div id="tree_2.4.2"> <a href="www.2_4_2.com">Chapter 2.4.2</a></div>
        <div id="tree_2.4.3"> <a href="www.2_4_3.com">Chapter 2.4.3</a></div>
        <tree>
          <div id="tree_2.4.3.1"> <a href="www.2_4_3_1.com">Chapter 2.4.3.1</a></div>
          <div id="tree_2.4.3.2"> <a href="www.2_4_3_2.com">Chapter 2.4.3.2</a></div>
        </tree>
      </tree>
      <div id="tree_2.5"> <a href="www.2_5.com">Chapter 2.5</a></div>
      <div id="tree_2.6"> <a href="www.2_6.com">Chapter 2.6</a></div>
    </tree>
    <div id="tree_3"> <a href="www.3.com">Chapter 3</a></div>
    <div id="tree_4"> <a>Chapter 4 (without introductory text, hence no link)</a></div>
    <tree>
      <div id="tree_4.1"> <a href="www.4_1.com">Chapter 4.1</a></div>
    </tree>
  </tree>

</body>
</html>

--Kelti (Diskussion) 08:06, 6. Mai 2015 (CEST)[Beantworten]

Wäre es in Ordnung, für das Speichern des Zustandes des Baums die HTML5-Objekte 'localStorage' oder 'sessionStorage' zu verwenden? --Kelti (Diskussion) 11:50, 9. Mai 2015 (CEST)[Beantworten]

Ich habe obigen Sourcecode erweitert. Nun ist es möglich, den Baum nach belieben ein- und auszuklappen. In einer neuen Browser-Sitzung nimmt er wieder seinen letzten (Grafik-)Zustand an. Damit kann diese Techik in einem Template eingesetzt werden, welches beim Navigieren über mehrere Seiten den Zustand des Baumes immer wieder herstellt, so dass der Eindruck entsteht, der Baum würde nicht noch einmal geladen. Sowohl CSS wie auch JavaScript sind - entgegen der üblichen Vorgehensweise - im BODY untergebracht, denn in Wiki habe ich keinen Zugriff auf den HEAD - oder doch??? Es gibt noch einige ToDo's:

  • Kann man CSS und JavaScript als separate Dateien in Wiki speichern?
  • Kann man diese Dateien via 'href' oder 'import' in den HEADER laden?
  • Gibt es Anregungen oder Kritik?

Die vorgestellte Lösung wurde mit IE, Firefox und Chrome auf Win7 und Android 4.x getestet. --Kelti (Diskussion) 15:11, 13. Mai 2015 (CEST)[Beantworten]

  • Ich weiß nicht, ob der obige Code von dir stammt, oder hast du ihn im Grundgerüst irgendwo abkopiert?
    • Falls letzteres, wäre es kollegial, wenn du die ursprüngliche URL dazuschreibst.
    • Ich kenne Dutzende solcher Klappbäume; der älteste, den ich in meiner Schnipsel-Sammlung gefunden habe, ist über 15 Jahre alt.
  • Möglicherweise kennst du dich mit JS, CSS, XML als solchem aus.
    • Mit der Verwendung der ersten beiden im Wiki hast du aber offenkundig noch nie gearbeitet, wie die Frage zeigt; das dritte ist überhaupt nicht.
    • Lies doch mal als Einstieg Wikipedia:Technik/Skin/Tutorial nebst verlinkten Seiten. Dann stolperst du auch über die Antwort auf den zweiten Punkt.
    • Um eine dauerhafte Lösung für alle Leser mit allen Browsern und Skins und mobil und mit deaktiviertem JavaScript hinzubekommen, reicht es nicht aus, eine Lösung zu basteln, die erstmal funktioniert; damit das auch robust über Jahre klappt, braucht man mehr Know-How, als wenn man etwas nur für sich selbst nutzt.
  • Der Lösungsweg oben hat einen fundamentalen Denkfehler, der nicht mit einem Wiki kompatibel ist: Hilfe:Tags #Verbotenes HTML – es gibt kein XML im Wiki.
  • Ich erwähnte schon, dass ich längst eine eigene Lösung habe, die mit der Wiki-Technologie kompatibel ist und ohne irgendwelches zusätzliches JavaScript auskommt.
    • Sie ist aber noch nicht erprobt.
    • Ich bin zu beschäftigt, als dass ich mich mehrere Intensivdenkstunden daransetzen könnte.
VG --PerfektesChaos 22:10, 13. Mai 2015 (CEST)[Beantworten]

Englische Wikipedia[Quelltext bearbeiten]

Warum ist das Modul nicht auf der englischen Wikipedia verfügbar? Gibt es prinzipielle Probleme oder ist es lediglich noch nicht transferiert worden? --Kelti (Diskussion) 18:50, 29. Apr. 2015 (CEST)[Beantworten]

Warum sollte es dort verfügbar sein?
Der Austausch von Modulen ist nicht so häufig, und viele sind auch nicht internationalisiert geschrieben.
VG --PerfektesChaos 19:25, 29. Apr. 2015 (CEST)[Beantworten]

Hilfe:Wikisyntax/Validierung[Quelltext bearbeiten]

Bin ich zu dusselig dafür, oder sehe nur ich nirgendwo innerhalb des Hilfebaumes diesen Link. Das ist mir schon neulich aufgefallen, habe es aber dann wohl ignoriert, weil ich eh schon ständig nerve. Ich hätte erwartet, dass man das unterhalb von Hilfe:Wikisyntax am Ende beispielsweise unter CSS findet. --Liebe Grüße, Lómelinde Diskussion 17:57, 23. Jan. 2018 (CET)[Beantworten]

  • Hilfe:Wikisyntax richtet sich an normale, womöglich unerfahrene Autoren.
    • Für diese werden aufgezählt: Textgestaltung, Überschrift, Links, Listen und Tabellen, Einzelnachweise, Sonderzeichen, Farbe, Mathematische Formeln, Poem, Notensatz, Syntaxhighlight, Tags, CSS.
    • Das sind 13 Links, und damit reicht es dann auch.
  • /Validierung /Parsermigration /Hintergrund sind Seiten für Insider, die also nicht wie Autoren nach einer Anleitung zur Textformatierung beim Artikelschreiben suchen.
  • In Modul:PageTree/Hilfe:! sind sie per list=false explizit ausgeblendet.
    • Das bedeutet: Die Kinder kennen ihre Eltern und können aufwärts springen, aber die Eltern-Box verleugnet sie und listet sie nicht als 14., 15., 16. Link für Autoren auf.
  • Auf Hilfe:Wikisyntax #Fortgeschritten wird das dann nochmal auseindergedröselt, wobei „Parsermigration“ eine Detailfrage von „Validierung“ ist.
LG --PerfektesChaos 19:30, 23. Jan. 2018 (CET)[Beantworten]
Achso, ich sah das false, wusste nur nicht weshalb. Dankeschön und nun bin ich still. --Liebe Grüße, Lómelinde Diskussion 20:29, 23. Jan. 2018 (CET)[Beantworten]