I'm trying to create a routeEnhancer for a simple GET parameter:
/?pageNumber=1&cHash=...
This parameter (including the cHash) is generated by the page browser of a multi-page sitemap (pure TypoScript), which can be simulated with the following simplified TypoScript:
page.10 = COA
page.10{
10 = LOAD_REGISTER
10{
pageNumber.cObject = TEXT
pageNumber.cObject.value = 0
pageNumber.cObject.override.data= GP:pageNumber
pageNumber.cObject.wrap = (|+1)
pageNumber.prioriCalc = intval
}
20 = TEXT
20{
data = register:pageNumber
typolink {
parameter.data = TSFE:id
additionalParams.data = register:pageNumber
additionalParams.wrap = &pageNumber=|
}
}
}
Result (without routeEnhancers):
On page 0 (the root page "/"): 1
On page 1: 2
On page 2: 3
And so on. That works as expected, but I'd like to have nicer URLs.
My routeEnhancers attempt for rewriting the URLs:
routeEnhancers:
PageBrowser:
type: Simple
routePath: '/page/{page_number}'
requirements:
page_number: '[0-9]'
_arguments:
page_number: 'pageNumber'
Result with this routeEnhancer:
On page 0: 1
On page 1 the link unfortunately remains unchanged: 1
It seems that the encoding works, but the decoding fails.
What am I doing wrong?
It looks there is some confusion with page_number and pageNumber:
I think this setup does, what you are looking for. (I had to manually delete cache too)
page = PAGE
page.10 = COA
page.10{
10 = LOAD_REGISTER
10{
pageNumber.cObject = TEXT
pageNumber.cObject.value = 0
pageNumber.cObject.override.data= GP:pageNumber
pageNumber.cObject.wrap = (|+1)
pageNumber.prioriCalc = intval
}
20 = TEXT
20{
data = register:pageNumber
typolink {
parameter.data = TSFE:id
additionalParams.data = register:pageNumber
additionalParams.wrap = &pageNumber=|
}
}
}
routeEnhancers:
PageBrowser:
type: Simple
routePath: '/page/{pageNumber}'
requirements:
pageNumber: '[0-9]+'
Related
I have a menu (HMENU with special = updated) that gives me the latest sub and sub-sub pages from 3 categories.
The page structure looks like this in the backend:
In addition to the title, I would like to output the name of the respective category (the parent level-1 page).
This is my TypoScript attempt:
lib.myMenu = HMENU
lib.myMenu {
special = updated
special{
value.field = 10,11,12
beginAtLevel = 1
limit = 99
}
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10{
wrap = <h3>|</h3>
field = seo_title // title
typolink.parameter.field = uid
}
20 = HMENU
20{
wrap = <div class="category attempt-1">|</div>
special = rootline
special.range = 1|1
special.value.field = uid # does not work
1 = TMENU
1.NO.allWrap = |
}
30 = TEXT
30{
wrap = <div class="category attempt-2">|</div>
data = leveltitle : 1 # does not work as expected
}
}
}
}
}
Unfortunately it does not work, because …
special = rootline does not support special.value.
data = leveltitle : 1 uses the ID of the current page, instead of the TMENU item ID.
Does anyone have another approach how I can get the title of the respective category using TypoScript?
Edit: Background information / what this is needed for
With this menu I intend to replace the news module ext:news of an existing project. Instead of news records, pages are now used and this menu creates the list view. Of course a TypoScript page browser will be added.
I would not rebuild the complete menu item generation (NO.doNotLinkIt = 1).
Just use NO.after.cObject = COA.
leveltitle : 1 is correct if you want to have the title for the current page.
The same if you show a rootline menu: it is generated for the current page.
If you want the levelfield for another page you need to build it by yourself.
In typoscript you might use a userfunction. (there is a core function for getting the rootline for a given page id)
If you generate your menu with FLUID you might use a viewhelper. (You might get inspired from this option of viewhelper menu.directory or this option of VH page.breadCrumb in ext:vhs.)
Edit:
you might store the needed information directly in the pagesrecord.
add a new field to the record (or use any unused).
then make sure that each category page contains some page TS_config:
TCADefaults.pages.<yourfield> = CategoryName
With this configuration each new page below will get this value set automatically.
Of course you need to set these values for all existing pages by hand or by some manual queries.
And if the editors are to be prevented from changing this value you need to remove the field from the edit form with this TSConfig on the top-page:
TCEForm.pages.<yourfield>.hide= 1
I have found a pure TypoScript solution that may not be very elegant, but it works:
lib.myMenu = HMENU
lib.myMenu {
special = updated
special{
value.field = 10,11,12
beginAtLevel = 1
limit = 99
}
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10{
wrap = <h3>|</h3>
field = seo_title // title
typolink.parameter.field = uid
}
20 = HMENU
20{
wrap = <div class="category">|</div>
special = list
special.value.field = pid
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = HMENU
cObject{
special = list
special.value.field = pid
1 = TMENU
1.NO.doNotLinkIt = 1
}
}
}
}
}
}
}
}
}
If the menu is to go over further levels, the override must of course be nested even deeper.
Edit – Improvements:
RECORDS instead of HMENU: Bernd Wilke suggested in the comments to use CONTENT instead of HMENU to generate the category title. This caused problems in my tests when sysfolders (as subpages of the categories) were used to structure the items. This could be related to the bug/feature #20933 (Enable working with SysFolders in CONTENT). But RECORDS might be comparable. I tried it and was able to improve the render times a little bit (see table below).
lib.myMenu.1.NO.stdWrap.cObject.20 = RECORDS
lib.myMenu.1.NO.stdWrap.cObject.20{
stdWrap.wrap = <div class="category">|</div>
source.field = pid
tables = pages
conf.pages = TEXT
conf.pages {
field = seo_title // title
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = RECORDS
cObject{
source.field = pid
tables = pages
conf.pages = TEXT
conf.pages.field = seo_title // title
}
}
}
}
CONTENT instead of HMENU: if no sysfolders are needed (as of TYPO3 10.4 sysfolders should also work)
lib.myMenu.1.NO.stdWrap.cObject.20 = CONTENT
lib.myMenu.1.NO.stdWrap.cObject.20{
stdWrap.wrap = <div class="category">|</div>
table = pages
select {
uidInList.field = pid
pidInList = 0
selectFields = uid, pid, seo_title, title
}
renderObj = TEXT
renderObj {
field = seo_title // title
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = CONTENT
cObject{
table = pages
select {
uidInList.field = pid
pidInList = 0
selectFields = uid, pid, seo_title, title
}
renderObj = TEXT
renderObj.field = seo_title // title
}
}
}
}
userFunc instead of HMENU: Bernd Wilke suggested in his answer to use a userfunction. Even if this is not a pure TypoScript solution, I would have liked to test it to be able to compare the performance. The method getRootLine() has unfortunately been marked as deprecated. Since I'm not an extension developer, it's not clear to me yet how to read the category via a userFunc and if this is actually more effective. If I still come across a solution regarding this, it will be added here.
Rendertime: I have test-implemented the menu in the live site (in the existing template) and compared the website render times with and without the output of the categories to see how much the nested menu affects the performance. The values are average values from 10 measurements. I also limited the output to 20 items, which should be a more realistic value per page later on:
mode
20 items
100 items
without category
99 ms
218 ms
categories via HMENU
133 ms
353 ms
categories via RECORDS
132 ms
331 ms
categories via CONTENT
121 ms
255 ms
categories via userFunc
TBD
TBD
You should neither use a separate HMENU nor a userFunc but a simple LOAD_REGISTER within the menu items of the parent level. This generates register entries, that can be added, changed or restored while looping through the different levels of the HMENU structure.
So you don't need the custom code of a PHP function and you won't get the performance penalty of a nested HMENU.
Basically it's shown in the official documentation, but with a CSS class instead of a title. But of course you could hand over other information from the parent to its children the same way.
Here is the example:
10 = COA
10 {
### left menu table column
10 = LOAD_REGISTER
10 {
ulClass = col-left
}
### right menu table column
20 = LOAD_REGISTER
20 {
ulClass = col-right
}
30 = HMENU
30 {
special = list
special.value = 1
1 = TMENU
# ...
3 = TMENU
3 {
stdWrap {
preCObject = COA
preCObject {
10 = RESTORE_REGISTER
}
dataWrap = <ul class="{register:ulClass}">|</ul>
}
wrap =
SPC = 1
SPC {
allStdWrap {
replacement {
10 {
search = ---
replace =
}
}
dataWrap = </ul>|<ul class="{register:ulClass}">
}
}
}
}
}
And here the link to the full documentation page:
https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/UsingSetting/Register.html
The official TYPO3 Documentation explains how to create (or copy) and use a lib.dynamicContent to render columns into a Fluidtemplate.
I do not understand exactly whats going on in this example.
The TypoScript there is:
lib.dynamicContent = COA
lib.dynamicContent {
10 = LOAD_REGISTER
10.colPos.cObject = TEXT
10.colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
20 = CONTENT
20 {
table = tt_content
select {
orderBy = sorting
where = colPos={register:colPos}
where.insertData = 1
}
}
90 = RESTORE_REGISTER
}
I use this snippet in a ton of TYPO3 projects and often had asked myself whats going on there.
I have changed this by experimenting a bit and ended with:
lib {
dynamicContent = COA
dynamicContent {
10 = CONTENT
10 {
table = tt_content
select {
orderBy = sorting
where {
data = field:colPos
wrap = colPos=|
}
}
}
}
}
That seems to do "exactly the same" thing - it outputs my content when called via cObject ViewHelper.
Can somebody explain if or why this is the worse way to render Content?
Here's the link to the lib.dynamicContent-doc: https://docs.typo3.org/c/typo3/cms-fluid-styled-content/master/en-us/Installation/InsertingContentPageTemplate/Index.html#based-on-the-fluidtemplate-content-object-cobj
Here you go!
you can try this,
# Clear out any constants in this reserved room!
styles.content >
# get content
styles.content.get = CONTENT
styles.content.get {
table = tt_content
select.orderBy = sorting
select.where = colPos=0
}
# Left Column
styles.content.getLeft < styles.content.get
styles.content.getLeft.select.where = colPos=1
# Right content
styles.content.getRight < styles.content.get
styles.content.getRight.select.where = colPos=2
Also, you can use variable in the fluid page object, check this out:
lib.pageTemplate = FLUIDTEMPLATE
lib.pageTemplate {
variables {
content = CONTENT
content {
table = tt_content
select.orderBy = sorting
select.where = colPos=0
}
contentRight = CONTENT
contentRight {
table = tt_content
slide = -1
select.orderBy = sorting
select.where = colPos=2
}
}
}
You can find out more here:
Adding the page content to a fluid template
Typo3 7.6 typoscript problems with markers
Hope this make sense, Cheer...!
You should look at this snippet together with some information about the Fluid view helper <f:cObject> which can be found here: https://docs.typo3.org/other/typo3/view-helper-reference/9.5/en-us/typo3/fluid/latest/CObject.html
As you can see there are the parameters data, currentValueKey and table that will be handed over to the typoscriptObjectPath, which is why the snippet makes perfect sense. The reason is, that it's a bit hard to put the different options into the where clause of the CONTENT object. So it increases readability and those registers can be easily extended.
So the register in this example is used to put in either the value of the data field colPos or if that is empty it will take the current value from the currentValueKey and if that is empty too it will fall back to a value of 0 to make sure the query won't produce an exception.
lib.dynamicContent = COA
lib.dynamicContent {
10 = LOAD_REGISTER
10.colPos.cObject = TEXT
10.colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
20 = CONTENT
20 {
table = tt_content
select {
orderBy = sorting
where = colPos={register:colPos}
where.insertData = 1
}
}
90 = RESTORE_REGISTER
}
We used a modified version of that snippet to sneak in some more parameter values for the CONTENT object.
So we can hand over a data field pageUid, if that is not set we will use the uid of the current page. This will be overriden if the current or the target page is configured to show content from another page and finally we can trigger a slide with another data field.
lib.dynamicContent = COA
lib.dynamicContent {
5 = LOAD_REGISTER
5 {
colPos.cObject = TEXT
colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
pageUid.cObject = TEXT
pageUid.cObject {
field = pageUid
ifEmpty.data = TSFE:id
}
contentFromPid.cObject = TEXT
contentFromPid.cObject {
data = DB:pages:{register:pageUid}:content_from_pid
data.insertData = 1
}
}
20 = CONTENT
20 {
table = tt_content
slide = -1
slide.if.isTrue.field = slide
select {
includeRecordsWithoutDefaultTranslation = 1
orderBy = sorting
where = {#colPos}={register:colPos}
where.insertData = 1
pidInList.data = register:pageUid
pidInList.override.data = register:contentFromPid
}
}
90 = RESTORE_REGISTER
}
This enables us to make use of the <f:cObject> view helper while triggering additional parameters just by handing over some more values within the data array.
In TYPO3 6.2 (just upgraded from 4.5) I have a TMENU with Images, using a cObject in NO to build the menu as desired.
It works in the main language, but in the second language's frontend, the images are not rendered - unless they are filled in in the second language's media field.
How do you force FILES to refer to the media field of the original language?
In my case, always. In other cases, a fallback solution may be desired.
temp.menu = COA
temp.menu {
wrap = <div class="teasermenu">|</div>
15 = HMENU
15 {
special = list
//special.value.cObject < temp.displayedpages
// recieves a list, such as:
special.value = 1,3,9
1 = TMENU
1 {
noBlur = 1
maxItems = 16
wrap = <ul>|</ul>
NO {
wrapItemAndSub = <li>|</li>
ATagBeforeWrap = 1
ATagParams = || || || || class="red" |*| |*|
stdWrap.cObject=COA
stdWrap.cObject{
10 = TEXT
10.field = nav_title // title
10.wrap = <strong class="teasermenu_header">|</span></strong>
20=FILES
20{
if{
isInList.field = uid
//value.cObject < temp.displayedpages_wimage
// receives another list, like:
// value = 3,9
}
references {
table=pages
fieldName=media
}
renderObj=IMAGE
renderObj{
file{
height=80
maxH=80
import.data=file:current:publicUrl
}
altText.field=title
titleText.field=title
}
}
}
}
}
}
}
PS there are many media field / FAL fallback related bugs on forge, e.g. this one. But I have a feeling this might be a simpler issue.
mergeIfNotBlank is gone now, the current solution (TYPO3 8.7) seems to be to set
$GLOBALS['TCA']['pages']['columns']['media']['config']['behaviour']['allowLanguageSynchronization'] = 1;
But based on https://forum.typo3.org/index.php/t/217033/-typo3-ug-freiburg-media-feld-in-den-seiteneigenschaften (thanks) there's this snippet. It also works with cropVariants:
temp.bgimg_wide = CONTENT
temp.bgimg_wide{
table = sys_file_reference
select{
pidInList = {$pids.pidHome}
where = tablenames='pages' AND fieldname='media'
orderBy = sorting_foreign
languageField = 0
selectFields = uid_local
max = 1
begin = 0
}
renderObj = FILES
renderObj{
files.stdWrap.field = uid
renderObj = IMG_RESOURCE
renderObj {
file {
import.data = file:current:uid
treatIdAsReference = 1
width = 1600
cropVariant = bgimg_wide
}
}
}
}
}
This works!
With TYPO3 CMS 7.6 you need to exclude field media of table pages from [FE][pageOverlayFields] as set in ~/typo3_src-7.6.10/typo3/sysext/core/Configuration/DefaultConfiguration.php, until it is solved - see forge issue https://forge.typo3.org/issues/65863
Write in your AdditionalConfiguration
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields'] = 'uid,doktype,title,subtitle,nav_title,keywords,description,abstract,author,author_email,url,urltype,shortcut,shortcut_mode';
or in your Extension ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields'] = str_replace(',media', '', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']);
Based on Urs' answer, here comes a slight variation.
lib.getCurrentPageMedia = CONTENT
lib.getCurrentPageMedia {
table = sys_file_reference
select{
pinInList = root, this
where = tablenames='pages' AND fieldname='media' AND uid_foreign=###pid###
orderBy = sorting_foreign
languageField = 0
selectFields = uid_local
max = 1
begin = 0
markers {
pid.data = TSFE:id
}
}
renderObj = TEXT
renderObj.stdWrap.field = uid
}
Fluid:
<f:image src="{f:cObject(typoscriptObjectPath:'lib.getCurrentPageMedia')}" alt="" width="400c" height="400c" treatIdAsReference="1" class="img-responsive" />
Advantage: you can define cropping, alt-text, etc. in your template.
You might want to try to set the TCA of the media field to l10n_mode => mergeIfNotBlank .
http://docs.typo3.org/typo3cms/TCAReference/Reference/Columns/Index.html#columns-properties-l10n-mode
Put this into the typo3conf/AdditionalConfiguration.php:
$TCA['pages']['columns']['media']['l10n_mode'] = 'mergeIfNotBlank';
Since this issue is from Februari, you've probably found a solution by now. I just ran into this issue and solved it by including:
$GLOBALS['TCA']['pages_language_overlay']['columns']['media']['l10n_mode'] = 'mergeIfNotBlank';
in my ext_tables.php
I'm building a site with Fluid Template. I have created two different front-end layouts and two different back-end layout but I always get this error #1288085266: No template has been specified. Use either setTemplateSource() or setTemplatePathAndFilename(). Accordingly to Typo3 Wiki this should be a solution Exception/CMS/1288085266
but not in my case. This is my code:
config.doctype = html5
page = PAGE
page {
includeCSSLibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css
includeCSS.style = fileadmin/templates/rka2015/css/style.css
includeJSlibs.jquery = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
includeJSlibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js
includeJS.custom = fileadmin/templates/rka2015/js/custom.js
}
page.10 = FLUIDTEMPLATE
page.10 {
file = fileadmin/templates/rka2015/layouts/main_layout.html
layoutRootPath = fileadmin/templates/rka2015/layouts/
patialRootPath = fileadmin/templates/rka2015/partials/
variables {
siteName = TEXT
siteName.value = rka2015
contentMain < styles.content.get
contentMain.select.where = colPos = 0
content_column_1 < styles.content.get
content_column_1.select.where = colPos = 1
content_column_2 < styles.content.get
content_column_2.select.where = colPos = 2
}
}
page.10.file.stdWrap.cObject = CASE
page.10.file.stdWrap.cObject
{
key.data = levelfield:-1, backend_layout_next_level, slide
key.override.field = backend_layout
default = TEXT
default.value = fileadmin/templates/rka2015/main_1_column.html
1 = TEXT
1.value = fileadmin/templates/rka2015/main_1_column.html
2 = TEXT
2.value = fileadmin/templates/rka2015/main_2_column.html
}
I have already checked all; section name is OK, ID for back-end layouts are ok, template is defined, everything seem to be as it should be. I really don't have a clue where else to search.
UPDATE!!!
Seems like there is a problem with a file path. I am running my site on a subdomain and it looks like that ts doesn't find the file paths if they are defined only as fileadmin/... Any thoughts? Thanks
SOLUTION!
page {
includeCSSLibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css
includeCSS.style = fileadmin/templates/rka2015/css/style.css
includeJSlibs.jquery = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
includeJSlibs.jquery.external = 1
includeJSlibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js
includeJS.custom = fileadmin/templates/rka2015/js/custom.js
}
page.10 = FLUIDTEMPLATE
page.10 {
template = CASE
template {
key.data = levelfield:-1,backend_layout_next_level,slide
key.override.field = backend_layout
1 = FILE
1.file = fileadmin/templates/rka2015/main_1_column.html
2 = FILE
2.file = fileadmin/templates/rka2015/main_2_column.html
}
partialRootPath = fileadmin/templates/rka2015/partials/
layoutRootPath = fileadmin/templates/rka2015/layouts/
variables {
siteName = TEXT
siteName.value = rka2015
contentMain < styles.content.get
contentMain.select.where = colPos = 0
content_column_1 < styles.content.get
content_column_1.select.where = colPos = 1
content_column_2 < styles.content.get
content_column_2.select.where = colPos = 2
}
}
First, check out if TYPO3 can read the file by overwriting the page object by appending this to the end of your template:
page.10 >
page.10 = FILE
page.10.file = fileadmin/templates/rka2015/layouts/main_layout.html
If that doesn't generate a page with the raw, uninterpreted output of your template file, then theres something wrong with either the file path or file permissions.
Secondly, in Fluid, Templates and Layouts are different things with different uses and should propably not be put into the same directory.
Most importantly, theres something wrong with the backend layout switch you're trying to build with the CASE in page.10.file.stdWrap.cObject . You see, the stdWrap object actually wraps around the text you've already set. If stdWrap cant find a pipe to figure out how to wrap, it just appends instead. Remove the line where you set the file in the top part and only leave the stdWrap case and you should be good to go.
at the first look it looks right... but check your file paths, maybe they are wrong as "Jost" commented.
i'm not sure but i think the problem is that the template path (file = ...) is the same as layout root path...
by the way... if you include external styles and javascripts you need to set something like the follows i think...
includeJSlibs.jquery = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
includeJSlibs.jquery.external = 1
I am using the typoscript below to display news content via a CONTENT object. Everything is working great except the link doesn't go to the page of the article. Is there a way to tell the typolink that this is a news article and that it should use the cached CoolURI link for it?
Also, the additionalParameter I'm trying to append to the querystring isn't appearing.
temp.MMtest = COA
temp.MMtest {
10 = CONTENT
10.table = tt_news
#10.select.pidInList = 170 # Uid of the sysfolder where News records are stored
10.select.pidInList = 18
10.select.recursive = 10
#10.select.where = uid=10 # Uid of an existing News record
10.select.andWhere = deleted=0 AND hidden=0
10.renderObj = COA
10.renderObj {
10 = TEXT
10.field = title
10.wrap = Title: |<br>
10.typolink.parameter.field=uid
typolink.parameter.dataWrap=|
#typolink.additionalParams.insertData=1
typolink.additionalParams.data=&my_extra_param=something
#if.isTrue.field=header
}
10.renderObj.20=IMAGE
10.renderObj.20{
wrap=|
# show it only if inserted
stdWrap.if.isTrue.field=image
stdWrap.typolink.parameter.field=uid
file.import=uploads/pics/
file.import.field=image
file.width=100
file.height=100
}
}
I do not know, which parameters you need, so in short:
10.typolink {
# you need a page to link too
parameter = PAGE_ID_OF_SINGLE_VIEW
# create an cacheable link, that does not depend on cooluri or realurl.
useCacheHash = 1
# add the additional params
additionalParams.wrap = &tx_ttnews[uid]=|
# data expects special commands
# "&my_extra_param=something" cannot work on .data
additionalParams.data = field:uid
}
If you need more then one additionalParams i would do it this way:
10.typolink {
parameter = PAGE_ID_OF_SINGLE_VIEW
useCacheHash = 1
# Create an Content Object Array
# so you can separat the different entries
# the cObject will return &tx_ttnews[uid]=123&what[ever]=hardcodedvalue
# additionalParams is filled with that string and added to the url
additionalParams.cObject = COA
additionalParams.cObject {
10 = TEXT
10.wrap = &tx_ttnews[uid]=|
10.field = uid
20 = TEXT
20.wrap = &what[ever]=|
20.value = hardcodedvalue
}
}
You do not need
10.select.andWhere = deleted=0 AND hidden=0
this is added automatically by the CONTENT Object.
Read more about typolink about COA and about stdWrap and its property data and finally have a look at getText.