web-dev-qa-db-fra.com

Existe-t-il une méthode tronquée HTML sûre dans Rails?

J'ai une chaîne de code HTML dans Rails. J'aimerais tronquer la chaîne après un certain nombre de caractères n'incluant pas le balisage HTML. De plus, si la scission tombe au milieu d'une balise d'ouverture et de fermeture, j'aimerais fermer la/les balises ouvertes. Par exemple;

html = "123<a href='#'>456</a>7890"
truncate_markup(html, :length => 5) --> "123<a href='#'>45</a>"
39
Jesse Hattabaugh

Il existe deux solutions complètement différentes portant le même nom: truncate_html

  1. https://github.com/ianwhite/truncate_html : Ceci est un joyau utilisant un analyseur HTML (nokogiri)
  2. https://github.com/hgmnz/truncate_html : Ceci est un fichier que vous avez mis dans votre répertoire helpers. Il utilise des expressions régulières et n'a pas de dépendances.
34
gdelfino

la fonction truncate normale fonctionne correctement, il suffit de passer :escape => false comme option pour conserver le code HTML intact. par exemple:

truncate(@html_text, :length => 230, :omission => "" , :escape => false)

RubyOnRails.org

* Edit Je n'ai pas lu la question très attentivement (ou pas du tout TBH), donc cette réponse ne résout pas cette question ... Elle IS la réponse que je cherchais mais si tout va bien, cela aide 1 ou 2 personnes :)

76
msanteler

Vous devriez résoudre ce problème avec CSS plutôt que Ruby. Vous faites quelque chose qui affecte la disposition du DOM, et il n'existe aucun moyen de concevoir par programme une solution qui fonctionnera de manière cohérente.

Supposons que votre joyau de l’analyseur HTML fonctionne et que vous trouviez le plus petit nombre de caractères de dénominateur commun qui fonctionne la plupart du temps.

Que se passe-t-il si vous modifiez la taille des polices ou la présentation de votre site? Vous devrez recalculer le nombre de caractères à nouveau.

Ou supposons que votre code HTML contienne quelque chose comme ceci: <p><br /></p><br /> C'est zéro caractère, mais cela entraînerait l'insertion d'un gros bloc de texte vierge. Il pourrait même s'agir d'une balise <blockquote> ou <code> avec trop de remplissage ou de marge pour que votre mise en page soit complètement fausse.

Ou l'inverse, supposons que vous avez ce 3&nbsp;&#8773;&nbsp;&#955; (3 ≅ λ), qui compte 26 caractères, mais pour l'affichage, ce n'est que 5.

L'important étant que le nombre de caractères ne vous indique pas comment quelque chose va être rendu dans le navigateur. Sans parler du fait que les analyseurs syntaxiques HTML sont de gros morceaux de code qui peuvent parfois être peu fiables.

Voici un bon CSS pour gérer cela. La pseudo-classe: after ajoutera un fondu blanc à la dernière ligne du contenu. Très belle transition.

body { font-size: 16px;}
p {font-size: 1em; line-height: 1.2em}
/* Maximum height math is:
   line-height * #oflines - 0.4
   the 0.4 offset is to make the cutoff  look nicer */
.lines-3{height: 3.2em;}
.lines-6{height: 6.8em;}
.truncate {overflow: hidden; position:relative}
.truncate:after{
    content:""; 
    height: 1em; 
    display: block; 
    width: 100%; 
    position:absolute;
    background-color:white; 
    opacity: 0.8; 
    bottom: -0.3em
}

Vous pouvez ajouter autant de classes .lines-x que vous le souhaitez. J'ai utilisé em mais px est tout aussi bien.

Appliquez ensuite ceci à votre élément: <div class="truncate lines-3">....lots of stuff.. </div>

et le violon: http://jsfiddle.net/ke87h/

15
mastaBlasta

Vous pouvez utiliser le plugin truncate_html pour cela. Il utilise nokogiri et htmlentities gems et fait exactement ce que le nom du plugin suggère.

6
Mark

Cela vous aidera sans effort supplémentaire

raw your_string.truncate(200)
3
Asnad Atta

Nous avions ce besoin sur zendone.com. Le problème était que les solutions existantes étaient très lentes lorsque l'on tronçonnait des documents HTML longs (MB) en documents plus courts (KB). J'ai fini par coder une bibliothèque basée à Nokogiri appelée truncato . La bibliothèque comprend quelques repères comparant ses performances avec d’autres bibliothèques.

1
jmanrubia

Vous pouvez utiliser 

truncate(html.gsub(/(<[^>]+>)/, ''), 5)
1
priyanka Ukirde

Nous pouvons le faire avec l'aide de simple_format http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format

html = "123<a href='#'>456</a>7890"
simle_format(truncate_markup(html, :length => 5)) 

=> "123 456 7890"

0
Vijay Chouhan