Реализация анонсов к новостям через тег [cut]Отсебятина от 09 сентября 2008 года. Теги: MySQL Юзабилити Новостная лента
На многих сайтах довольно часто можно наблюдать следующую картинку — новостная лента с анонсами, где анонс обрубается на полуслове, а через пробел или на следующей строке присутствует ссылка "Далее...". Кто-то пишет более оригинальные алгоритмы по обрубанию статьи в анонс, где учитывается конец предложения. Но давайте подумаем,
неужели нельзя сделать анонсы лучше, повысив при этом производительность?
Неужели нельзя сделать кнопку "Вставить разделитель для анонса" в редакторе, ведь редактору будет совсем не сложно выделить из статьи абзац и кликнуть по кнопке, чтобы разделитель вставился автоматом. Да и к тому же, обрубание текста обычно происходит на PHP, поэтому такая вещь существенно влияет на скорость формирования новостей. Почему? Давайте посмотрим:
1. Сначала к базе идет запрос вида:
SELECT * FROM `news` ORDER BY `id` DESC LIMIT 10
Таким образом, выбирается десять последних статей полностью всего лишь для ленты анонсов. Если статьи большие (по 50 тысяч знаков), то это будет слишком накладно для данной задачи — после выборки mysql хранит некоторое время результат (а значит, статьи занимают место. Например, если текст в кодировке ANSI, то статьи занимают 488 кб), да и к тому же, результат пересылается к php по протоколу TCP, а на это нужно время, плюс ко всему PHP этот объем необходимо обработать.
2. PHP: в цикле обработки результатов MySQL, каждая статья обрубается по N-символу, а потом ищется ближайшая точка от конца и текст вновь обрубается.
Таким образом получается автоматический анонс. Но, к сожалению, хороших скриптов по построению анонсов не будет до тех пор, пока не будет изобретен ИИ, поэтому самый оптимальный и красивый вариант - вешать задачу разграничения анонса на редактора.
Сейчас уже многие сайты обладают "ручным разбивателем", однако, я не знаю, как он реализован — проекты частные и доступ к исходному коду не предоставляют.
При разработке этого "сайта" я сразу определился, что анонсы буду определять я сам и разбивать статьи на страницы — тоже, поэтому хочу поделиться своими идеями насчет анонсов, которые, на мой взгляд, весьма оптимальны, потому что база присылает именно анонс, а не текст статьи.
В примере будет разобраны манипуляции с одним текстом, который имеет содержание "Мама мыла раму, а папа мыл велосипед". При желании, запрос к базе можно модифицировать для выборки произвольного количества анонсов.
Концепция
1 Часть - пользовательская
2 Часть - базаобразная
3 Часть - PHP-образная
|
Реализация
1 Часть
И так, представим, что статья пишется в обычном текстовом поле aka textarea (да, сейчас применяются визуальные редакторы, но при желании, можно переделать код и под них). Приделаем простую кнопку для добавления тега cut и получим код:
<input type="button" onClick="cut_add()" value="Добавить cut">
<textarea id="text"></textarea>
Теперь дополним функцией JavaScript:
function cut_add () {
document.getElementById("text").innerHTML += '[cut]';
}
Главное, чтобы редактор не забывал отделять анонс.
2 Часть
Как я уже сказал, анонс выделяется из статьи не на стороне PHP, а уже в СУБД MySQL (в моем случае). Это экономит ресурсы сервера и избавляет нас от засорения систему MySQL-ОС-PHP.
Что за бред я придумал? Все очень просто - в запросе к СУБД мы объявляет, что она должна найти этот тег cut в тексте и вернуть все, что располагается до него. Все это можно сделать следующим запросом:
SELECT `id`, SUBSTRING(`text`, 1, (INSTR(`text`, "[cut]")-1)) as `text` FROM `items`
WHERE `id`=1
Что сие значит?
Все очень просто, но для начала представим такой текст: Мама мыла раму[cut], а папа мыл велосипед
Эпат 1 — выполняется поиск позиции вхождения [cut] в текст: INSTR(`text`, "[cut]"). Функция возвращает результат 15 &mdash это позиция символа "[" относительно начала текста.
Эпат 2 — вычитается 1 из результата функции. Ведь нам нужно получить текст с 1 по 14 символ.
Эпат 3 — текст обрезается с 1 по 14 символ, таким образом, возвращая всего лишь 14 символов, вместо 41.
Какие могут быть ошибки?
Не ленитесь в запросе перечислять все столбцы — это важно! Не используйте SELECT *, SUBSTR... as `text`... В этом случае MySQL выберет поле text полностью, а потом сохранит в результате еще и наш анонс с тем же именем text. Таким образом нарушается вся задумка, и MySQL сохранит и перешлет в PHP статьи полностью.
Не забывайте после применения функций указывать результат именем столбца, который используется в функции, чтобы заменить его содержание, либо другим именем, если есть такая необходимость. В противном случае, в возвращенном результате столбец будет называться SUBSTRING(`text`, 1, (INSTR(`text`, "[cut]")-1))
Что еще?
Конечно, я упустил запрос с выборкой статьи полностью, тот вариант, когда человек кликнул по ссылке "прочитать полный вариант".
SELECT `id`, `text` FROM `items`
WHERE `id`=1
3 Часть
И так мы получаем чистенький анонс, который можно использовать, подставляя сразу в нужное место и присоединяя ссылку прочитать полный вариант".
Если читается уже полный вариант, то необходимо просто вырезать тег [cut], потому что мы не стали вызывать функцию вырезания в базе.
<?php
$text = strtr($row['text'], Array("[cut]", "")); //Вторым аргументом используется Array, так как количество искомых символов и заменяемых различно
//Другой вариант
$text = str_replace("[cut]", "", $row['text']);
?>
Заключение
Таким образом, слегка усложнив работу редактора и запрос к базе, мы облегчили обработку текста в скрипте новостной ленты, а так же улучшили читаемость самой ленты в разы.
В следующей статье я расскажу, как осуществить разбивку текста статьи по страницам.
|