Секция files
01.09.2010Голосование
| Тип | Вопрос |
| Состояние | Исправлено |
| Приоритет | Средний |
| Версия | 3.78 |
| Система | * |
| Воспроизводимость | Нет |
| Автор | philipp |
| Исполнитель | Блоголётчик |
Хорошо бы это обсудить.
Во-первых, вопрос - могу ли я в шаблоне получить данные из настроек - размер превьюшки?
Во-вторых - может случиться так, что кто-нибудь решит закачать в пост разные данные. К примеру, картинки и зип. И плюс еще видео. Ну и как это приличным образом вывести? В длинную-длинную колонку?
Можно конечно хитрым образом поиграться с css-селекторами, но придется хитрить очень сильно. Что может облегчить жизнь - это введение дополнительной "обертки", т.е. файлы группируются по типу, и
каждый тип - отдельный список.
и в третьих, хорошо бы в админке иметь возможность переставлять местами приаттаченные файлы.
ИМХО, это все надо как-то решить, потому что без этого - функция малопригодна для серьезных проектов.
Код
class tpostpreview extends tevents {
public static function instance() {
return getinstance(__class__);
}
public function ongetfilelist(array $list, $excerpt) {
if (!$excerpt) return false;
return '<p>excerpt</p>';
}
public function install($self) {
$files = tfiles::instance();
$files->ongetfilelist = $self->ongetfilelist;
}
public function uninstall($self) {
tfiles::unsubscribeclass($self);
}
}
← Ранее Не могу попасть в админку
Позже Ошибки на litepublisher.ru →
Комментарии (59) на запись “Секция files”
Оставить комментарий
Тогда хорошо бы чтобы этот порядок регулировался секциями в шаблоне например.
Не свойства конкретного файла, а настройка ширина/высота картинки в предпросмотре, чтобы можно это было в css засунуть.
Блоголётчик пишет:
Так в этом и вопрос - можно ли их прямо сейчас получить в шаблоне? $options.previewheight у меня не работает.
А что касается вопроса про количество превьюшек - вопрос смысла в общем не имеет, я пытался думать not litepublisher way. Правильно будет добавить посту свойство excertpreviw и заполнять его при сохранении поста. Можно ли где-то посмотреть как 1. Расширять таблицу 2. Вероятно, подписываться на событие - потому что перкрывать методы (запись из админки и сохранение из блог-клиента) наверное перебор :)
Эти данные доступны из $mediaparser.previewwiddth и $mediaparser.previewheight
не понял насчет перекрытия/событий. Если требуется перехватывать вывод списка файлов в анонсе, то да, в настоящее время нет таких событий, но я могу добавить. Сейчас посмотрел исходники - проще будет добавить собтия в tfiles, где собственно и происходит генерация конечного html.В следующий релиз добавлю соответствующие события
Можно внедрять свои собственные свойства в любые классы. Для постов это делается так:
$posts = tposts::instance);
$posts->itemcoclasses[] = 'myclassname';
$posts->save();
в твоем классе обязоно быть свойство для записи post - после автоматического создания твоего обекта ооно будет привязоно к одному конкретному посту, у каждого поста сой индивидуальный экземплр твоего класса, а все остальное по желанию - можешь определять в своем классе любые свойства - если в посте не будет найдено свойство, то ооно будет искаться в твоем классе. Свойства в классе можно определять как функцию getnme() где name твое свойство.
Отлично! Заодно я понял что такое эти coclasses, как раз собирался спрашивать.
Блоголётчик пишет:
Должно сохранять только свойства моего класса, так? Примера навскидку в коде не нашел, где они используются?
Соклассы были добавлены во время разработки тикет системы и не пригодились, но сама идея и ее реализация остались. Например твой класс может декларироваться так:
tmyclass extends tevents {
public $post;
public static function instance() {
returngetinstance(__class__);
}
public function getmyprop() {
if (count($this->post->files) == 0) return '';
}
}
1. Обязательно нужен метод save(), в котором сохраняется мое поле, чтобы пост мог его автоматом вызывать $coinstance->save(); ,так?
С учетом того, что я планирую хранить его в таблице постов данные из которой уже загружены к моменту вызова $coinstance->load(), как мне получить данные без лишних запросов к базе? Или я чего-то принципиально не понял?
С самого начала задача была поставлена неправильно - ты сформулировал "новое свойство" для поста, хотя задача должна была бы звучать как "новый тег в шаблоне", но это так лирика. Я описал решение для нового свойства, но проблема этого решения в том, что твой класс будет дергаться всегда при создании поста, вне зависимости от того, будет ли твой класс исползоваться. Возможно, что для некоторых задач как раз это нужно, но нужно ведь нечто иное. Предлагаю другое решее - добавить собственный тегв $template, напримерpostpreview, и в шаблон ты сможешь вставлять тег $template.postpreview Опишу как его добавить:
$tags = ttemplatetags::instance();
$tags->add('postpreview', 'tmyclass', 'getpostpreview');
а в своем классе
class tmyclass {
public function getpostpreview() {
$post = ttheme::$vars['post'];
...
}
}//class
теперь что ксается твоего вопроса о load и save. Если твой класс не хранит своих собственных данных, которые отсутствуют в посте, то их реализоывать не надо. Если же данные есть, то для второго случая с тегом описанном здесь, то данные следует загружать создавать после $post = ... Если тебе требуется добавить небольшое количество данных к посту, то для этого есть специальный класс tmetapost. Общаться с этими данными (добавлять/удалять) следует так:
$post->meta->myprop = 'some value';
echo $post->meta->myprop;
в приведенном коде ты добавляешь новое свойство myprop, которое впоследствии можешь использовать где угодно. Если обратишься к несуществующему свойству (ранее его не присвоил), то произойдет ошибка.
Блоголётчик пишет:
Наверное да. Значит еще раз проверяю постановку задачи:
Нужен тег в шаблоне для вывода превьюшки для поста.
Это добавляется в инсталяторе класса, так?
Адрес превьюшки будет храниться в metapost. Сразу вопрос - создаст ли это дополнительные запросы к БД, или эта таблица и так запрашивается? и если создаст, то много ли (1 на страницу, 1 на каждый пост на странице...)
Данные нужно создавать - значит, нужно подписаться на запись поста, и там создавать/обновлять $post->meta->myprop . Это будет работать и в БД, и в файловой версиях.
так?
Админка не задействуется, поэтому ее я не трогаю. Остается понять как аккуратно удалить записи при удалении плагина. Есть ли где-нибудь примеры?
В общем я полазив по коду ответил на большинство своих вопросов. Я правильно понял, что любой запрос мета-свойства приводит к запросу к БД?
тогда получается что выгоднее все-таки пользоваться соклассом, и после
$post = ttheme::$vars['post']; я смогу просто вызвать echo $post->postpreview; предварительно задав его конечно?
Сейчас выложил версию 3.79, куда в tfiles добавил новое событие ongetfilelist, обработчик события должен быть таким:
public function ongetfilelist(array $list, $eexcerpt) {
if (!$excerpt) return false;
//$list это список id файлов
...
return $result; //готовый html списка файлов в анонсе
}
если идет подряд несколько add, delete и прочее то для файловой версии желатено заключать эти вызовы в lock() .. unlock(). где то надоsave, а где то и нет. Конкретно для тегов не нужно, добавление нужно в инсталяторе, в Uninstall нужно добавить
$tags = ttemplatetags::instance();
$tags-deleteclass(get_class($self));
Что кассается мета - удаление поста не требуется обрабатывать, так как мета данные будут тоже автоматически удалены, а вот создание/редактирование нужно (редактирование по обстоятельствам). Соответственно нужно добавить обработчики событий для tposts added (edited), чтобы инициализировать/изменить свои данные. Присвоение данных в мета автоматически их сохраняет. Если мета данные не исползуются, то иникаких запросов к бд не будет. Для всех мета данных одного поста осуществляется всего один запрос к бд. Данные должны быть простого типа - число/строка. Чтобы в бд удалитьсразу все свои данные в мета достаточно такого кода:
litepublisher::$db->table = 'postsmeta';
litepublisher::$db->delete("name = 'myprop'");
Нет, либо встраиваться соклассом, либо добавлять тег в $template. Подписка на событие:
$files = tfiles::instance();
$files->ongetfilelist = $myobj->ongetfilelst;
и в деинсталяции удалить подписку на событие. Добавление свойства - 1 запрос. Получение любого свойства из мета - 1 запрос на все свойства. Так что добавляется всего 1 запрос.сепг
Сколько запросов сейчас - честно говоря не помню, отложилась эта цифра. Или это было в самом начале до всех оптимизаций? +7 запросов - это если по 7 постов на страницу, на каждый - 1 запрос для meta.
Я неправильно подписываюсь?
public function install($self) {
$files = tfiles::instance();
$files->ongetfilelist = $self->ongetfilelist;
}
if (!$excerpt) return false;
return 'test';
}
Без эффекта. Вывод стандартный. В <!--excerpt--> стоят и $post.excerptfilelist, и $post.filelist.
Выложить весь класс? там еще только instance и uninstall
Запостил в Код.
Под админом файлы работают - надо будет проверить под юзером. У тебя ошибки в коде:
public function install($self)
неправильно - надо
public function install()
и далее везде заменить self на this - по идее php должен был выдать ошибку или предупреждение о несуществующем объекте self
$files = tfiles::instance();
$files-unsubscribeclass($this);
echo __method__, 'br>';
И точно (это я про $self и $this)
Инсталл и анинсталл отрабатывают. ongetfilelist - нет.
$this->ongetfilelist($list, $excerpt) в tfiles::getfilelist всегда возвращает false, как будто подписки таки не происходит.
В запуске скриптов
$files = tfiles::instance();
echo $files->eventexists('ongetfilelist');
возвращает 1
Как проверить подписан ли конкретный класс?
echo "<pre>\n";
var_dump$this->data['events'['ongetfilelist']);
echo "</pre>\n";
NULL
таки нет прдписки.
Код инсталлятора сейчас
public function install() {
$files = tfiles::instance();
$files->ongetfilelist = $this->ongetfilelist;
}
$files-ongetfiles(array(), false);
Кажется я понял причину проблем - в бд версии данные в классах в бд другие данные хрант в options, который сохраняет свои данные только один раз по окончании страницы. Скажи, во время инсталяцции были ли исключения/ошибки/другие события (ну там простынка сообщений в конце страницы)? Чтобы принудительно сохранить данные добавь в install строку
litepublisher::$options->savemodified();
но этот способ ненормален