2

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.

Urs
  • 4,984
  • 7
  • 54
  • 116

3 Answers3

2

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.

Urs
  • 4,984
  • 7
  • 54
  • 116
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.

Urs
  • 4,984
  • 7
  • 54
  • 116
derhansen
  • 5,585
  • 1
  • 19
  • 29
  • I saw that too, isn't it a bit complex for a native feature? At first, I thought the categories should be available via getText or similar. But that probably doesn't exist yet then? And how would you pass that on to tx_news, in the sense of 'display news that have the same category as the page' (as tx_news uses system categories, that would come in very handy) – Urs Feb 15 '15 at 18:04
  • I could'nt find a native feature to get all page categories by TypoScript too, so actually it seems that using the CONTENT object is the only working solution to get the categories. Anyway, I found out, that you can't pass anything else than a plain string to the "categories" TypoScript setting of tx_news. I created a simple `tmp.cat = TEXT tmp.cat.value = 1,2` object and passed that to the "categories" setting of tx_news and that throws a fatal error, since the object is an array. So probably it it not possible at all to fetch categories by TS and pass the result to tx_news settings. – derhansen Feb 15 '15 at 19:17
  • Thanks - for my use, I could still set one category as maximum. What do you think about the use case in general (use page categorys to display news) - does it make sense to you? I think I'd open two feature requests on forge then – Urs Feb 16 '15 at 08:41
  • Ah, maybe I'll try RECORDS.categories, http://docs.typo3.org/typo3cms/TyposcriptReference/ContentObjects/Records/Index.html#cobj-records-properties-categories this will return a string – Urs Feb 16 '15 at 10:06
  • I tried the approach using RECORDS too, but RECORDS does'nt seem to support a select-method, so you may end up with all records (categories). In generall, I think it makes sense what you try to archieve and I think that retrieving all selected page categories is a missing Core feature. – derhansen Feb 16 '15 at 12:48
  • I'm on it, for the record, here is a related post http://typo3.toaster-schwerin.de/typo3_german/2013_10/msg00467.html – Urs Feb 16 '15 at 19:54
  • Sorry for the zillion comments - you did test your snippet, didn't you? On my site, it returns nothing at all (on a page where one category has been selected in the page settings). I replaced pidInList = 1 with a constant for my categories sysfolder. Could you explain what the SELECT does or how I could debug it? Is {field:uid} the current page's uid, and where does TS get that from? – Urs Feb 16 '15 at 21:10
  • Yes, I tested the code snippet. I did'nt use pidInList with a constant but only with a direct entry as posted (doubt that makes a difference). {fied:uid} is the current page uid, and the `where.insertData = 1` renders the current page uid into the `where` clause. The `CONTENT` object creates a plain SQL query; but I don't know a good way to debug it. As soon as you add something to the `WHERE` clause that causes invalid SQL, TYPO3 throws an exception with the last SQL Query created. That helped me debugging the TS – derhansen Feb 17 '15 at 07:28
  • Thanks, the debugging works. Where {field:uid} is, I get the uid of the tscobj-Plugin with which I insert the query, so there could be something wrong there. I tried to make it simple by querying sys_category_record_mm which contains all the information we need, but TCA won't let me (I'm pasting that code above for the record) – Urs Feb 17 '15 at 09:30
  • Super strange. My solution is completely different in relation to which values are passed to the select. Also, the storage location of the categories records (I understand that this was what you passed to pidInList) is not needed. Hey, and big thanks for keeping me on track! – Urs Feb 17 '15 at 10:22
  • Great you found a solution! I did'nt really know that tx_news had this `useStdWrap` setting. Very usefull :-) – derhansen Feb 17 '15 at 12:34
0

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 = | |"|
     }
  }
}