8791 sujets

Développement web côté serveur, CMS

Bonjour à tous,

Je me trouve devant un cas un peu particulier.
D'habitude je tronque mes chaines par rapport à un nombre de caractère (avec ajout des "..." au dernier espace).

Mais là j'ai une div conteneur avec largeur et hauteur fixe, et son contenu peut contenir des saut de ligne "<br />", ce qui fausse totalement le système si je coupe par rapport à un nombre de caractère.

En fait je souhaiterais couper la chaine lorsqu'elle atteint un nombre de ligne défini, sans enlever les sauts de ligne.

Existe-t-il un fonction qui permettrait cela ?

D'après mais recherche, une solution pur CSS n'existe pas : un overflow:hidden seul ne suffit pas car je souhaite avoir les "..." et vu que c'est en mutli-ligne le text-overflow:ellipsis ne fonctionne pas.

En vous remerciant par avance.
Modérateur
Bonjour, le principal problème est que le nombre de lignes peut varier pour un même contenu. Police, taille de police, taille du conteneur, etc.

Il existe des bricoles pour obtenir ce résultat un javascript (en gros tu pourrais ajouter le contenu au fur et à mesure et checker la taille du conteneur...) mais c'est lourd et il vaudrait mieux éviter.

Sinon lorsque tu coupes ou résumes un contenu, le nombre de mot peut éventuellement avoir du sens, mais le nombre de lignes, je vois pas. Comment savoir si il y aura assez de choses dites?

Et tu prend les choses à l'envers. Une mise en page doit mettre en valeur un contenu, là tu souhaites charcuter le contenu pour respecter ta mise en page. Fais simplement en sorte que le visuel rende bien sur une ligne, 2 ou 10.
Merci kustolovic de te pencher sur mon problème.

C'est vrai que c'est un peu particulier comme mise en page, mais là je n'ai pas le choix. C'est pour ça que je suis bloqué car c'est la première fois que je me trouve confronter à ce problème.

En fait c'est pour résumé un article dans un petit bloc, le titre apparait en entier et le texte est coupé.

Pour le nombre de ligne, je le connait car la taille de police, le line-height et la taille du conteneur sont fixes.

Après je suis pas à une ligne près, le texte peut prendre une ligne de moins par sécurité.

J'avais pensé à faire une fonction php qui fonctionne comme un "coupe chaine par rapport au nombre de caractère" mais en attribuant un nombre de caractère aux <br /> (à peu près le nombre de "m" contenu dans une ligne).
Mais je bloque un peu sur la programmation de cette fonction.

Que penses-tu du fonctionnement de cette fonction ?
Salut Smiley cligne

Je pensais à quelque chose comme ça :

a écrit :

Ma chaîne = "text
sans
aucune


balise html";

Nbre de retour = Compter le nombre de retour chariot dans la chaîne (\n | \r)

Si nbre de retour > à ma limite

Alors, je cherche la position de ma limite dans ma chaîne (position extreme = strpos(chaîne, \n, malimite);)
Et je retourne uniquement en partie ma chaine avec mes limites (substr(chaîne, 0, position extreme);)

Ensuite, j'affiche le contenu en faisant le traitement d'affichage

function truncate($string, $limit, $break=' ', $pad='') {
	
	if (mb_strlen($string) <= $limit + mb_strlen($pad))
		return $string;
	
	$string = mb_substr($string, 0, $limit);

	if (false !== ($breakpoint = mb_strrpos($string, $break)))
		$string = mb_substr($string, 0, $breakpoint);

	return trim($string, "\t\n\r\0\x0B ':;,!?.«’").$pad;
}

$texte = truncate($texte, 100, ' ', '…');
Modérateur
leSans rentrer dans les détails de programmation le problème est: que se passe-t-il s'il y a des nouvelles lignes entre les br? De plus ce problème peut empirer si l'utilisateur augmente la taille de police, ou n'utilise simplement celle que tu as définie... Et ceci ne peut pas être prévu en php.
Merci à tous pour vos propositions.

Alors voici ce que j'ai bidouillé, sachant que la taille de police et le line-height sont fixes.


$heightDivText = 200; //hauteur max de la div conteneur calculer en fonction de la hauteur de la photo au dessus

$nbCarNom = strlen($nomActu);
$nbLigneNom = round($nbCarNom / 20); // correspond au titre environ 20 caractères par ligne
$heightNom = $nbLigneNom*16; // le titre a un line-height de 16px

$cible   = array("\r\n", "\n", "\r");
$replace = '<br />';								
$texteActu = str_replace($cible, $replace, $texteActu);
$tabTexteActu = explode("<br />", $texteActu);
$i = 0;
$stop = false;
$nbLigneTexte = 1; // car il y a un <br /> sous le titre
$heightTexte = 0;
$heightTexteOld = 0;
$texteActuCut = "";
while($i < count($tabTexteActu) && $stop == false) {
	$nbLigneTexteTmp = ceil(strlen($tabTexteActu[$i]) / 30); // texte - environ 30 caractères par ligne
	if($nbLigneTexteTmp == 0) $nbLigneTexteTmp = 1; // si la ligne n'est qu'un seul <br />
	$nbLigneTexte += $nbLigneTexteTmp;
	$heightTexte = $nbLigneTexte*14; // le texte a un line-height de 14px
	if($heightNom + $heightTexte + 14 > $heightDivText) { //si la prochaine ligne dépasse
		$stop = true;
		if($heightNom + $heightTexte > $heightDivText) { // si ces lignes dépasse
			$heightRestant = $heightDivText - ($heightNom + $heightTexteOld);
			$ligneRestant = floor($heightRestant / 14);
			$texteActuCut .= strCoupe($tabTexteActu[$i],(($ligneRestant*30) - 5), " (...)");
		} else {
			$texteActuCut .= strCoupe($tabTexteActu[$i],(($nbLigneTexteTmp*30) - 5), " ");
			$texteActuCut .= " (...)";
		}
	} else {
		$texteActuCut .= $tabTexteActu[$i];
		if($i + 1 < count($tabTexteActu)) $texteActuCut .= "<br />";
		$heightTexteOld = $heightTexte;
	}
	$i++;
}


Ca fonctionne pas mal, c'est approximatif bien sûr mais j'ai joué la sécurité et ça me coupe toujours mon texte avant le dépassement, parfois il reste 1 ou 2 lignes vide mais ce n'est pas très grave.

Que pensez-vous de ce bidouillage ?
N'hésitez pas si vous voyez le moyen de l'améliorer ...
Modérateur
Que tu as tort! ^^
a écrit :
sachant que la taille de police et le line-height sont fixes.

Sauf que tu ne le sais pas, l'utilisateur pouvant en changer.
Modifié par kustolovic (09 Mar 2012 - 12:42)
Oui tu as complètement raison, désolé, je me suis très mal exprimé ...

Disons que mon bidouillage fonctionne avec la taille définie à la base.
Juste pour alléger un peu ton code :

<?php
$cible   = array("\r\n", "\n", "\r");

$replace = '<br />';								

$texteActu = str_replace($cible, $replace, $texteActu);
?>


Ca peut se remplacer par :

<?php
$texteActu = nl2br($texteActu);
?>


Pour la fonction nl2br
En fait, cela ne revient pas vraiment à la même chose. Et dans mon cas le replace est important.

La fonction nl2br insère des "<br />" mais ne supprime pas les \n ou \r, et vu que mon calcul se base sur le nombre de caractère (déjà approximatif), je préfère les supprimer.