Делаем 2 последних слова анонса ссылкой на статью (А ля "Читать дальше...")

Главные вкладки

Аватар пользователя VladSavitsky VladSavitsky 5 февраля 2008 в 23:01

Задачу описал в заголовке.
Хотел сначала решить с помощью регулярных выражений - не получилось. Сделал по тупому. Если кто знает как это упростить/ускорить/улучшить - пишите, потому что таких анонсов со ссылками на странице будет много и они могут сильно грузить сервер ненужными вычислениями.

Итак, код в студию:

$teaser=' В России ежедневно увольняют десятки человек за умышленное нанесение материального ущерба своей фирме. "Не беда", – говорит, ухмыляясь, такой сотрудник в отделе кадров обворованного им предприятия. И с широкой улыбкой идет в здание по соседству и в очередном отделе кадров гордо предъявляет трудовую книжку с привычной записью "по собственному желанию".
К сожалению, по существующему законодательству проще уволить человека по собственному желанию, чем с формулировкой "утрата доверия". Более того, мизерный процент работодателей имеет желание судиться с проворовавшимся сотрудником: несовершенство судебной системы и проблемы с доказательной базой – вот то, с чем сталкиваются многие работодатели. в кругу заинтересованных лиц.';
$node->nid=3;
var_dump(teaser_with_link($teaser, $node->nid));
//Функция делает последние 2 слова анонса ссылкой на статью.
function teaser_with_link($teaser='', $nid='0') {
if (!$teaser) return;
if (!$nid) return $teaser;
//Берём только последнюю часть анонса для работы (последние 50 символов не считая HTML-тегов):
$subject=trim(substr(strip_tags($teaser),-50));
//Получаем массив слов этого отрывка:
$words=preg_split('/ /', $subject, -1);
//Получаем последние 2 слова анонса:
$last_word=array_pop($words);
$pre_last_word=array_pop($words);
//Тест с начала предпоследнего слова и до конца анонса:
$link_text=trim(substr($teaser, strrpos($teaser, $pre_last_word)));
$link_text=str_replace ('', '', $link_text);
$link=l($link_text, 'node/'.$nid, array(), NULL, NULL, FALSE, TRUE);
$new_teaser=str_replace($link_text, $link, $teaser);
return $new_teaser;
}
?>

Я оформил в виде функции, чтобы можно было функцию поместить в шаблон и вызывать в разных местах. В общем - есть место для творчества.

Комментарии

Аватар пользователя olk olk 2 июля 2008 в 10:51

Один нюанс Smile помоему (не проверял) но судя по коду, если случайно в тизере втретится фрагмент совпадающие с $link_text, то они тоже заменятся на ссылку Smile $new_teaser=str_replace($link_text, $link, $teaser); и еще один момент
(я правда не знаю может друпал сам разруливает эту ситуацию), но может при обработке строк все же лучше использовать функции из семейства mb_*

Аватар пользователя VladSavitsky VladSavitsky 21 июля 2008 в 12:46

Лучше, конечно, функции mb_*, так как они корректно обрабатывают Юникод, но вроде бы корректно работает и так - отсекает корректно.

Если возникают проблемы с заменой в центре тизера, то можно
увеличить количество слов, которые делаются ссылкой - это уменьшит вероятность совпадения
использовать preg_replace() для замены, но эта функция работает медленнее, чем str_replace

Аватар пользователя namli namli 18 августа 2008 в 12:57

А можно как нибудь использовать данную функцию так, чтобы не править модуль node. Например из template.php.
UPD: Можно так: в template.php ставим саму функцию. А в node.tpl.php:

<div class="content clear-block">
<?php   if ($teaser==TRUE) {
    $content=teaser_with_link($content,$node->nid);
   }
?>
    <?php print $content ?>
  </div>
Аватар пользователя namli namli 6 ноября 2008 в 19:42

"Химический Али" wrote:
А зачем все это?

Дак вот считается плохим тоном заканчивать тизер словами "Подробнее" "Далее"