Deprecated: Return type of Requests_Cookie_Jar::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Cookie/Jar.php on line 63

Deprecated: Return type of Requests_Cookie_Jar::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Cookie/Jar.php on line 73

Deprecated: Return type of Requests_Cookie_Jar::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Cookie/Jar.php on line 89

Deprecated: Return type of Requests_Cookie_Jar::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Cookie/Jar.php on line 102

Deprecated: Return type of Requests_Cookie_Jar::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Cookie/Jar.php on line 111

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 40

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 51

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 68

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 82

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /html/typo3.andreas-huber.at/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 91
Typoscript Archive - Typo3 Wissensdatenbank

Cookie Consent in Typo3

Der eine oder andere dürfte es vielleicht noch nicht umgesetzt haben und ist auf der Suche nach einer einfachen Integration des Cookie Consent bzw. einer Cookie Bar in Typo3 um die DSGVO zu erfüllen.

Sehr schön habe ich folgende Lösung von https://cookieconsent.insites.com gefunden. Und diese ist leicht mittels Typoscript zu integrieren:

######################################################
# Cookie Notice 
# https://cookieconsent.insites.com/download/
######################################################

page.headerData.123 = TEXT
page.headerData.123.value (

<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.js"></script>
<style> ... hier kann man noch eigene Styles für DIVs definieren wenn man möchte </style>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
  "palette": {
    "popup": {
      "background": "#444444",
      "text": "#efefef"
    },
    "button": {
      "background": "#89bb16",
      "text": "#fff"
    }
  },
  "theme": "classic",
  "content": {
    "message": "Um unsere Webseite für Sie optimal zu gestalten und verbessern zu können, verwenden wir Cookies. Durch die Nutzung der Webseite stimmen Sie deren Verwendung zu.",
    "dismiss": "OK",
    "link": "Zur Datenschutzerklärung",
    "href": "/datenschutzerklaerung/"
  }
})});
</script>

)

Die externen JS und CSS müssten  um die DSGVO zu erfüllen lokal gespeichert werden.

Das ganze funktioniert auch mit mehreren Sprachen – dann einfach obigen Code nochmal reinkopieren, Texte in andere Sprache ändern und folgende Typoscript-Condition um den Code einfügen:

[globalVar = GP:L = 1]
{-- Code von oben nur Textausgabe in anderer Sprache --}
[global]

 

Noch nicht final geklärt ist ja die Frage, ob ein reines Informieren der User über die Cookies ausreicht, oder ob diese erst gesetzt werden dürfen, wenn der User aktiv anklickt, dass Cookies erlaubt sind.

Auch das wäre mit Cookie Consent möglich – es gibt eine Opt-in und Opt-out Funktion.

Fluid in Typo3: Override Templates hat sich geändert

Der Typoscript Code um Templates zu überschreiben (override templates) hat sich geändert. Ich musste dies bei mir in Typo3 8.x ändern – und hab die Lösung erst nach einigem Suchen gefunden.

Die Typoscript lib hat sich geändert von lib.contentElement zu lib.fluidContent.

Richtig heisst der Typoscript-Code also um Templates in Fluid zu überschreiben:

lib.fluidContent {
   templateRootPaths {
      200 = fileadmin/ABCDE/Resources/Private/Templates/
   }
   partialRootPaths {
      200 = fileadmin/ABCDE/Resources/Private/Partials/
   }
   layoutRootPaths {
      200 = fileadmin/ABCDE/Resources/Private/Layouts/
   }
}

 

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
}

 

Canonical Tags bei News-Urls in Typo3 Multi-Domain System

Hat man in einer Typo3-Installation mehrere Domains laufen und publiziert News (via tt_news) auf mehreren Domains dann läuft man Gefahr, ein Duplicate-Content Problem bei Google zu bekommen.

Man kann mit folgendem Typoscript-Code bei der News ein Canonical Tag hinterlegen, und verweist somit auf eine „Haupt-Url“ der News:

page.headerData.40 = TEXT
page.headerData.40 {
 typolink.parameter.data = TSFE:id
 typolink.forceAbsoluteUrl = 1
 typolink.returnLast = url
 typolink.additionalParams.cObject = COA
 typolink.additionalParams.cObject {
 10 = TEXT
 10.dataWrap = &tx_ttnews[tt_news]={GP:tx_ttnews|tt_news}
 10.if.isTrue.data = GP:tx_ttnews|tt_news
 20 = TEXT
 20.dataWrap = &tx_ttnews[cat]={GP:tx_ttnews|cat}
 20.if.isTrue.data = GP:tx_ttnews|cat
 }
 wrap = <link href="|" rel="canonical">
}

 

HTML Body-Tag: Bestimmte Klassen ausgeben

Je nach Template kann es notwendig sein, beim Body-Tag bestimmte CSS-Klassen aus Typo3 auszugeben.

Dies kann z.B. mit folgendem Code bewerkstelligt werden, es können aber auch direkt in Typoscript schon Unterscheidungen getroffen werden:

Unterscheidung in HTML nach IE-Version:

page.bodyTagCObject = TEXT
page.bodyTagCObject.value (
<!--[if lt IE 7 ]> <body class="ie6"> <![endif]-->
<!--[if IE 7 ]> <body class="ie7"> <![endif]-->
<!--[if IE 8 ]> <body class="ie8"> <![endif]-->
<!--[if IE 9 ]> <body class="ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <body> <!--<![endif]-->
)

 

Unterscheidung in Typoscript, hier wird z.B. die Seiten ID mitgegeben:

page.bodyTag >

page.bodyTagCObject = TEXT
page.bodyTagCObject.field = uid
page.bodyTagCObject.wrap = <body id="blog-|">

Typoscript: Menü der Unterseiten inkl. Beschreibung und Bild

Bildschirmfoto 2016-08-23 um 09.26.39

Um schöne Teaser der Unterseiten in Typo3 anzeigen zu können kann man mittels Typoscript eine neue Darstellung des Menüs „Menü der Unterseiten inkl. Abstract“ erstellen. So ist eine Darstellung der Unterseiten mit Titel, Kurzbeschreibung und Bild (jeweils aus dem Seitenheader der Unterseiten) möglich:

######################################################
# MENÜ DER UNTERSEITEN MIT BILD AUS PAGEHEADER
######################################################

tt_content.menu {
 20 {
 10 = HMENU
 10 {
 special = directory
 #special = list
 #special.value.field = pages
 1 = TMENU
 1.wrap = |
 1.NO {
 doNotLinkIt = 1
 stdWrap.cObject = COA
 stdWrap.cObject {
 10 = FILES
 10 {
 references {
 table = pages
 fieldName = media
 }
 renderObj = IMAGE
 renderObj {
 file {
 width = 80c
 height = 65c
 maxW = 81c
 maxH = 66c
 # height 263c
 # width 155c
 import.data = file:current:publicUrl
 }
 altText.field = title
 imageLinkWrap = 1
 imageLinkWrap {
 enable = 1
 typolink.parameter.field = uid
 }
 }
 stdWrap.wrap = <div class="row"><div class="col-md-2">|</div>
 }
 
 20 = TEXT
 20.field = title
 20.typolink.parameter.field = uid
 20.wrap = <div class="col-md-10"><h3 class="subpage-teaser">|</h3>
 
 30 = TEXT
 30.field = abstract
 30.wrap = <p>|</p></div></div>
 }
 }
 } 
 }
}