Carnet Wiki

Astuces SPIP

Version 93 — Janvier 2012 — 81.14.xx.xx


Attention, cette page concerne uniquement des astuces SPIP courtes.

Les astuces trop longues ont été déplaçées ici. Merci de vous rendre éventuellement dans la partie privé pour lire les règles de publication dans le forum attaché à cet article.


UTF8

-  Convertir sa base en UTF-8 :

À utiliser pour une recherche alphabétique exacte ou pour avoir une jolie base dans PHPMyadmin. Passer par un code caché : ?exec=convert_sql_utf8 pour convertir sa base en UTF-8 (http://archives.rezo.net/archives/s...)

<blockquote class="spip">

plutôt utiliser le critère {collecte...}. À voir sur le glossaire de spip.net

</blockquote>

PLUGINS

-  Trouver si un plugin est là (dialogue via irc) :

dans un squelette 1.9.2 : [(#EVAL{DIR_PLUGIN_PREFIX}|?{' ',”}) Mon action ]
depuis SPIP 2 : [(#PLUGIN{XXX}) Mon action ]
en php : if (defined('_DIR_PLUGIN_XXX')){ ... }

-  Récupérer le chemin d’un plugin dans un squelette :

#SET{cheminmonplugin, #EVAL{_DIR_PLUGIN_MONPLUGIN}}
#GET{cheminmonplugin}

-  Adopter plutôt une numérotation x.y.z comme numéro de version

z est incrémenté sur une correction
y sur une évolution fonctionnelle
x sur une incompatibilité avec les version précédentes.

exemple : version plugin 1.3.8


CSS

-  Pipeline automatique de CSS dans un plugin :

style_public_plugin_xxx.html et, pour l’espace privé : prive/style_prive_plugin_xxx.html

-  Faire un CSS qui soit un squelette (cela permet de récupérer des variables) :

[(#REM) dans la page monstyle.html et en première ligne ]
#HTTP_HEADER{'Content-Type: text/css'}
.couleurdefond {
  background-color:green;
  [(#ENV{id_article}|={33}|?{background-color:pink;})]
}

Appeler la CSS dans une page SPIP

[(#REM) dans la page article.html par exemple cela retournera /?page=styles&id_article=33]
<link rel="stylesheet" type="text/css" href="[(#URL_PAGE{monstyle}|parametre_url{id_article,[(#ENV{id_article})] )]" />
...
<div class="couleurdefond">
change ici la couleur de fond en rose si article=33
</div>

Eenlever la puce qui précède le titre dans une liste :
Mettre une classe sur la liste visée : <ul class="toto">
et enlever la puce via css :
ul.toto { list-style-type: none; }


BALISES

Quand on crée une balise, on peut vouloir récupérer des variables du contexte (il y a un article déjà sur contrib qui explique cela) ; mais quand on veut trouver le « type » de boucle du contexte, il faut aller le chercher dans la pile $p :

$p->boucles[$p->id_boucle]->id_table

FILTRES

-  Utiliser |textebrut pour compter la chaîne correctement, sinon l’apostrophe compte 5 :

[(#TITRE|textebrut|strlen|>{30}
|et{[(#TITRE|textebrut|strlen|<{60})]}|oui)
[(#INTRODUCTION|PtoBR|couper{85})] 
]

-  |unique dans un modèle :

Un modèle inséré dans un texte ne peut pas simplement appeler le filtre |unique car il arrive que SPIP calcule plusieurs fois le #TEXTE (par exemple pour les besoins de #INTRODUCTION) et l’environnement de |unique n’est pas réinitialisé à chaque fois...
Pour ces besoins, on utilisera un « unique nommé », avec un nom généré dynamiquement de manière ... unique à chaque fois : #SET{ident, #REM|uniquid} ; puis utiliser |unique{#GET{ident}}.

-  Utiliser |replace pour créer l’équivalent d’un sprintf dans la définition d’un #SET utilisé dans une boucle itérateurs (_fil_ et BoOz sur irc) :

#SET{req, #VAL{"
  SELECT a.truc_1,
         s.truc_2,
         s.truc_x
    FROM spip_matable s,
         spip_auteurs a
   WHERE a.id_auteur = s.id_auteur
     AND date_format(s.truc_x, '%Y %m %d') = '%s'
ORDER BY s.truc_x desc
   LIMIT , 100
"}|replace{'%s', #ENV{ladate}}}


<BOUCLE_rech(DATA) {source sql, #GET{req}}>
  ...

-  N’afficher que les images d’un texte :

<BOUCLE_f(ARTICLES) {id_article}>
  #SET{tab_img, #TEXTE|extraire_balises{img}}
  [(#GET{tab_img}|implode{'<br />'}|image_reduire{150})]
</BOUCLE_f>

CRITÈRES

-  Critère conditionnel, sans parenthèses ni crochets, seulement des bisoux, euh, des accolades... :

<BOUCLE_seulement_pour_la_rubrique_dix(RUBRIQUES) {id_rubrique=#ID_RUBRIQUE|=={10}|?{10}}>
   Mon code ....
</BOUCLE_seulement_pour_la_rubrique_dix>

-  Afficher les articles ayant le mot clef « truc » :

<BOUCLE_g(ARTICLES) {titre_mot=truc}>
#TITRE
</BOUCLE_g>
<blockquote class="spip">

{titre_mot} étant obsolète on peut écrit désormais :

<BOUCLE_g(ARTICLES) {mots.titre}>
</blockquote>

-  Le critère {par multi titre} permet de trier les titres alphabétiquement quand ils utilisent la balise multi pour le multilinguisme.

-  Le critère {fusion} permet de faire un « GROUPBY » :

exemple sur un fil RSS, pour éviter des articles de même nom, on peut faire :

<BOUCLE_syndic(SYNDIC_ARTICLES) {fusion titre} {0, 10}>

On peut également faire une fusion pour avoir les articles tous issus de sites différents :

<BOUCLE_syndic(SYNDIC_ARTICLES) {fusion syndic_articles.id_syndic}>

-  Un simple {statut?} dans une boucle annule la restriction de statut sur la boucle document (comme sur une boucle article), on peut aussi demander {statut=prepa}

-  Utiliser un critère optionnel, et demander le critère via l’url :

<BOUCLE_articles(ARTICLES) {branche ?} {id_mot ?} {id_auteur ?}>

-  N’afficher que les articles dont le « num titre » est pair :

on considère que tous les titres des articles sont préfixés avec un nombre suivi d’un point suivi d’un espace (« 123. Le titre ») :

<BOUCLE_art_pair(ARTICLES) {par num titre} {titre==^[[:digit:]]*[02468][.][[:space:]]} {"<br />"}>
#TITRE
</BOUCLE_art_pair>
<hr>
<BOUCLE_art_impair(ARTICLES) {par num titre} {titre==^[[:digit:]]*[13579][.][[:space:]]} {"<br />"}>
#TITRE
</BOUCLE_art_impair>


-  un formulaire simple (pas cvt) qui boucle sur la page et y renseigne un critère de boucle :

par exemple un select de mots-clefs (name="avec_mot") dont chaque value est un « id_mot » mais avec une option « tous les mots »

la boucle ARTICLES correspondante (au retour du formulaire) utilisera donc le critère {id_mot ...}.
mais comment ? puisque la boucle doit retourner les articles liés soit à un id_mot unique soit à n’importe quel id_mot

pour la boucle on utilisera les REGEXP de mysql avec comme critère :
   {id_mot == ^#ENV{avec_mot}$}

dans le select, on passera comme value pour l’option ’tous les mots’
 :
pour un formulaire en method get :
<code > <option code><option value=".%2B">tous les mots
pour un formulaire en method post :
<code > <option code><option value=".+">tous les mots


-  Afficher les articles « sauf » ceux qui ont un flash dans le corps de leur texte :

On travaille en 2 boucles. La première va extraire les id_article depuis la table spip_documents_liens des articles (objet) liés à un document (id_document) inséré dans le corps du texte (vu) et d’extension .flv :

#SET{noflash, #ARRAY}
<BOUCLE_noflash(spip_documents_liens) {objet = article} {vu = oui} {spip_documents.extension = flv}>
#SET{noflash, #GET{noflash}|push{#ID_OBJET}}
</BOUCLE_noflash>

la seconde boucle exclue ces articles (!IN) de sa recherche :

<BOUCLE_a(ARTICLES) {id_article !IN #GET{noflash}} {"<br />"}>
#TITRE
</BOUCLE_a>


-  N’afficher que les articles dont le surtitre contient la lettre « x » à une certaine position, position fournie dans une variable d’environnement (par exemple, passée en url).

SPIP ne permettant pas d’utiliser la fonction « SUBSTRING » de mysql comme critère de boucle, nous utiliserons les expressions régulières (REGEXP) de mysql.

tout d’abord, construire la regexp :

#SET{reg, #VAL{.}|str_repeat{#ENV{position}|moins{1}}}

deux cas de figure :

  • si la position où rechercher la lettre « x » est 1 (c’est à dire au début du surtitre) ; la regexp sera vide «   »
  • si la position n’est pas 1, par exemple si #ENV{position} est égale à 4, nous aurons « ... »

il ne reste plus qu’à écrire le critère de boucle en ajoutant ^  commence par ») et le x final :

<BOUCLE_p(ARTICLES) {surtitre == ^#GET{reg}x}>
  #SURTITRE  -- (x en #ENV{position}e position)
  ...

MES_OPTIONS

Quelques constantes sont répertoriées ici

Dans config/mes_options.php

-  Éviter de voir les numéros ou les balises multis des titres dans l’espace privé (par exemple sur médiathèque) :

$table_des_traitements['TITRE'][] = test_espace_prive() ? 'typo(%s)' : 'typo(supprimer_numero(%s))';

-  Changer la qualité par défaut de compression jpg :

define('_IMG_GD_QUALITE', 95);

Limiter les opérations graphiques sur des images trop grosses :

if (!defined('_LOGO_MAX_SIZE')) define('_LOGO_MAX_SIZE',xxGD2); // Poids max des logos
if (!defined('_IMG_MAX_SIZE')) define('_IMG_MAX_SIZE',xxGD2); // Poids max des images 

Toutefois l’appel de SPIP à GD2 détecte la taille maximum qu’il pourra gérer, et ne lancera normalement pas une opération graphique qui pourrait échouer (une marge de 10% est rajoutée pour SPIP3)

-  En local, interdire le compactage des js et css dans le privé, et tout envoi de mails par facteur

if ($_SERVER["HTTP_HOST"] == "127...1") {
        define('_INTERDIRE_COMPACTE_HEAD', true);
        define('_TEST_EMAIL_DEST', ''); // Facteur n'envoie jamais rien 
} rien 
} 

SQUELETTES

-  Récupérer le nom du fichier sans extension (blabla.pdf blabla.zip deviendront blabla)
avec [(#FICHIER|basename{.#EXTENSION})] dans une boucle document.

-  Sans boucle, afficher le titre d’un objet SPIP ...avec le plugin bonux

#INFO_TITRE{#OBJET,#ID_OBJET} exemple #INFO_TITRE{article,122}
ou
#INFO_<QUOI>{type_objet, id_objet}

-  Utiliser le filtre |ou :

[(#ENV{id_article}
        |ou{#ENV{id_rubrique}}
        |ou{#ENV{id_article}}
        |ou{#ENV{id_breve}}
) alors afficher ce texte ]

-  la balise #TITRE peut s’écrire dans une boucle (ici avec jointure sur spip_articles)

    <BOUCLE_image(DOCUMENTS){id_article}>
    #FICHIER - #INFO_TITRE{article, #ID_ARTICLE}
    </BOUCLE_image>

-  Le calendrier ICAL ne fonctionne pas ? Assurez-vous dans le fichier généré que la première ligne n’est pas vide ! Pour ma part la ligne 1 est devenue #HTTP_HEADER{Content-Type: text/calendar; charset:#CHARSET}BEGIN:VCALENDAR

-  Remplaçer « lire la suite » par « autre chose » :

[(#TEXTE|couper{110, <a href="#URL_RUBRIQUE"><em>autre chose ...</em></a>})]

-  Une syntaxe (à partir de SPIP 2) pour tester l’existence d’un élément :

[(#PLUGIN{ABONNEMENT}|oui)
    #INCLURE{fond=inc/menu_abonnement}]
[(#PLUGIN{ABONNEMENT}|non)
    #INCLURE{fond=prive/menu_inscription2}]

-  Le critère {ajax} permet de recharger uniquement le morceau de noisette appelé :

utilisé en SPIP 2 avec pagination :

<INCLURE{fond=inc-manoisette, ajax}>

Mais comment faire fonctionner le callback ? et hop :

$(document).ready(function() {
  var fonction_a_rappeler=function() {
    ...
  }
  if (typeof onAjaxLoad == 'function') onAjaxLoad(fonction_a_rappeler);
  if (window.jQuery) jQuery(document).ready(function() {
    fonction_a_rappeler.apply(document);
  });
});

-  changer le caractère séparateur de pagination

d’abord modifier un peu le modèle de pagination qu’on a choisi, ligne 5 :

#SET{separateur,#ENV{separateur,'|'}}

devient :

#SET{separateur,#ENV{separateur}|sinon{'|'}}

et passer ensuite le paramètre de pagination dans la boucle elle-même :

[<p class="pagination">(#PAGINATION{page}{separateur=' '})</p>]

(il faut bien renseigner le modèle choisi si on renseigne la valeur du séparateur)

-  Empêcher l’apparition des boutons de recalcule sur une page en particulier :

à plaçer sur la première ligne du squelette) :[(#HTTP_HEADER{Content-type: text/html[; charset=(#CHARSET)]})] (voir http://www.spip.net/fr_article4631....).

-  Se servir de #VAL :

par exemple pour |image_typo cela donnerait une image (avec la police victor.ttf) du mot « Actuellement » :

[(#VAL{Actuellement}|image_typo{police=Victor.ttf, taille=14, largeur=150})]

-  Tester les autorisations d’écriture ou de modification d’un auteur (à partir de SPIP 2) :

[(#AUTORISER{modifier, article, #ENV{id_article}}) vous pouvez modifier l'article ] 

Voir la doc

-  Savoir si l’on se trouve dans une « branche » particulière :

Comment savoir si l’article (ou la rubrique) en cours est un descendant direct ou non d’une rubrique donnée (dans la même « branche » donc) ?

[(#ID_RUBRIQUE|in_array{#VAL{12}|calcul_branche|explode{','}}|oui) je suis bien dans la descendance de la rubrique 12 ; dans la même branche donc.]

(On pourra, bien sûr, utiliser #SET et #GET pour remplacer le #VAL)

-  Afficher le dernier article publié de chaque auteur :

C’est impossible en une seule boucle ? Qu’à cela ne tienne : nous en ferons donc deux.

<BOUCLE_aut(AUTEURS)>
<p>
<BOUCLE_art(ARTICLES) {id_auteur} {!par date} {0,1}>
auteur n° #_aut:ID_AUTEUR : #_aut:NOM<br />
dernier article publié le #DATE (n° #ID_ARTICLE : "#TITRE")
</BOUCLE_art>
</p>
</BOUCLE_aut>

La première boucle récupère toutes les informations sur les auteurs qui ont au moins un article publié mais elle n’affiche rien.

La seconde, imbriquée, va récupérer toutes les informations du plus récent article publié par l’auteur sélectionné à chaque passage de la première boucle. Et c’est elle qui affichera les informations sur cet auteur en utilisant l’écriture #_NomDeBoucle:BALISE.

-  Faire un menu de mots à sélection multiple

  • proposer les mots des groupes 1, 2 et 3 seulement
  • afficher comme déjà sélectionnés les mots situés dans l’environnement (issu d’un précédent POST du formulaire ou bien présents dans l’url)
<BOUCLE_groupes (GROUPES_MOTS){par num titre}{id_groupe IN 1,2,3}>
        <select name="mots[#ID_GROUPE]" class="select" style="width: 135px;">
        <option value="">- indifférent -</option>
        <BOUCLE_mots(MOTS){id_groupe}{par num titre}>        
                <option value='#ID_MOT'  [(#ENV{mots}|table_valeur{#ID_GROUPE}|=={#ID_MOT}|?{selected,})] >
                            [(#TITRE|supprimer_numero)]-#ID_MOT
                </option>
        </BOUCLE_mots>
        </select>
</BOUCLE_groupes>

MODELES

Comment passer une variable à un modèle ?
Un modèle SPIP, inclus dans le texte d’un article, ne permet pas de récupérer la variable #ENV (qui passe par une transmission d’un include à l’autre). Si l’on veut par exemple récupérer le contenu de "toto" que l’on a dans l’url (?toto=truc) on ne peut le faire avec #ENVtoto comme on pourrait le faire si on était dans un squelette et pas dans un modèle.

L’astuce est ici d’utiliser #SELF (qui lui, passe vers le modèle) et d’en extraire la chaine qui nous intéresse, ici "truc", qui se trouve juste après "toto=", grâce au filtre "match" :

[-->(#SELF|match{'toto='(\w+)$, 1})<--]

LANG

<blockquote class="spip">

Voir sur le carnet spip la FAQ Multilangue

</blockquote>

-  Variable dans une chaîne de langue en squelettes :

<:ma_chaine{nom=Charles Martin, age=37}:>

permet de passer deux paramètres 'ma_chaine'=>"Bonjour, je suis @nom@ et j'ai @age@ ans".

-  Variable dans une chaîne de langue en php (utilisé par le plugin medias) :

"._T("medias:erreurs_voir", array('nb'=>count($erreurs)))"

-  Des chaînes de langue dynamiques :

dans un fichier de langue nous avons :

'chaine_a' => 'traduction un',
'chaine_b' => 'traduction deux',
'chaine_c' => 'traduction trois',
...

dans le squelette, <:prefixe:chaine_#VARIABLE:> ne fonctionnera pas. Il faut alors utiliser :[(#VAL{prefixe:chaine_#VARIABLE}|_T)] qui affichera la bonne traduction en fonction de la valeur de #VARIABLE.


1 - CONFIG

-  Accéder aux données contenues dans les metas du site (nécessite le plugin CFG : voir doc) :

#CONFIG{meta::descriptif_site}


2 - MODELE

-  Le raccourci sera <charte|typo> si le fichier se nomme modeles/charte_typo.html

-  Avec #MODELE, définir plusieurs paramètres dans un array (voir le plugin nuage) :

[(#MODELE{nuage} {notid=5|6|7})]

définira les groupes à exclure dans la boucle du modèle

{id_groupe !== ^((#ENV{notid, -1}))$}

3 - ARRAY

-  Déclarer un ARRAY puis le remplir dans une boucle incrémentée par le compteur :

#SET{articles, #ARRAY}
<BOUCLE_articles_rub(ARTICLES) {id_rubrique}>
#SET{articles, #GET{articles}|array_merge{#ARRAY{#COMPTEUR_BOUCLE, #ID_ARTICLE}}}
</BOUCLE_articles_rub>

Encore plus court :

#SET{arraymot, #ARRAY}
 <BOUCLE_mot(MOTS) {id_groupe}>
#SET{arraymot, #GET{arraymot}|push{#ID_MOT}}
 </BOUCLE_mot>

MYSQL

-  Faire le ménage en base de données :

Aller directement dans la base pour modifier ou supprimer ; par exemple lorsque vous avez 2000 sites qui encombrent, un gros coup de balai peut être nécessaire ! La méthode rapide est donc de lancer une commande directement depuis MYSQL (par exemple via l’interface phpmyadmin)

  • sélectionner les sites en proposition :
    SELECT * FROM `spip_syndic` WHERE `statut` =  'prop'
  • Supprimer les sites en proposition :
    DELETE FROM `spip_syndic` WHERE `statut` =  'prop'

-  Supprimer les syndications trop anciennes

Vous avez beaucoup de sites syndiqués et ils ne possèdent pas tous l’option effacer au bout de 2 mois
Voici la requête pour effacer toutes les vieux articles syndiqués (modifier la date selon vos besoins) :

DELETE FROM `spip_syndic_articles` WHERE date <  '2007-12-31 10:00:00'

-  Déplacer tous les articles de la rubrique 39 à la rubrique 12 :

UPDATE spip_articles SET id_rubrique = 12 WHERE id_rubrique = 39;


attention : si les deux rubriques ne sont pas dans le même secteur, il faut aussi mettre à jour id_secteur

-  Transférer les données crées avec EXTRA2 (mettre en réserve vos spip_metas, iextras et les champs créés) :
En ligne :

  • créer les champs supplémentaires dans phpmyadmin, du style
    ALTER TABLE `spip_auteurs` ADD  `nom_champ_nouveau` text NOT NULL;
  • Le plus important : supprimer tmp/meta_cache.php
  • MODIFIER spip_metas, iextras dans la base en collant le contenu précédemment sauvegardé
  • vider le cache, voila

URLS et LIENS

-  Fabriquer une url publique avec #OBJET et #ID_OBJET
[(#ID_OBJET|generer_url_entite{#OBJET})]

-  Passer un tableau de variables en url :

[(#SELF|parametre_url{'id_mot[]', #ID_MOT})]

ne fonctionne pas ; il faut écrire : [(#SELF)]&id_mot[]=#ID_MOT
et pour vider l’url on écrira : [(#SELF|parametre_url{id_mot, ''})]

-  Créer un lien vers la page site avec la variable id_syndic=xx
à mettre dans une boucle de syndication
corrige également l’erreur produite par generer_url_site (maj SPIP) :

[(#URL_PAGE{site}|parametre_url{id_syndic,#ID_SYNDIC})]

-  Créer un lien vers l’article 54 en se passant de boucle :

<a href="#URL_ARTICLE{54}">lien</a>

-  Créer un lien vers une page de l’espace prive de style /ecrire/?exec=unepageprive :
#URL_ECRIRE{unepageprive}

-  URL propres arborescentes

cf http://comments.gmane.org/gmane.com...

$type_urls = 'arbo';
define('_SET_HTML_BASE', 1); // ajoute aux pages html une directive  
<base..> et traite les ancres des pages produites


-  
Y’a-t-il moyen d’avoir des URL plus longues ?
Oui, en mettant dans

mes_options.php :
@define('_URLS_PROPRES_MAX', 100); 

Ou plus que 100, si on veut avoir des urls de plus de 100 caractères.

-  Afficher les requêtes SQL (SPIP 2) :

http://adresse_spip/?var_profile

permet d’afficher les requêtes SQL que fait SPIP pour créer la page ainsi que les temps de calcul pour chaque boucle et inclusion.

-  Afficher les noisettes d’un squelette (SPIP 2) :
http://adresse_spip/?var_mode=inclure

<blockquote class="spip">

voir [Les aides au débuggage débogage de squelettes->http://www.spip.net/fr_article4453.html]

</blockquote>

-  Obtenir une URL raccourci à la bit.ly, yourls, ....
C’est natif dans SPIP, il suffit de prendre le numéro de l’article
Par ex. http://www.spip-contrib.net/Soyez-s... est raccourci par http://www.spip-contrib.net/3125


SITES D’ASTUCES

-  http://www.weblog.eliaz.fr/rubrique...


RACCOURCIS TYPOS

Pour faire un lien dans un texte, on utilise le raccourci [->artXX] ou [->rubXX] ou [->motXX], etc.
Mais comment fait-on si on veut pointer vers une page en lui transmettant des paramètres ? Un nom d’onglet par exemple : l’onglet des sites sur une page de mots-clés...
C’est simple il suffit d’écrire [->motXX?parametre=valeur] (dans notre ex. ce pourrait être [->mot33?onglet=sites]) Spip transforme alors le raccourci en URL cliquable du type spip.php?motxx&parametre=valeur
Remarquez comment Spip jongle automatiquement avec les & et les ?.


INCLURE dans un squelette

On utilisera la constante des squelettes pour indiquer à SPIP de rechercher automatiquement un fond dans les dossiers de son choix.

-  Définir une variable calculée par une noisette
sans variable on utilise <INCLURE{fond=monsquelette}> ou [(#INCLURE{fond=monsquelette})]
pour définir la variable calculée :#SET{mavariable, #INCLURE{fond=monsquelette}{monparam=#ENV{monparam}}}

INCLURE dans un formulaire

$date_recolte = recuperer_fond('formulaires/inc-date_recolte', $flux['args']['contexte']);
$code = recuperer_fond("inclure/inc-liste-articles", array( 'id_rubrique' => $id_rubrique));

Voir http://programmer.spip.org/recupere...


Retour à la version courante

Toutes les versions