菜单

TypoScript reference – getText

2010年10月12日 - typoscript

This page is document in progress. TypoScript

getText is an advanced TypoScript datatype. It enables you to access almost any data in the TYPO3 system. getText is so flexible, that it deserves it’s own page and hopefully some day this page will have enough information to be pointed to by the TSref.

It is defined in typo3/sysext/cms/tslib/class.tslib_content.php function getData.

Luckily this datatype is available everywhere, where a property has the addition stdWrap. Namely the stdWrap.data and the stdWrap.dataWrap properties. If stdWrap.insertData is set to 1, then also the property itself is parsed similar as .dataWrap is.

# Sample:
page.40 = HTML
# Note, that the HTML.value property has the stdWrap addition/processing.
# We set a literal value here, which won't last long ...
page.40.value = Hello world
# ... as we now replace it with .data to access fields from the current page record:
# the navigation title; if that isn't set, the authors name; finally fall back to the
# pages unique identifier
page.40.value.data = field:nav_title // field:author // field:uid
page.40.value.wrap = <h1>|</h1>

General Syntax (used by stdWrap.data)

The general syntax of getText is <type> : <parameter> [<optional parameters>]

Depending on the type there are optional parameters and they must be given separated by ‘,’ or ‘|’ or ‘:’ (type specific). E.g.

# Access the title field of the current page. If that isn't set look up the title
# of every parent page along the rootline until a title is found.
# Note, that the whole TEXT object is feed to / processed by stdWrap as opposed to the
# HTML object, where only the value property has the stdWrap processing.
temp.title = TEXT
temp.title.data = leveltitle : -1, slide

Here the type is ‘leveltitle’ (which accesses the title field of the current or some parent page), -1 is the required parameter (-1 meaning: access the titel of the current page), slide is an optional parameter forcing TYPO3 to not only look at the current page, but also at every parent/grandparent page, until a title is actually set. If no title value is found in the rootline (this page and every parent page), this TypoScript returns an empty string. The type ‘leveltitle’ expects its optional parameters sepearatd by comma ‘,’, white space is ignored, as usual.

Syntax differences for stdWrap.dataWrap

The syntax given above is meant for the stdWrap.data property. When using the stdWrap.dataWrap property the syntax is still the same, but you have to enclose it into curly braces. Strings outside the curly braces are taken literally except for the vertical bar ‘|’, which is, as usual for wraps, replaced by the existing value.

# Same as above, decorated with some explaining text
temp.title = TEXT
temp.title.value = title of this page
temp.title.dataWrap = Here is the&nbsp; | &nbsp;or some parent: {leveltitle : -1, slide}

.dataWrap also allows for several insertions at once. Just enclose each field in it’s own pair of curly braces:

# Render parents Title and UID, be aware, this code will show crap on the root page of your website
temp.title = TEXT
# note that we don't set a value
temp.title.dataWrap = |Parent page is {leveltitle : -2} with UID {field : pid}

Syntax differences, when stdWrap.insertData is set

When stdWrap.insertData is set to 1, then the property having the stdWrap processing itself is handled similar as described above for the .dataWrap property. The only difference is, that the vertical bar ‘|’ now stands for itself and isn’t replaced with anything.

# Same as above, decorated with a shorter text
temp.title = TEXT
temp.title.value = |{leveltitle : -1, slide}| is the title of this page or some parent.
# force replacement of the curly braces content, else it would be taken literally
temp.title.insertData = 1

This will render the string ‘|<some_title>| is the title of this page or some parent.’

.insertData is especially useful, when several values are to be inserted:

# A verbose page title
temp.title = COA
temp.title {
  10 = TEXT
  10.value = Page title: {page:title},&nbsp;
  20 = TEXT
  20.value = Pages UID: {TSFE:id},&nbsp;
  30 = TEXT
  30.value = Today is: {date:r}
  # force replacement of all curly braces content in one run
  stdWrap.insertData = 1
}

The whole COA object is feed through stdWrap, which parses out all 3 curly brace pairs and replaces the fields in just one run. That is more performant as calling stdWrap 3 times for every TEXT object and the TypoScript is cleaner/more readable.

Syntax extension: short-circuit OR with //

Sometimes you don’t know, if a certain field is filled in by the author but there might be other fields you can fall back to. All getText properties support a syntax extension similar to the short-circuit OR in PERL. To use that, list all fields separated by ‘//’ in the order from most wanted to least wanted. This is much simpler than trying to work with if.

# Render the field abstract, if not set the description and fall back to the subtitle
temp.abstract = TEXT
# No need to set temp.abstract.value, it will be overwritten anyway
temp.abstract.data = field : abstract // field : description // field : subtitle
temp.abstract.noTrimWrap = |Page abstract: ||
# Similar as above using .insertData and having a final fallback
temp.abstract = TEXT
temp.abstract.value = Abstract: {field:abstract//field:description//field:subtitle//date:\n\o \a\b\s\t\r\a\c\t}
temp.abstract.insertData = 1

The first field having a value is used and returned. If none of the fields has content, then the value is set to the empty string. Note the ‘creative abuse’ of the date field in the second sample; by escaping all chars with the backslash they are not interpreted as format chars but spit out literally.

Motivation

getText has overwhelming features, not well documented elsewhere. For instance, while TYPO3 renders content, it sometimes writes (intermediate) processing results to some place accessible via

...stdWrap.data = register : <whatever>

This document tries also, to give some hints to <whatever> is to be set to and in what context that <whatever> will yield results.

Again: getText is essentially a way to access TYPO3 dynamic data of all sort at rendering time.

Available Types

This is the list of all available types sortet alphabetically.

Although all types are essentialy processed case insensitive, they are given here in the official mix of upper/lower case and you should write them down, as shown here (and everywhere else). And the parameters are not case insensitive mostly, so respect the given case!

cObj:parentRecordNumber

current:1

This type does exactly the same as stdWrap.current. It sets the content of the property having stdWrap handling to the content of the internal “current” TYPO3 scratch area. Thus a better name would have been “getCurrent”. Compare stdWrap.setCurrent and stdWrap.setContentToCurrent.

The “current” scratch area is filled in by TYPO3 sometimes while processing/rendering content. The most prominent place is the stdWrap.split handling. stdWrap.split is used to loop over the parts of a token separated string and process each part (potentially different). While looping, TYPO3 sets the “current” scratch area to the part just working on.

# reformat a comma separated string into a HTML list of strings
temp.list = TEXT
temp.list {
  # not really usefull, just for the sample purpose
  value = first,second,third
//  # much more usefull: access all the media file names of the page processed
//  field = media
  split {
    # We split on the comma ...
    token = ,
    # ... and want to handle each part identically
    cObjNum = 1
    # While TYPO3 loops over the 3 parts it only sets the "current" scratch area.
    # To actually work on a part we have to fetch it from there into our content ...
    1.data = current:1
    # ... and now the content is set, we wrap it into a list item
    1.wrap = <li>|</li>
  }
  # the whole thing is wrapped into an unordered list
  wrap = <ul>|</ul>
}

This yields the HTML:

<ul><li>first</li><li>second</li><li>third</li></ul>

… which could have been specified directly in the value property in the first place 🙂 . But this sample makes more clear, what happens.

TYPO3 stores several database fields as token separated strings, namely pages.media and tt_content.image (both comma separated) and several others (TODO: which fields, which token???). So if you will replace “temp.list.value = ...” with “temp.list.field = media” you’ll get a list of the files associated with the current page (as plain strings without a path).

There are other places/functions where TYPO3 sets the “current” scratch area silently behind the scenes.

(TODO: really? As current = 1 is found very often in the stock TypoScript I just assume that. Someone with more insight please correct this document!).

And don’t forget about stdWrap.setCurrent and stdWrap.setContentToCurrent. You always can set the “current” scratch area to whatever you want and access/reuse it later in the rendering process (unless TYPO3 has it overwritten silently).

The only parameter “current” accepts is “1” (meaning: yes, do it, get the “current” value).

date:<format>

This renders the current date/time according to the given <format> parameter.

# render the current date in numerical german format (24.12.2007)
temp.today = TEXT
temp.today.data = date : d.m.Y

The date type is essentially a wrapper for the PHP function date(), so please look up the valid format characters there.

There is no way to specify another timestamp than “now” so if you are looking for a way to format a date/time for some file or record please refer to stdWrap.date or stdWrap.strftime.

(Besides, if you don’t give a format, the default is “d/m Y” [24/12 2007], I guess, that is the danish format? Don’t rely on this however, it isn’t part of the official spec)!

As you might have seen by looking up the PHP date() function you have noticed, that many chars of the alphabet are interpreted as format characters and thus replaced with the corresponding date/time value. But you might also have noticed, that you can escape any special meaning from the format characters by prefixing them with the ‘\’ backslash char.

So, when you intend to format your date with literal characters better escape ALL of these with a backslash:

# same as above, but prefix with 'Hamburg, den '
temp.today = TEXT
# "Hamrgdn" are format chars, "bu ,e" ain't. Anyway, just let's escape all chars
# (except white space/punctuation), to be clear, what we intend to do here.
temp.today.data = date : \H\a\m\b\u\r\g, \d\e\n d.m.Y

Sometimes abusing the date esacaping also comes in handy when you have a need to render a (short) plain string while using the extended short-circuit // OR syntax of getText:

# Render the current pages abstract, if missing note the fact
temp.abstract = TEXT
temp.abstract.value = Abstract of this page is {field : abstract // date : \m\i\s\s\i\n\g}
temp.abstract.insertData = 1

because getText has no other way of inserting plain text/HTML.

DB:<tablename>:<uid>:<fieldname>

This type allows you to access any field in any row of any table configured in the TCA (table configuration array). Be aware though, that fields from records marked as deleted are not accessible, so if you give the uid of a deleted (or not existing) record this type returns the empty string.

# Access some info about Denmark
temp.denmark = COA
temp.denmark {
  10 = TEXT
  10.value = {DB:static_countries:56:cn_iso_2}: {DB:static_countries:56:cn_official_name_local} (
  20 = TEXT
  20.value = {DB:static_countries:56:cn_official_name_en}), capital: {DB:static_countries:56:cn_capital}
  stdWrap.insertData = 1
}

This will render:

DK: Kongeriget Danmark (Kingdom of Denmark), capital: Copenhagen

To look up available tables and column names go to “Tools->Configuration”, in the drop down menu select “$TCA (tables.php)” and you see a list of all defined tables. Expand the table of interest and look up available column names by expanding “columns”. To look up available UIDs either use phpMyAdmin or go with the list module to the page/sysfolder containing the records and hover over the icon of interest: the tooltip will show the UID of the record. In case of the sample the records of “static_countries” are visible on the very root of your TYPO3 page tree (the one with the globe) if you have installed the extension static_info_tables.

The type DB: is SQL-Safe, so you can do something like

dataWrap = DB:tx_t3blog_post:{GPvar:tx_t3blog_pi1|blogList|showUid}:tagClouds

to get an uid from GET/POST

debug:<parameter>

This type allows you to render debug information about some TYPO3 internals, very usefull when something in your setup doesn’t work as expected. The 3 supported parameters are data, fullRootLine and rootLine.

debug:data

The current data array ($cObj->data) TYPO3 works on is returned. This is the data you can access with type field:<name>.

field:<name>

Es ist möglich aus dem aktuell bearbeiteten Datensatz ein bestimmtes Feld anzusprechen. Intern werden die im $cObj-Array geladenen Daten angesprochen.

# Beispiel
.data = field:header

Entscheidend ist dabei, welcher Datensatz gerade angesprochen wird. Auf der Ebene von page ist das die Tabelle pages, also die Seitenebene. Allerdings kann via TSref/De:select select auf jede beliebige Tabelle zugegriffen werden.

# Beispiel
# Den Inhalt der Spalte "normal" laden
# hinter diesem Aufruf verbirgt sich ein select-Statement, dass auf die Tabelle tt_content zugreift.
page.40 < styles.content.get
page.40.renderObj.stdWrap.append = COA
page.40.renderObj.stdWrap.append.10 = HTML
# Achtung, das Datum wird als unix-timestamp geliefert und somit einfach als Zahl ausgegeben
page.40.renderObj.stdWrap.append.10.value.data = field:date
# damit sie schön ausschaut, benötigt es noch eine Formatierung via strftime
page.40.renderObj.stdWrap.append.10.value.strftime = %e.%m.%y
page.40.renderObj.stdWrap.append.10.value.wrap = <h2>Datum: |</h2>

Welche Felder in der Datenbank existieren, lässt sich am einfachsten mit Hilfe der Extension phpmyadmin herausfinden.

fullRootLine:<position>,<fieldname>[,slide]

This object retrieves the title of the page on the second level. On the first level, that object will be empty.

10 = TEXT
10.data = fullRootLine:2,title

This object from the 10th level down to the root if there is an title.

10 = TEXT
10.data = fullRootLine:10,title,slide

Not all fields are available in the rootline. If you need the subtitle, you have to add it in the install-tool / localconf.php

$TYPO3_CONF_VARS['FE']['addRootLineFields'] = 'subtitle';

getenv:<variable_name>

getIndpEnv:<variable_name>

Name of the “environment variable”/”server variable” you wish to use. Valid values are SCRIPT_NAME, SCRIPT_FILENAME, REQUEST_URI, PATH_INFO, REMOTE_ADDR, REMOTE_HOST, HTTP_REFERER, HTTP_HOST, HTTP_USER_AGENT, HTTP_ACCEPT_LANGUAGE, QUERY_STRING, TYPO3_DOCUMENT_ROOT, TYPO3_HOST_ONLY, TYPO3_HOST_ONLY, TYPO3_REQUEST_HOST, TYPO3_REQUEST_URL, TYPO3_REQUEST_SCRIPT, TYPO3_REQUEST_DIR, TYPO3_SITE_URL, _ARRAY

http://typo3.org/fileadmin/typo3api-4.0.0/d3/d3d/classt3lib__div.html#8de3416a12d356d9b2c0bf8ef12dfdfc

global:<parameter>

DEPRECATED. Use getIndpEnv, GPvar or TSFE instead!

GPvar:<parameter>[|key]

This returns the according GET/PUT Parameter

level:1

Gets the current level in the rootline.

levelfield:<position>,<fieldname>[,slide]

<position> position in rootline Examples: 0: Level 0 1: Level 1 etc -1: The Level of this Page -2: One Level Up etc <fieldname> name of a field of table pages. (see notes) “ , slide” parameter forces a walk to the bottom of the rootline until there’s a “true” value to return.

  1. Get the subtitle of
10 = TEXT
10.data = levelfield : -1 , subtitle  , slide

Notes: In order to enable a field for sliding add the following to you typo3conf/localconf.php

  1. enable fields subtitle and nav_title for sliding in levelfield
 $TYPO3_CONF_VARS['FE']['addRootLineFields'] = ',subtitle,nav_title';

levelmedia:<position>[,slide]

leveltitle:<position>[,slide]

leveluid:<position>[,slide]

LLL:<path>

10 = TEXT
10.data = LLL:EXT:tt_news/pi/locallang.xml:latestHeader
10.wrap = LLL:EXT:tt_news/pi/locallang.xml:latestHeader: |

page:<fieldname>

parameters:<param_name>

path:<path>

register:<name>

TSFE:<key>[|<subkey>[|<subsubkey>…]]

This gives you complete access to the TypoScript Front End array (multidimensional) containing almost everything neccessary to render a page. This includes records of the current page and every parent page (the rootline), the currently logged in front/backend end user (if any) … and your complete Typoscript setup (including many values you won’t like to show to the public)!

Intermediate TSFE values

While TYPO3 processes and renders certain content elements it sometimes puts intermediate processing results into the TSFE array, which are often very usefull. In this section all known values are listet.

TODO: this currently only is a raw listing of (might be) usefull vars found in class.tslib_content.php, these will be filtered/explained some time in the future.

IMG_RESOURCE:

While rendering an img_resource TYPO3 sets TSFE:lastImgResourceInfo which is a numerical array of image information

IMAGE:

While rendering an image TYPO3 sets TSFE:lastImageInfo which is a numerical array of image information

CONFIG:

CONTENT:

RECORD:

IMGTEXT:

HMENU:

SEARCHRESULT:

TEMPLATE:

in split processing:

Displaying what TSFE has to offer

To see, what is available in the TSFE you can

The sample script:

<?php

/* Store this code as fileadmin/test_pagegen.php on your server. */

// protect against direct call 
if ( ! is_object($GLOBALS['TSFE'])) {
    die("You cannot execute this file directly. It's meant to be included from index_ts.php");
}

$tmp = '';

if (true) {
    // Print only the top level key/value pairs of TSFE
    foreach ($GLOBALS['TSFE'] as $key => $value) {
        if ( ! isset($value)) {
            $value = 'NULL';
        }
        $tmp .= $key . ' => ' . $value . "\n";
    }
}
else {
    // Print ALL of the TSFE. Be aware, this IS REALLY LENGTHY !!!
    $tmp = print_r($GLOBALS['TSFE'], true);
}

$GLOBALS['TSFE']->set_no_cache();
$GLOBALS['TSFE']->content = "<pre>\n" . $tmp . "\n</pre>\n";

?>

Now set up a special page type in your TSSetup (additional to your normal page top level object):

page = PAGE
... whatever you need, don't change

# the test page called with another page type
test_page = PAGE
# an unused and hard to guess type number here (could be even 4711 or so)
test_page.typeNum = 37
# call our script to render content bypassing the normal TYPO3 rendering process
test_page.config.pageGenScript = fileadmin/test_pagegen.php

Now call any of your pages with the additional parameter type=37:

http://www.example.com/index.php?id=1&type=37

This will render (better look at the HTML source code, if you have used the else ... print_r():

id => 1
type => 37
idParts => Array
cHash => NULL
no_cache => 0
rootLine => Array
page => Array
...
LL_labels_cache => Array
LL_files_cache => Array
config => Array
no_cacheBeforePageGen => 0

Don’t forget to remove the script and setup, when you are done!!! Especially with print_r() there is far too much internal info revealed about your setup and server configuration. Be warned: leaving that script active is a security risk!!!

Further Examples

nested brackets

# untested!
#
# nested brackets are not allowed, but it's possible to use a constant inside a bracket expression
# this works, because the constant is substituted before the typoscript is evaluated
headerData.10.data = PATH:{$plugin.sg_customlayout.ieStyle}

access to environment variables

# Returns the urls of the current page
page.10 = TEXT
page.10.value = {getIndpEnv:TYPO3_REQUEST_URL}
page.10.value.insertData = 1
# and even shorter
page.10 = TEXT
page.10.data = getIndpEnv:TYPO3_REQUEST_URL

发表评论

电子邮件地址不会被公开。 必填项已用*标注