TYPO3 CONTENT select pass Argument to USER/USER_INT - typo3

typoscript:
lib.category = CONTENT
lib.category {
table=sys_category
select {
pidInList = root
selectFields = sys_category.*
join = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid
where.field = sys_category_record_mm.uid_foreign = data.uid
languageField = 0
}
renderObj = USER_INT
renderObj {
userFunc = InstantAitExt\AitContacts\GetPageCategories->testExecute
alias = TEXT
alias.value = data.uid
}
}
so i have to pass 1-x arguments to testExecute. one of those parameters should hold the uid of a given page. this uid gets passed to lib.category=CONTENT via
<f:cObject typoscriptObjectPath="lib.category" data="{page}" />
so data.uid is basically page.data.uid
thing is if i pass data.uid to alias.value the argument holds "data.uid" as a string and not the actual value i need.
so how is it possible to pass the actual pageId to alias.value
also, the query works but i am not able to verify/debug
where.field = sys_category_record_mm.uid_foreign = data.uid
to check if the query really gets the correct value (page id from view)
help is much appreciated

you can't debug it as it is an syntax error.
the attribute is where and if you use where.field you want to set the value from a field (of current context). after the equal sign the name of a field is expected.
But you give an expression sys_category_record_mm.uid_foreign = data.uid. That can't be evaluated.
What you want is an expression with a data. this data should be replaced.
So you either use a wrap for the replaced data (or field)
where.data = data.uid
where.wrap = sys_category_record_mm.uid_foreign = |
which is equal to
where.field= uid
where.wrap = sys_category_record_mm.uid_foreign = |
as data is the current context, so you can access the field directly.
or you use an insertData:
where = sys_category_record_mm.uid_foreign = {data.uid}
where.insertData = 1
EDIT:
if you only want to submit the page uid to the typoscript viewhelper you can use
<f:cObject typoscriptObjectPath="lib.category" data="{page.uid}" /> or a simple array like:
<f:cObject typoscriptObjectPath="lib.category" data="{uid:page.uid}" />
while the second call would not change the typoscript above (you only have a smaller data array which contains only the field uid while the original call contains the whole pages record).
For the viewhelper with just the uid value you have to use current:
where = current
where.wrap = sys_category_record_mm.uid_foreign = |

Related

Assign register value to TYPO3 CASE key

Am making some complex menus and would like to use CASE (or similar) to determine the number of submenus in a given branch in order to determine the style of menu to use.
Code:
5 = HMENU
5 {
entryLevel = -1
1 = TMENU
1 {
expAll = 1
NO = 1
NO {
...
}
IFSUB = 1
IFSUB {
10 = CASE
10 {
key.data = {register:count_menuItems}
1 = COA
1 {
data = {field:title}
data.insertData = 1
}
2 = COA
2 {
data = {field:title}
data.insertData = 1
}
default = COA
default {
data = {field:title}
data.insertData = 1
}
}
wrapItemAndSub = |
}
}
2 = TMENU
2 {
maxItems = 2
expAll = 1
...
}
}
How can I get CASE to work? I've tried it with and without the braces.
you should get more information how to access fields, register and other data in typoscript.
if you have a property you mostly can modify the way to get other information than a constant text.
In your example it is the key property where constants are not meaningful.
if you want to access a field of the 'current' record/data you just use key.field = fieldname
if it is other data you modify it to key.data = register:registername
accessing a field can be done with key.data = field:fieldname
If you want these data connected to other information you could use a wrap:
key.data = register:registername
key.wrap = prefix- | -suffix
Notice: the parts of the wrap are trimmed before they are connected
another way would be an inline notation where you even can use multiple values:
key = {register:registername}-with-{field:fieldname}
key.insertData = 1
here you have two replacements. each has to be wrapped in braces {} and you need to tell TYPO3 that there are replacements to do: insertData = 1
special case TEXTobject:
10 = TEXT
10.value = constant Text
20 = TEXT
20.field = fieldname
30 = TEXT
30.data = register:registername
40 = TEXT
40.value = register is '{register:registername}' and field is '{field:fieldname}'
40.insertData = 1
ADDED:
see the manual of the typoscript data type getText where you can find what else can be used instead of register:
then the manual entry for data which is a property of the function .stdWrap and of type getText.
This entry is followed by the property field stating, it is a shortcut for data = field:
(This explaines why your COA with .data results in anything, as doing a .stdWrap.data on any object will replace the object's content.)
be aware that field (either as property or as key of getText) will select
a field of the current record, which might vary dependent on context:
for page rendering it is the record of the current page (table pages),
for rendering a content element it is the element (table tt_content),
inside a filesProcessor it is a file (table sys_file_reference`),
in the renderObj of CONTENT, RECORDS, or split it is the selction you define.
Found the answer. As far as I can tell, CASE works on stdwrap.cObjects and so the code
10 = CASE
10 {
key.data = {register:count_menuItems}
...
}
should be
stdWrap.cObject = CASE
stdWrap.cObject {
key.data = register:count_menuItems
if.isTrue.data = register:count_menuItems
...
}
This way it works.

Page object isn't returned with the categories

I am developping a plugin to list all the page of a certain type. I added the new type without any difficulties. I also wanted to display the categories of the page but when I debug the objects in the template, I only see the number of categories associated with the page.
The repository doesn't return the categories of the page and I can't find why. Also, as a test, I checked if a normal page would return the childrens but it doesn't even count the number of categories attributed to the page.
I took a look into the sys_category_record_mm table and the rows are created correctly. I haven't touched the categories in the TCA.
This is the items configuration in the sys_category TCA
items
config
allowed = *
internal_type = db
MM = sys_category_record_mm
MM_oppositeUsage
pages
0 = categories
sys_file_metadata
tt_content
tx_news_domain_model_news
0 = categories
show_thumbs =
size = 10
type = group
exclude = 0
label = LLL:EXT:lang/locallang_tca.xlf:sys_category.items
This is my page categories config in the TCA
categories
config
autoSizeMax = 50
foreign_table = sys_category
foreign_table_where = AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.sorting ASC
maxitems = 9999
MM = sys_category_record_mm
MM_match_fields
fieldname = categories
tablenames = pages
MM_opposite_field = items
renderType = selectTree
size = 10
treeConfig
appearance
expandAll = 1
maxLevels = 99
showHeader = 1
parentField = parent
type = select
exclude = 1
label = LLL:EXT:lang/locallang_tca.xlf:sys_category.categories
I didn't add more category selector to the page. Either manually or via the makeCategorizable so that should still the default configuration.
Are you using extbase as you are talking about objects? If yes, then the categories property got a wrong type in your model. Instead of string, use
/**
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\Category>
* #lazy
*/
protected $categories;
If you are not using extbase, just do an additional query to sys_category_record_mm to fetch the according counts.

Insert comma separated list created with HMENU in TEXT.value

I want to insert my comma separated list created with HMENU at the value of the TEXT item. If I fill the list manually, all working fine, but I can't fill my value from the created hmenu:
temp.pageIds = HMENU
temp.pageIds.entryLevel = 2
temp.pageIds.1 = TMENU
temp.pageIds.1 {
NO.stdWrap.field = uid
NO.allWrap = |,
NO.doNotLinkIt = 1
}
#output temp.pageIds for example 13,53,12,34,
temp.orderedContent = TEXT
temp.orderedContent {
value < temp.pageIds # <------ not working (value = 23,25,57,... working)
split {
token = ,
cObjNum = 1
1 = COA
1 {
10 = CONTENT
10 {
table = tt_content
select {
pidInList.current = 1
where = colPos = 0
}
}
}
}
}
Any ideas?
The value property of a TEXT object will not be interpreted. If you just copy the temp.pageIds-object, it will be just be the literal string HMENU (and have some subproperties), which is not a list of page IDs.
To get it evaluated, notice in the docs that the type of value is of type string/stdWrap, so the value will be filtered through the stdWrap-function. stdWrap has the property cObject, which can be used to interpret content objects.
So this should work:
value.cObject < temp.pageIds

How to get page categories in Typoscript (and use with tx_news)

I would like to read out a page's system categories for further use with tx_news (to display news that have the same categories as the page - as tx_news is using system categories).
I was looking for a native solution, hopefully via getText, something like:
plugin.tx_news.settings.categories.data = page:categories
but that doesn't seem to exist yet
Also, I tried to simplify the query by using sys_category_records_mm, which contains all the information needed for that case, but TYPO3 complains that "there is no entry in the $TCA array":
lib.categoryUid = CONTENT
lib.categoryUid {
wrap = kategorien:|
table = sys_category_record_mm
select {
selectFields = uid
where = uid_foreign = {TSFE:id}
where.insertData = 1
}
renderObj = TEXT
renderObj {
field = uid
wrap = |,
}
}
So that would be nice, but it's not allowed.
Here's a solution that works in my setup. The editor chooses categories for the page, and gets all news items that belong to the category.
temp.categoryUid = CONTENT
temp.categoryUid {
table = pages
select {
// dontCheckPid doesn't exist for CONTENT objects, so make it recursive from root page (or pidInList.data = leveluid:-2
pidInList = {$pidRoot}
recursive = 99
selectFields = sys_category.uid as catUid
join = sys_category_record_mm ON pages.uid = sys_category_record_mm.uid_foreign JOIN sys_category ON sys_category.uid = sys_category_record_mm.uid_local
where = sys_category_record_mm.tablenames = 'pages' AND sys_category_record_mm.uid_foreign = {TSFE:id}
where.insertData = 1
// not necessary for this use case
// orderBy = sys_category.sorting
}
renderObj = TEXT
renderObj {
field = catUid
// Hack: if there are no cats selected for a page, all news are displayed
// so I just pass a catUid that's quite unlikely
wrap = 999999,|,
}
}
lib.newstest = USER
lib.newstest {
userFunc = tx_extbase_core_bootstrap->run
extensionName = News
pluginName = Pi1
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
limit = 5
orderBy = datetime
orderDirection = desc
detailPid = {$pidNachrichtenDetail}
overrideFlexformSettingsIfEmpty := addToList(detailPid)
startingpoint = {$pidNachrichtenRecords}
// for use in my fluid template
// pluginTitle = {$llAktuell}
// latest = 0
// recordType = aktuell
// https://forge.typo3.org/issues/52978
useStdWrap = categories
categories.override.cObject < temp.categoryUid
categoryConjunction = or
}
view =< plugin.tx_news.view
}
What is unclear to me still is if recursive = 1 in the select has no setback. Actually, I don't want to check for the current page's parent uid at all, but WHERE pages.pid IN ({current pid}) is always inserted automatically. Therefore the recursive = 1.
I found this example (in German) and modified it to display the category UIDs.
The following TypoScript will display the UIDs of all categories for the current page seperated by a comma.
10 = CONTENT
10 {
table = pages
select {
uidInList.field = uid
pidInList = 1 # UID or list of UIDs, where your categories are saved
selectFields = sys_category.uid as catUid
join = sys_category_record_mm ON pages.uid = sys_category_record_mm.uid_foreign JOIN sys_category ON sys_category.uid = sys_category_record_mm.uid_local
where = sys_category_record_mm.tablenames = 'pages' AND sys_category_record_mm.uid_foreign = {field:uid}
where.insertData = 1
orderBy = sys_category.sorting
}
renderObj = TEXT
renderObj {
field = catUid
wrap = |,
}
# HACK
# If category is empty, the mechanism below won't work
# As long as I don't know how to query if this is empty or not,
# just add an imaginary extra category!
wrap = 12345,|
}
Unfortunately you have to set pidInList manually to a list of UIDs, where your categories are stored.
Looking for the cat-id of a page:
I did it this way:
lib.cat = CONTENT
lib.cat {
wrap = |
table = sys_category
select {
pidInList = 1
selectFields = sys_category.uid, sys_category.title
max = 1
join = sys_category_record_mm ON(sys_category_record_mm.uid_local = sys_category.uid)
where = sys_category_record_mm.tablenames='pages'
andWhere.dataWrap = sys_category_record_mm.uid_foreign = {TSFE:id}
}
renderObj = COA
renderObj {
10 = TEXT
10 {
field = uid
wrap = class="category|
}
20 = TEXT
20 {
field = title
case = lower
stdWrap.noTrimWrap = | |"|
}
}
}

Typoscript issue with GP vars?

I want to execute a query using typoscript . My query is
SELECT * FROM TABLE where sld like '{GP:SID}' . I want to warp the SID variable inside a single/double quotes. Tried the below script, but didnt worked for me.
lib.products = CONTENT
lib.products {
table = TABLE
select {
pidInList = 26506
orderBy = name
where = sid like '{GP:SID}'
}
renderObj = COA
renderObj {
10 = COA
10 {
10 = TEXT
10.dataWrap ={field:name}[\n]
}
}
}
Can any help me with this ?
You code is insecure! Don't use it on production.
What you should do instead - is to use TS query markers, which uses prepared statements in a background.
lib.products = CONTENT
lib.products {
table = TABLE
select {
pidInList = 26506
orderBy = name
where = sid like '###sid###'
markers {
sid.data = GP:SID
}
}
renderObj = COA
...
}
Also, if you want to use LIKE, you need % sign to make it work, otherwise it is same as 'equals', but slower. However, I'm not sure, what happens, if GP:SID contains % sign at the beginning or at the end of a string.