Grouped List Layout
From TYPO3Wiki
Contents |
Grouped List Layout
Several FE plugins have a common task: report data from underlying database. Usually the report layout has a common list structure, but in some cases it needs more hierarchical levels.
Below there is an example of this means, where a list of publications is grouped by year.
<h1>Publications</h1>
<dl>
<dt>Year 2005</dt>
<dd>
<ul>
<li>Liquid gallium in confined droplets under high-temperature and high-pressure conditions</li>
<li>Metalization of the Ge(111) surface at high-temperature probed by energy-loss and Auger spectroscopies</li>
</ul>
</dd>
<dt>Year 2004</dt>
<dd>
<ul>
<li>Structure of crystalline and amorphous Ge probed by x-ray absorption and diffraction techniques</li>
<li>Melting of the Ge(111) surface probed by EELS</li>
</ul>
</dd>
</dt>
The list represents a 2 level tree structure.
Other issues
Level browser
Consider the second level from the previous example and imagine an hundred of <li> elements. It might be useful to browse those items using a pagebrowser, as pi_base already does.
Pages
Pages are the way to separate items or a fixed number of them. These are examples of pages:
- classical odd-even alternating colour effect;
- columned layout, where each column correspond to a page.
In both cases pagebreaks occur after a fixed number of elements that can be calculated automatically on the total number of items and pages, or set manually.
Implementation
FE side
I tried to solve those problems creating a new class that extends pi_base. There are two main steps the base class affords:
- Fetch data from a data source;
- grouped list rendering.
Data fetching
On this step the data is retrived from the datasource, by choosing one (or more?) of these methods:
- freeSelect (some TS to configure an exec_SELECTquery call)
- typoSelect (uses Typo3 select function)
- userSelect (an external function)
- [...perhaps I can add elba (as the island :) ?) SELECT method here...]
Every of those methods returns an array of rows.
Rendering
This is divided into two steps:
- grouping
- rendering
Grouping creates a tree of items, looking to every row from datasource and assigning it to a group. Every group is represented by a node of the tree and has a key and a group leader. The key may be generated by a user function call, allowing customized grouping criteria. The actual implementation can group byField concatenation.
Rendering walks depth-first throught the tree and generates markup as specified by TS. The idea is the same of HMENU objects, where each level of the tree is assigned to a TS. [NOTE: this part will be updated as soon as possible]
BE utility
On BE plugin configuration it might be useful to select from a list of different layouts (that might correspond to different grouping criteria...).
A similar issue is known to be covered by Template Selector. I tried to implement a general approach adding a configurable TCEForm user function, called ts_selector. Below an example of how it is used in a flexform configuration.
<TCEforms>
<label>layout</label>
<config>
<type>select</type>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="0">[Default Layout]</numIndex>
<numIndex index="1">default</numIndex>
</numIndex>
</items>
<itemsProcFunc>tx_sicicore_be->ts_selector</itemsProcFunc>
<TSSelector>plugin.tx_sicistcsrc_pi1.layout:title</TSSelector>
</config>
</TCEforms>
This means that plugin.tx_sicistcsrc_pi1.layout contains the different layouts. Every layout has a title property used to produce the title of the select items.
Pro & Cons
TS and user functions make it possible to tailor this approach to different situations, but complex layouts are not easy to configure on the other hand: a lot of TS is needed.
Existing extensions
Currently, the concepts we have talked about are inluded into the following extension(s):
