PDA

Просмотр полной версии : Подсчет и вывод записей в текущей категории средствами typoscript


thebat
09.05.2011, 17:50
И так начну описывать задачу.
Есть три категории новостей в этих трёх категориях есть по несколько десятков записей новостей.
Вывод на странице делается базовыми средствами расширения. Вставил элемент контента "tt_news", код вывода "LATES", количество строк 3

На выводе имеем:
==================
[Категория 1]
[Заголовок 1]
[короткое описание 1]
-----------------------
[Категория 2]
[Заголовок 2]
[короткое описание 2]
-----------------------
[Категория 3]
[Заголовок 3]
[короткое описание 3]
==================
Все записи >>>

Каждая из этих категорий имеет разносное количество записей.
Нужно возле каждой категории вывести количество присоединенных к ней записей, а именно вот здесь...

plugin.tt_news.categoryTitles_stdWrap.wrap = | [Количество записей]

Для начало записал TS во так:
displayLatest {
categoryTitles_stdWrap {
append = CONTENT
append {
stdWrap.numRows {
table = tt_news [таблица с записами]
select.pidInList = 1 [место где есть записи]
}
}
}
category_stdWrap.wrap = |
}

На выводе имеем:
-----------------------
[Категория 3] [Количество записей]
[Заголовок 3]
[короткое описание 3]
==================
Все записи >>>

Все кажется хорошо, но возле каждой категории одинаковое количество записей подсчитанных и выведенных из [место где есть записи]. В то время как к каждой категории привязано резное количество записей.

Стал вопрос, как вывести количество записей привязных к текущей категории выведенных в списке последних записей?

К примеру вот так:
==================
[Категория 1] [Количество записей 10]
[Заголовок 1]
[короткое описание 1]
-----------------------
[Категория 2] [Количество записей 45]
[Заголовок 2]
[короткое описание 2]
-----------------------
[Категория 3] [Количество записей 5]
[Заголовок 3]
[короткое описание 3]
==================
Все записи [Количество записей 60] >>>

Понимаю, что нужно воспользоваться свойством "andWhere" или "where", но как не знаю?

Есть у кого либо какие то идеи?

thebat
15.05.2011, 18:12
..., и так стало понятно, что вариантов пока нет! Может кто направит в нужное русло?

-=UncleByte=-
16.05.2011, 01:20
А описанный в TSRef select для CONTENT не подойдет разве? В нем как раз есть и where и andwhere.

thebat
16.05.2011, 01:48
Да, я знаю об этих свойствах, но не могу построить подходящую конструкцию (запрос) и не знаю как их можно использовать в моем случае?

-=UncleByte=-
16.05.2011, 02:25
Логично делать запрос к таблице новостей с условиями типа категория = 1 и новость не удалена и не спрятана:
Что-то типа SELECT *
FROM `tt_news`
WHERE `deleted` =0
AND `hidden` =0
AND `category` =2

thebat
16.05.2011, 22:58
Не выходит что-то у меня. Может давайте сложим в месте эту конструкцию?
К примеру:
=========
10 = CONTENT
10 {
table = tt_news # таблица с записями новостей
select {
selectFields = ??? # здесь не ясно что... возможно выделить столбец "category"
join = ??? # с этим я не знаю что делать
where = tt_news.deleted = 0 AND tt_news.hidden = 0 # учитывать все записи у кого 0 (то есть видна и не удалена), а если 1 и другое, то не учитывать.
andWhere {
dataWrap = tt_news.category = {field:uid} # текущая категория ...???
}
}
}

-=UncleByte=-
17.05.2011, 03:12
Насколько я понимаю для подсчета нужно использовать count(*). Т.е. сгруппировать по полю category и потом посчитать по нему же. Как-то так.

thebat
17.05.2011, 09:53
Отлично..., теперь у нас есть во это:

10 = CONTENT
10 {
table = tt_news # таблица с записями новостей
select {
pidInList = 1 # место где содержатся записи
selectFields = count(*) # выделить все записи в таблице "tt_news"
where = tt_news.deleted = 0 AND tt_news.hidden = 0 # учитывать все записи у кого 0 (то есть видна и не удалена), а если 1 и другое, то не учитывать.
andWhere {
dataWrap = tt_news.category = {field:uid} # текущая категория ...???
}
groupBy = tt_news.category # группировать по категории ...правильно ли?
}
}

Первое, нужно же определить текущую категорию и наверное составить условия ..., если совпадаю текущая категория с выделенной (найденной) в таблицей, то посчитать и показать возле текущей категории..., правильно ли я мыслю?

-=UncleByte=-
17.05.2011, 12:21
Мне так кажется что не нужно каждый раз указывать полное имя таблица.поле, т.е. получается что-то типа:
10 = CONTENT
10 {
table = tt_news
select {
pidInList = 1
selectFields = count (*) category
where = NOT deleted AND NOT hidden
groupBy = category
...
}
}
Вот что должно быть на месте многоточия я пока еще не думал и не придумал.

thebat
17.05.2011, 18:39
Нет, мы не там копаем.

Я обследовал таблицу "tt_new" и заметил, что поле "category" не содержит "uid" категории, выходит, что мы не можем таким образом отфильтровать записи определенной категории и вывести их количество.

Это означает, что нам надо взяться за таблицу "tt_news_cat"

-=UncleByte=-
17.05.2011, 23:27
Посмотрел базу, насколько понял все отношения между новостями и категориями описываются в tt_news_cat_mm - там расписано к каким категориям имеет отношение новость: если к нескольким, то там несколько записей для одной новости.

thebat
18.05.2011, 00:48
Мы уже на шаг подошли ближе к решению.

Теперь нужно определить, как использовать полученную информацию?

Есть вопрос, где или в какой таблице делать выборку... tt_new или tt_news_cat_mm

Я выяснил, что связи с записями tt_news прописаны в поле uid_local таблицы tt_news_cat_mm.

tt_news_cat_mm связан сего полем uid_foreign и в поле UID в таблиці tt_news_cat.

Схематично: tt_news.uid <> uid_local.tt_news_cat_mm - tt_news_cat_mm.uid_foreign <> uid.tt_news_cat

Возможно я ошибся ..., может кто поправит если это не так.

-=UncleByte=-
18.05.2011, 02:52
Наверное логично будет использовать tt_news_cat_mm потому что любая из новостей может быть в нескольких категориях. То есть группируем по категории и подсчитываем количество новостей в данной категории учитывая при этом состояние новости в tt_news.

thebat
22.05.2011, 18:09
Спасибо, но система отвечает, что это не так...

table = tt_news_cat_mm

Oops, an error occured!
There is no entry in the $TCA array for the table "tt_news_cat_mm". This means that the function enableFields() is called with an invalid table name as argument.

Нет $TCA масива для "tt_news_cat_mm" это значить что "tt_news_cat_mm" отбрасываем и у нас остаетсяч только ""tt_news_cat" или ""tt_news"

-=UncleByte=-
22.05.2011, 18:26
Странно, ведь таблица в базе присутствует. Или у меня какой-то неправильный tt_news?

thebat
22.05.2011, 18:50
Да, нет tt_news такой же и таблица "tt_news_cat_mm" присутствует, но при написании такой конструкцию typoscript

10 = CONTENT
10 {
stdWrap.numRows {
table = tt_news_cat_mm
}
}

..., я получаю ошибку, описанную выше.

-=UncleByte=-
22.05.2011, 19:03
Так может обойтись без numRows просто select'ом?
Т.е.

10 = CONTENT
10 {
table = tt_news_cat_mm
select {
pidInList = this
groupBy = uid_foreign
selectFields = count(uid_foreign)
...
}
}

За синтаксис mysql ручаться не буду, но принцип, думаю, отразил верно.

thebat
22.05.2011, 19:26
Ничего не выходит..., без разницы, что так:

10 = CONTENT
10 {
stdWrap.numRows {
table = tt_news_cat_mm
select {
pidInList = this
selectFields = count(*)
}
}
}

.., что так..

10 = CONTENT
10 {
table = tt_news_cat_mm
select {
pidInList = this
selectFields = count(*)
}
}

Ошибка та же. ...???

И мне еще не понятно из чего вы взяли, что это "count(*)" подсчитывает записи в таблице? Я пробовал составленную вам конструкция и на выводе ничего не получил ..., просто пусто, даже если указать что считать, к примеру во так "count(uid)" и даже если это считать в таблице "tt_news" ....????

-=UncleByte=-
22.05.2011, 19:50
Ну вообще из примеров по запросам mysql. http://www.google.ru/search?q=подсчитать+записи+в+таблице+по+полю+mysql

thebat
22.05.2011, 20:16
..., возможно, но вот этот простой typoscript:
20 = CONTENT
20 {
table = tt_news
select {
pidInList = 1
selectFields = count(*)
}
wrap = [|]
}
..., на выводе ничего не дал..., вообще ничего, а точнее [no news_id given] ...почему?

-=UncleByte=-
23.05.2011, 08:46
Вероятнее всего потому что не задан никакой отличный от обычного для tt_news вариант рендеринга контента.

thebat
23.05.2011, 13:37
Да... становится очень интересно! Вы имеет ввиду свойство "renderObj"?

-=UncleByte=-
23.05.2011, 14:04
Ну скорее всего необходимо сделать этот самый RenderObj потому что по умолчанию для этой таблицы нет никакого представления рендеринга. Плюс если посмотреть описание той функции что выдает ошибку There is no entry in the $TCA array for the table "tt_news_cat_mm". This means that the function enableFields() is called with an invalid table name as argument.видно что она проверяет как раз наличие полей типа deleted - hidden и т.д. Само собой их там нет, поскольку таблица создается не для хранения контента, но для связи категорий и новостей.
Поэтому, скорее всего, и нужно "придумать" и описать каким образом это рендерить.
Хотя, честно сказать, я думаю что проще сделать внешнюю функцию, в которую запихать один цикл и один общий sql запрос и просто брать из нее результат.

thebat
23.05.2011, 15:03
Да, я знаю, что можно написать PHP скрипт и он все это сделает, но задача стоит сделать это именно средствами TYPOSCRIPT, и к тому же я не программист.

Главное что я уже знаю наверняка, что обращаться к таблице "tt_news_cat_mm" не надо.

Возьмем две таблицы "tt_news_cat" и "tt_news" в "tt_news_cat" определяем категорию, а в "tt_news" считаем новости в это категории.

Честно говоря я уже близок к решению.

-=UncleByte=-
23.05.2011, 15:33
Я вот смотрю в таблицу tt_news и вижу что в category встречается только цифры 1 и 2, в то время как на самом деле есть 3 работающих категории и одна удаленная и это реально отражено только в таблице tt_news_cat_mm и нигде больше.

thebat
23.05.2011, 15:39
Да, смотрел я уже все таблицы и все так как вы пишите есть на самом деле.

И так, к примеру есть список новостей в том виде в котором я описывал выше.

Вопрос как определить "uid" текущей категории?

Определив "uid" текущей категории можно будьте посчитать привязанные к ней новости.

-=UncleByte=-
23.05.2011, 16:04
Значит надо каким-то образом обрабатывать tt_news_cat_mm - а как это сделать я пока не придумал. Внешней функцией было бы проще всего.

thebat
23.05.2011, 16:05
Осталось еще чуть чуть...

Вот мне здесь нужно поставить uid текущей категории

andWhere = tt_news_cat_mm.uid_foreign = uid текущей категории

Как её определить, я имею ввиду uid текущей категории?

-=UncleByte=-
23.05.2011, 17:03
Насколько помню через register как-то можно, надо смотреть документацию по tt_news

thebat
23.05.2011, 17:31
И так, проблема решена.

Вот он выстраданный код:

andWhere.wrap = tt_news_cat_mm.uid_foreign = {register:newsCategoryUid}
andWhere.insertData = 1
join = tt_news_cat_mm ON (tt_news_cat_mm.uid_local = tt_news.uid)

Всем спасибо.

-=UncleByte=-
23.05.2011, 18:02
Ура! Задача решена и сниппет есть!
А целиком весь код можно привести?

thebat
23.05.2011, 19:33
Основа это то что в предыдущем посте, а все остальное это импровизация.

10 = CONTENT
10 {
table = tt_news
select {
pidInList = 1
selectFields = count(*) as uid
where = NOT deleted AND NOT hidden
andWhere.wrap = tt_news_cat_mm.uid_foreign = {register:newsCategoryUid}
andWhere.insertData = 1
join = tt_news_cat_mm ON (tt_news_cat_mm.uid_local = tt_news.uid)
}
}

И это все можно прицепить, переопределить, вставить ну и так далее.

thebat
24.05.2011, 20:33
Забыл еще добавит к теме..., что есть расширение key: dkm_ttnewscatcount (http://typo3.org/extensions/repository/view/dkm_ttnewscatcount/current/) для tt_news которое должное было бы решать такую задачу, но оно к сожалению не работает..., возможно только у меня не работало...

demav
10.08.2011, 14:01
Не могли бы вы полностью привести TS для displayCatMenu ?
Никак не могу отобразить количество записей в категории - всегда выводит пусто.

Для проверки воспользовался кодом
displayCatMenu {
mode = nestedWraps

catmenuItem_NO_stdWrap {
wrap = |,uid={register:newsCategoryUid}
insertData = 1
}
}

Выводятся названия категории, а затем ",uid=" - кода категории нет

UPD:
В общем, выяснилось из исходников, что при выводе displayCatMenu регистры не заполняются.
А dkm_ttnewscatcount - очень странный модуль. Для его использования надо подключить plugin.tt_news.displayCatMenu.mode = countedmenu (на память пишу, может ошибаюсь). Но судя по коду, он ну никак не мог работать.

thebat
24.08.2011, 20:27
Как я уже писал выше, основа написано, но если вам нужны детали, то посетите эту страницу (http://typo3.org.ua/snippets.html) где опубликован весь код и силка на демонстрацию работы данного примера.