pt_extlist für entwickler

Werbung
pt_extlist
Daniel Lienert & Michael Knoll
pt_extlist
Agenda für heute
Teil I :: pt_extlist Übersicht
Teil II :: pt_extlist für Integratoren
• TypoScript Konfiguration
• Einbindung als Seiteninhaltselement
• Templates und Partials
Teil III :: pt_extlist für Entwickler
• Architektur & Komponenten
• Lifecycles
• pt_extlist erweitern
pt_extlist
Komponenten
pt_extlist
Schränkt Auswahl der Elemente ein (SQL: where)
Sortiert Elemente (SQL: order by)
Listdaten
Daten der Abfrage (gefiltert, sortiert, „gepaged“)
Aggregate
Aggregate der Daten
Liemitiert Anzahl (SQL: limit)
pt_extlist
Agenda für heute
Teil I :: pt_extlist Übersicht
Teil II :: pt_extlist für Integratoren
• TypoScript Konfiguration
• Einbindung als Seiteninhaltselement
• Templates und Partials
Teil III :: pt_extlist für Entwickler
• Architektur & Komponenten
• Lifecycles
• pt_extlist erweitern
pt_extlist
TypoScript, Flexform & Co
PT_EXTLIST FÜR INTEGRATOREN
pt_extlist
Einbinden des Plugins
• Wie bisher auch:
1. Liste in TypoScript definieren
2. Liste per FlexForm als Seiteninhalt einbinden
pt_extlist
Einbinden des Plugins 2
• Neu: Listen‐Konfigurationen werden automatisch erkannt:
pt_extlist
Einbinden im Cached Mode
• Liste wird gecached
– Gleiche URLs führen zu gecachten Aufrufen
• „Zweiter“ Plugin‐Typ für gecachte Version
pt_extlist
Einbinden im Cached Mode
• Vorteil: extlist auch für Frontend‐Listen verwendbar.
• Nachteil: Soll der Benutzer auf die Liste einwirken, kann nur EINE Liste (sprich Komponenten zu einem Listidentifier) auf einer Seite eingesetzt werden.
pt_extlist
TypoScript Prototypen
• Prototyp ist erweiterte „Default‐
Konfiguration“
– Keine Default‐Werte in PHP Code
– Alle Konfiguration in TypoScript
• Zeigt Konfigurationsmöglichkeiten auf
• Macht Konfiguration einfacher und transparent
• Zerteilt in flexible Bausteine
pt_extlist
plugin.tx_ptextlist.prototype.filter {
TypoScript Prototypen 2
string {
filterClassName = Tx_PtExtlist_Domain_Model_Filter_StringFilter
partialPath = Filter/String/StringFilter
defaultValue =
accessGroups =
• Wo befinden sich Prototypen?
– Im Filesystem:
Configuration/TypoScript/BaseConfig/Prototype
breadCrumbString = TEXT
– Im TS‐Baum:
breadCrumbString {
# Fields that can be used are 'label' and 'value'
plugin.tx_ptextlist.prototype
dataWrap = {field:label} equals {field:value}
}
• Wie wird Prototyp verwendet? }
11 < plugin.tx_ptextlist.prototype.filter.string
11 {
filterIdentifier = allFields
label = All defined Fields
fieldIdentifier = *
}
pt_extlist
TypoScript Konfiguration
• plugin.tx_ptextlist
• Konfiguration findet sich unter „settings“
pt_extlist
TypoScript Konfiguration 2
• plugin.tx_ptextlist.settings
pt_extlist
TypoScript Konfiguration 3
• plugin.tx_ptextlist.settings.listConfig
• Namensraum für Listenkonfiguration
• Jede Liste bekommt List‐Identifier
pt_extlist
TypoScript Konfiguration 4
• [...].<listIdentifier>.backendConfig (neu!)
– Benutzung von Prototypen für einfache Konfiguration (hier: Backend‐Prototyp „typo3“):
backendConfig < plugin.tx_ptextlist.prototype.backend.typo3
pt_extlist
TypoScript Konfiguration 5
• [...].<listIdentifier>.fields (früher „data“)
Backend: SQL
Backend: extbase
Zugriff auf ein Objektelement
Zugriff auf ein komplettes Objekt
pt_extlist
TypoScript Konfiguration 6
• [...].<listIdentifier>.columns (wie früher)
pt_extlist
TypoScript Konfiguration 6 / 2
• [...].columns.<column>.cellCSSClass
– Dynamische Definition der CSS Classe einer Zelle:
columns {
5 {
cellCSSClass {
renderObj = COA
RenderObj {
10 = TEXT
10.value = greenBox
10.if {
value.data = field:sumOpen
equals = 0
}
}
…
pt_extlist
TypoScript Konfiguration 7
• [...].<listIdentifier>.filters (einige Änderungen!)
– Prototypen für jeden Filtertyp
– Alle Filter mit Auswahlfunktion haben vorkonfiguriertes RenderObjekt
renderObj = TEXT
renderObj {
dataWrap = {field:allDisplayFields} ({field:rowCount})
}
pt_extlist
TypoScript Konfiguration 8
• [...].<listIdentifier>.aggregateData (neu!) aggregateData {
# methods: sum, min, max, avg
sumPhone {
fieldIdentifier = phone
method = sum
scope = page
special = }
}
• method: sum/avg/max/min
• scope (Neu): page / query (default: page)
• special: special SQL Query
pt_extlist
TypoScript Konfiguration 8 / 2
• [...].<listIdentifier>.aggregateRow
aggregateRows {
10 {
phoneColumn {
aggregateDataIdentifier = sumPhone, avgPhone, maxPhone, minPhone
renderObj = TEXT
renderObj.dataWrap (
Min.: <b>{field:minPhone}</b><br /> )
}
}
}
pt_extlist
Templates & Partials
• Wo finde ich die Templates & Partials
– Templates befinden sich in
Resources/Private/Templates/
– Partials befinden sich in Resources/Private/Partials/
pt_extlist
Templates & Partials 2
• Verwendung von FLUID Syntax:
– ViewHelper: <f:viewHelperName attrib= “value“>
– Variablen: {object.property}
• Weitere Hilfe: Extbase & FLUID Cheatsheet
pt_extlist
Templates & Partials 3
• Verfügbare Objekt in Templates werden im Header angegeben:
…
Here is a list of objects / variables that can be accessed in this template:
Tx_PtExtlist_Domain_Configuration_ConfigurationBuilderconfig
Tx_PtExtlist_Domain_Model_List_Header_ListHeaderlistHeader
Tx_PtExtlist_Domain_Model_List_RowlistCaptions
Tx_PtExtlist_Domain_Model_List_ListDatalistData
Tx_PtExtlist_Domain_Model_List_ListDataaggregateRows
A instance of the configurationbuilder
A instance with header information.
A row with captions for every column.
A collection of rows.
A collection of aggregateRows
pt_extlist
Templates & Partials 4
• Templates sind per Konvetion von Controller und Action abhängig:
ListController‐>listAction()
Æ Resources/Private/Templates/List/list.html
• Eigener Controller Æ per TS „überschreibbar“:
plugin.tx_ptextlist.settings
.controller
.<CONTROLLER NAME WITHOUT „CONTROLLER“>
.<ACTION NAME WITHOUT „ACTION“>
.template = path_to_template
pt_extlist
Verwendung von Partials in Columns
• FLUID Templates können für das Rendering von Tabellenzellen verwendet werden
• TS‐Konfiguration:
30 {
label = Country
columnIdentifier = country
fieldIdentifier = country_en, capital, tld
renderTemplate = EXT:pt_extlist/Configuration/
TypoScript/Demolist/
Demolist_Typo3_02.hierarchicStructure.html
}
pt_extlist
Verwendung von Partials in Columns 2
• Zugriff auf Listen‐Werte im Partial / Template
<ul>
<f:for each="{data}" as="dataRow">
<li><b><f:format.html>{dataRow.country_en}
</f:format.html></b>
<ul>
<li>City: {dataRow.capital}</li>
<li>TLD: {dataRow.tld}</li>
</ul>
</li>
</f:for>
</ul>
pt_extlist
Export
Exports werden über eigene Templates und Views realisiert.
Konfigurationen unter Export
plugin.tx_ptextlist.settings.export {
exportConfigs {
csvExport < plugin.tx_ptextlist.prototype.export
csvExport {
viewClassName = Tx_PtExtlist_View_Export_CsvListView
fileExtension = csv
}
fluidTemplateExport < plugin.tx_ptextlist.prototype.export
fluidTemplateExport {
viewClassName = Tx_PtExtlist_View_Export_FluidListView
fileExtension = txt
templatePath = typo3conf/ext/pt_extlist/Resources/Private/Templat
es/Export/export.html
}
}
}
pt_extlist
Dokumentation
pt_extlist
Beispiele
• Demolisten im Paket
• Sammlung der Beispiele und Funktionen:
http://ry25.extlist.devel.intern.punkt.de
pt_extlist
Agenda für heute
Teil III :: pt_extlist für Entwickler
• Architektur & Komponenten
• Lifecycles
• pt_extlist erweitern
pt_extlist
Agenda für heute
Teil II :: pt_extlist für Entwickler
• Architektur & Komponenten
• Lifecycles
• pt_extlist erweitern
pt_extlist
Architektur, Komponenten, Erweiterung
PT_EXTLIST FÜR ENTWICKLER
pt_extlist
Architektur
pt_extlist
Architektur 2
• Architekturziele:
– Portierung auf Extbase Framework
– Möglichkeit der Nutzung von Domain Objects
– Entkopplung von Logik und Controllern
– Austauschbarkeit von Komponenten
pt_extlist
Komponenten
• Data Backend
– „Anschluss“ an Datenquelle
– Erzeugung von datenquellenspezifischen Anfragen (SQL, Extbase QueryObject)
– Übertragung in pt_extlist eigenes Datenformat (DataMapper)
– Berücksichtigt dabei Filter, Pager, Sorter...
pt_extlist
Komponenten 2
• Configuration Builder
– Objekte für (TypoScript‐)Konfiguration
– Verschmelzen von Prototypen und aktueller Konfiguration
– Überprüfung auf Konsistenz
– Erzeugen von hilfreichen Fehlermeldungen zur Konfiguration
pt_extlist
Komponenten 3
• Filter, Sorter, Pager
– Wie früher auch: Beeinflussung der angezeigten Daten hinsichtlich
• WHERE (Filter)
• SORT BY (Sorter)
• LIMIT (Pager)
– Neu: • Klare Trennung von Controller und Logik
• Abhängigkeiten sind in einem Durchlauf aufgelöst pt_extlist
Komponenten 4
• Mapper, RenderChain, ListDataStructureM
– Mapper: Abbildung der Datenquellen‐spezifischen Datenstruktur (Array, Objekte) auf Listen‐Struktur
– RenderChain: Hintereinander verknüpfbare
Renderer zur Darstellung der Listen‐Struktur
– ListDataStructure: Container für Listendaten
• Zeilen (rows)
• Spalten (cols)
pt_extlist
Komponenten 5
• (M)VC Stack
– Abstrakter Controller als ActionController
• Enthält alle notwendigen pt_extlist Komponenten
• Erzeugt diese aber nicht
– Abstrakte View als Basisklasse für Views
• Überschreiben von Templates / Partials in TS möglich
– FLUID Templates und Partials für Rendering
• Eigene Viewhelper (z.B. für Generierung von Links)
pt_extlist
pt_extlist Lifecycle
Controller::_construct()
Build FieldConfiguration
Controller::resolveViewObjectName(
)
LifecycleManagerFactory::
getInstance()
Build DataMapper
Controller::callAction()
SessionPersistenceMananagerFactor
y::getInstance()
Build DataSource
Builder QueryInterpreter
ListFactory::createList($dataBackend, $configuration)
ConfigurationBuilderFactory::
getInstance($listIdentifier)
Build PagerCollection
RendererChain::renderList($listData)
DataBackendFactory::
createDataBackend($configuration)
Build ListeHeader
View::render()
Build FilterboxCollection
pt_extlist
Namespaces
Idee:
Nutze Pfade in GP Vars und Session als Namespace
Æ Automatisches Mapping der Parameter
pt_extlist
Object Lifecycle
1. TYPO3 Seitenaufruf
7. Lifcycle Manager wird beendet
6. Lifcycle Manager schreibt Objektdaten in Session
2. Lifecycle Manager wird gestartet
Benutze Object‐
Namespace
3. Session‐persistentes
Objekt wird erzeugt
3.1. Objekt‐Daten werden aus Session in Objekt geschrieben
5. Lifcycle Manager bekommt Endsignal
4. Objektdaten werden verändert
pt_extlist
Object Lifecycle 2
• ObjectNamespace
– Objekt‐Typ + Objekt‐Identifier
• Beispiel: tx_ptextlist.filters.filterbox1.countryFilter
• ObjectData
– Array‐Werte, die persistiert werden sollen
pt_extlist
Konzepte & Paradigmen
• Factories zur Objekterzeugung
– Reduzierungen der Abhängigkeiten
– Trennung von Erzeugung und Logik
– Bessere Testbarkeit
– Dynamische Ermittlung der konfigurierten Klassen
pt_extlist
Konzepte & Paradigmen 2
• Erweiterungen von Extbase
– Eigene Abstrakte Controller
• Alle default Werte in allen Controllern verfügbar
– Eigene Abstrakte View
• Überschreibung von Templates
und Partials durch TS
pt_extlist
Query Object
• Idee: Kapseln von DB‐Anfragen in Objekt
• Vorteile:
– Unabhängigkeit von Datenquelle (SQL, Extbase)
– Mehr Sicherheit
• SQL Injection
– Einheitliche Schnittstelle für Komponenten
• constraints, limits, sorting...
pt_extlist
Query Object 2
pt_extlist
Query Object 3
pt_extlist
Query Object 4
• Beispielcode Query‐Erzeugung:
protected function buildFilterCriteria(
Tx_PtExtlist_Domain_Configuration_Data_Fields_FieldConfig $fieldIdentifier) {
$filterValue = '%'.$this->filterValue.'%‘;
$criteria = Tx_PtExtlist_Domain_QueryObject_Criteria::like(
$this->fieldName, $filterValue);
return $criteria;
}
pt_extlist
Query Object 5
• Beispielcode Übersetzung:
public function getWhereClauseFromFilter
(Tx_PtExtlist_Domain_Model_Filter_AbstractFilter $filter) {
$whereClauseFromFilter = $this->queryInterpreter->getCriterias(
$filter->getFilterQuery());
return $whereClauseFromFilter;
}
pt_extlist
Eigene Erweiterungen: Filter
• Es gibt 3 Basisklassen für Filter:
– AbstractFilter: Basisklasse aller Filter
– AbstractSingleValueFilter: Basisklasse für Filter ohne Zugriff auf Daten
– AbstractOptionsFilter: Basisklasse für Filter mit Zugriff auf Listendaten (Auswahlfilter)
pt_extlist
Eigene Erweiterungen: Filter 2
• Zu implementierende Funktionen:
– SingleValueFilter:
• buildFilterCriteria($fieldIdentifier)
• Erzeugt ein Filter‐Kriterium für Filterwert
– OptionsFilter:
• getOptions()
• Gibt auswählbare Optionen zurück
pt_extlist
Eigene Erweiterungen: Filter 3
• Optional zu implementierende Optionen
– Session‐Persistenz:
• Wenn „mehr als nur ein Wert“ in der Session gespeichert werden soll.
• Beispiel: TimeSpan Filter: Von‐ und Bis‐Wert muss gespeichert werden
– Breadcrumbs:
• Eigene Funktion für die Ausgabe der Breadcrumbs
pt_extlist
Beispiel: TimeSpanFilter
• Funktion: Filter soll Werte von Start bis Stopp filtern
– Beispiel: Zeit von 1.1.2010 – 31.12.2010
• Benötigte Filter‐Werte:
– FilterValueFrom
– FilterValueTo
pt_extlist
Beispiel: TimeSpanFilter 2
• Session‐Initialisierung:
protected function initFilterBySession() {
$this->filterValueFrom = array_key_exists(
'filterValueFrom', $this->sessionFilterData) ?
$this->sessionFilterData['filterValueFrom'] :
$this->filterValueFrom;
$this->filterValueTo = array_key_exists(
'filterValueTo', $this->sessionFilterData) ?
$this->sessionFilterData['filterValueTo'] :
$this->filterValueTo;
}
pt_extlist
Beispiel: TimeSpanFilter 3
• Session‐Persistierung:
public function persistToSession() {
return array(
'filterValueFrom' => $this->filterValueFrom,
'invert' => $this->invert,
'filterValueTo' => $this->filterValueTo
);
}
pt_extlist
Beispiel: TimeSpanFilter 4
• GP‐Vars auslesen:
protected function initFilterByGpVars() {
if (array_key_exists(
'filterValueFrom', $this->gpVarFilterData)) {
$this->filterValueFrom =
$this->gpVarFilterData['filterValueFrom'];
}
if (array_key_exists(
'filterValueTo', $this->gpVarFilterData)) {
$this->filterValueTo =
$this->gpVarFilterData['filterValueTo'];
}
}
pt_extlist
Beispiel: TimeSpanFilter 5
• Filter‐Criteria erzeugen:
protected function buildFilterCriteria($fieldIdentifier) {
if ($this->filterValueFrom == ''||$this->filterValueTo == '') {
return NULL;
}
// ... //
$criteria1 = Tx_PtExtlist_Domain_QueryObject_Criteria::
greaterThanEquals($fieldName, $this->filterValueFrom);
$criteria2 = Tx_PtExtlist_Domain_QueryObject_Criteria::
lessThanEquals($fieldName, $this->filterValueTo);
$criteria = Tx_PtExtlist_Domain_QueryObject_Criteria::
andOp($criteria1, $criteria2);
return $criteria;
}
pt_extlist
Beispiel: TimeSpanFilter 6
• Breadcrumbs erzeugen:
protected function getFieldsForBreadcrumb() {
$parentArray = parent::getFieldsForBreadCrumb();
$parentArray['fromValue'] = $this->filterValueFrom;
$parentArray['toValue'] = $this->filterValueTo;
return $parentArray;
}
• Verwendung in TS:
breadCrumbString {
dataWrap = {field:label} is between {field:fromValue} and
{field:toValue}
}
pt_extlist
Beispiel: TimeSpanFilter 7
• TS Prototype:
dateRange {
filterClassName =Tx_PtExtlist_Domain_Model_Filter_TimeSpFilter
partialPath = Filter/Range/DateRangeFilter
defaultValue =
accessGroups =
breadCrumbString = TEXT
breadCrumbString {
dataWrap = {field:label} is between {field:fromValue} and
{field:toValue}
}
}
pt_extlist
Eigene Erweiterungen: Renderer
• Möglichkeit, eigene Renderer zu schreiben
• Renderer sind in Chain angeordnet
– Werden nacheinander abgearbeitet
– Eingangsdatenstruktur = Ausgangsdatenstruktur
RendererChain
ListDataStructure
Renderer 1
...
Renderer n
ListDataStructure
pt_extlist
Eigene Erweiterungen: Renderer 2
pt_extlist
3rd Party‐Extensions
• Möglichkeiten der Einbindung:
– Als eigenes Content‐Element (trivial)
– Als Widget (noch nicht implementiert)
– Durch Verwendung von Objekten (hier gezeigt)
pt_extlist
3rd Party‐Extensions 2
• listContext
– Hält alle relevanten Objekte bereit
– Kann mit beliebiger Konfiguration für – Beliebige ListIdentifier erzeugt werden
– „Herzstück“ der externen Verwendung von pt_extlist
pt_extlist
3rd Party‐Extensions 3
pt_extlist
3rd Party‐Extensions 4
• Erzeugung eines ExtlistContexts aus TS‐array
Tx_PtExtlist_ExtlistContext_ExtlistContextFactory::
getContextByCustomConfiguration(
$listConfigurationArray, $listIdentifier);
pt_extlist
3rd Party‐Extensions 5
• Rendern einer Liste (PHP)
public function listAction() {
$this->extListContext->getPagerCollection()->
setItemsPerPage($this->getItemsPerPage);
$this->view->assign('listData',
$this->extListContext->getRenderedListData());
$this->view->assign('pagerCollection',
$this->extListContext->getPagerCollection());
$this->view->assign('pager',
$this->extListContext->getPager());
}
pt_extlist
3rd Party‐Extensions 6
• Rendern einer Liste (FLUID‐Template)
<div class="tx-yag-items">
<f:for each="{listData}" key="rowIndex" as="listRow">
<f:render
partial="{config.itemListConfig.imageThumbPartial}"
arguments="{config: config, image:
listRow.image.value, rowIndex:
listRow.specialValues.absoluteRowIndex, pager:
pager, pagerCollection:pagerCollection}" />
</f:for>
</div>
pt_extlist
3rd Party‐Extensions 7
• Rendern einer Liste (FLUID‐Partial)
<div class="tx-yag-thumb-innerframe">
<div><extlist:link.action action="show" controller="Item"
arguments="{itemUid: rowIndex}">
<yag:image item="{image}" resolutionName="thumb" />
</extlist:link.action></div>
</div>
pt_extlist
pt_extlist ViewHelper
• Image
– Sorting :: Rendert Bilder für Sortierung
• Link
– Action :: Rendert Link für Actionn
– Sorting :: Rendert Linkf für Sortierung
• Namespace
– FormElementName :: Rendert Formularnamen nach NS – GPArrayViewHelper :: Rendert Argument Array
• Uri
– Action :: Fügen state‐hash hinzu, wenn in Cache‐Mode
pt_extlist
Herunterladen