Тизер - каковы правила формирования?

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

Аватар пользователя Toologic Toologic 1 марта 2007 в 12:07

Доброго дня всем!

Помогите разобраться с правилами формирования тизера (анонса). Я так понимаю, что делается это автоматически в пределах размера тизера, установленного в админке.
Но... почему на одних материалах он (его размер) приближается к заданному, а на других... ну кратно короче.

У меня установлено значение 400 символов.
-есть материалы у который действительно тизер близок к этому значению.
-есть материалы у которых он сформирован ну где-то 100-150 символов.
- и уж совсем уникальное попадание, когда тизер был сформирован в 230 символов, причем разрыв текста попал на код двойной кавычки <<
и получилось "тутта некий текст анонса &la" - вот так вот прямо и вывел?

Подскажите где смотреть код формирования тизера, переопределяется ли он (код)?

Комментарии

Аватар пользователя Toologic Toologic 1 марта 2007 в 12:33

Сам себе отвечаю на вопрос... Думаю всем будет полезно.

На api.drupal.org находим... node_teaser

  // The teaser may not be longer than maximum length specified. Initial slice.
  $teaser = truncate_utf8($body, $size);
  $position = 0;
  // Cache the reverse of the teaser.
  $reversed = strrev($teaser);

  // In some cases, no delimiter has been specified. In this case, we try to
  // split at paragraph boundaries.
  $breakpoints = array('</p>' => 0, '<br />' => 6, '<br>' => 4, "\n" => 1);
  // We use strpos on the reversed needle and haystack for speed.
  foreach ($breakpoints as $point => $offset) {
    $length = strpos($reversed, strrev($point));
    if ($length !== FALSE) {
      $position = - $length - $offset;
      return ($position == 0) ? $teaser : substr($teaser, 0, $position);
    }
  }

Вот ответ на первую часть вопроса:
-сначала отрезается текст до указанного размера
-а потом начиная с конца ищем ближайший закрывающий тэг абзаца или принудительный перенос строки

А уж если их не найдено, то ищется ближайшее законченное предложение.

  // When even the first paragraph is too long, we try to split at the end of
  // the last full sentence.
  $breakpoints = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1);
  $min_length = strlen($reversed);
  foreach ($breakpoints as $point => $offset) {
    $length = strpos($reversed, strrev($point));
    if ($length !== FALSE) {
      $min_length = min($length, $min_length);
      $position = 0 - $length - $offset;
    }
  }
  return ($position == 0) ? $teaser : substr($teaser, 0, $position);
}

Что пропущено? Правильно - обработка спецтегов представления текста как то - евро. кавычки, скобки и прочая.

Далее... с абзацами. мне думается надо искать не закрывающий тэг, а наоборот- открывающий. если он есть - то надо просто добавить закрывающий.

Принудительный БР вообще не нужно обрабатывать. Почему это, страшивается тизер может (а по ихнему должен) состоять из
одного абзаца? Уверен что нет!

Как быть? кому писать чтоб переделали.
Если есть спецы в ПХП - напишите плз исправленный код для меня - буду ядро править ))))

Мой сайт
-на drupal 4.7 - www.travelweekly.ru
-на drupal 5 - пока не готов.

Аватар пользователя ShaRP ShaRP 1 марта 2007 в 12:41

Посмотрите на офсайте в модулях - там AFAIR было несколько модулей переформирования тизера. Может, и спецов звать не придется.

Аватар пользователя Krotty@drupal.org Krotty@drupal.org 1 марта 2007 в 12:42

Код формирования тизера - в модуле node.module функция node_teaser.
Тизер режется по , первому параграфу и наконец ограничивающему размеру...

О, уже и сам нашел... Маладца... Smile

Аватар пользователя Toologic Toologic 1 марта 2007 в 13:35

Порылся на оффсайте и вот что нашел!

Оказывается этот вопрос беспокоит не только меня ж)

http://drupal.org/node/115912

node_teaser() is supposed to return 'in a given format', but it only works for PHP evaluator filter
Записано багом от 4 -02-2007

The docs for node_teaser(): say that it will return 'a teaser for a node body in a given format' if a $format is passed to it. However, it only checks $format for the prescene of the PHP eval filter, not others, such as the HTML filter. Shouldn't this work for any generic filter format that is passed in?

Аватар пользователя Valeratal Valeratal 12 марта 2007 в 18:09

Да, excerpt - это скорее для того, чтобы делать тизер отдельно от страницы.

А мне хотелось бы как сделано в трекере

http://www.drupal.ru/tracker

Просто ссылки

Если в трекере так можно, наверно можно и с тизером так сделать?

Аватар пользователя marazmus marazmus 12 марта 2007 в 20:06

Не стоит плодить сущности без нужды! Темизация вывода нодов решит поставленную проблему. Smile

Я не знаю специфики сайта и возможностей пользователя. Поэтому посоветовал views - как наиболее универсальное решение в данной ситуации.

Но если человеку не лень, и он умеет верстать темы - то можно и темизацию поковырять.

Аватар пользователя Natalie Natalie 12 марта 2007 в 20:50

Можно создать отдельное поле для кратенького тизера в ССК, а потом настроить так, чтобы оно не появлялось в полной версии.
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.

Аватар пользователя Valeratal Valeratal 12 марта 2007 в 21:35

Так, товарищи, мне нужно, чтобы было на главной так:
http://www.hr-portal.ru/

С главной я почти разобрался - переделал с помощью view тизер.

Это одна часть проблемы

Другая часть проблемы в том, что если я просматриваю статьи по какому либо термину -то опять таки вылезают тизеры в H2 (так и хочется спросить разрабов, как они себе представляли вывод этак 200 статей).

Вот пока нерешенная для меня проблема.

А что такое темизация вывода нод??

Аватар пользователя Krotty@drupal.org Krotty@drupal.org 13 марта 2007 в 18:11

"Темизация вывода нод" - это изменение темы оформления нода.
Поставленную задачу для plain тем можно решить комментированием всего одной строки выводящей тизер.
<?php
function chameleon_node($node, $teaser = 0, $page = 0) {
$output = "

status) ? ' node-unpublished' : '') ."\">\n";
if (!$page) {
$output .= "

". ($teaser ? l($node->title, "node/$node->nid") : check_plain($node->title)) ."

\n";
}
$output .= "

\n";
if ($teaser && $node->teaser) {
//$output .= $node->teaser; ТИЗЕР НЕ НУЖЕН
}
else {
$output .= $node->body;
}
?>

Для тем основанных на phptemplate добавить одно else...
Теги форматирования сильно искажают код, поэтому ограничусь словесным комментарием - нужно выводить переменную $content только в случае если $page!=0