Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Prikaz skraćene verzije novosti.

[es] :: PHP :: Prikaz skraćene verzije novosti.

[ Pregleda: 2491 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Ilidan13

Član broj: 18118
Poruke: 48
*.adsl.net.t-com.hr.



Profil

icon Prikaz skraćene verzije novosti.17.10.2009. u 09:35 - pre 176 meseci
Pozdrav!
Na sajtu imam napravljeno dodavanje novosti preko Yahoo Rich Text Box-a. On formatira tekst novosti dodavanje html tagova, tako da u bazi pod tekstom novosti imam i dodane odgovarajuće html tagove, tipa <br>, <b> <p>.
E sad, ja želim korisniku prikazati listu novosti na taj način da mu prikažem naslov novosti, i ispod njega odgovarajuću skraćenu verziju teksta novosti (npr. prvih 50 znakova novosti, ili prvih 15 riječi). Tada korisnik može kliknuti na naslov i otvoriti čitavu novost.
Međutim kod prikaza skraćene verzije mi ponekad poremeti čitavu strukturu web stranice, pretpostavljam zbog toga što dohvati dio teksta novosti i samo dio tagova unutar njega, pa ostane poneki ne zatvoreni tag. Zanima me na koji način se to može riješiti?
Hvala!
 
Odgovor na temu

Nemanja Avramović
Engineering Manager
MENU Technologies
Beograd, Srbija

Moderator
Član broj: 32202
Poruke: 4391
77.46.242.*

Sajt: https://avramovic.info


+46 Profil

icon Re: Prikaz skraćene verzije novosti.17.10.2009. u 09:55 - pre 176 meseci
Ja koristim kombinaciju ove dve f-je.

Code:
function close_tags ( $html )
{
    preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result );
    $openedtags = $result[1];

    preg_match_all ( "#</([a-z]+)>#iU", $html, $result );
    $closedtags = $result[1];
    $len_opened = count ( $openedtags );
    if( count ( $closedtags ) == $len_opened )
    {
        return $html;
    }
    $openedtags = array_reverse ( $openedtags );
    for( $i = 0; $i < $len_opened; $i++ )
    {
        if ( !in_array ( $openedtags[$i], $closedtags ) )
        {
            $html .= "</" . $openedtags[$i] . ">";
        }
        else
        {
            unset ( $closedtags[array_search ( $openedtags[$i], $closedtags)] );
        }
    }
    return $html;
}

function elliStr($s,$n) {
    for ( $x = 0; $x < strlen($s); $x++ ) {
        $o = ($n+$x >= strlen($s) ? $s : ($s{$n+$x} == " " ? substr($s,0,$n+$x) . "..." : ""));
        if ( $o != "" ) { return $o; }
    }
}


Moguće je da može i ovako doći do problema, ali teže nego kad ručno to radiš

A ove dve f-je kombinuješ ovako:

Code:
echo close_tags(elliStr($dugacak_text, $duzina));


To će odseći $dugacak_text posle $duzina karaktera, s tim što neće preseći reč na pola već će naći kraj reči i tu će iseći string. Zatim f-ja close_tags() prolazi kroz taj odlomak teksta, nalazi otvorene (a nezatvorene) tagove i zatvara ih.
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
 
Odgovor na temu

Miroslav Ćurčić
ex mVeliki
Novi Sad

Član broj: 19034
Poruke: 1118
*.adsl.eunet.rs.



+19 Profil

icon Re: Prikaz skraćene verzije novosti.17.10.2009. u 16:30 - pre 176 meseci
Sa strip_tags() ukloniš sve tagove iz teksta i to prikažeš.

Pre toga bi trebalo da odradiš $txt= str_replace( '</', ' </', $txt ); što će dodati razmake na spojevima tagova što će tekst učiniti čitkijim.
"The quieter you become, the more you are able to hear."
Blog | PowerCMS
 
Odgovor na temu

Aleksandar Ružičić
Software Architect, Appricot d.o.o.
Beograd

Član broj: 26939
Poruke: 2881

Jabber: krckoorascic@gmail.com
Sajt: krcko.net


+44 Profil

icon Re: Prikaz skraćene verzije novosti.17.10.2009. u 17:49 - pre 176 meseci
evo moje funkcije za to:
Code:

define('XHTML_CHOP_WORDS',            0x00);
define('XHTML_CHOP_CHARS',            0x01);
define('XHTML_CHOP_NO_WORD_BREAK',    0x10);
define('XHTML_CHOP_ELIPSIS_OUT',    0x20);
define('XHTML_CHOP_NO_EMPTY_TAGS',    0x40);
define('XHTML_CHOP_LETTERS',        XHTML_CHOP_CHARS | XHTML_CHOP_NO_WORD_BREAK);

function xhtml_chop($html, $max, $mode = XHTML_CHOP_WORDS, $elipsis = '...') {

    $stack = array();
    $ret = '';
    $total = 0;
    $done = false;

    $nonempty = create_function('$word', 'return !empty($word);');

    $html = preg_replace('/\s+/', ' ', $html);

    while ($html and !$done) {

        if (!preg_match('|<(/?\w+)[^>]*/?>|', $html, $matches, PREG_OFFSET_CAPTURE)) {

            $text = $html;
            $tag = false;

        } else {

            $tag = $matches[0][0];
            $tag_start = $matches[0][1];
            $text = substr($html, 0, $tag_start);
        }

        if ($text) {

            if ($text[0] == ' ') {
                $ret .= ' ';
            }

            if ($mode & XHTML_CHOP_CHARS) {

                $num_chars = strlen($text = trim($text, ' '));

                if ($total + $num_chars > $max) {

                    $done = true;

                    if ($mode & XHTML_CHOP_NO_WORD_BREAK) {

                        $num_chars = $max - $total;
                        $text = substr($text, 0, $num_chars) . preg_replace('/\s.*$/', '', substr($text, $num_chars));

                    } else {
                        $text = rtrim(substr($text, 0, $max - $total));
                    }
                }

                $total += $num_chars;

            } else { // XHTML_CHOP_WORDS

                if (($num_words = count($words = array_filter(explode(' ', $text), $nonempty))) > 0) {

                    if ($total + $num_words > $max) {
                        $done = true;
                        $words = array_slice($words, 0, $max - $total);
                    }

                    $total += $num_words;
                    $text = implode(' ', $words);
                }
            }

            $ret .= $text;
        }

        if (!$tag) {
            break;
        }

        if ($matches[1][0][0] != '/') {
            $stack[] = $matches[1][0];
        } else {

            if (empty($stack) and !$done) {
                $html = substr($html, $tag_start + strlen($tag));
                continue;
            }

            while ($close_tag = array_pop($stack)) {
                if (strtolower($close_tag) == strtolower(substr($matches[1][0], 1))) {
                    break;
                } else {
                    $ret .= "</$close_tag>";
                }
            }
        }

        if ($tag_start and $html[$tag_start - 1] == ' ') {
            $ret .= ' ';
        }

        $ret.= $tag;
        $html = substr($html, $tag_start + strlen($tag));
    }

    if ($mode & XHTML_CHOP_NO_EMPTY_TAGS and substr(rtrim($ret, ' '), -1) == '>') {
        array_pop($stack);
        $ret = substr($ret, 0, strrpos($ret, '<'));
    }

    if ($done and ~$mode & XHTML_CHOP_ELIPSIS_OUT) {
        $ret .= $elipsis;
    }

    if (!empty($stack)) {

        $self_closing = array('img', 'input', 'br', 'hr', 'link', 'base', 'meta');

        while ($tag = array_pop($stack)) {
            if (!in_array(strtolower($tag), $self_closing)) {
                $ret .= "</$tag>";
            }
        }
    }

    if ($done and $mode & XHTML_CHOP_ELIPSIS_OUT) {
        $ret .= $elipsis;
    }

    return $ret;
}

"duza" je od Nemanjine, ali zato pri brojanju uzima samo text u obzir, ne i markup. takodje je moguce birati izmedju broja reci (sto je preferiram) ili broja karaktera (sa opcijom da se ne dozvoli secenje reci)...

ja je koristim vec dugo (napisao sam je upravo iz istog razloga: trebala mi je fja koja ce neki html iseci na odredjeni broj reci s tim da se markup zadrzi koliko god je moguce) i nisam nailazio na probleme sa njom. ako joj se prosledi validan xhtml, validan ce i vratiti...
 
Odgovor na temu

Ilidan13

Član broj: 18118
Poruke: 48
*.adsl.net.t-com.hr.



Profil

icon Re: Prikaz skraćene verzije novosti.18.10.2009. u 12:44 - pre 176 meseci
Super. Zahvaljujem svima na odgovoru. Ostaje mi samo još da malo proučim ove funkcije i odlučim koja mi najbolje odgovara.
Hvala još jednom.
 
Odgovor na temu

[es] :: PHP :: Prikaz skraćene verzije novosti.

[ Pregleda: 2491 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.