Russian TYPO3 community

Russian TYPO3 community (http://forum.typo3.ru/index.php)
-   TypoScript практикум (http://forum.typo3.ru/forumdisplay.php?f=27)
-   -   Подсчет и вывод записей в текущей категории средствами typoscript (http://forum.typo3.ru/showthread.php?t=9461)

thebat 09.05.2011 17:50

Подсчет и вывод записей в текущей категории средствами typoscript
 
И так начну описывать задачу.
Есть три категории новостей в этих трёх категориях есть по несколько десятков записей новостей.
Вывод на странице делается базовыми средствами расширения. Вставил элемент контента "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 для 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

Как я уже писал выше, основа написано, но если вам нужны детали, то посетите эту страницу где опубликован весь код и силка на демонстрацию работы данного примера.


Часовой пояс GMT +4, время: 19:52.

Работает на vBulletin® версия 3.8.1.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot