Typo3 Fluid: if Viewhelper (if – then – elseif – else)

Mit Typo3 8 wurde Fluid als Standalone Plugin weiterentwickelt und einigen Änderungen und Erweiterungen unterzogen. Da die Frage immer wieder mal auftaucht – hier eine kurze Übersicht die der if Viewhelper in Typo3 Fluid aufgebaut ist. Einmal in Typo3 7 und früher, einmal in Typo3 ab Version 8.

Fluid if Viewhelper in Typo3 7 und früher

Hier gab es das elseif-Konstrukt noch nicht, und man musste die if-Conditions in der Regel verschachteln:

<f:if condition="{variable} == 'bestimmterWert'">
    <f:then>
       // dann führe folgendes aus
    </f:then>
    <f:else>
        <f:if condition="{andereVariable} == 'bestimmterWert'">
            <f:then>
                // dann führe folgendes aus
            </f:then>
           <f:else>
               // dann führe diese Anweisungen aus
           </f:else>
        </f:if>
    </f:else>
</f:if>

Eine Ausnahme gab es, um ohne die if-Verschachtelung auszukommen – man konnte via Arrays die logische UND-Verknüpfung (&&) wie folgt nachbauen, und sich somit das Verschachteln der if-Anweisungen sparen:

<f:if condition="{0: jahre, 1: monate} == {0: vergleichsJahr, 1: vergleichsMonat}">
// dann führe folgendes aus
</f:if>

 

Fluid if-Viewhelper in Typo3 8 und höher

<f:if condition="{variable} == 'bestimmterWert'">
     <f:then>
          // dann führe folgendes aus
     </f:then>
     <f:else if="{andereVariable} == 'bestimmterWert'">
          // dann führe folgendes aus
     </f:else>
     <f:else>
         // für den Rest führe folgendes aus..
     </f:else>
</f:if>

Möglich ist auch, diese Abfragen mit logischen UND bzw. ODER in kürzerer Schreibweise zu schreiben:

<f:if condition="({variableOne} && {variableTwo}) || {variableThree} || {variableFour}">
// Done if both variable one and two evaluate to true,
// or if either variable three or four do.
</f:if>

Weitere Beispiele:

<f:if condition="{variable} || {andereVariable}">
    // dann führe folgendes aus
</f:if>

Ist wahr, wenn eine der beiden Variablen gesetzt ist.

 

Inline Schreibweise von if-Conditions:

If – Abfragen können auch inline geschrieben werden. Das ist z.B. sinnvoll, wenn in Fluid-Templates je nach gesetzten Variablen oder bei bestimmten Varialben-Werten bestimmte CSS-Klassen ausgegeben werden sollen.

 

Beispielsweise wenn im Backend bei Inhaltselementen im Reiter „Erscheinungsbild“ bestimmte Layouts, Frames oder Abstände ausgewählt werden.

Hier die generelle Schreibweise:

{f:if(condition: variable1, then: 'bestimmterWert')}

// Hier wird "bestimmterWert" ausgegeben, wenn die Variable "variable1" gesetzt ist
{f:if(condition: '{variable1} == "Yes"', then: 'bestimmterWert')}

// Hier wird "bestimmterWert" ausgegeben, wenn die Variable "variable1" dem String "Yes" entspricht
{f:if(condition: '{variable1} == 1', then: 'bestimmterWert')}

// Hier wird die Variable "bestimmterWert" ausgegeben, wenn die Variable "variable1" der Zahl 1 entspricht.
{f:if(condition: '{variable1} == 1', then: 'bestimmterWert', else: 'andererWert')}

// Wenn die Variable "variable1" der Zahl 1 entspricht wird "bestimmterWert" ausgegeben, in allen anderen Fällen "andererWert".

 

Bootstrap 3 Spaltenelemente in Typo3

Ich setze bei meinen Projekten ganz gerne auf die Lösung von  Stefan Schäfer / merec.org, um Spaltenelemente basierend auf Bootstrap 3 Klassen zu realisieren.

Aufgrund der Anforderung, dass die Redakteure das Aussehen der Inhalte, im speziellen Fall auch der Bootstrap Spalten, anpassen sollen, habe ich das Typoscript Setup von Stefan noch etwas erweitert bzw. geändert.

Die prinzipielle Struktur die ich gerne wollte war:

<div class="container>
  <div class="row undweitereKlassen">
    <div class="col-md-6 usw">INHALTE</div>
    <div class="col-md-6 usw">INHALTE</div>
  </div>
</div>

Folgende Dinge soll der Redakteur beeinflussen können:

  • Ob die Zeile 100% der Seitenbreite einnimmt oder die vordefinierte Inhaltsbreite (aus dem Reiter „Erscheinungsbild“ -> Frame)
  • Abstand davor und Abstand danach (aus dem Reiter „Erscheinungsbild“ -> Space Before / Space After)
  • Hintergrundfarbe der Zeile (aus dem Reiter „Erscheinungsbild“ -> Layout)
<div class="container>   <-- bei 100% diesen DIV nicht rendern
  <div class="row undweitereKlassen">    <--- SpaceBefore, SpaceAfter Klassen, Hintergrundfarbe
    <div class="col-md-6 usw">INHALTE</div>
    <div class="col-md-6 usw">INHALTE</div>
  </div>
</div>

 

Ich habe also beim Typoscript Code von Stefan folgendes ergänzt (heller hinterlegte Zeilen):

plugin.tx_gridelements_pi1.setup.uebb_bootstrap_2col {

  preCObject = LOAD_REGISTER
  preCObject {
    containerClasses.cObject = COA
    containerClasses.cObject {
      10 = TEXT
      10 {
        value = equal-height
        fieldRequired = flexform_equalHeight
        noTrimWrap = | ||
      }
      11 = TEXT
      11 {
        value = v-align-children
        fieldRequired = flexform_verticalAlign
        noTrimWrap = | ||
      }
    
    
      20 = TEXT
      20 {
        field = flexform_visibility_element
        noTrimWrap = | ||
        split {
          token = ,
          cObjNum = 1
          1.current = 1
          1.noTrimWrap = | ||
          }
        }
      30 = CASE
      30 {        
        key.field = layout
        default = TEXT
        default.value =  
        1 = TEXT
        1.value = 
        2 = TEXT
        2.value = bg-primary
        3 = TEXT
        3.value = bg-secondary
        4 = TEXT
        4.value = bg-dark
        5 = TEXT
        5.value = bg-dark bg-dark2
        noTrimWrap = | | |
        }
        
      40 = CASE
      40 {        
        key.field = space_before_class
        default = TEXT
        default.value =
        extra-small = TEXT
        extra-small.value = frame-space-before-extra-small
        extra-small.noTrimWrap = | ||
        small = TEXT
        small.value = frame-space-before-small
        small.noTrimWrap = | ||
        medium = TEXT
        medium.value = frame-space-before-medium
        medium.noTrimWrap = | ||
        large = TEXT
        large.value = frame-space-before-large
        large.noTrimWrap = | ||
        extra-large = TEXT
        extra-large.value = frame-space-before-extra-large
        extra-large.noTrimWrap = | ||
        }
    
      50 = CASE
      50 {        
        key.field = space_after_class
        default = TEXT
        default.value =
        extra-small = TEXT
        extra-small.value = frame-space-after-extra-small
        extra-small.noTrimWrap = | ||
        small = TEXT
        small.value = frame-space-after-small
        small.noTrimWrap = | ||
        medium = TEXT
        medium.value = frame-space-after-medium
        medium.noTrimWrap = | ||
        large = TEXT
        large.value = frame-space-after-large
        large.noTrimWrap = | ||
        extra-large = TEXT
        extra-large.value = frame-space-after-extra-large
        extra-large.noTrimWrap = | ||
        }
    
      stdWrap.insertData = 1
      stdWrap.trim = 1
    }

    containerAttributes.cObject = COA
    containerAttributes.cObject {
      10 = TEXT
      10 {
        data = register: containerClasses
        #noTrimWrap = | class="|"|
        noTrimWrap = | class="row |"|
      }
    }

    outerWrapContainerClasses.cObject = COA
    outerWrapContainerClasses.cObject {

      40 = CASE
      40 {        
        key.field = frame_class
        default = TEXT
        default.value = <div class="container">|</div>
        no-frame = TEXT
        default.value = <div class="container">|</div>
        wide = TEXT
        wide.value = 
        widebg = TEXT
        widebg.value = 
        }
    }

    innerWrapContainerClasses.cObject = COA
    innerWrapContainerClasses.cObject {

      10 = CASE
      10 {        
        key.field = frame_class
        default = TEXT
        default.value = 
        no-frame = TEXT
        default.value =
        wide = TEXT
        wide.value = 
        widebg = TEXT
        widebg.value = <div class="container">|</div>

        }
    }


  wrap = {register: innerWrapContainerClasses}
  wrap.insertData = 1

  wrap2 = <div{register: containerAttributes} wrap>| </div>
  wrap2.insertData = 1

  outerWrap = {register: outerWrapContainerClasses}
  outerWrap.insertData = 1

  columns.0 {

    preCObject = LOAD_REGISTER
    preCObject {
      contentColumnClass.cObject = COA
      contentColumnClass.cObject {
        10 = TEXT
        10 {
          field = flexform_width_column_xs_1
          noTrimWrap = || |
          required = 1
        }

        11 = TEXT
        11 {
          field = flexform_width_column_sm_1
          noTrimWrap = || |
          required = 1
        }

        12 = TEXT
        12 {
          field = flexform_width_column_md_1
          noTrimWrap = || |
          required = 1
        }

        13 = TEXT
        13 {
          field = flexform_width_column_lg_1
          noTrimWrap = || |
          required = 1
        }

        20 = TEXT
        20 {
          field = flexform_visibility_col1
          noTrimWrap = | ||
          split {
            token = ,
            cObjNum = 1
            1.current = 1
            1.noTrimWrap = | ||
          }
        }

        stdWrap.noTrimWrap = | class="|"|
      }
    }

    outerWrap = <div{register: contentColumnClass}> | </div>
    outerWrap.insertData = 1

    renderObj =< tt_content
  }

  columns.1 < .columns.0
  columns.1 {
    preCObject {
      contentColumnClass.cObject {
        10.field = flexform_width_column_xs_2
        11.field = flexform_width_column_sm_2
        12.field = flexform_width_column_md_2
        13.field = flexform_width_column_lg_2
        20.field = flexform_visibility_col2
      }
    }
  }
}

plugin.tx_gridelements_pi1.setup.uebb_bootstrap_3col < plugin.tx_gridelements_pi1.setup.uebb_bootstrap_2col
plugin.tx_gridelements_pi1.setup.uebb_bootstrap_3col {
  columns.2 < .columns.0
  columns.2 {
    preCObject {
      contentColumnClass.cObject {
        10.field = flexform_width_column_xs_3
        11.field = flexform_width_column_sm_3
        12.field = flexform_width_column_md_3
        13.field = flexform_width_column_lg_3
        20.field = flexform_visibility_col3
      }
    }
  }

}

plugin.tx_gridelements_pi1.setup.uebb_bootstrap_4col < plugin.tx_gridelements_pi1.setup.uebb_bootstrap_3col
plugin.tx_gridelements_pi1.setup.uebb_bootstrap_4col {
  columns.3 < .columns.0
  columns.3 {
    preCObject {
      contentColumnClass.cObject {
        10.field = flexform_width_column_xs_4
        11.field = flexform_width_column_sm_4
        12.field = flexform_width_column_md_4
        13.field = flexform_width_column_lg_4
        20.field = flexform_visibility_col4
      }
    }
  }
}

tt_content.gridelements_pi1.20.10.setup {
  uebb_bootstrap_2col < plugin.tx_gridelements_pi1.setup.uebb_bootstrap_2col
  uebb_bootstrap_3col < plugin.tx_gridelements_pi1.setup.uebb_bootstrap_3col
  uebb_bootstrap_4col < plugin.tx_gridelements_pi1.setup.uebb_bootstrap_4col
}