Dotclear

Vous n'êtes pas identifié(e).

Annonce

13 février 2024 Sortie de Dotclear 2.29

#1 2010-08-06 14:29:03

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Méthode cutString

Bonjour

Je voudrais afficher un extrait d'un billet au format html. J'ai essayé d'utiliser text::cutString mais forcément la fonction me coupe les balises html.

Est-ce que quelqu'un sait comment couper le contenu d'un billet html ? En fait, je pense qu'il me faudrait utiliser un genre de "parser" qui me validerait le code et supprimerait ce qui ne va pas ?

Si quelqu'un a une idée pour me débloquer ?

@++

Hors ligne

#2 2010-08-06 15:02:58

Philippe
Stagiaire
Lieu : Toulon
Inscription : 2004-06-13
Site Web

Re : Méthode cutString

Dans une balise de template, cut_string doit être utilisé avec remove_html.

Si c'est une fonction personnelle, il te faut auparavant filtrer la chaîne avec php pour supprimer les balises html

Hors ligne

#3 2010-08-06 15:41:42

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Re : Méthode cutString

En fait, c'est dans une fonction du plugin newsletter, j'ai déjà un extrait au format texte qui fonctionne très bien. Par contre, je voudrais permettre d'extraire un aperçu des billets en html et conserver la mise en forme html de la partie récupérée. J'arrive à extraire le contenu du post en entier mais ça fait un peu gros dans un mail :p

Hors ligne

#4 2010-08-09 08:14:54

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Re : Méthode cutString

Je reviens là-dessus :p

En fait, ce que je cherche, c'est une fonction qui me parse un contenu html et qui me ferme les balises manquantes. Est-ce qu'on a ça au sein de Dotclear où il faut que j'aille chercher une librairie externe ?

Hors ligne

#5 2010-08-09 10:30:40

Philippe
Stagiaire
Lieu : Toulon
Inscription : 2004-06-13
Site Web

Re : Méthode cutString

Tu peux essayer d'utiliser ce script en faisant un strip_tags sur la chaîne avant

Hors ligne

#6 2010-08-09 10:45:32

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Re : Méthode cutString

Merci pour le conseil mais c'est toujours un extrait au format texte que j'ai déjà.

En fait, j'ai fait ça qui me valide l'html via tidy qui est appelé par htmlFilter. (extrait de code que j'ai trouvé dans les librairies Dotclear)

$news_content = context::cut_string($news_content,$taille);
$filter = new htmlFilter;
$news_content = trim($filter->apply($news_content));

Par contre, certains tags ne sont pas traités comme le strong qui n'est pas fermé s'il manque le tag de fermeture.
Je laisse comme ça tant que je n'ai pas trouvé mieux ;)

Hors ligne

#7 2010-08-09 11:02:32

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Pourrais-tu indiquer le code complet utilisé ? Cela m'intéresserait également.
Il s'agit d'une nouvelle fonction que tu as créée dans le _public.php du thème ?

Hors ligne

#8 2010-08-09 11:25:05

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Re : Méthode cutString

fix a écrit :

Pourrais-tu indiquer le code complet utilisé ? Cela m'intéresserait également.
Il s'agit d'une nouvelle fonction que tu as créée dans le _public.php du thème ?

Aucun rapport avec un quelconque thème, je maintiens le code du plugin newsletter et ceci est un extrait au milieu du code du plugin.

Hors ligne

#9 2010-08-09 12:33:53

Moe
Responsable du mini-bar
Lieu : France
Inscription : 2004-09-19
Site Web

Re : Méthode cutString

Hors ligne

#10 2010-08-09 12:51:53

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Re : Méthode cutString

Moe a écrit :

Sympa la fonction ;) Je vais essayer de me l'adapter pour fonctionner aussi avec la longueur de la chaine.
Merci :)

Hors ligne

#11 2010-08-09 16:10:36

Moe
Responsable du mini-bar
Lieu : France
Inscription : 2004-09-19
Site Web

Re : Méthode cutString

Tu ne veux pas l'utiliser après avoir coupé la chaîne avec cut_string() ?

Hors ligne

#12 2010-08-09 16:49:01

kwon
Membre
Lieu : Bordeaux
Inscription : 2006-08-05
Site Web

Re : Méthode cutString

Euh ça y est j'ai déjà mis ça dans une fonction cut_html_string qui normalement va couper la chaine au mot prêt et fermer la balise qui va bien.

Mais c'est vrai que ça va parcourir un mot (et s'il est long, ça risque de retourner une grande chaine ...). Je vais voir pour suivre ton conseil et ajouter l'utilisation du cut_string.

Hors ligne

#13 2010-08-26 12:58:40

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

J'ai voulu reprendre l'idée de réutiliser la fonction indiquée par Moe ci-dessus, mais le succès n'est pas au rendez-vous : les balises sont affichées comme du texte, au lieu d'être "interprétées". Autrement dit, au lieu d'afficher un paragraphe si le texte est contenu dans une balise <p>, le navigateur affiche "<p>mon texte</p>"...

Voici ce que j'ai fait : j'ai commencé par copier/coller la fonction dans le _public.php du thème, en supprimant ce qui concerne le comptage du nombre de mots (qui m'est inutile), ce qui donne :

public static function text_cut($attr,$content)
	{
		static $tags = array ('div', 'span', 'b', 'u', 'i', 'a', 'ul', 'li');
		$pos = 0;
		$str_len = strlen($content);
		$str = $content.' <';
		$open_tags = array ();
		
		while ($pos < $str_len) {
			$pos = min(strpos($str, ' ', $pos), strpos($str, '<', $pos));
			if ($str[$pos] == '<') {
				if ($str[$pos + 1] == '/') {
					array_pop($open_tags);
				} else {
					$sub = substr($str, $pos + 1, min(strpos($str, ' ', $pos), strpos($str, '>', $pos)) - $pos - 1);
					if (in_array($sub, $tags)) { array_push($open_tags, $sub); }
				}
				$pos = strpos($str, '>', $pos) + 1;
			} else {
				$pos++;
			}
		}
		
		$str = substr($str, 0, $pos);
		
		if (count($open_tags) > 0) {
			foreach($open_tags as $value) { $str .= '</' . array_pop($open_tags) . '>'; }
		}
		
		return $str;
	}

Et j'appelle cette fonction grâce à :

<tpl:text_cut>{{tpl:EntryContent encode_html="1" cut_string="300"}}</tpl:text_cut>...

Où ai-je fait fausse route ?

Hors ligne

#14 2010-08-26 13:13:32

Moe
Responsable du mini-bar
Lieu : France
Inscription : 2004-09-19
Site Web

Re : Méthode cutString

Peux-tu donner le code complet avec la déclaration de la balise pour qu'on puisse essayer ?

À première vue, je pense qu'il faudrait créer une fonction calquée sur {{tpl:EntryContent}} qui récupère le contenu du billet pour ensuite le couper. Il doit même être possible de modifier la fonction {{tpl:EntryContent}} pour lui ajouter le paramètre que tu veux, à la volée. Il me semble que Dsls arrive à faire ce genre de modifications.

Hors ligne

#15 2010-08-26 13:28:20

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Peux-tu donner le code complet avec la déclaration de la balise pour qu'on puisse essayer ?

Il me semble qu'il est complet :) Pour déclarer la balise, il suffit d'ajouter ceci avant :

<?php
$core->tpl->addBlock('text_cut', array('tplMyThemeAdditions', 'text_cut'));
class tplMyThemeAdditions {

Et on ferme avec '} ?>' après le code...

Moe a écrit :

Il me semble que Dsls arrive à faire ce genre de modifications.

Mais que n'arrive-t-il pas à faire ??? :)

Bon je vais suivre ton conseil et aller voir du côté de EntryContent... à moins que Dsls ne passe par là, et n'indique comment modifier cette fonction à la volée, sans la dupliquer :)

Hors ligne

#16 2010-08-26 13:29:27

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

La première balise code du message précédent est une erreur, bien sûr :) A moins que Moe et les autres modérateurs de ce forum ne soient que des machines à coder ???

Hors ligne

#17 2010-08-26 14:01:03

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Bon, ça n'a pas l'air si simple... (Si kwon passe par ici, peut-être pourrait-il partager sa solution ?)

Voici le problème : la balise EntryContent affiche le contenu du billet grâce au code suivant (simplifié) :

$f = $this->getFilters($attr);
return '<?php echo '.sprintf($f,'$_ctx->posts->getContent('.$urls.')').'; ?>';

L'ennui, c'est que cela n'est pas réutilisable dans une fonction du _public.php : le code suivant ne fonctionne pas, par exemple :

$str = sprintf($f,'$_ctx->posts->getExcerpt()." ".$_ctx->posts->getContent()');

Une telle ligne, en effet, afficherait sur le blog le texte "context::global_filter($_ctx->posts->getExcerpt()."".$_ctx->posts->getContent(),1,0,500,0,0,'text_cut')" au lieu d'attribuer le contenu du billet à la variable $str...

Hors ligne

#18 2010-08-26 14:07:09

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Un simple $str = $_ctx->posts->getExcerpt($attr)." ".$_ctx->posts->getContent($attr); est peut-être possible, ceci dit...

M'en vais tester ça...

Hors ligne

#19 2010-08-26 14:12:40

Dsls
Modérateur couteau-suisse
Inscription : 2004-11-18
Site Web

Re : Méthode cutString

fix: ton code ne fonctionnera pas, car le $content que tu vas récupérer sera du code php, et tu vas donc couper du code php...

J'allais te proposer de définir un vrai filtre, mais visiblement ce n'est pas possible en l'état (encore un ticket que je vais ouvrir sur le core, tiens).

Du coup je propose une alternative, qui passe par une définition d'alias vers EntryContent :

<?php

$core->tpl->addBlock('TrunkedEntryContent',array('MyFilter','EntryContent'));

$core->addBehavior('publicAfterContentFilter',array('MyFilter','afterContentFilter'));

class MyFilter {
	public static function text_cut($content)
	{
		static $tags = array ('div', 'span', 'b', 'u', 'i', 'a', 'ul', 'li');
		$pos = 0;
		$str_len = strlen($content);
		$str = $content.' <';
		$open_tags = array ();
		
		while ($pos < $str_len) {
			$pos = min(strpos($str, ' ', $pos), strpos($str, '<', $pos));
			if ($str[$pos] == '<') {
				if ($str[$pos + 1] == '/') {
					array_pop($open_tags);
				} else {
					$sub = substr($str, $pos + 1, min(strpos($str, ' ', $pos), strpos($str, '>', $pos)) - $pos - 1);
					if (in_array($sub, $tags)) { array_push($open_tags, $sub); }
				}
				$pos = strpos($str, '>', $pos) + 1;
			} else {
				$pos++;
			}
		}
		
		$str = substr($str, 0, $pos);
		
		if (count($open_tags) > 0) {
			foreach($open_tags as $value) { $str .= '</' . array_pop($open_tags) . '>'; }
		}
		
		return $str;
	}
	
	public static function afterContentFilter ($core,$tag,$args) {
		if ($tag == 'TrunkedEntryContent') {
			$args[0] = self::text_cut($args[0]);
		}
	}
	
	
	public static function EntryContent($attr) {
		return $GLOBALS['core']->tpl->EntryContent($attr);
	}
}

?>

(non testé, ça reste à mettre au point)


Dyslexics have more fnu!

Hors ligne

#20 2010-08-26 14:26:24

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Merci de t'être penché sur le problème !

Je dois bien appeler la fonction de la manière suinte ?

<tpl:text_cut>{{tpl:EntryExcerpt encode_html="1" cut_string="500"}}</tpl:text_cut>

En l'état, ça affiche "object", et c'est tout :)

Hors ligne

#21 2010-08-26 14:27:25

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Inutile de chercher *suinte* dans le dico. C'est *suivante*...

Hors ligne

#22 2010-08-26 14:28:29

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Au fait, tous mes test sont visibles ici.

Hors ligne

#23 2010-08-26 14:49:26

Dsls
Modérateur couteau-suisse
Inscription : 2004-11-18
Site Web

Re : Méthode cutString

fix a écrit :
<tpl:text_cut>{{tpl:EntryExcerpt encode_html="1" cut_string="500"}}</tpl:text_cut>

En l'état, ça affiche "object", et c'est tout :)

Avec mon code, c'est plutôt ça :

{{tpl:TrunkedEntryExcerpt encode_html="1" cut_string="500"}}

(et remplacer EntryContent par EntryExcerpt dans le code que j'ai fourni)


Dyslexics have more fnu!

Hors ligne

#24 2010-08-26 15:03:08

fix
Membre
Inscription : 2005-01-20
Site Web

Re : Méthode cutString

Dans ce cas, ça n'affiche plus rien :) Plus précisément, le contenu des billets est comme vide (il s'agit du carrousel en haut à gauche)...

... d'autre part, si l'on veut une fonction "TrunkedEntryExcerpt" en plus de "TrunkedEntryContent", il suffit de dupliquer et modifier le nouvel "EntryContent" ?

Hors ligne

#25 2010-08-26 15:12:46

Dsls
Modérateur couteau-suisse
Inscription : 2004-11-18
Site Web

Re : Méthode cutString

Le code qui fonctionne mieux :

$core->tpl->addValue('TrunkedEntryContent',array($core->tpl,'EntryContent'));
$core->tpl->addValue('TrunkedEntryExcerpt',array($core->tpl,'EntryExcerpt'));

$core->addBehavior('publicAfterContentFilter',array('MyFilter','afterContentFilter'));

class MyFilter {

	public static function text_cut($content)
	{
		static $tags = array ('div', 'span', 'b', 'u', 'i', 'a', 'ul', 'li');
		$pos = 0;
		$str_len = strlen($content);
		$str = $content.' <';
		$open_tags = array ();
		
		while ($pos < $str_len) {
			$pos = min(strpos($str, ' ', $pos), strpos($str, '<', $pos));
			if ($str[$pos] == '<') {
				if ($str[$pos + 1] == '/') {
					array_pop($open_tags);
				} else {
					$sub = substr($str, $pos + 1, min(strpos($str, ' ', $pos), strpos($str, '>', $pos)) - $pos - 1);
					if (in_array($sub, $tags)) { array_push($open_tags, $sub); }
				}
				$pos = strpos($str, '>', $pos) + 1;
			} else {
				$pos++;
			}
		}
		
		$str = substr($str, 0, $pos);
		
		if (count($open_tags) > 0) {
			foreach($open_tags as $value) { $str .= '</' . array_pop($open_tags) . '>'; }
		}
		
		return $str;
	}
	
	public static function afterContentFilter ($core,$tag,$args) {
		if (substr($tag,0,7)== 'Trunked') {
			$args[0]=self::text_cut($args[0]);
		}
	}
}

Dyslexics have more fnu!

Hors ligne

Vous n'êtes pas identifié(e).

Pied de page des forums

Sites map