Задачу описал в заголовке.
Хотел сначала решить с помощью регулярных выражений - не получилось. Сделал по тупому. Если кто знает как это упростить/ускорить/улучшить - пишите, потому что таких анонсов со ссылками на странице будет много и они могут сильно грузить сервер ненужными вычислениями.
Итак, код в студию:
$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;
}
?>
Я оформил в виде функции, чтобы можно было функцию поместить в шаблон и вызывать в разных местах. В общем - есть место для творчества.
Комментарии
еа заметку
А если два последних слова будут какой-нибудь ссылкой?
Ссылка будет пересекаться со ссылкой - будет каша.
Если знаете как - подскажите как исправить.
А добавить проверку на то, являются ли два последних слова частью ссылки?
Давайте добавим.
Один нюанс помоему (не проверял) но судя по коду, если случайно в тизере втретится фрагмент совпадающие с $link_text, то они тоже заменятся на ссылку $new_teaser=str_replace($link_text, $link, $teaser); и еще один момент
(я правда не знаю может друпал сам разруливает эту ситуацию), но может при обработке строк все же лучше использовать функции из семейства mb_*
Лучше, конечно, функции mb_*, так как они корректно обрабатывают Юникод, но вроде бы корректно работает и так - отсекает корректно.
Если возникают проблемы с заменой в центре тизера, то можно
увеличить количество слов, которые делаются ссылкой - это уменьшит вероятность совпадения
использовать preg_replace() для замены, но эта функция работает медленнее, чем str_replace
А можно как нибудь использовать данную функцию так, чтобы не править модуль node. Например из template.php.
UPD: Можно так: в template.php ставим саму функцию. А в node.tpl.php:
<?php if ($teaser==TRUE) {
$content=teaser_with_link($content,$node->nid);
}
?>
<?php print $content ?>
</div>
А зачем все это?
Дак вот считается плохим тоном заканчивать тизер словами "Подробнее" "Далее"