userfunc condition for detecting mobile device - typo3

Since TYPO3 7 the condition 'device' and 'useragent' are deprecated. No I'm looking for a userFunc to use as a condition for detecting mobile devices. My aim is to hide or to show some special pages on mobile devices.
I used the extension 'contexts_wurfl' for a while but I guess that there should be 'smaller solutions'.
Thanks for any help.

You can accomplish this with TypoScript using the PAGE Object.
The code below shows you how to execute your own code before executing something else (like the template engine/content rendering etcetera).
page.01 = USER_INT
page.01 {
userFunc = TYPO3\MyExt\Utility\MobileDeviceUtility->detectMobileDevice
}
And in code:
<?php
namespace TYPO3\MyExt\Utility;
class MobileDeviceUtility {
/**
* Is Mobile Device
*
* #return boolean
*/
static public function isMobileDevice() {
// calculates if the user agent is on a mobile device
return TRUE;
}
/**
* Detect Mobile Device
*
* #param string $content
* #param array $conf
* #return void
*/
static public function detectMobileDevice($content, array $conf = NULL) {
global $TSFE;
if (self::isMobileDevice()
&& (boolean) $TSFE->page['mycustom_device_checkbox']
) {
// do something
}
}
}
OR otherwise you should create your own condition [YourVendor\YourPackage\YourCondition = var1 = value1, var2 != value2, ...].

If you would like to avoid writing a custom user function the globalString function of Typo3 can still be used in the later versions of Typo3 to access the useragent and other information like this:
[globalString = IENV:HTTP_USER_AGENT = *<User-Agent>*]
# Statements here will only affect browsers with the useragent matching <User-Agent>
[else]
# Statements here will only affect browsers with the useragent not matching <User-Agent>
[end]
Detailed documentation for conditions using globalStringcan be found here.
A Full list of variables that can be used with the globalString function can be found here.
To execute different typoscript for mobile and stationary devices I found the following snippet to be working for Typo3 8.7 LTS and 9.5 LTS:
[globalString = IENV:HTTP_USER_AGENT = *Android*]||[globalString = IENV:HTTP_USER_AGENT = *iPhone*]||[globalString = IENV:HTTP_USER_AGENT = *Mobile*]||[globalString = IENV:HTTP_USER_AGENT = *Windows Phone*]
# Statements for mobile devices only
[else]
# Statements for stationary devices only
[end]

Related

Contentsliding is not stopping at sysfolder since TYPO3 v10 - How to solve?

The TSref entry for slide explains:
Up to Version 9 of TYPO3 the sliding stopped when reaching a folder.
Beginning with TYPO3 10 this is not longer the case. See
$cObj->checkPid_badDoktypeList.
Ok, this variable is still 255 (formerly directly, now via constant PageRepository::DOKTYPE_RECYCLER).
What exactly should I see there that will help me? Or better, how to get content sliding still working like before?
You have to extend the ContentObjectRenderer class and overwrite the getSlidePids method with your own extension.
In the boot function of ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class] = [
'className' => \YourVendor\YourExtensionKey\ContentObject\ContentObjectRenderer::class
];
Then you have to create your own "Classes/ContentObject/ContentObjectRenderer.php" with:
<?php
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace YourVendor\YourExtension\ContentObject;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class ContentObjectRenderer extends \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
{
/**
* Returns all parents of the given PID (Page UID) list
*
* #param string $pidList A list of page Content-Element PIDs (Page UIDs) / stdWrap
* #param array $pidConf stdWrap array for the list
* #return string A list of PIDs
* #internal
*/
public function getSlidePids($pidList, $pidConf)
{
// todo: phpstan states that $pidConf always exists and is not nullable. At the moment, this is a false positive
// as null can be passed into this method via $pidConf. As soon as more strict types are used, this isset
// check must be replaced with a more appropriate check like empty or count.
$pidList = isset($pidConf) ? trim($this->stdWrap($pidList, $pidConf)) : trim($pidList);
if ($pidList === '') {
$pidList = 'this';
}
$tsfe = $this->getTypoScriptFrontendController();
$listArr = null;
if (trim($pidList)) {
$listArr = GeneralUtility::intExplode(',', str_replace('this', (string)$tsfe->contentPid, $pidList));
$listArr = $this->checkPidArray($listArr);
}
$pidList = [];
if (is_array($listArr) && !empty($listArr)) {
foreach ($listArr as $uid) {
$page = $tsfe->sys_page->getPage($uid);
if($page['doktype'] == PageRepository::DOKTYPE_SYSFOLDER)
break;
if (!$page['is_siteroot']) {
$pidList[] = $page['pid'];
}
}
}
return implode(',', $pidList);
}
}

Change language parameters in site configuration for some pages in a site

Is there a possibility in TYPO3 10 LTS to change the option fallbackType in the site configuration for a single page?
Background:
I use for the site the option fallbackType fallback. But for a few page I need fallbackType strict. Up to TYPO3 8 this could be achieved with a simple extension template and different config configurations. Is there a way in TYPO3 10?
As far as i know there is no possibility to configurate TYPO3 to behave in this way. The only way to override the language configuration for a single page is a custom middleware.
You can find a working example here: https://github.com/qbus-agentur/typo3-dynamic-language-mode.
I changed the main function:
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$lang = $this->getCurrentSiteLanguage($request);
$pageArguments = $this->getPageArguments($request);
if ($lang === null || $pageArguments === null) {
return $handler->handle($request);
}
// get current page ID
$currentRouting = $request->getAttribute('routing');
$currentPage = $currentRouting->getPageId();
$site = $request->getAttribute('site');
$default = $site->getLanguages()[0];
if ($lang->getLanguageId() !== $default->getLanguageId()) {
// Check if page is in $pagesWhereToChange and apply a dynamic language configuration in that case
if (in_array($currentPage, $this->pagesWhereToChange) > 0) {
\Closure::bind(function() use ($lang, $newId) {
$lang->fallbackType = 'free';
$lang->fallbackLanguageIds = [];
}, null, SiteLanguage::class)();
}
}
return $handler->handle($request);
}
Where $this->pagesWhereToChange is an array of pages:
/**
* pagesWhereToChange
*
* #var array
*/
protected $pagesWhereToChange = [30,41];
It's not possible to configure the array with typoscript because TSFE is not rendered yet.

TYPO3: Render a plugin via Typoscript or ViewHelper and change settings

I would like to load a plugin dynamically according to some data. First I tried to do it with Typoscript, but after some research I figured out, that it is not possible to change the settings of the plugin (see old forum entry).
I need to change settings.simplepoll.uid according to the passed data:
This is the Typoscript I tried:
lib.loadSimplepoll = USER
lib.loadSimplepoll {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = Simplepoll
pluginName = Polllisting
vendorName = Pixelink
switchableControllerActions {
SimplePoll {
1 = list
}
}
settings < plugin.tx_simplepoll.settings
settings {
simplepoll {
uid.current = 1
}
}
}
The call in the template looks like that:
<f:cObject typoscriptObjectPath="lib.loadSimplepoll">{newsItem.simplepoll}</f:cObject>
After figuring out, that changing the settings is not possible, I tried a viewhelper:
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class LoadSimplepollViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
/**
* #param int $uid Uid of poll
* #return string
*/
public function render($uid) {
$cObj = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
$configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$simplepollTs = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
'simplepoll',
'Polllisting'
);
$ttContentConfig = array(
'tables' => 'tt_content',
'source' => 1030,
'dontCheckPid' => 1
);
// returning this works perfectly!
// but I need to change the "settings.simplepoll.uid"
$data = $cObj->RECORDS($ttContentConfig);
$cObj->start($data, 'tx_simplepoll_domain_model_simplepoll');
$renderObjName = '<tt_content.list.20.simplepoll_polllisting';
$renderObjConf = $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['simplepoll_polllisting.'];
$renderObjConf['persistence']['storagePid'] = 394; // This does not work!
$renderObjConf['settings'] = $simplepollTs;
$renderObjConf['settings']['simplepoll']['uid'] = $uid;
return $cObj->cObjGetSingle($renderObjName, $renderObjConf);
}
}
The viehelper is called like this:
{vh:LoadSimplepoll(uid: '{newsItem.simplepoll}')}
Now I am able to change the uid of the poll with this line:
$renderObjConf['settings']['simplepoll']['uid'] = $uid;
My problem is now, that it loads the poll, but not the answers. I tracked this down to the fact, that the plugin somehow does not know the Record Storage Page anymore. The line $renderObjConf['persistence']['storagePid'] = 394; does not help.
How can I tell the plugin the Storage Pid?
Or is there another/better way to load a plugin with changing data?
Why shouldn't it be possible to modify settings.simplepoll.uid in typoscript?
because the extension simplepoll does not handle any stdWrap functionality to its typoscript settings.
Have a look into the code:
this special setting is used here:
$simplePoll = $this->simplePollRepository->findByUid($this->settings['simplepoll']['uid']);
no stdWrap, just plain usage.
compare it to ext:news:
before any settings is used it is processed. A dedicated join of typoscript settings with the settings in the plugin. And if necessary there is a stdWrap possible: here
$this->originalSettings = $originalSettings;
// Use stdWrap for given defined settings
if (isset($originalSettings['useStdWrap']) && !empty($originalSettings['useStdWrap'])) {
$typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
$typoScriptArray = $typoScriptService->convertPlainArrayToTypoScriptArray($originalSettings);
$stdWrapProperties = GeneralUtility::trimExplode(',', $originalSettings['useStdWrap'], true);
foreach ($stdWrapProperties as $key) {
if (is_array($typoScriptArray[$key . '.'])) {
$originalSettings[$key] = $this->configurationManager->getContentObject()->stdWrap(
$typoScriptArray[$key],
$typoScriptArray[$key . '.']
);
}
}
}
As you can see:
extbase does not support you with typoscript stdWrap functionality.
You (and every extension author) need to do it by hand. But that was so even before extbase.
In this way: as you can not configure your value you only can trick TYPO3 (and the plugin):
if you have a small number of uids you can have one variant for each uid
lib.loadSimplepoll123 < lib.loadSimplepoll
lib.loadSimplepoll123.settings.simplepoll.uid = 123
lib.loadSimplepoll234 < lib.loadSimplepoll
lib.loadSimplepoll234.settings.simplepoll.uid = 234
lib.loadSimplepoll345 < lib.loadSimplepoll
lib.loadSimplepoll345.settings.simplepoll.uid = 345
lib.loadSimplepoll456 < lib.loadSimplepoll
lib.loadSimplepoll456.settings.simplepoll.uid = 456
and call it like
<f:cObject typoscriptObjectPath="lib.loadSimplepoll{newsItem.simplepoll}" />
or you build a pull request implementing the stdWrap functionality and send it to the extension author.
Why shouldn't it be possible to modify settings.simplepoll.uid in typoscript?
you just need the correct construction to modify it.
For a single value you can use current, but use it properly. It is a stdWrap function which needs to be evaluated.
If there is no stdWrap evaluation by default it might work with a cObject of type TEXT
settings.simplepoll.uid.cObject = TEXT
settings.simplepoll.uid.cObject.current = 1
or to indicate a stdWrap you need to use stdWrap literally:
settings.simplepoll.uid.stdWrap.current = 1
another variant of data transfer are named parameters. Just build an associative array as data parameter and access the values individual:
fluid:
<f:cObject typoscriptObjectPath="lib.arraytest" data="{a:'abc',b:'xyz'}" >
inside text
</f:cObject>
and the typoscript:
lib.arraytest = COA
lib.arraytest {
10 = TEXT
10.field = a
10.wrap = /|/
20 = TEXT
20.field = b
20.wrap = \|\
}
which results in an output of /abc/\xyz\. Be aware: the inner text of the f:cobject tag will be lost as the data parameter has priority about inner children.
In the meantime I got the Viewhelpter to work:
Viewhelper:
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class LoadSimplepollViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
/**
* #return void
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('simplepollUid', 'int', 'Uid of simplepoll', false);
}
/**
* #return string
*/
public function render()
{
$configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$simplepollTs = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
'simplepoll',
'Polllisting');
$cObj = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
$renderObjName = '<tt_content.list.20.simplepoll_polllisting';
$renderObjConf = $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['simplepoll_polllisting.'];
$renderObjConf['settings'] = $simplepollTs;
$renderObjConf['settings']['simplepoll']['uid'] = (int)$this->arguments['simplepollUid'];
return $cObj->cObjGetSingle($renderObjName, $renderObjConf);
}
}
Call the viewhelper in the template (don't forget to register the namespace):
{vh:LoadSimplepoll(simplepollUid: '{newsItem.ipgSimplepoll}')}
That's it.

How can I make a Condition in TypoScript for loading different JavaScript-Files to different Backend-Layouts? (TYPO3)

After a "long way" with Google, Searching and many tries:
I created a lib.variable for the current Page:
lib.currentPage = TEXT
lib.currentPage.data = page:uid
If I debug it in my FluidTemplate in the Frontend with:
Testing currentPage: <f:cObject typoscriptObjectPath="lib.currentPage" />
I got the correct value.
Now I want to use that Variable in a Condition in my pageSetup.ts like follows:
[DB:pages:lib.currentPage:backend_layout = pagets__pagelayout_logoclaim_subpage]
page.includeJSFooter.belayoutlogoclaim = EXT:rm_base/Resources/Public/JS/be_logoclaim.js
[end]
I testet this with some other Conditions, but nothing works like expected.
Tested Conditions:
[page|backend_layout = pagelayout_logoclaim_subpage]
[globalVar = TSFE:page|backend_layout = pagelayout_logoclaim_subpage]
I also tested the Condition in the TypoScript Object Browser, and here it looks like good working:
TypoScript Object Browser - If I activate the Condition
SourceCode in the Frontend on a Site with the correct PageLayout
I need this, because I have two different Menus, and they need different JavaScripts, to avoid wrong behaviour in the Frontend.
Update:
I inserted the pageLayouts like this:
page = PAGE
page {
10 = FLUIDTEMPLATE
10 {
partialRootPath = EXT:rm_base/Resources/Private/Templates/Fluid/Partials/
layoutRootPath = EXT:rm_base/Resources/Private/Templates/Fluid/Layouts/
file.stdWrap.cObject = CASE
file.stdWrap.cObject {
key.data = pagelayout
// Default-Template is LogoFull_Subpage (No Navigation Dependence)
default = TEXT
default.value = EXT:rm_base/Resources/Private/Templates/Fluid/LogoFull_Subpage.html
// LogoClaim - Subpage
pagets__pagelayout_logoclaim_subpage = TEXT
pagets__pagelayout_logoclaim_subpage.value = EXT:rm_base/Resources/Private/Templates/Fluid/LogoClaim_Subpage.html
}
}
You see: The Backendlayouts are in Files of my Extension, not in the Database-Table: backend_layouts.
Update 2:
I would prefer a TypoScript-Way, if someone knows how - with external BE-Layouts. Thank you.
As I've seen the prefix pagets__ ,I guess that the problem here is that the backend_layouts are not stored in the database, so I think that a condition about that would not work.
If you are using a different html template for each backend layout and you are running TYPO3 8.7.x there is a different way to solve this issue: Add to your template file a new section called:
<f:section name="FooterAssets">
<!--your code here-->
</f:section>
This section will be loaded just before the closing of </body>. As far as I remember you don't even have to call this section in your layout file.
i would opt for using the VHS extension which provides an asset viewhelper.
you than include the asset view helper into the frontend template you are rendering. and it takes care about plaching the javascript in the header / footer
it allows also to definde dependancies and loads the script in the correct order. also supports concatination / minification ...
an example include might look like this:
<v:asset.script path="EXT:your_ext/Resources/Public/JavaScript/menu_a.js" dependencies="jquery" />
this requires you that you specified "jquery" via typoscript (or another assit view helper)
example typoscript:
plugin.tx_vhs.settings.asset.jquery {
path = EXT:your_ext/Resources/Public/JavaScript/jquery.js
type = js
}
I found another solution, that uses a TypoScript Custom Condition:
First I create a BackendlayoutCondition.php in my Extension here:
/Classes/TypoScript/BackendlayoutCondition.php
Its content is this (See Comments for more Detail):
<?php
namespace RM\RmBase\TypoScript;
use \TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractCondition;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;;
class BackendlayoutCondition extends AbstractCondition
{
/**
* Evaluate condition
*
* #param array $conditionParameters
* #return bool
*/
public function matchCondition(array $conditionParameters)
{
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($conditionParameters,'cond Params');
# Return false if in Backend (Condition for Frontend only)
if (!$GLOBALS['TSFE']) return false;
# QueryBuilder for Table: pages
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
# Check if current BackendLayout is inside the $conditionParameters
if (!empty($conditionParameters) && substr($conditionParameters[0], 0, 1) === '=') {
# Trim the Parameter to get the correct Value of the Parameter (behind '=')
$conditionParameters[0] = trim(substr($conditionParameters[0], 1));
# Get Backendlayout on this Page
$backendLayoutOnThisPage = $queryBuilder
->select('backend_layout')
->from('pages')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(intval($GLOBALS['TSFE']->id), \PDO::PARAM_INT))
)
->execute();
# Store Backendlayout Value of the current Page in $backendLayoutOnThisPage
$backendLayoutOnThisPage = $backendLayoutOnThisPage->fetch()['backend_layout'];
} else {
# If no ConditionParameter was set return false
return false;
}
# Check if parent BackendLayout_NextLevel is inside the $conditionParameters
if ($backendLayoutOnThisPage == '') {
# Get pageRepository
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$pageRepository = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
# Get Rootline of the current Page
$pageRootline = $pageRepository->getRootLine(intval($GLOBALS['TSFE']->id));
# Set rootlineIndex to the Parent Page Index
$rootlineIndex = count($pageRootline)-2;
# Check Parent Page Backendlayout_NextLevel till 0 or Backendlayout found
while ($rootlineIndex > 0) {
if ($pageRootline[$rootlineIndex]['backend_layout_next_level'] == $conditionParameters[0]) {
return true;
} else {
$rootlineIndex--;
}
}
# No BackendLayout_NextLevel found till 0
return false;
} else {
# If Condition Backendlayout found return true, otherwise return false
if ($backendLayoutOnThisPage == $conditionParameters[0]) {
return true;
} else {
return false;
}
}
}
}
(Edited 2)
Than I just have to use the following Condition in my pageSetup.ts:
[RM\RmBase\TypoScript\BackendlayoutCondition = pagelayout_logoclaim_subpage]
page.includeJSFooter.belayoutlogoclaim = EXT:rm_base/Resources/Public/JS/be_logoclaim.js
[global]
Now I have this Sourcecode in the Frontend:
<script src="/typo3conf/ext/rm_base/Resources/Public/JS/be_logoclaim.js?1523005944" type="text/javascript"></script>
not that:
<script src="/typo3conf/ext/rm_base/Resources/Public/JS/be_logoclaim.js" type="text/javascript"></script>
if I use the FooterAssets method:
<f:section name="FooterAssets">
<script src="/typo3conf/ext/rm_base/Resources/Public/JS/be_logoclaim.js" type="text/javascript"></script>
</f:section>
Edit: I found some errors in my Answer, i fix it and edit my answer then.
Edit2: Now the Condition checks the Backendlayouts and the Backendlayouts_Nextlevel Fields for Backendlayouts to get all possible BE-Layouts including the inherited.
The problem with the backend_layout field is that there also is a field backend_layout_next_level which affects subpages. so you can't build a simple condition.
Either you use stdWrap.if where you can calculate the current value for backend_layout overlaying an inherited value from backend_layout_next_level.
Or you define a userfunc where you evaluate it yourself in PHP.
Be aware that layouts defined in records have another prefix than layouts defined in pagesTS.
edit:
Example
temp.layout = CASE
temp.layout {
key.data = levelfield:-1, backend_layout_next_level, slide
key.override.field = backend_layout
default = TEXT
default.value = default-layout
1 = TEXT
1.value = layoutdefinition_from_record
pagets__layout2 = TEXT
pagets__layout2.value = layoutdefinition_from_pageTSconfig
sitepackage__layout3 = TEXT
sitepackage__layout3.value = layoutdefinition_from_sitepackage
}
Now you can use temp.layout for further decisions:
10 = TEXT
10.field = bodytext
10.wrap = <div class="demo">|</div>
10.wrap.if {
equals.cObject < temp.layout
value = default-layout
}

How to select a random image from files in a directory using typoscript?

I'm using Typo3 4.5.3 and I have image files in a directory from which I want to randomly select one to display on the current page, but I can't seem to get the typoscript right to make listnum = rand work. Here's my extension template:
# Pick a random image to display
temp.banner = IMAGE
temp.banner {
file {
height = 165
width = 954
import {
filelist = {$templatePathPrefix}images/banners | jpg,jpeg,png,gif | name | | 1
listNum = rand
}
}
params = class="bannerPic"
}
If I change the listnum setting to 0, 1, etc. it inserts the corresponding img HTML into the page. Setting it to 'last' also works, but rand always inserts the first image no matter how many times I refresh. Since I can select specific images (0, 1, ...) I know the general setup works, just not the random selection.
I've seen TS for various other uses of rand which wrap the outer object in a COA_INT object, but that didn't work for me either. Did I miss something about where to place the listNum = rand? I'm pretty new at Typo3 so lots of it is still pretty opaque to me at this point (or does it show?). Thanks for any insight you can provide.
mak_stdwrapextended extension adds the possibility to use rand with listNum.
Works well on 4.5.
I would not recommend you to do a random selection via TypoScript. Since you want a random image everytime you load the page, your random element must be a USER_INT or COA_INT element and is therefore not cacheable.
A simple solution for this is to do it via JavaScript. You define a default image if JavaScript is not available on the client, and a JavaScript that randomly select an image. With this solution, you get a random image everytime, and your content is fully cacheable.
The following TypoScript code can give you some inspiration for this. It basically reads out Image-Elements from the border collumn and generates JavaScript to output them randomly. Also, the images are linkable.
lib.teaser = COA
lib.teaser.10 = CONTENT
lib.teaser.10 < styles.content.getBorder
lib.teaser.10 {
slide = -1
table=tt_content
select{
begin = 0
max = 1
#language
languageField=sys_language_uid
#from wich column
where=colPos=3
}
wrap=<div class="teaserimage">|</div>
renderObj=COA
#image with gallery function
renderObj.10 = COA
renderObj.10 {
stdWrap.required=1
# get image
10 = IMAGE
10 {
#if not empty
required=1
file.import=uploads/pics/
file.import.field=image
#file.width=266
#file.height=180
file.import.listNum = 0
stdWrap.insertData=1
params = id="imgbig_{TSFE:currentRecord}"
imageLinkWrap < tt_content.image.20.1.imageLinkWrap
imageLinkWrap.typolink.ATagParams = id="link_imgbig_{TSFE:currentRecord}"
imageLinkWrap.typolink.ATagParams.stdWrap.insertData=1
}
# standard image configuration from tt_content
10.altText < tt_content.image.20.1.altText
10.titleText < tt_content.image.20.1.titleText
10.longdescURL < tt_content.image.20.1.longdescURL
# random function for gallery images
30 = COA
30 {
stdWrap.required=1
stdWrap.dataWrap(
<script type="text/javascript">
/* <![CDATA[ */
var imgArray = new Array(|);
var randnum = Math.round(Math.random()*(imgArray.length-1));
document.getElementById('imgbig_{TSFE:currentRecord}').src ='uploads/pics/' + imgArray[randnum];
/* ]]> */
</script>
)
# first gallery image
10 = TEXT
10.field = image
10.listNum.splitChar=,
10.listNum=0
10.if.isTrue.field=image
10.if.isTrue.listNum=1
10.if.isTrue.listNum.splitChar=,
10.dataWrap = "|"
# other gallery images
20 = TEXT
20.field = image
20.split {
token = ,
cObjNum = 1
1 = COA
1.if.isPositive.data = TSFE:register|SPLIT_COUNT
1 {
10 = TEXT
10.data = current:1
10.dataWrap = ,"|"
}
}
}
# random function for gallery links
40 = COA
40 {
stdWrap.required=1
stdWrap.dataWrap(
<script type="text/javascript">
/* <![CDATA[ */
//var imgLinkArray = new Array(randnum);
var imgLinkArray = new Array(|);
if(document.getElementById('link_imgbig_{TSFE:currentRecord}')) document.getElementById('link_imgbig_{TSFE:currentRecord}').href = imgLinkArray[randnum];
/* ]]> */
</script>
)
# first gallery link
10 = TEXT
10.field = image_link
10.listNum.splitChar=,
10.listNum=0
10.dataWrap = "|"
10.typolink.parameter.field = image_link
10.typolink.returnLast = url
# other gallery links
20 = TEXT
20.field = image_link
20.split {
token = ,
cObjNum = 1
1 = COA
1.if.isPositive.data = TSFE:register|SPLIT_COUNT
1 {
10 = TEXT
10.data = current:1
10.dataWrap = ,"|"
10.typolink.parameter.data = current:1
10.typolink.returnLast = url
}
}
}
}
}
only typo3 V4.6 and above has listNum = rand in the core, see this http://forge.typo3.org/issues/16180
for typo3 V4.5 you have to extend tslib/the class.tslib_content.php
add this to localconf.php:
$TYPO3_CONF_VARS['FE']['XCLASS']['tslib/class.tslib_content.php'] = PATH_site.'fileadmin/template/class.ux_tslib_content.php';
and add this code to class.ux_tslib_content.php:
<?php
/***************************************************************
* Copyright notice
*
* (c) 1999-2008 Kasper Skaarhoj (kasperYYYY#typo3.com)
* 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.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* 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!
***************************************************************/
/**
* Contains classes for Content Rendering based on TypoScript Template configuration
*
* $Id: class.tslib_content.php 4254 2008-09-27 13:35:44Z dmitry $
* Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
* XHTML compliant
*
* class tslib_cObj : All main TypoScript features, rendering of content objects (cObjects). This class is the backbone of TypoScript Template rendering.
*
* #author Kasper Skaarhoj <kasperYYYY#typo3.com>
*/
/**
* This class contains all main TypoScript features.
* This includes the rendering of TypoScript content objects (cObjects).
* Is the backbone of TypoScript Template rendering.
*
* There are lots of functions you can use from your include-scripts.
* The class "tslib_cObj" is normally instantiated and referred to as "cObj".
* When you call your own PHP-code typically through a USER or USER_INT cObject then it is this class that instantiates the object and calls the main method. Before it does so it will set (if you are using classes) a reference to itself in the internal variable "cObj" of the object. Thus you can access all functions and data from this class by $this->cObj->... from within you classes written to be USER or USER_INT content objects.
*
* #author Kasper Skaarhoj <kasperYYYY#typo3.com>
* #package TYPO3
* #subpackage tslib
* #link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&cHash=4ad9d7acb4
*/
class ux_tslib_cObj extends tslib_cObj{
/**
* Exploding a string by the $char value (if integer its an ASCII value) and returning index $listNum
*
* #param string String to explode
* #param string Index-number. You can place the word "last" in it and it will be substituted with the pointer to the last value. You can use math operators like "+-/*" (passed to calc())
* #param string Either a string used to explode the content string or an integer value which will then be changed into a character, eg. "10" for a linebreak char.
* #return string
*/
function listNum($content,$listNum,$char) {
$char = $char ? $char : ',';
if (t3lib_div::testInt($char)) {
$char = chr($char);
}
$temp = explode($char,$content);
$last = ''.(count($temp)-1);
if($listNum === 'rand'){ $listNum = rand(0,count($temp)-1);} //taywa added: rand feature!
$index=$this->calc(str_ireplace('last',$last,$listNum));
return $temp[$index];
}
}
?>