Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 4 odgovora
  • 3.336 pregleda

Najnovija ↓

Prikaz skraćene verzije novosti. 17.10.2009. u 10:35 · pre 207 meseci #1
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!
Re: Prikaz skraćene verzije novosti. 17.10.2009. u 10:55 · pre 207 meseci #2
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.
Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Prikaz skraćene verzije novosti. 17.10.2009. u 17:30 · pre 207 meseci #3
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.
Potpis
"The quieter you become, the more you are able to hear."
Blog | PowerCMS
Re: Prikaz skraćene verzije novosti. 17.10.2009. u 18:49 · pre 207 meseci #4
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...
Potpis
rafforum.rs - Forum Računarskog Fakulteta
Re: Prikaz skraćene verzije novosti. 18.10.2009. u 13:44 · pre 207 meseci #5
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.
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme