Olá Pessoal!
Como apresentar soluções para problemas cotidianos, é um dos objetivos deste blog, vou compartilhar com vocês uma solução que escrevi para que vocês possam abreviar um texto, sem cortar qualquer palavra pela metade.
É extremamente chato, quando estamos lendo o resumo de uma notícia e nos deparamos com uma palavra cortada, dificultando a compreensão do texto. É feio, principalmente para a estética do layout.
A maioria das funções escritas (em qualquer linguagem) para abreviar um texto, acabam cortando o texto pela metade. Você passa 2 parâmetros: String Texto e Int Limite.
Texto é o texto própriamente dito, e Limite é o tamanho máximo que o texto deve ocupar. Se o texto for maior que 250 caractéres, o script abrevia o texto sem estourar o limite e sem cortar palavras pela metade, caso contrário, deixa o textocomo está.
A solução que escrevi foi esta:
[php]
public function abreviaString($texto, $limite, $tres_p = ‘…’)
{
$totalCaracteres = 0;
//Retorna o texto em plain/text
$texto = Biblioteca::somenteTexto($texto);
//Cria um array com todas as palavras do texto
$vetorPalavras = explode(" ",$texto);
if(strlen($texto) <= $limite):
$tres_p = "";
$novoTexto = $texto;
else:
//Começa a criar o novo texto resumido.
$novoTexto = "";
//Acrescenta palavra por palavra na string enquanto ela
//não exceder o tamanho máximo do resumo
for($i = 0; $i <count($vetorPalavras); $i++):
$totalCaracteres += strlen(" ".$vetorPalavras[$i]);
if($totalCaracteres <= $limite)
$novoTexto .= ‘ ‘ . $vetorPalavras[$i];
else break;
endfor;
endif;
return $novoTexto . $tres_p;
}
[/php]
Note que eu chamei uma função estática chamada somenteTexto(). Quem quiser o fonte dela e saber como ela está implementada, está ai:
[php]
public static function somenteTexto($string)
{
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip($trans_tbl);
return trim(strip_tags(strtr($string, $trans_tbl)));
}
[/php]
Esta é a solução enviada pelo Carlos André Ferrari nos comentários do blog:
[php]
function abreviaString($texto, $limite, $tres_p = ‘…’) {
//Retorna o texto em plain/text
$texto = Biblioteca::somenteTexto($texto);
if (strlen($texto) <= $limite)
return $texto;
return array_shift(explode(‘||’, wordwrap($texto, $limite, ‘||’))) . $tres_p;
}
[/php]
É importante que, antes de abreviarmos um texto, recebermos o texto puro, livre de tags htmls, scripts ou qualquer outra coisa que não faça parte do texto. Quando isso ocorre, dificulta a abreviação pois o algoritmo não sabe o que é texto e o que é metacaracter.
E é isso aí pessoal, o código está bem comentádo e documentado, caso vocês tenham alguma dúvida, fiquem a vontade para perguntar nos comentários.
Qualquer outra implementação que vocês tenham, que faça a mesma coisa, até mesmo em outras linguagens, o share é totalmente bem-vindo.
[]’s
Igor.
Olá, Igor.
Realmente palavras pela metade ficam bem deselegantes. Porém, creio que a função “wordwrap” do próprio PHP já ajude com isso. O único complemento seria incluir os três pontos, caso ocorreu redução do texto.
Outra solução alternativa que vi recentemente é baseada em CSS 3. Escrevi sobre isso lá no meu blog. A visita é bem vinda:
http://rubsphp.blogspot.com/2011/08/text-overflow.html
A vantagem dela é que o texto é quebrado de acordo com a largura do navegador (e do espaço reservado ao texto), e a quebra fica por conta do próprio navegador realizar.
LikeLike
Olá Rubéns!
O método wordwrap não serve para “abreviar” um texto e sim para forçar a quebra de linha ou algo do gênero.
Utilização boa do wordwrap é quando não queremos que uma palavra muito grande anule o “truncate” automático do browser.
$text = "A very long woooooooooooord.";
$newtext = wordwrap($text, 8, "\n", true);
echo "$newtext\n";
A very
long
wooooooo
ooooord.
A função que eu passo acima ela faz outra coisa.
Ela limpa os metacaracteres da string, corta a atring e quando corta ela não deixa palavras pela metade, entendeu?
LikeLike
sempre usei a wordwrap:
function abreviaString($texto, $limite, $tres_p = ‘…’) {
if (strlen($texto) <= $limite) return $texto;
return array_shift(explode('||', wordwrap($texto, $limite, '||'))) . $tres_p;
}
echo abreviaString('O rato roeu a roupa do rei de roma', 50);
LikeLike
Fala Carlos!
Você está usando o wordwrap para truncar palavras, e este é o propósito da função. A sua solução também é válida, posso agrega-la ao post?
LikeLike
Bem mais inteligente by the way ;D
LikeLike
O problema é se no texto abreviado tiver || também, né? (hehehe)
LikeLike
Parabéns pelos artigos, mas eu cortaria a frase a um limite considerável (depende do layout em questão) e usaria o bom e velho CSS para resolver o problema, assim como o google faz no gMail/gDocs 😀
LikeLike
Eu também faço desta forma, Mike 🙂
Vale lembrar que nem todas as aplicações PHP são web, então, todo snippet é válido 🙂
LikeLike
Puts, é verdade (viajei aqui). Em todo caso, fica a sugestão do text-overflow.
LikeLike
Muito legal cara, vou estudar mais sobre isso. Estou montando um portal no WordPress e um dos problemas que venho enfrentando é sobre isso, definir um número de caracteres não resolveu 100%.
Agora vou ver como consigo aplicar isso no WordPress, tem alguma dica?
Obrigado pelo post de qualquer forma!
LikeLike
claro que pode agregar kra.. nem precisava perguntar.
LikeLike
Eu não sabia como utilizar wordwrap para este fim e sempre fiz de forma semelhante ao que o Igor escreveu, valeu Carlos! Valeu também Igor!
Bruno, o the_excerpt(); do WordPress já faz o efeito previsto neste post, retorna um limite sem cortar palavras.
LikeLike
Sempre vejo os posts do Igor Escobar, ajuda muito quem está iniciando PHP, e esta função aí é super interessante. Valeu Carlos & Igor.
LikeLike
Estou com uma dúvida, estou usando o while do SQL e ele me retorna um erro desse tipo: ” Fatal error: Cannot redeclare abreviaString() (previously declared in..”
LikeLike
vc ta repetindo a função em algum lugar
LikeLike
poxa
que função que me ajudou muito
valeu meu queridão
Att,
Cornélio José Wiedemann ( TI & DBA )
LikeLike