Archiv der Kategorie: Extbase/Fluid

TYPO3: Fluid Powered TYPO3 – Custom Flux Controller

FluidTYPO3 alleine ist schon eine geniale Lösung. Damit ist es ein leichtes Seitentemplates und Contentelemente anzulegen.

Im Hintergrund arbeitet Flux und übergibt automatisch die wichtigsten Daten für das Frontendrendering.

Bei Seiten sind dies alle benötigten Daten zu Seiteneigenschaften, bei Contentelementen alle benötigten Daten aus den gepflegten Feldern der Flexform des Contentelements und noch einiges mehr.

Für den Fall dass dies nicht ausreichen sollte gibt es die Möglichkeit in der Providerextension einen „Custom Flux Controller“ anzulegen.

In diesem ist es möglich zusätzliche Daten an die View zu übergeben, die nicht durch Flux geliefert werden.

Wie dies genutzt werden kann will ich folgend kurz beschreiben.

Zunächst müssen im Ordner „Classes/Controller“ zwei Controller Dateien angelegt werden:

  • ContentController.php
  • PageController.php

Beispielcode zum ContentController:

<?php
namespace Yourvendorname\Yourextensionkey\Controller;

use FluidTYPO3\Flux\Controller\AbstractFluxController;

/**
 * Additional ContentController
 *
 * As default Flux generates internally a ContentController an assigns most common objects to the view.
 * If a custom ContentController with a known action is found. Flux will execute the action additionally (performSubRendering).
 *
 * @package Yourextensionkey
 * @subpackage Controller
 */
class ContentController extends AbstractFluxController
{


//    public function fooAction()
//    {
//        $this->view->assign('foo', 'bar');
//    }

}

Beispielcode zum PageController:

<?php
namespace Yourvendorname\Yourextensionkey\Controller;

use FluidTYPO3\Fluidpages\Controller\AbstractPageController;

/**
 * Additional PageController
 *
 * As default Flux generates internally a PageController an assigns most common objects to the view.
 * If a custom PageController with a known action is found. Flux will execute the action additionally (performSubRendering).
 *
 * @package Yourextensionkey
 * @subpackage Controller
 */
class PageController extends AbstractPageController {

//    public function fooAction()
//    {
//        $this->view->assign('foo', 'bar');
//    }

}

Dies allein sollte schon ausreichen um einen Custom Flux Controller für Page und Content anzulegen.

Für den Fall dass dies nicht ausreichen sollte muss wie hier beschrieben im Ordner „Migrations/Code“ die Datei ClassAliasMap.php angelegt werden.

<?php

return array(
	'Tx_Yourextensionkey_Controller_ContentController' => 'Yourvendorname\\Yourextensionkey\\Controller\\ContentController',
	'Tx_Yourextensionkey_Controller_PageController' => 'Yourvendorname\\Yourextensionkey\\Controller\\PageController',
);

 

Fluid Powered TYPO3 auf Github.

TYPO3: Fluid Powered TYPO3

Ich möchte hier kurz Fluid Powered TYPO3 vorstellen. Dieses war mir schön länger bekannt, nur leider habe ich die Genialität dahinter nicht verstanden. Mit dem Gedanken „wer braucht den bitte Flux“ habe ich dieses Thema immer schnell abgehakt.

FluidTYPO3 besteht aus einer Kombination diverser Extensions für TYPO3 CMS. flux, fluidcontent, fluidcontent_core, fluidpages und vhs bilden zusammen ein sehr geniales gespannt.

Diese müssen natürlich nicht allesamt genutzt werden. flux und fluidcontent alleine reichen schon aus um schnell flexible Contentelemente anzulegen. fluidpages weitet das ganze auf Seitentemplateebene aus. fluidcontent_core ersetzt css_styled_content. vhs selbst ist eine Sammlung von oft benötigten ViewHelpern.

Wie auf der Homepage von FluidTYPO3 zu lesen ist steht „convention-over-configuration“ im Vordergrund. Und das ist auch sehr genial umgesetzt.

Doch wie findet man einen einfachen Einstieg um dies zu nutzen? Fast ein wenig versteckt ist in der sehr umfangreichen Dokumentation die Extension „builder“ erwähnt. Ich persönlich hätte den builder mehr in einem QuickStart Tutorial hervor gehoben.

fluidtypo3-builder

Mit dieser ist es möglich wie zu den alten Extension Kickstarter Zeiten eine FluidTYPO3 „provider extension“ zu erstellen. Dies ist über ein Backend Modul möglich oder man nutzt dazu den CLI Dispatcher auf der Kommandozeile. Deren Grundgerüst sieht dann wie folgt aus:

provider-extension

Dies ist auf den ersten Blick eine ganz normale Extbase Ordnerstruktur, in der Datei ext_tables.php wird diese Extension als „Provider Extension“ bei Flux registriert und die Magie beginnt.

Als Beispiel sind über den Builder dort schon zwei Templates angelegt worden, diese sind zum einen ein Seiten-Template und zum anderen ein Contentelement-Template. Jedes weitere Template das im Ordner „Page“ oder „Content“ angelegt wird, wird automatisch im TYPO3 Backend als Seitentemplate oder als Contentelement zur Verfügung gestellt.

Hinzu kommt dass in diesen Template Dateien die komplette Konfiguration enthalten ist. Configuration (BE Eingabe), Preview (BE) und Main (FE rendering) sind dort zentral in einer Datei enthalten. Und das alles ohne eine einzige Zeile TypoScript!

Beispiel Konfigurationsdatei für ein Seitentemplate:

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
	xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
	f:schemaLocation="https://fluidtypo3.org/schemas/fluid-master.xsd"
	xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
	flux:schemaLocation="https://fluidtypo3.org/schemas/flux-master.xsd"
	xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
	v:schemaLocation="https://fluidtypo3.org/schemas/vhs-master.xsd">
	<f:layout name="Page" />

	<f:section name="Configuration">
		<flux:form id="fluidpage" options="{icon: 'Icons/Page/Standard.gif'}">
			<!-- Insert fields, sheets, grid, form section objects etc. here, in this flux:form tag -->
		</flux:form>
		<flux:grid>
			<!-- Edit this grid to change the "backend layout" structure -->
			<flux:grid.row>
				<flux:grid.column colPos="0" colspan="3" name="main" />
				<flux:grid.column colPos="1" name="right" />
			</flux:grid.row>
		</flux:grid>
	</f:section>

	<f:section name="Main">
		<h1>I am a page template!</h1>
		<p>
			My template file is EXT:myprovider/Resources/Private/Page/Standard.html.
		</p>
		<div style="float: left; width: 75%;">
			<h2>Content main</h2>
			<v:content.render column="0" />
		</div>
		<div style="float: left; width: 25%;">
			<h2>Content right</h2>
			<v:content.render column="1" />
		</div>
	</f:section>
</div>

Beispiel einer Konfigurationsdatei für ein Contentelement:

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
	xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
	f:schemaLocation="https://fluidtypo3.org/schemas/fluid-master.xsd"
	xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
	flux:schemaLocation="https://fluidtypo3.org/schemas/flux-master.xsd">
	<f:layout name="Content" />

	<f:section name="Configuration">
		<flux:form id="fluidcontent" options="{icon: 'Icons/Content/Example.gif', group: 'FCE'}">
			<!-- Insert fields, sheets, grid, form section objects etc. here, in this flux:flexform tag -->
		</flux:form>
	</f:section>

	<f:section name="Preview">
		<!-- uncomment this to use a grid for nested content elements -->
		<!-- <flux:widget.grid /> -->
	</f:section>

	<f:section name="Main">
		<h3>I am a content element!</h3>
		<p>
			My template file is EXT:myprovider/Resources/Private/Content/Example.html.
		</p>
	</f:section>
</div>

Im Hintergrund kümmert sich flux um alles und übergibt automatisch an die Templates (Views) alle benötigten Objekte für das Rendering im Frontend.

Wie schon erwähnt ein in meinen Augen ziemlich geniales Gespann mit dem man einfach, schnell und flexibel Seitentemplates und Contentelemente (FCE’s) anlegen kann.

Fluid Powered TYPO3 auf Github

Extbase / Fluid: Image ViewHelper erweitern für Lazyloading

Mobile ist im kommen. Vielleicht kann es auch auf umfangreichen Seiten mit vielen Bilder nötig sein, Bilder erst zu laden wenn diese im sichtbaren Bereich erscheinen um Ladezeiten zu verkürzen bzw. aufzuteilen. Twitter und Facebook nutzen diese Technik und bei der Bildersuche in Suchmaschinen dürfte dieses Feature schon mal aufgefallen sein.

Im jQuery Plugin Fundus gibt es eine Lösung: Lazy Load Plugin for jQuery . Weitere Argumente für Lazy Loading sind auf dieser Homepage zu finden ;-)

Und zu guter letzt auch noch ein LazyImage ViewHelper für Fluid. Dieser erweitert den Standard ViewHelper und tauscht das „src“-Attribut gegen das „data-original“-Attribut für das jQuery Plugin.

<?php
namespace YourVendor\YourExtKey\ViewHelpers;

/***************************************************************
 *  Copyright notice
 *
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/

class LazyImageViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\ImageViewHelper {

	/**
	 * Initialize arguments.
	 *
	 * @return void
	 */
	public function initializeArguments() {
		parent::initializeArguments();
		$this->registerTagAttribute('data-original', 'string', 'original image for lazy loading', FALSE);
	}

	/**
	 * Resizes a given image (if required) and renders the respective img tag
	 *
	 * @see http://typo3.org/documentation/document-library/references/doc_core_tsref/4.2.0/view/1/5/#id4164427
	 * @param string $src a path to a file, a combined FAL identifier or an uid (integer). If $treatIdAsReference is set, the integer is considered the uid of the sys_file_reference record. If you already got a FAL object, consider using the $image parameter instead
	 * @param string $width width of the image. This can be a numeric value representing the fixed width of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.
	 * @param string $height height of the image. This can be a numeric value representing the fixed height of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.
	 * @param integer $minWidth minimum width of the image
	 * @param integer $minHeight minimum height of the image
	 * @param integer $maxWidth maximum width of the image
	 * @param integer $maxHeight maximum height of the image
	 * @param boolean $treatIdAsReference given src argument is a sys_file_reference record
	 * @param FileInterface|AbstractFileFolder $image a FAL object
	 *
	 * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
	 * @return string Rendered tag
	 */
	public function render($src = NULL, $width = NULL, $height = NULL, $minWidth = NULL, $minHeight = NULL, $maxWidth = NULL, $maxHeight = NULL, $treatIdAsReference = FALSE, $image = NULL) {
		if (is_null($src) && is_null($image) || !is_null($src) && !is_null($image)) {
			throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('You must either specify a string src or a File object.', 1382284106);
		}
		$image = $this->imageService->getImage($src, $image, $treatIdAsReference);
		$processingInstructions = array(
			'width' => $width,
			'height' => $height,
			'minWidth' => $minWidth,
			'minHeight' => $minHeight,
			'maxWidth' => $maxWidth,
			'maxHeight' => $maxHeight,
		);
		$processedImage = $this->imageService->applyProcessingInstructions($image, $processingInstructions);
		$imageUri = $this->imageService->getImageUri($processedImage);

		$this->tag->addAttribute('data-original', $imageUri);
		$this->tag->addAttribute('width', $processedImage->getProperty('width'));
		$this->tag->addAttribute('height', $processedImage->getProperty('height'));

		$alt = $image->getProperty('alternative');
		$title = $image->getProperty('title');

		// The alt-attribute is mandatory to have valid html-code, therefore add it even if it is empty
		if (empty($this->arguments['alt'])) {
			$this->tag->addAttribute('alt', $alt);
		}
		if (empty($this->arguments['title']) && $title) {
			$this->tag->addAttribute('title', $title);
		}

		return $this->tag->render();
	}
}

?>

 

Fluid: Fluid-Templates ohne Extbase nutzen

Fluid Templates ohne Extbase nutzen.

$renderer = t3lib_div::makeInstance('Tx_Fluid_View_TemplateView');
$renderer->setControllerContext(t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_ControllerContext'));
$template = t3lib_extMgm::extPath(strtolower($this->extensionName)) . 'Resources/Private/...';
$renderer->setTemplatePathAndFilename($template);
$renderer->assign('helloworld', $helloworld);
$rendered = $renderer->render();

Quelle:

http://modi.de/2010/02/12/fluid-without-extbase/
http://de.slideshare.net/plobacher/typo3camp-2009-einfhrung-in-fluid

 

Extbase / Fluid: Inline Javascript einfügen?

Schön ist es vielleicht nicht wenn man in Extbase/Fluid Inline JavaScript ins Fluid-Template mit aufnehmen will. Aber in manchen Fällen kommt man einfach nicht drum herum ;-) Die Stelle an der es tricky wird ist wenn dynamische Werte mit der geschweiften Klammer in das JavaScript mit aufgenommen werden sollen.

In diesem Fall muss mit einem <![CDATA[ … ]]> gearbeitet werden.

<script type="text/javascript">
	<![CDATA[
	$(document).ready(function(){
		$('.selector]]>{myvalue}<![CDATA[').click()
	})
	]]>
</script>

Ein anderes Szenario ist wenn die eingefügten Inhalte ebenfalls JavaScript oder Json enthalten. Hier müssen die Daten mit dem Fluid „format.html“ ViewHelper eingefügt werden.

<script text="type/javascript"> 

var myObject= <f:format.html parseFuncTSPath="">{json}</f:format.html>

</script>