Zum Inhalt springen

Gespräch:Verschachtelte Parser Funktion

aus AufEinWort, der freien Forschung

Über diese Seite Gespräch

Hallo Nikolaos — kurz und präzise:
ChatGPT Sophos GPT-4
20. August 2025 n. Chr. erst.  
19:18 Uhr Ausgabe 01
Ausgabe 01
unüberarbeitet ungeprüft
2025082001 Verschachtelte Parser Funktion

Hallo Sophos,

Ich versuche in Semantic Mediawiki eine verschachtelte Parser Funktion mittels {{#if…}} durchzuführen.

Die Syntax ist derzeit wie folgt:

{{#if:{{{Urwerk|}}} 
| Auf dem Werk “[[ist Urwerk::Werk:{{{Urwerk}}}|{{{Urwerk}}}]] [[Kategorie:{{{Urwerk}}}]]“ gründend von
| {{#if:{{{Ururheber|}}}
| [[Kategorie:Urwerk von {{{Ururheber}}}]] [[ist Ururheber::{{{Ururheber}}}| ]] [[AufEinWort Liste {{{Ururheber}}}|{{{Ururheber}}}]]
| [[Kategorie:AufEinWort Ururheber und oder Urwerk eintragen]]
}}
}}

In den Local Settings habe ich dazu folgendes Eingetragen: wfLoadExtension( 'ParserFunctions' ); $wgPFEnableStringFunctions = true; Einzelne ‘if Abfragen funktionieren – nur nicht die verchachtelten.

Gibt es noch zsätzlich etwas, daß aktiviert sein muß, damit ich verschachtelte #if Funktionen verwenden kann?

Ansatz ist im Prinzip korrekt

(20. Aug. 2025, 19:18)

Hallo Nikolaos,

dein Ansatz ist im Prinzip korrekt – verschachtelte #if-Abfragen sind mit der ParserFunctions-Extension möglich, wenn sie syntaktisch sauber geschlossen sind. Du brauchst also in den LocalSettings.php keine zusätzliche Freischaltung über das hinaus, was du schon gemacht hast:

wfLoadExtension( 'ParserFunctions' );
$wgPFEnableStringFunctions = true;

Das genügt.

Typische Fehlerquellen bei verschachtelten #if

Klammern und geschweifte Klammern
  1. Jede #if-Struktur braucht ihr eigenes }} zum Schließen. Wenn man mehrere Ebenen verschachtelt, ist das häufigste Problem ein fehlendes oder zu viel gesetztes }}. Beispiel einer funktionierenden Verschachtelung:
    {{#if: {{{Urwerk|}}}
     | Text wenn Urwerk gesetzt
     | {{#if: {{{Ururheber|}}}
        | Text wenn Ururheber gesetzt
        | Text wenn nichts gesetzt
       }}
    }}
    
    → Beachte die doppelte Schließung: erst für die innere, dann für die äußere Abfrage.

Parameterweitergabe
  1. Wenn deine Vorlage Parameter wie {{{Urwerk}}} enthält, musst du sicherstellen, dass keine weiteren geschweiften Klammern innerhalb des #if verloren gehen. Beispiel: Falsch (schneidet zu früh ab):
    [[Kategorie:{{{Urwerk}}}]]
    }}
    
    Richtig:
    [[Kategorie:{{{Urwerk}}}]]
    
    (erst danach die }} der Parserfunktion schließen).
Whitespace oder unsichtbare Zeichen
  1. ParserFunctions interpretiert jede nicht-leere Zeichenkette als „wahr“, auch ein Leerzeichen. Wenn du z. B.
    {{#if: {{{Urwerk| }}} | ... }}
    
    schreibst, ist der Parameter immer „wahr“, weil du in der Default-Option ein Leerzeichen gesetzt hast. → Lösung: Als Default immer leer lassen ({{{Urwerk|}}}).

Dein Beispiel korrigiert (lesbarer eingerückt)

So sollte es fehlerfrei laufen:

{{#if: {{{Urwerk|}}}
 | Auf dem Werk „[[ist Urwerk::Werk:{{{Urwerk}}}|{{{Urwerk}}}]] [[Kategorie:{{{Urwerk}}}]]“ gründend von
 | {{#if: {{{Ururheber|}}}
    | [[Kategorie:Urwerk von {{{Ururheber}}}]]] [[ist Ururheber::{{{Ururheber}}}| ]] [[AufEinWort Liste {{{Ururheber}}}|{{{Ururheber}}}]]
    | [[Kategorie:AufEinWort Ururheber und oder Urwerk eintragen]]
   }}
}}

👉 Fazit:

  • Nein, du musst nichts Zusätzliches in den LocalSettings aktivieren.
  • Es liegt fast sicher an Klammer-/Schließungsfehlern oder Whitespace im Defaultwert.

Willst du, dass ich dein Beispiel Schritt für Schritt so umbauen, dass du für jede der drei Situationen (Urwerk gesetzt, nur Ururheber gesetzt, gar nichts gesetzt) einen Minimaltest-Output bekommst, mit dem du es prüfen kannst?

lesbare Einrückung meinem Beispiel

Mein Beispiel entspricht bis auf die lesbare Einrückung meinem Beispiel – richtig?

Wenn dem so ist, hatte mein Beispiel keinen Fehler, da auch dein beispiel nur das Ergebnis des ersten #if jedoch nicht des zweiten #if bringt.

Obwohl {{{Ururheber}}} einen Wert hat, wird die zweite #if Funktion nicht ausgeführt. Mein MediaWIki ist Version 1.43 und Semantic WMediaWiki 5.1. Recherchiere bitte für mich in Vertrauenswürdigen Quellen nach Lösung dieses Fehlers – ich denke, da ist etwas falsch.

kurze Diagnose

Nachgedacht
Die zweite Bedingung wird nur ausgeführt, wenn "Urwerk" leer ist, weil sie im "else"-Zweig der ersten Bedingung liegt. Wenn "Urwerk" gesetzt ist, wird der zweite Zweig übersprungen. Vielleicht möchten sie, dass beide Bedingungen unabhängig voneinander ausgeführt werden, abhängig davon, ob "Urwerk" oder "Ururheber" gesetzt ist.

Wenn beide Bedingungen unabhängig voneinander ausgewertet werden sollen, müssen separate #if-Blöcke verwendet werden, nicht verschachtelt. Auch #ifexpr oder #switch könnten helfen. Wenn "Urwerk" tatsächlich einen Wert hat, wird der zweite Zweig nicht ausgeführt. Ich werde die Dokumentation durchstöbern und die richtigen Quellen zitieren.

Durchsuchen der Dokumentation zu MediaWiki ParserFunctions

Ich werde die Seite "Parser Funktionen und bedingte Werte" durchsuchen, da sie erklärt, dass alle Parameter für Parserfunktionen immer ausgewertet werden, was beide #set-Befehle ausführt. Es wird auch empfohlen, bei Verwendung von #set spezielle Handhabung mit #vardefine zu nutzen. Mal sehen, was ich dort finde.

Öffnen der SMW-Seite zu Parserfunktionen

Die Seite hält fest, dass alle Parameter ausgewertet werden, aber bei Nebenwirkungen durch Bedingungen müsste die Struktur anders aufgebaut werden. Obwohl der Benutzer #set nicht nutzt, erscheinen Annotations wie [[ist Ururheber::...]] als Nebenwirkungen. Das Symptom des Benutzers scheint von einer falschen Erwartung zu kommen; die Logik funktioniert, aber der äußere Zweig wurde ausgeführt, weshalb der innere nicht.

Um beide Bedingungen unabhängig zu bewerten, könnte der Code so aussehen, dass für "Urwerk" und "Ururheber" jeweils eigene #if-Bedingungen gesetzt werden. Wichtig ist dabei zu beachten, dass das "else" im zweiten Block auch dann ausgelöst wird, wenn "Urwerk" vorhanden ist, aber "Ururheber" fehlt. Deshalb könnte eine zusätzliche Bedingung nötig sein.

Fertig

Hallo Nikolaos,

kurze Diagnose – präzise:

  • Deine Syntax ist korrekt. ParserFunctions erlaubt verschachtelte #if ohne weitere Aktivierung. MediaWiki+1
  • Warum dein zweites #if “nicht ausgeführt” wird: In deinem Code liegt das zweite #if im else-Zweig des ersten. Es wird nur ausgewertet, wenn Urwerkleer ist. Hat Urwerk einen Wert, wird ausschließlich der true-Zweig des ersten #if gerendert – genau das beobachtest du. Das ist erwartetes Verhalten: Pro #ifwird nur der gewählte Zweig ausgewertet/ausgegeben. MediaWiki

Was willst du logisch?

Fallunterscheidung (3-Wege):
  • Urwerk gesetzt → Ausgabe A
  • sonst, wenn Ururheber gesetzt → Ausgabe B
  • sonst → Ausgabe C

Das entspricht deinem aktuellen, verschachtelten Aufbau und funktioniert, sofern Urwerk wirklich leer ist, wenn du B willst.

Beide Bedingungen unabhängig prüfen (A und ggf. B):
  1. Dann nicht verschachteln, sondern zwei getrennte #if verwenden:
    {{#if: {{{Urwerk|}}}
     | Auf dem Werk „[[ist Urwerk::Werk:{{{Urwerk}}}|{{{Urwerk}}}]] [[Kategorie:{{{Urwerk}}}]]“ gründend von
    }}
    
    {{#if: {{{Ururheber|}}}
     | [[Kategorie:Urwerk von {{{Ururheber}}}]] [[ist Ururheber::{{{Ururheber}}}| ]] [[AufEinWort Liste {{{Ururheber}}}|{{{Ururheber}}}]]
    }}
    

Hinweis: Die “leer”-Zweige weglassen, wenn du nur im gesetzten Fall ausgeben willst – sonst würdest du im zweiten Block eine „Fehlt“-Kategorie setzen, obwohl Urwerk ggf. vorhanden ist.

Häufige Stolpersteine

  • Default-Whitespace: {{{Param| }}} (Leerzeichen!) macht die Bedingung immer “wahr”. Achte darauf, dass der Default wirklich leer ist ({{{Param|}}}). MediaWiki
  • Seiteneffekte in Parametern (SMW): Parser-Argumente werden intern breit evaluiert; Side-Effects wie #set in Zweigen können “trotzdem” greifen, wenn sie als Parameter übergeben werden. Lösung: Effekt außerhalb der Parameter direkt in den gewählten Zweig schreiben oder Wertebedingung in den Wert selbst legen. (Siehe SMW-Hinweis.) Semantic MediaWiki

Fazit

  • Kein Bug in MW 1.43/SMW 5.1 nötig – es ist Logik/Struktur: Dein zweites #if liegt im else des ersten. Wenn du beide Bedingungen unabhängig willst, entkoppel sie wie oben. ParserFunctions-Grundlagen und Auswertungsregeln bestätigen das Verhalten. MediaWiki+1

Wenn du mir kurz sagst, welches Zielverhalten du exakt willst (A→B→C oder A & B), formatiere ich dir die endgültige Vorlage in deiner Zielschreibweise.

nur eine Ausgabe wenn Urwerk und Ururheber

Danke. Ich will an sich nur eine Ausgabe wenn Urwerk und Ururheber je einen Wert hat und wenn ein Wert fehlt einen Hinweis, daß Daten nachzutragen sind. MediaWiki kann keine und-Funktion – oder?

Lösung mit verschachteltem #if

(20. Aug. 2025, 19:32)

Sehr gut formuliert – jetzt ist klar, was du brauchst.

1. Kann MediaWiki ein logisches UND?

ParserFunctions bringt nur #if, #ifeq, #ifexpr, #switch usw. mit.

  • Ein direktes #and gibt es nicht.
  • Du kannst ein UND aber mit #ifexpr und der Parserfunktion len/Stringlängenprüfung simulieren oder durch geschickte Verschachtelung von #if erreichen.

2. Dein Ziel:

  • Fall A: Urwerk gesetzt und Ururheber gesetzt → gewünschte Ausgabe
  • Fall B: Einer der beiden fehlt → Hinweis “Daten nachzutragen”

3. Lösung mit verschachteltem #if (sauberstes Standardmittel)

{{#if: {{{Urwerk|}}}
 | {{#if: {{{Ururheber|}}}
    | Auf dem Werk „[[ist Urwerk::Werk:{{{Urwerk}}}|{{{Urwerk}}}]]“ gründend von [[ist Ururheber::{{{Ururheber}}}| ]] [[AufEinWort Liste {{{Ururheber}}}|{{{Ururheber}}}]]
    | '''Hinweis: Ururheber fehlt – bitte nachtragen.'''
   }}
 | '''Hinweis: Urwerk fehlt – bitte nachtragen.'''
}}

Das ist eine klassische UND-Prüfung:

  • Zuerst prüft #if Urwerk.
  • Nur wenn gesetzt, wird #if Ururheber geprüft.
  • Trifft beides zu → Ausgabe A.
  • Sonst → Fehlhinweis.

4. Alternative mit #ifexpr (numerisch)

Man kann tricksen, indem man die Länge (#len) der Parameter abfragt:

{{#ifexpr: {{#len:{{{Urwerk|}}}}} > 0 and {{#len:{{{Ururheber|}}}}} > 0
 | Ausgabe wenn beide gesetzt
 | Hinweis: mindestens ein Wert fehlt
}}

Dafür brauchst du allerdings die StringFunctions ($wgPFEnableStringFunctions = true;), die du ja schon aktiviert hast.


👉 Empfehlung für dich: Variante 3 (verschachtelt) ist die robusteste und am besten lesbare, besonders im SMW-Kontext.

Soll ich dir daraus eine komplette Vorlage bauen, die direkt Kategorien setzt (z. B. Kategorie „Fehlende Daten“), wenn Urwerk oder Ururheber leer ist?

funktioniert nur für den Fall das ein Wert fehlt

Die "3. Lösung mit verschachteltem" funktioniert nur für den Fall das ein Wert fehlt. Wenn beide Werte Fehlen kommt dennoch "Hinweis: Urwerk fehlt – bitte nachtragen.!" Kann man dies mit einer dreierverschachtelung lösen – ich habe gerade gelesen, daß bis zu 7 Verschachtelungen möglich seien.

mit einer dreifach-Verschachtelung lösen

Ganz genau – wenn beide fehlen, springt der äußere #if in den else-Zweig, der nur auf „Urwerk fehlt“ prüft. Deshalb siehst du nicht, dass beide fehlen.

Das lässt sich tatsächlich mit einer dreifach-Verschachtelung lösen. ParserFunctions erlaubt (wie du gelesen hast) mehrere Ebenen, bis zu 7 tief.

Zielbild

  • Fall A: Urwerk und Ururheber gesetzt → Ausgabe mit beiden
  • Fall B: Nur Urwerk fehlt → Hinweis „Urwerk fehlt“
  • Fall C: Nur Ururheber fehlt → Hinweis „Ururheber fehlt“
  • Fall D: Beide fehlen → Hinweis „Urwerk und Ururheber fehlen“

Lösung (dreifach verschachtelt)

{{#if: {{{Urwerk|}}}
 | <!-- Urwerk ist gesetzt -->
   {{#if: {{{Ururheber|}}}
    | <!-- Urwerk + Ururheber gesetzt -->
      Auf dem Werk „[[ist Urwerk::Werk:{{{Urwerk}}}|{{{Urwerk}}}]]“ gründend von [[ist Ururheber::{{{Ururheber}}}| ]] [[AufEinWort Liste {{{Ururheber}}}|{{{Ururheber}}}]]
    | <!-- Urwerk gesetzt, Ururheber fehlt -->
      '''Hinweis: Ururheber fehlt – bitte nachtragen.'''
   }}
 | <!-- Urwerk fehlt -->
   {{#if: {{{Ururheber|}}}
    | <!-- Urwerk fehlt, Ururheber gesetzt -->
      '''Hinweis: Urwerk fehlt – bitte nachtragen.'''
    | <!-- Urwerk fehlt, Ururheber fehlt -->
      '''Hinweis: Urwerk und Ururheber fehlen – bitte nachtragen.'''
   }}
}}

Erklärung

  • Der äußere #if prüft Urwerk.
  • Innerhalb jedes Zweiges wird nochmal ein #if für Ururheber gemacht.
  • Dadurch bekommst du vier sauber getrennte Fälle.

👉 Ja, das ist eine dreifache Verschachtelung, und genau der richtige Weg.

Wenn du magst, kann ich dir daraus eine kompakte Variante mit #ifexpr schreiben, die nur eine Abfrage enthält, aber die Lesbarkeit ist dann schlechter.

Willst du lieber kompakte Syntax (knapp, aber schwer lesbar) oder klare verschachtelte Syntax (länger, aber gut nachvollziehbar)?