Универсальный код для подстановки тега <!--more-->

Тема в разделе "PHP", создана пользователем System777, 18 ноя 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. System777

    System777 Создатель

    Регистр.:
    20 апр 2008
    Сообщения:
    30
    Симпатии:
    13
    Кто знаком с WordPressом - вероятно слышал о такой вещи как тег "<!--more-->" - который ставится для отделения анонса поста во всём тексте.

    Задача стоит следующая: всякие статьи парсятся с разных источников, а потом публикуются на Wordpress-блоге. И моему PHP-скрипту нужно автоматически проставлять тег <!--more--> после заданного абзаца (например, 2 или 3го, чтобы только это ограниченное число абзацев было в анонсе).

    Сложность в том, что:

    - попадаются теги как <p>, так и <P> (и в перемешку на одной странице - тоже).

    - также закрывающий тег </p> или </P> не всегда имеется на странице, а только <p>

    - возможны варианты отделения вообще только <br> или </ br>, а также другие виды тега <p> - <P align="center"> к примеру.

    Нужно в любом из этих случаях проставлять тег more после заданного абзаца.

    Подразумевается, что код уже обработан от лишних мусорных тегов (вроде <table>) с помощью strip_tags - оставлены только <b><i><img><p><br><strong><em>)

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

    Заранее благодарю.
     
  2. ZCFD

    ZCFD

    Регистр.:
    16 янв 2008
    Сообщения:
    989
    Симпатии:
    437
    Я делал так

    -strip_tags()
    - убираю ишние пробелы
    - explode(". Эбююю) - т.е. по концу предложения
    - implode(". ", случайного числа элементов ( от 4 до 5 )

    Т.е. в анонс выводится случайное число предложений из начала текста, обычно вполне приемлемый результат

    PS разве что ( хз как в WORDPress ) лучше делать так , что бы после тега выводился ПОЛНЫЙ текст , но без анонса
     
    System777 и valkiriy нравится это.
  3. System777

    System777 Создатель

    Регистр.:
    20 апр 2008
    Сообщения:
    30
    Симпатии:
    13
    Идея, в принципе, интересная, спасибо.

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

    Поэтому зацепка с тегами абзаца <p> - вроде более подходящая, так как совсем не гут будет, если в анонсе будут обрывки в предложении. Ну, и впрочем, анонс абзацев больше похож на анонс от "человека", а не от машины, что также важно...
     
  4. ZCFD

    ZCFD

    Регистр.:
    16 янв 2008
    Сообщения:
    989
    Симпатии:
    437
    1) разбивка не по точке. А по точке и пробелу ( при нормальном наборе это правило типографики обычно сохраняется). Этим отсекаются многоточия, числа и т.д. т.е. ". " - пробел важен
    2) если придложение заканчивается на другой знак - что ж , в анонсе просто будет больше предложений, больше ничего не изменится

    недостатки есть, посто в описанной тобой задаче рабивка по тегам слишком многовариантна
     
  5. zetar

    zetar

    Регистр.:
    18 май 2007
    Сообщения:
    497
    Симпатии:
    348
    вот готовое решение

    http://blog.portal.kharkov.ua/2008/05/10/auto_more_3/

    PS
    и еще у самого wp есть балансировка тагов
    для получения правильного текста
    PHP:
    $text balanceTags($text,$force=false);
     
    System777 нравится это.
  6. System777

    System777 Создатель

    Регистр.:
    20 апр 2008
    Сообщения:
    30
    Симпатии:
    13
    Насчёт цифр согласен, а вот в ситуации (насчёт сокращений:(

    "Если оплатить 180р. за эту книгу, то..."

    Здесь порезка будет после р. - вот я имею ввиду как раз то, что в анонсе может быть оборванное предложение (причём подобные сокращения есть и в нормальных текстах), что нередко может искажать серьёзно вид блога... ;)

    Понятно. Впрочем с тегами не так уж много вариантов - только p и br - просто, думаю, наверное вначале приводить их все к единому регистру, формату (путём того же str_replace)

    А чтобы не цеплять атрибуты, к примеру, для <p> использовать просто <p - и всё.

    Вообщем попробую что-то на основе всех этих данных что-то "склеить". За советы всем выражаю благодарность.
     
  7. kud

    kud Постоялец

    Регистр.:
    18 фев 2009
    Сообщения:
    89
    Симпатии:
    11
    я делаю следующим образом:
    1) Вырезаем все теги в тексте
    2) Разбиваем текст на предложения следующим образом:
    PHP:
    <?php preg_match_all("#(.+)(?<!([a-z0-9])+)\.(?!([a-z0-9а-я])+)#Usi",$text,$out); ?>
    3) Обертываем полученные предложения в абзацы, например 20% предложений = 1 абзац:
    PHP:
    <?php
    if (!empty($out[0])) {
        
    $total count($out[0]);
        
    $need_one ceil(20*$total/100);
        
    $text '<p>';
        for (
    $st 0$st $total$st++) {
            
    $text .= $out[0][$st-1];
            if ((
    $st+1) % $need_one == $text .= '</p>' "\n" '<p>';
        }
        
    $text .= '</p>';
    }
    // удаляем пустые абзацы
    $text preg_replace("#<p></p>#Usi","",$text);
    ?>
    4. Ну а, последнее, как превью показываем первый абзац, то есть, тавим тег more после первого абзаца:
    PHP:
    <?php
    $text 
    preg_replace("#</p>[\s]*<p>#Usi","</p><!--more--><p>",$text,1);
    ?>
    Впринципе, можно доработать и рендомно ставить размер превью в зависимости от кол-ва предложений ..
     
    System777 нравится это.
Статус темы:
Закрыта.