Cycle2-Slider aus den Seiten-Ressourcen in TYPO3 generieren

Mit ein wenig Typoscript lassen sich alle Bilder unter Seiteneigenschaften > Ressourcen > Media ausgeben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
lib.pageheader = COA
lib.pageheader {
  10 = FILES
  10 {
    references {
      data = levelmedia:-1, slide
    }
    renderObj = COA
    renderObj {
      10 = IMAGE
      10 {
        file.import.data = file:current:publicUrl
        file.treatIdAsReference = 1
        titleText.data = file:current:title
        altText.data = file:current:title
        #params = class="img-responsive"
        wrap = |
      }
    }
  }
}

Dieses Typoscript lässt sich mit noch einer kleinen Änderung bereits nutzen, um einen Slider mit Hilfe des jQuery-Plugins Cycle2 zu erstellen.

Dazu muss das COA-Objekt mit einem wrap erweitert werden:

lib.pageheader.stdWrap.wrap = <div id="teaser" class="cycle-slideshow" data-cycle-fx="fade" data-cycle-pause-on-hover="false" data-cycle-timeout="4000" data-cycle-speed="3000" data-cycle-log="false">|</div>

Nun lässt sich der Slider über ein Fluid-Template einfügen:

<f:cObject typoscriptObjectPath="lib.pageheader" />

Erweiterung des TYPO3 Kategoriensystems

Seit der Version 6.0 stellt TYPO3 ein generisches Kategoriensystem zur Verfügung, das zur Kategorisierung von Inhaltselementen und Dateien genutzt werden kann. Dabei kommt es manchmal vor, dass die üblichen Methoden findAll(), findByUid() etc., die jedes extbase-Repository zur Verfügung stellt, nicht ausreichen.

Anhand einer fiktiven Extension sf_boilerplate will ich erklären, wie man das CategoryRepository um benötigte Methoden erweitern kann.

In einem ersten Schritt muss das Kategorie-Model erweitert werden.

1
2
3
4
5
6
7
8
9
10
11
<?php
// FILE: sf_boilerplate/Classes/Domain/Model/Category.php
namespace Systemfehler\SfBoilerplate\Domain\Model;

/**
 * Category
 */

class Category extends \TYPO3\CMS\Extbase\Domain\Model\Category {
 
}
?>

Des Weiteren muss man das Kategorie-Repository erweitern. In diesem Fall erbt unser CategoryRepository von der entsprechenden extbase-Klasse und wird um eine zusätzliche Methode findChildrenByParent() erweitert, die zu einem späteren Zeitpunkt benutzt wird, um die Unterkategorien einer gegebenen Kategorie zu ermitteln.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
// FILE: sf_boilerplate/Classes/Domain/Repository/CategoryRepository.php
namespace Systemfehler\SfBoilerplate\Domain\Repository;

/**
 * The repository for Categories
 */

class CategoryRepository extends \TYPO3\CMS\Extbase\Domain\Repository\CategoryRepository {
  protected $defaultOrderings = array('sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING);
 
  public function findChildrenByParent($category = 0, $excludeCategories = array()) {
    $constraints = array();
    $query = $this->createQuery();
    $query->getQuerySettings()->setRespectStoragePage(false);
   
    $constraints[] = $query->equals('parent', $category);
   
    if (count($excludeCategories) > 0) {
      $constraints[] = $query->logicalNot($query->in('uid', $excludeCategories));
    }

    $query->matching($query->logicalAnd($constraints));
   
    return $query->execute();
  }
}
?>

Mit folgendem Eintrag im TS-Setup unserer Extension macht man die erweiterten Systemkategorien für alle extbase-Extensions verfügbar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# FILE: sf_boilerplate/Configuration/TypoScript/setup.txt
config.tx_extbase {
  persistence {
    classes{
      Systemfehler\SfBoilerplate\Domain\Model\Category {
        mapping {
          tableName = sys_category
          columns {

          }
        }
      }
    }
  }
}

Sollte man die zusätzlichen Repository-Methoden nur für die eigene Extension benötigen, so kann man anstelle von config.tx_extbase einfach plugin.tx_sfboilerplate schreiben.

Nun kann man diese Änderungen z. B. dafür verwenden, um über einen ViewHelper ein Dropdown mit den Unterkategorien einer gegebenen Kategorie auszugeben. Dazu muss man einen entsprechenden ViewHelper erstellen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
// FILE: sf_boilerplate/Classes/ViewHelpers/GetCategoriesViewHelper.php
namespace Systemfehler\SfBoilerplate\ViewHelpers;

class GetCategoriesViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
  /**
    * @var \Systemfehler\SfBoilerplate\Domain\Repository\CategoryRepository
    * @inject
    */

  protected $categoryRepository;
 
  public function initializeArguments() {
    $this->registerArgument('parentCategory', 'integer', 'The parent category', true, 0);
    $this->registerArgument('excludeCategories', 'string', 'Exclude categories', false);
    $this->registerArgument('as', 'string', 'Name of the template variable that will contain the categories', true);
  }
   
  /**
   * Return child categories
   *
   * @param integer $parentCategory
   *
   * @return mixed
   * @api
   */

  public function render() {
    $parent = $this->categoryRepository->findByUid($this->arguments['parentCategory']);
    $excludeCategories = ($this->arguments['excludeCategories'] ? explode(',', $this->arguments['excludeCategories']) : array());
    $children = $this->categoryRepository->findChildrenByParent($this->arguments['parentCategory'], $excludeCategories);
    $as = (string)$this->arguments['as'];
    $options = array(); // for dropdown select
   
    $options[0] = $parent->getTitle();
   
    foreach ($children as $child) {
      $options[$child->getUid()] = $child->getTitle();
    }
       
    $this->templateVariableContainer->add($as, array(
      'parent' => $parent,
      'children' => $children,
      'options' => $options
    ));
   
    $output = $this->renderChildren();
    $this->templateVariableContainer->remove($as);
   
    return $output;
  }
}
?>

Dieser kann nun in einem Fluid-Template verwendet werden, um das gewünschte Dropdown zu generieren.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<f:layout name="Default" />

<div xmlns="http://www.w3.org/1999/xhtml"
 xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
 xmlns:sf="http://typo3.org/ns/Systemfehler/SfBoilerplate/ViewHelpers">
   
<f:section name="main">
  <div class="category-dropdown">
    <sf:getCategories parentCategory="1" as="categories">
      <div class="form-group">
        <label><f:translate key="categories.label"/></label>
        <f:form.select name="category" options="{categories.options}" class="form-control" />
      </div>
    </sf:getCategories>
  </div>
</f:section>

TYPO3 unter HTTPS laufen lassen

Um sowohl das TYPO3-Backend als auch das -Frontend ausschließlich über HTTPS erreichbar zu machen, sind folgende Einstellungen notwendig.

Im TS-Template:

1
2
3
4
config {
  absRefPrefix = https://www.domain.de
  baseURL = https://www.domain.de
}

In der .htaccess-Datei:

1
2
3
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.domain.de/$1 [R,L]

Über das Install-Tool noch folgende Variable setzen:
$TYPO3_CONF_VARS['BE']['lockSSL'] = 2

Diese Einstellungen setzen natürlich voraus, dass der Server SSL unterstützt.

Zufallshintergrundbild aus Seiten-Ressourcen

Um ein Zufallshintergrundbild aus den Seiten-Ressourcen anzuzeigen, kann man wie folgt vorgehen:

CSS:

1
2
3
4
body {
  background-attachment: fixed;
  background-size: cover;
}

TypoScript:

1
2
3
4
5
6
7
8
9
10
11
12
tmp.bg = COA_INT
tmp.bg.10 = IMG_RESOURCE
tmp.bg.10 {
  file {
    import.data = levelmedia:-1, slide
    import.listNum = rand
    treatIdAsReference = 1
  }
}

page.headerData.123 < tmp.bg
page.headerData.123.stdWrap.wrap = <style type="text/css"> body { background-image: url(|); } </style>

ul-Liste in mehrere Spalten aufteilen

Folgendes Less-Snippet kann dazu verwendet werden, die Einträge einer ul-Liste auf mehrere Spalten zu verteilen.

1
2
3
4
5
6
7
8
9
.ul-columns(@columns: 2, @gap: 20px) {
  -moz-column-count: @columns;
  -moz-column-gap: @gap;
  -webkit-column-count: @columns;
  -webkit-column-gap: @gap;
  column-count: @columns;
  column-gap: @gap;
  list-style-position: inside;
}

Da manche Browser (vor allem Chrome) dabei den Aufzählungspunkt nicht richtig bzw. nicht mehr anzeigen, wird zusätzlich die Eigenschaft list-style-position: inside; benötigt.