Vous n'êtes pas identifié(e).
13 février 2024 Sortie de Dotclear 2.29
Bonjour,
j'ai un problème un peu similaire à cette discussion (http://forum.dotclear.org/viewtopic.php?id=47798), mais je ne cherche pas seulement à modifier le contenu, mais également certains aspects comme le tri des entrées selon la catégorie. Du coup je ne peux pas me contenter de l'imbrication suivante dans category.html :
<tpl:Entries>
<tpl:CategoryIf url="Formations">
{{tpl:include src="_entry-short-listFormations.html"}}
</tpl:CategoryIf>
<tpl:CategoryParents>
<tpl:CategoryIf url="Eleveurs">
{{tpl:include src="_entry-short-listEleveurs.html"}}
</tpl:CategoryIf>
</tpl:CategoryParents>
<tpl:CategoryIf url="!Formations">
<tpl:CategoryParents>
<tpl:CategoryIf url="!Eleveurs">
{{tpl:include src="_entry-short.html"}}
</tpl:CategoryIf>
</tpl:CategoryParents>
</tpl:CategoryIf>
</tpl:Entries>
En clair : si la catégorie est Formations, j'affiche selon un certain tpl, si la cat est un enfant de Eleveurs, un autre, et pour les autres cas le mode par défaut (bon, il est relou mon mode par défaut vu qu'il manque un tpl:Else dans le langage ;-)
Ça ne marche que si <tpl:Entries> englobe mes tests. Cela ne me permet donc pas de jouer sur les possibilités que m'offre cette balise, comme age="-2 months" ou sortby="title" que j'ai également besoin de modifier selon la catégorie affichée.
Je peux faire :
<tpl:CategoryIf url="Formations">
<tpl:Entries>
{{tpl:include src="_entry-short-listFormations.html"}}
</tpl:Entries>
</tpl:CategoryIf>
une fois. Mais si je les imbrique à plusieurs reprises dans mes CategoryIf, ça ne fonctionne plus.
J'ai essayé de sortir le test du fichier : créé _category.html à partir de category.html, et dans category.html j'importe simplement _category.html
Au préalable dans _category.html j'ai créé un block de template au niveau de l'affichage des billets : <tpl:Block name="cat-content'>
Dans catégorie.html j'ai essayé de faire mes tests et d'appeler un template de liste qui se charge d'écrire le <tpl:Block "cat-content">, ça marche pas mieux.
Bref, je tourne en rond, peut-être bien parce que je ne m'y prends pas dans l'ordre. P'têt faudrait simplement jouer à mettre l'histoire en plugin, mais j'étais pas parti pour ça au début...
Merci pour vos lumières.
Michel
Dernière modification par vertacoo (2016-03-19 01:19:21)
Hors ligne
S'il s'agit de trier différemment les billets en fonction des catégories, j'ai développé un petit plugin qui s'occupe de ça → http://plugins.dotaddict.org/dc2/details/catOrder
Peut-être qu'il suffit ?
Dotclear addicted since 2004
Hors ligne
Pour ma part, j'ai ajouté dans le _public.php du thème ce bout de code :
$core->addBehavior('urlHandlerBeforeGetData',array('mybehaviors','altCategoryTpl'));
function CleanText($txt)
{
$old = array('à','á','â','ã','ä','å','ò','ó','ô','õ','ö','ø','é','è','ê','ë','ç','ì','í','î','ï','ù','ú','û','ü','ÿ','ñ',' ');
$new = array('a','a','a','a','a','a','o','o','o','o','o','o','e','e','e','e','c','i','i','i','i','u','u','u','u','y','n','');
return str_replace($old, $new, $txt);
}
class mybehaviors
{
public static function altCategoryTpl($_ctx)
{
global $core;
if ($_ctx->current_tpl == "category.html") {
$tpl = 'category-'.$_ctx->categories->cat_id.'.html';
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
} else {
$tpl = 'category-'.CleanText(mb_strtolower($_ctx->categories->cat_title)).'.html';
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
}
}
}
}
}
Usage :
altCategoryTpl
permet l'utilisation d'un fichier de contexte différent de category.html.
Le nom du fichier devra être...
- de la forme category-xxx.html (xxx = ID de la catégorie)
- de la forme category-zzz.html (zzz = nom de la catégorie en minuscules, sans espaces, ni caractères accentués).
Si category-xxx.html n'existe pas, alors recherche de la présence de category-zzz.html.
Si aucun de ces 2 fichiers n'existe, alors le contexte standard sera utilisé.
Ce qui me permet de proposer des fichiers template spécifiques à certaines de mes catégories...
Le B.A.BA : https://abc.dotaddict.org
La doc DC2 : https://fr.dotclear.org/documentation/2.0
Mes extensions : https://www.mirovinben.fr/blog/index.ph … pluginsDC2
Mes marqueurs de template : https://www.mirovinben.fr/blog/index.php?post/id3553
Hors ligne
Autre solution, bricolée par Pep
#Bricoland code for category and posts templates according to cat_id
$core->url->register('category','category','^category/(.+)$',array('myURLHandlers','category'));
$core->url->register('post','post','^post/(.+)$',array('myURLHandlers','post'));
$core->url->register('preview','preview','^preview/(.+)$',array('myURLHandlers','preview'));
class myURLHandlers extends dcUrlHandlers
{
public static function category($args)
{
$_ctx =& $GLOBALS['_ctx'];
$core =& $GLOBALS['core'];
$n = self::getPageNumber($args);
if ($args == '' && !$n) {
self::p404();
}
$params['cat_url'] = $args;
$params['post_type'] = 'post';
$_ctx->categories = $core->blog->getCategories($params);
if ($_ctx->categories->isEmpty()) {
self::p404();
} else {
if ($n) {
$GLOBALS['_page_number'] = $n;
}
$tpl = 'category-'.$_ctx->categories->cat_id.'.html';
if (!$core->tpl->getFilePath($tpl)) {
$tpl = 'category.html';
}
self::serveDocument($tpl);
exit;
}
}
public static function post($args)
{
if ($args == '') {
self::p404();
}
$_ctx =& $GLOBALS['_ctx'];
$core =& $GLOBALS['core'];
$core->blog->withoutPassword(false);
$params = new ArrayObject();
$params['post_url'] = $args;
$_ctx->posts = $core->blog->getPosts($params);
$_ctx->comment_preview = new ArrayObject();
$_ctx->comment_preview['content'] = '';
$_ctx->comment_preview['rawcontent'] = '';
$_ctx->comment_preview['name'] = '';
$_ctx->comment_preview['mail'] = '';
$_ctx->comment_preview['site'] = '';
$_ctx->comment_preview['preview'] = false;
$_ctx->comment_preview['remember'] = false;
$core->blog->withoutPassword(true);
if ($_ctx->posts->isEmpty())
{
# No entry
self::p404();
}
$post_id = $_ctx->posts->post_id;
$post_password = $_ctx->posts->post_password;
# Password protected entry
if ($post_password != '')
{
# Get passwords cookie
if (isset($_COOKIE['dc_passwd'])) {
$pwd_cookie = unserialize($_COOKIE['dc_passwd']);
} else {
$pwd_cookie = array();
}
# Check for match
if ((!empty($_POST['password']) && $_POST['password'] == $post_password)
|| (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] == $post_password))
{
$pwd_cookie[$post_id] = $post_password;
setcookie('dc_passwd',serialize($pwd_cookie),0,'/');
}
else
{
self::serveDocument('password-form.html','text/html',false);
exit;
}
}
$post_comment =
isset($_POST['c_name']) && isset($_POST['c_mail']) &&
isset($_POST['c_site']) && isset($_POST['c_content']) &&
$_ctx->posts->commentsActive();
# Posting a comment
if ($post_comment)
{
# Spam trap
if (!empty($_POST['f_mail'])) {
http::head(412,'Precondition Failed');
header('Content-Type: text/plain');
echo "So Long, and Thanks For All the Fish";
exit;
}
$name = $_POST['c_name'];
$mail = $_POST['c_mail'];
$site = $_POST['c_site'];
$content = $_POST['c_content'];
$preview = !empty($_POST['preview']);
if ($content != '')
{
if ($core->blog->settings->wiki_comments) {
$core->initWikiComment();
} else {
$core->initWikiSimpleComment();
}
$content = $core->wikiTransform($content);
$content = $core->HTMLfilter($content);
}
$_ctx->comment_preview['content'] = $content;
$_ctx->comment_preview['rawcontent'] = $_POST['c_content'];
$_ctx->comment_preview['name'] = $name;
$_ctx->comment_preview['mail'] = $mail;
$_ctx->comment_preview['site'] = $site;
if ($preview)
{
$_ctx->comment_preview['preview'] = true;
}
else
{
# Post the comment
$cur = $core->con->openCursor($core->prefix.'comment');
$cur->comment_author = $name;
$cur->comment_site = html::clean($site);
$cur->comment_email = html::clean($mail);
$cur->comment_content = $content;
$cur->post_id = $_ctx->posts->post_id;
$cur->comment_status = $core->blog->settings->comments_pub ? 1 : -1;
$cur->comment_ip = http::realIP();
$redir = $_ctx->posts->getURL();
$redir .= strpos($redir,'?') !== false ? '&' : '?';
try
{
if (!text::isEmail($cur->comment_email)) {
throw new Exception(__('You must provide a valid email address.'));
}
# --BEHAVIOR-- publicBeforeCommentCreate
$core->callBehavior('publicBeforeCommentCreate',$cur);
if ($cur->post_id) {
$comment_id = $core->blog->addComment($cur);
# --BEHAVIOR-- publicAfterCommentCreate
$core->callBehavior('publicAfterCommentCreate',$cur,$comment_id);
}
if ($cur->comment_status == 1) {
$redir_arg = 'pub=1';
} else {
$redir_arg = 'pub=0';
}
header('Location: '.$redir.$redir_arg);
exit;
}
catch (Exception $e)
{
$_ctx->form_error = $e->getMessage();
$_ctx->form_error;
}
}
}
# The entry
$tpl = 'post.html';
if ($_ctx->posts->cat_id) {
$alt_tpl = 'post-cat-'.strtolower($_ctx->posts->cat_id).'.html';
if ($core->tpl->getFilePath($alt_tpl)) {
$tpl = $alt_tpl;
}
}
self::serveDocument($tpl);
exit;
}
public static function preview($args)
{
$core = $GLOBALS['core'];
if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) {
self::p404();
}
$user_id = $m[1];
$user_key = $m[2];
$post_url = $m[3];
if (!$core->auth->checkUser($user_id,null,$user_key)) {
self::p404();
}
self::post($post_url);
exit;
}
}
Si on veut un template différent pour la catégorie d'id xx, il suffit de créer une copie de category.html en la nommant category-xx.html. Pour les billets de cette catégorie, un template post-cat-xx.html peut être créé de la même façon
Hors ligne
Génial,
merci pour vos réponses. Je décortique tout ça et je m'y jette. Je vous dirai la solution retenue.
Merci à tous
Michel
Hors ligne
Et pour un fichier template spécifique à un mot-clé :
Ajouter en dessous de
$core->addBehavior('urlHandlerBeforeGetData',array('mybehaviors','altCategoryTpl'));
ça :
$core->addBehavior('urlHandlerBeforeGetData',array('mybehaviors','altTagTpl'));
et juste après la fonction
public static function altCategoryTpl($_ctx)
{
global $core;
if ($_ctx->current_tpl == "category.html") {
$tpl = 'category-'.$_ctx->categories->cat_id.'.html';
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
} else {
$tpl = 'category-'.CleanText(mb_strtolower($_ctx->categories->cat_title)).'.html';
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
}
}
}
}
ça
public static function altTagTpl($_ctx)
{
global $core;
if ($_ctx->current_tpl == "tag.html") {
$tpl = 'tag-'.CleanText($_ctx->meta->meta_id_lower).'.html';
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
}
}
}
Usage :
altTagTpl
permet l'utilisation d'un fichier de contexte différent de tag.html.
Le nom du fichier devra être de la forme tag-xxx.html où xxx sera le mot-clé en minuscules, sans espaces, ni caractères accentués.
Si ce fichier n'existe pas, alors c'est le contexte standard qui sera utilisé
Ce qui me permet de proposer des fichiers template spécifiques à certains de mes mots-clés comme ici ou là à comparer avec le fichier tag.html "normal" qui donne un truc comme ça...
Dernière modification par Mirovinben (2016-03-19 15:47:47)
Le B.A.BA : https://abc.dotaddict.org
La doc DC2 : https://fr.dotclear.org/documentation/2.0
Mes extensions : https://www.mirovinben.fr/blog/index.ph … pluginsDC2
Mes marqueurs de template : https://www.mirovinben.fr/blog/index.php?post/id3553
Hors ligne
Bonsoir,
alors... le gagnant est : Mirovinben ;-)
L'extension de Frank (le footer de merde, j'adore ;-) aurait presque fait le boulot, mais j'ai tout de même mon test à la con pour les billets des sous-catégories d'Eleveurs qui serait resté malpratique à l'écriture.
Le bricolage de Pep est peut-être plus complet, mais ça fait beaucoup de lignes, alors j'ai préféré la soluce de Mirovinben qui fonctionne pile poil.
J'ai ajouté un test sale pour les sous-rubriques d'éleveurs parce que je ne sais pas récupérer l'id de la rubrique parente en php :
class mybehaviors
{
public static function altCategoryTpl($_ctx)
{
global $core;
if ($_ctx->current_tpl == "category.html") {
$p = $_ctx->categories->cat_id;
if ($p == 18 || $p == 19) {
$tpl = 'category-listEleveurs.html' ;
} else {
$tpl = 'category-'.$_ctx->categories->cat_id.'.html';
}
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
} else {
$tpl = 'category-'.CleanText(mb_strtolower($_ctx->categories->cat_title)).'.html';
if ($core->tpl->getFilePath($tpl)) {
$_ctx->current_tpl = $tpl;
}
}
}
}
}
d'ailleurs si vous avez une idée...
Hors ligne
Une petite question de culture DC si vous repassez par là : quelle est la différence d'enregistrement du hook entre la méthode proposée par Philippe/Pep :
$core->url->register('category','category','^category/(.+)$',array('myURLHandlers','category'));
et celle de mirovinben :
$core->addBehavior('urlHandlerBeforeGetData',array('mybehaviors','altCategoryTpl'));
?
Du coup j'ai bien compris au passage que l'on peut sur le même modèle surcharger tout type de template en enregistrant la fonction au bon endroit. À là fin on va faire un SPIP ;-)
Sinon, je reste vachement intéressé pour comprendre comment trouver l'id parent d'une catégorie dans le contexte du _public.php. J'ai bien vu dans la classe class.dc.categories.php que dcCategories possédait bien une fonction getParent, mais je ne sais pas du tout comment l'appeler (faut dire que je suis un peu quiche en php de ce point de vue).
Michel
Hors ligne
Pour connaître l'ID d'une catégorie, je passe par le panneau d'administration du blog, item "Catégories", je fais passer le pointeur de ma souris sur le lien du nom d'une catégorie (ou de son URL) et mon navigateur (Firefox) affiche en bas l'ID de cette catégorie.
Nota : j'avais émis l'idée, lors d'une refonte de l'administration, qu'apparaisse en clair l'ID de chaque catégorie à côté de son URL mais ça n'avait pas été retenu.
Le B.A.BA : https://abc.dotaddict.org
La doc DC2 : https://fr.dotclear.org/documentation/2.0
Mes extensions : https://www.mirovinben.fr/blog/index.ph … pluginsDC2
Mes marqueurs de template : https://www.mirovinben.fr/blog/index.php?post/id3553
Hors ligne
L'idée me trottait dans la tête depuis un moment. Ta demande et mes réponses m'ont décidé. Je viens de pondre un billet récapitulant en un seul fichier tous les marqueurs de template que j'ai ajoutés à mon thème.
C'est là.
Le B.A.BA : https://abc.dotaddict.org
La doc DC2 : https://fr.dotclear.org/documentation/2.0
Mes extensions : https://www.mirovinben.fr/blog/index.ph … pluginsDC2
Mes marqueurs de template : https://www.mirovinben.fr/blog/index.php?post/id3553
Hors ligne
Bonjour,
sympa ton fichier, merci !
Par rapport à ta réponse d'hier matin, j'avais en fait trouvé comment découvrir l'id d'une catégorie dans l'admin.
Ce que je n'ai pas réussi à faire par contre, c'est déterminer l'id de la catégorie parente de la catégorie en cours dans le contexte de l'exécution du code dans _piblic.php. Je détaille :
La classe de catégorie permet un accès direct à son id : categories->cat_id dans le code que tu as donné en exemple
Mais il n'existe pas de pointeur permettant d'en déduire l'id de la catégorie parente du contexte, qui permettrait d'écrire par exemple ça : $_ctx->categories->parent_id
La fonction getParent existe dans la classe, mais je n'ai pas réussi à l'appeler depuis _public.php
Ceci étant dit je pourrai peut-être m'en sortir élégamment avec le altTagTpl en fait pour mon besoin actuel. Cependant si quelqu'un sait me dire comment récup' l'id parent, ça me plairaît mieux.
Michel
Hors ligne
La classe de catégorie permet un accès direct à son id : categories->cat_id dans le code que tu as donné en exemple
Mais il n'existe pas de pointeur permettant d'en déduire l'id de la catégorie parente du contexte, qui permettrait d'écrire par exemple ça : $_ctx->categories->parent_id
Essaie avec
$cat_id = $_ctx->categories->cat_id;
$rs = $core->blog->getCategoryParent($cat_id);
Hors ligne
Essaie avec
$cat_id = $_ctx->categories->cat_id;
$rs = $core->blog->getCategoryParent($cat_id);
C'est presque ça, sauf que $rs n'est pas un tableau, mais un objet, qui contient plein de trucs, et notamment des données protected, que je n'arrive pas à extraire. Ceci étant dit, un var_dump me prouve que la donnée voulue est dedans :
object(record)#59 (7) { ["__link":protected]=> object(mysqli)#3 (19) { ["affected_rows"]=> int(1) ["client_info"]=> string(6) "5.5.46" ["client_version"]=> int(50546) ["connect_errno"]=> int(0) ["connect_error"]=> NULL ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["field_count"]=> int(4) ["host_info"]=> string(25) "Localhost via UNIX socket" ["info"]=> NULL ["insert_id"]=> int(0) ["server_info"]=> string(23) "5.5.47-0ubuntu0.14.04.1" ["server_version"]=> int(50547) ["stat"]=> string(138) "Uptime: 22460 Threads: 1 Questions: 2553 Slow queries: 0 Opens: 1151 Flush tables: 1 Open tables: 400 Queries per second avg: 0.113" ["sqlstate"]=> string(5) "00000" ["protocol_version"]=> int(10) ["thread_id"]=> int(225) ["warning_count"]=> int(0) } ["__result":protected]=> object(mysqli_result)#60 (5) { ["current_field"]=> int(4) ["field_count"]=> int(4) ["lengths"]=> NULL ["num_rows"]=> int(1) ["type"]=> int(0) } ["__info":protected]=> array(4) { ["con"]=> object(mysqliConnection)#2 (5) { ["__driver":protected]=> string(6) "mysqli" ["__version":protected]=> string(23) "5.5.47-0ubuntu0.14.04.1" ["__link":protected]=> object(mysqli)#3 (19) { ["affected_rows"]=> int(-1) ["client_info"]=> string(6) "5.5.46" ["client_version"]=> int(50546) ["connect_errno"]=> int(0) ["connect_error"]=> NULL ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["field_count"]=> int(4) ["host_info"]=> string(25) "Localhost via UNIX socket" ["info"]=> NULL ["insert_id"]=> int(0) ["server_info"]=> string(23) "5.5.47" ["server_version"]=> int(50547) ["stat"]=> string(138) "Uptime: 22460 Threads: 1 Questions: 2554 Slow queries: 0 Opens: 1151 Flush tables: 1 Open tables: 400 Queries per second avg: 0.113" ["sqlstate"]=> string(5) "00000" ["protocol_version"]=> int(10) ["thread_id"]=> int(225) ["warning_count"]=> int(0) } ["__last_result":protected]=> object(mysqli_result)#60 (5) { ["current_field"]=> int(4) ["field_count"]=> int(4) ["lengths"]=> NULL ["num_rows"]=> int(1) ["type"]=> int(0) } ["__database"]=> string(10) "bergers-xxxxxxx" } ["cols"]=> int(4) ["rows"]=> int(1) ["info"]=> array(2) { ["name"]=> array(4) { [0]=> string(6) "cat_id" [1]=> string(9) "cat_title" [2]=> string(7) "cat_url" [3]=> string(8) "cat_desc" } ["type"]=> array(4) { [0]=> string(3) "int" [1]=> string(6) "string" [2]=> string(6) "string" [3]=> string(4) "blob" } } } ["__extend":protected]=> array(0) { } ["__index":protected]=> int(0) ["__row":protected]=> array(8) { ["cat_id"]=> &string(1) "6" ["cat_title"]=> &string(9) "Éleveurs" ["cat_url"]=> &string(8) "Eleveurs" ["cat_desc"]=> &string(210) " (...)
Et là, le cat_id qui vaut 6, c'est bien l'id de la catégorie parente, celui que je veux ! Mais impossible de le choper, je ne suis pas assez à l'aise.
J'ai tenté un bout de code trouvé sur http://php.net/manual/en/function.get-object-vars.php dans les commentaires : object-to-array-recursive, mais je n'arrive à sortir que : array(0) { } , tout vide quoi :-(
C'est rageant, j'ai mon résultat tout à côté, mais je ne sais pas comment l'attraper !
Petit complément : il me semble qu'il y a un problème avec la fonction getCategoryParent. En effet, si je m'amuse à faire un getCategory, je reçois un object(staticRecord) que je transforme facilement en tableau par get_object_vars :
array(1) { ["__data"]=> array(1) { [0]=> array(9) { ["cat_id"]=> string(2) "18" ["cat_lft"]=> string(1) "7" ["cat_rgt"]=> string(1) "8" ["level"]=> string(1) "2" ["cat_title"]=> string(6) "Drôme" ["cat_url"]=> string(14) "Eleveurs/Drome" ["cat_desc"]=> string(33) "bla bla" ["nb_post"]=> int(2) ["nb_total"]=> int(2) } } }
mais l'objet original n'a rien à voir avec le tas de pus renvoyé par getCategoryParent...
Dernière modification par vertacoo (2016-03-21 19:27:04)
Hors ligne
$id = $rs->cat_id
Photo, Art et Création Numérique : http://benoit-grelier.photo7.fr/
Hors ligne
Arrgh, trop fort adjaya !
Chuis vert parce que je me souviens bien d'avoir essayé dans cette direction avant de faire bien plus compliqué... bref: Merci !
Michel
Hors ligne
Vous n'êtes pas identifié(e).