Авто анонс
74
Задумался о добавлении возможности создания анонса. Полез в код… Оказывается, в ливстрит есть все, что нужно для создания анонса! Максу респект!
Но просто добавить новое поле в форму добавления топика мне показалось мало. Точнее я передумал. =)))
Вместо ручного добавления анонса решил сделать авто обрезание текста топика. Варианта три:
1) Отрезать определенное количество символов и тупо ставить троеточие.
2) То же самое, но до первого пробела. В этом случае целостность слов сохраняется.
3) То же самое, но до первого знака окончания строки. :)
Первый тупой и простой никому давно не интересен, поэтому расскажу, как сделать второй и третий.
Заходим в файл \classes\actions\ActionTopic.class.php
Находим строки 386 и 536 с текстом:
Вариант 2. Меняем их на:
Вариант 3. Меняем строки 386 и 536 на:
* * * * UPDATE * * * *
Чтобы была возможность использовать настройку этого хака — либо «да», либо стандартный cut, делаем нижеследующее.
Добавляем в config.php строчку:
Соответственно исправляем в \classes\actions\ActionTopic.class.php:
* * * * UPDATE 2 * * * *
Если не хотим «портить» конфиг и нас устраивает условие «есть кат — ничего не трогаем, нет ката — обрезаем» — тогда этот вариант для вас. Редактируем только "\classes\actions\ActionTopic.class.php", заменив "$sTextShort=$sText;" из строк 386 и 536 на:
Но просто добавить новое поле в форму добавления топика мне показалось мало. Точнее я передумал. =)))
Вместо ручного добавления анонса решил сделать авто обрезание текста топика. Варианта три:
1) Отрезать определенное количество символов и тупо ставить троеточие.
2) То же самое, но до первого пробела. В этом случае целостность слов сохраняется.
3) То же самое, но до первого знака окончания строки. :)
Первый тупой и простой никому давно не интересен, поэтому расскажу, как сделать второй и третий.
Заходим в файл \classes\actions\ActionTopic.class.php
Находим строки 386 и 536 с текстом:
$sTextShort=$sText;Вариант 2. Меняем их на:
// Ищем первый пробел в строке, начиная с 200 по направлению к началу
$sTextShort = substr ($sText, 0, 200 - strlen (strrchr (substr ($sText, 0, 200), ' ')));Вариант 3. Меняем строки 386 и 536 на:
// Обрезаем все, что больше 200 символов, но только после точки (или других знаков окончания предложения)
preg_match("/.{200}[^.!;?]*[.!;?]/si", $sText.". ", $matches);
$sTextShort = $matches[0];* * * * UPDATE * * * *
Чтобы была возможность использовать настройку этого хака — либо «да», либо стандартный cut, делаем нижеследующее.
Добавляем в config.php строчку:
define('BLOG_TOPIC_CUT',200); // 0 - используем стандартный cut, больше 0 - обрезаем анонс после этого символа.Соответственно исправляем в \classes\actions\ActionTopic.class.php:
if (BLOG_TOPIC_CUT > 0 and strlen($sText) > BLOG_TOPIC_CUT) {
// Обрезаем все, что больше BLOG_TOPIC_CUT символов, но только после точки (или других знаков окончания предложения)
preg_match("/.{".BLOG_TOPIC_CUT."}[^.!;?]*[.!;?]/si", $sText.". ", $matches);
$sTextShort = $matches[0];
} else {
$sTextShort = $sText;
}* * * * UPDATE 2 * * * *
Если не хотим «портить» конфиг и нас устраивает условие «есть кат — ничего не трогаем, нет ката — обрезаем» — тогда этот вариант для вас. Редактируем только "\classes\actions\ActionTopic.class.php", заменив "$sTextShort=$sText;" из строк 386 и 536 на:
if (strstr ($sText, '<cut>') or strlen ($sText) <= 200) {
$sTextShort = $sText;
} else {
// Обрезаем все, что больше 200 символов, но только после точки (или других знаков окончания предложения)
preg_match("/.200[^.!;?]*[.!;?]/si", $sText.". ", $matches);
$sTextShort = $matches[0];
}
- +3
- 18 мая 2009, 14:11
- skachko
Чет не добавляются новости с этим хаком. Пишет:
Notice: Undefined variable: sTextNew in /var/www/tpLVTg/tp.ks.ua/classes/actions/ActionTopic.class.php on line 404
SQL Error: Column 'topic_text' cannot be null at /var/www/tpLVTg/tp.ks.ua/classes/modules/topic/mapper/Topic.mapper.class.php line 64
Array ( [code] => 1048 [message] => Column 'topic_text' cannot be null [query] => INSERT INTO prefix_topic_content (topic_id, topic_text, topic_text_short, topic_text_source, topic_extra ) VALUES
Чего-то нехватает: если создать и сохранить материал, то обрезается все отлично. Но стоит отредактировать топик, как эффект автоанонса улетучивается. Или это только у меня так?

- CaptainFlint
- 18 мая 2009, 19:22
- ↓
Нужно аналогично отредактировать функцию SubmitEdit этого же класса.

- CaptainFlint
- 18 мая 2009, 19:25
- ↑
- ↓
Спасибо за хак. Возможно в определенных проектах будет полезен.
P.S. Считаю, что пользователь сам должен определять когда необходимо ставить «cut».
P.S. Считаю, что пользователь сам должен определять когда необходимо ставить «cut».

- kostyasorokin
- 18 мая 2009, 21:32
- ↓
Нашел косячок в 3-м варианте. Если длина текста меньше длины анонса, вылетает ошибка и в базу пишется пустое значение. Расширяем проверку:
if (BLOG_TOPIC_CUT > 0 and strlen($sText) > BLOG_TOPIC_CUT) {
От жеж редиска! Ё!
Просто у мну нет мультибайтовых строк, т.к. хостер не дает, и я от них вообще избавился и всё работает. :)
Просто у мну нет мультибайтовых строк, т.к. хостер не дает, и я от них вообще избавился и всё работает. :)
function WinToUtf8($s) {
$t = '';
for ($i = 0, $m = strlen($s); $i < $m; $i++) {
$c = ord($s[$i]);
if ($c <= 127) { $t .= chr($c); continue; }
if ($c >= 192 && $c <= 207) { $t .= chr(208) . chr($c - 48); continue; }
if ($c >= 208 && $c <= 239) { $t .= chr(208) . chr($c - 48); continue; }
if ($c >= 240 && $c <= 255) { $t .= chr(209) . chr($c - 112); continue; }
if ($c == 184) { $t .= chr(209) . chr(209); continue; };
if ($c == 168) { $t .= chr(208) . chr(129); continue; };
}
return $t;
}
function Utf8ToWin($fcontents) {
$out = $c1 = '';
$byte2 = false;
for ($c = 0;$c < strlen($fcontents);$c++) {
$i = ord($fcontents[$c]);
if ($i <= 127) {
$out .= $fcontents[$c];
}
if ($byte2) {
$new_c2 = ($c1 & 3) * 64 + ($i & 63);
$new_c1 = ($c1 >> 2) & 5;
$new_i = $new_c1 * 256 + $new_c2;
if ($new_i == 1025) {
$out_i = 168;
} else {
if ($new_i == 1105) {
$out_i = 184;
} else {
$out_i = $new_i - 848;
}
}
$out .= chr($out_i);
$byte2 = false;
}
if (($i >> 5) == 6) {
$c1 = $i;
$byte2 = true;
}
}
return $out;
}И прощай mb_string! :)
ну исходим из того, что сайт на русском языке и в тексте топика количество латиницы пренебрежимо мало :)
странно, способ «UPDATE 2» — вызвал ошибку при добавлении поста.
а способ из «update» — сразу заработал, им и пользуюсь :)
Автору огромное спасибо!
а способ из «update» — сразу заработал, им и пользуюсь :)
Автору огромное спасибо!
Для устранения ошибки в UPDATE 2 следует писать такой код:
Автор забыл в строке…
… число (в данном случае 200) заключить в фигурные скобки.
Я у себя на проекте заключил — все работает.
Автору плюс. Т.к. очень нужная для мну штука. Благодарствую.
if (strstr ($sText, '<cut>') or strlen ($sText) <= 200) {
$sTextShort = $sText;
} else {
// Обрезаем все, что больше 200 символов, но только после точки (или других знаков окончания предложения)
preg_match("/.{200}[^.!;?]*[.!;?]/si", $sText.". ", $matches);
$sTextShort = $matches[0];
}Автор забыл в строке…
preg_match("/.200[^.!;?]*[.!;?]/si", $sText.". ", $matches);
… число (в данном случае 200) заключить в фигурные скобки.
Я у себя на проекте заключил — все работает.
Автору плюс. Т.к. очень нужная для мну штука. Благодарствую.
А можно ли сделать кат не по колличеству символов, а по высоте блока. Например, чтобы отрезало когда пост больше 150px?
это можно через цсс сделать, сделать отдельный класс для блока в темплейте вывода всех постов для отдельного поста и в нём что то такое max-height:150px; overflow-y:hidden; и если текста будет больше чем на 150 пикселей в высоту они будут просто не видны. если ограничиться еще кол-вом символов, то те несколько строк лишнего текста не будут мешать
Вдруг обратил внимание на странную вещь. Я ставлю у себя кол-во символов 3000 до автовставки тега cut. Но почему то вставляется в р-не 1700-го символа. Если ставлю 2000 символов ограничение — обрезается в р-не 1200 символа. В чем подвох? оО
Эээ… признаться честно — не знаю. Судя по кол-ву выводимых перед катом символов — не считает. Тогда встречный вопрос — как посчитать и их тоже?
Ну я имею ввиду как вы определяете что выводит 1200 вместо 2000? Измеряете на выходе функцией strlen? Или как?

- ExtremeMan
- 15 октября 2009, 02:31
- ↑
- ↓
на сколько я понимаю такая разница происходит из-за того что функция preg_match встроенная в php по разному отрабатывает символы кириллицы и латиницы.
Потому как в том же notepad++
Для латинского текста вывел 1019 chars 1029 bytes
Для кирилицы — 556 chars 1018 bytes
Скорее всего константа BLOG_TOPIC_CUT для preg_match в строке
preg_match("/.{".BLOG_TOPIC_CUT."}[^.!;?]*[.!;?]/si", $sText.". ", $matches);
Указывает кол-во байт а не символов.
Подскажите гуру php как побороть данный вопрос?
Потому как в том же notepad++
Для латинского текста вывел 1019 chars 1029 bytes
Для кирилицы — 556 chars 1018 bytes
Скорее всего константа BLOG_TOPIC_CUT для preg_match в строке
preg_match("/.{".BLOG_TOPIC_CUT."}[^.!;?]*[.!;?]/si", $sText.". ", $matches);
Указывает кол-во байт а не символов.
Подскажите гуру php как побороть данный вопрос?
Как вариант:
заменить на
Проверил для русского текста результат 1004 char 1816 bytes при настройке BLOG_TOPIC_CUT — 1000.
Для предыдущего комментария BLOG_TOPIC_CUT тоже 1000.
mb_ereg_match("/.{".BLOG_TOPIC_CUT."}[^.!;?]*[.!;?]/si", $sText.". ", $matches);
$sTextShort = $matches[0];заменить на
$tmp_str = iconv("UTF-8", "CP1251", $sText);
preg_match("/.{".BLOG_TOPIC_CUT."}[^.!;?]*[.!;?]/si", $tmp_str.". ", $matches);
$sTextShort = iconv("CP1251", "UTF-8", $matches[0]);Проверил для русского текста результат 1004 char 1816 bytes при настройке BLOG_TOPIC_CUT — 1000.
Для предыдущего комментария BLOG_TOPIC_CUT тоже 1000.

Комментарии (70)
RSS свернуть / развернуть