Ajax Template preprocess Drupal 7

Ajax Template preprocess Drupal 7

7 févr. 2012Drupal 7.x, PHP

Le but de ce petit article n'est pas de vous expliquer en long et en large le fonctionnement des templates dans drupal 7, mais de mettre en lumières les fonctionnalités principales qui vous permettront de customiser vos pages selon vos désirs.

Je vais prendre un exemple simple, vous souhaitez générer des pages en ajax. La structure de votre node est correct, vous souhaitez juste l'afficher mais sans toutes les feuilles de styles, les headers et footers ... car ceux ci se trouvent la page qui va appeler en ajax le contenu.

Attention, je me base sur un thème de base ZEN pour la construction des templates. Si vous ne l'avez pas je vous invite à lire les avantages de ce thème de base.

Ce que je souhaite est donc très simple en réalité, le templating drupal permet de customiser le template que l'on souhaite utiliser suivant de nombreuses règles.

Fichiers templates par défaut

page.tpl.php – Toutes les pages. Affiche l'accueil, les taxonomies et les node. C'est la page par défaut utiliser si aucun template ne vient surcharger celui-ci.
html.tpl.php –  Toutes les pages. Structure globale de toutes les pages du site.

On veut donc pouvoir avoir des pages pour nos requêtes ajax avec un minimum de structure dans les 2 templates ci dessus.

Nous allons créer 2 templates qui n'afficherons donc que le contenu propre d'un node.

page--ajax.tpl.php

<?php ​print $content; ?>

html--ajax.tpl.php

<?php print $page; ?>

Maintenant il faut que nous puissions dire que notre page ne doit pas être construite avec les templates par défaut mais par les templates ajax que l'on a déterminés.

Template.php theme_preprocess_page()

On va ajouter deux fonctions dans le fichier template.php de votre theme. 

On détermine que lorsque l'on détecte la variable ajax en paramètre GET et que cette variable est =1, dans ce cas, on ajoute une suggestion de template pour l'affichage de cette page.

{syntaxhighlighter brush:php;}function votretheme_preprocess_page(&$vars, $hook) {
  if ( isset($_GET['ajax']) && $_GET['ajax'] == 1 ) {
    array_splice($vars['theme_hook_suggestions'], -1, 0, 'page__ajax');
  }
}
function votretheme_preprocess_html(&$vars, $hook) {
  if ( isset($_GET['ajax']) && $_GET['ajax'] == 1 ) {
    array_splice($vars['theme_hook_suggestions'], -1, 0, 'html__ajax');
  }
}{/syntaxhighlighter}

N'oubliez pas de changer dans le nom des fonction le votretheme par le nom du thème que vous utilisez.

Voilà, vous pouvez désormais afficher n'importe quelle page de node sans aucune structure html polluante. 

Démo

Drupal 7, Strict warning: Only variables should be passed by reference in include()

Drupal 7, Strict warning: Only variables should be passed by reference in include()

1 févr. 2012Drupal 7.x, PHP, error

Voici une petite erreur que l'on peut trouver quand on développe en drupal 7.

Strict warning: Only variables should be passed by reference in include()

Le cas se présente lorsque l'on souhaite afficher un node par exemple depuis une page de template ou autre.

Affichage d'un type de node dans un template drupal.

// on charge le node souhaité
$topic = node_load(1);
//on génère la construction de ce node en ajoutant un $view_mode qui permettra de définir
//le template que l'on veut lui appliquer (ici sommaire). ceci n'est pas nécessaire
print drupal_render(node_view($topic,"sommaire"));

Ce code vous générera l'erreur au dessus. Pour faire simple, les fonctions node_view, ou node _show ne retourne pas de référence. Depuis PHP 5.05, une erreur fatale est retourné.

La correction à apporter est cependant très simple.

Il vous suffit de retourner le résultat de votre fonction node_view dans une variable et de passer cette même variable dans la fonction render de drupal. Dans ce cas, vous n'avez plus de problèmes de passage de référence.

Passez donc par une variable intermédiaire

$topic = node_load(1);
$nodeView = node_view($topic,"sommaire");
print drupal_render($nodeView ); 
 
Pour ceux qui souhaiteraient en savoir plus sur le passage par référence.

 

Erreur JS unrecognized expression: [href=/]

Erreur JS unrecognized expression: [href=/]

25 janv. 2012Drupal 7.x, PHP

Erreur JS, jquery update sur drupal 7

En travaillant sur drupal 7, j'ai trouvé un petit bug JS.

Les modules activés pour reproduire le bug sont les modules admin  et Jquery update.

Uncaught Syntax error, unrecognized expression: [href=/]

Il se trouve qu'il y a une petite erreur comme l'explique cette page dans le code admin_menu.

Corrections à appliquer

/sites/all/modules/admin_menu/admin_menu_toolbar/admin_menu_toolbar.js

Initialement le fichier est celui ci :

{syntaxhighlighter brush:php;}Drupal.admin.behaviors.toolbarActiveTrail = function (context, settings, $adminMenu) {
  if (settings.admin_menu.toolbar && settings.admin_menu.toolbar.activeTrail) {
    $adminMenu.find('> div > ul > li > a[href=' + settings.admin_menu.toolbar.activeTrail + ']').addClass('active-trail');
  }
};{/syntaxhighlighter}

Remplacez les lignes ci-dessus par :

{syntaxhighlighter brush:php;}Drupal.admin.behaviors.toolbarActiveTrail = function (context, settings, $adminMenu) {
  if (settings.admin_menu.toolbar && settings.admin_menu.toolbar.activeTrail) {
    $adminMenu.find('> div > ul > li > a[href$="' + settings.admin_menu.toolbar.activeTrail + '"]').addClass('active-trail');
  }
};{/syntaxhighlighter}

Thanks to WillHall for this correction.

Redirect 301 de index.php Drupal

Redirect 301 de index.php Drupal

5 oct. 2011Drupal 6.x, PHP

Vous souhaitez rediriger votre page index.php de votre site en drupal (ou autre) vers la racine du site afin d'éviter que Goole ne considère votre homepage comme du duplicate content ?

Rien de plus simpe, éditez votre fichier setting.php (/site/default/) et ajoutez le code suivant :

{syntaxhighlighter brush:php;}if ($_SERVER['REQUEST_URI'] == "/index.php"){
    header( "HTTP/1.1 301 Moved Permanently" ); 
    header( "Location: /"); 
    exit();
}{/syntaxhighlighter}

Fonction PHP permettant de couper un texte HTML sans altérer les Tags

Fonction PHP permettant de couper un texte HTML sans altérer les Tags

30 sept. 2011PHP, Function

Voici une fonction PHP que j'ai développé pour un projet sur la base d'un fonction développée par Tilt.

La fontion permet de découper (split ) en plusieurs parties un texte HTML. Elle retourne un tableau de String.

Utilisation

$string ="<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor <i>invidunt ut labore et dolore</i> magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt</p><ul><li>ut labore et dolore</li><li> </li><li>magna aliquyam erat, sed diam voluptua.</li></ul><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et <strong>dolore magna aliquyam</strong> erat, sed diam voluptua.</p><p> </p><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>"

// on split la chaîne tous les 30 caractères (environ car la variable $breakWord est à false) 
print_r(stringPart($string,500,0)); 

// on split la chaîne tous les 30 caractères, mais on regroupe afin d'avoir 5x plus de textes 
print_r(stringPart($string,100,5)); 

//on split la chaîne en demandant explicitement que les mots soient coupés 
print_r(stringPart($string,200,5,true)); 

Résultat

Array
(
    [1] => <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor <i>invidunt ut labore et dolore</i> magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt</p><ul><li>ut labore et dolore</li><li>magna aliquyam erat, sed diam voluptua.</li></ul>
    [2] => <p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et <strong>dolore magna aliquyam</strong> erat, sed diam voluptua.</p><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
)
Array
(
    [1] => <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor <i>invidunt </i></p>
    [7] => <p><i>ut labore et dolore</i> magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt</p><ul><li>ut labore et dolore</li><li>magna aliquyam erat, sed diam voluptua.</li></ul><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed </p>
    [13] => <p>diam nonumy eirmod tempor invidunt ut labore et <strong>dolore magna aliquyam</strong> erat, sed diam voluptua.</p><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
)
Array
(
    [1] => <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor <i>invidunt ut labore et dolore</i> magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo du</p>
    [7] => <p>o dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt</p><ul><li>ut labore et dolore</li><li>magna aliquyam erat, sed diam voluptua.</li></ul><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et <strong>dolore magna aliquyam</strong> erat, sed diam voluptua.</p><p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
)

Voilà, j'espère que cette fonction pourra vous être utile. Vous pouvez bien évidement la modifier selon vos souhaits.


    /**

     * Helper function: Split an HTML text into several part
     * Modified from Tilt    
     * @author Baptiste Doré 
     * @param string
     * @param int 
     * @param int 
     * @param boolean 
     * @return array
     */ 
    function stringPart($string,$page_len, $coeff=1, $breakWord = false) {
        
        $string_without_tags = strip_tags_offset(&$string);
        preg_match_all("`(<[^>]+>)`",$string,$b,PREG_OFFSET_CAPTURE);
        $num0=end($b[1]);
        $num=($num0[1]>$num1[1])?$num0[1]:$num1[1];
        $page_total=ceil($num/$page_len);
        $p=1;
        $previousPage_len = 0;
        $currentPage_len = 0;
        while ($p<=$page_total) {
            $c=$string_without_tags;
            
            if($p > 1) $p += $coeff;
            if(!$breakWord)
                $currentPage_len = findSpaceFromPosition($c,$page_len*$p);
            else
                $currentPage_len = $page_len*$p;
            
            
            if($currentPage_len == NULL){
                $currentPage_len = $page_len*$p;
            }            
            $c = substr($c,$previousPage_len,($currentPage_len-$previousPage_len));
            
            $cBefore = "";
            $cAfter = "";
            foreach ($b[1] as $k=>$v) {
                if($v[1] <= $currentPage_len && $v[1] >= $previousPage_len)
                    $c=substr_replace($c,$v[0],$v[1]-$previousPage_len,strlen($v[0]));
                else if($v[1]  < $previousPage_len)
                    $cBefore .= $v[0];
                else if($v[1]  > $currentPage_len)
                    $cAfter .= $v[0];
                
            }
            $c = $cBefore.$c.$cAfter;
            
            $previousPage_len = $currentPage_len;
            
            $out[$p]=preg_replace("`> +<`","><",preg_replace("` {2,}`","",$c));
            
            $stringClean = $out[$p]; 
            while($stringClean != cleanEmptyBalise($stringClean)){
                $out[$p] = cleanEmptyBalise($out[$p]);
                $stringClean = $out[$p]; 
            }
            
            $p++;
        }
        return $out;
    }
    
   
    /** 
     * Helper function: Clean a string of all HTML tags.  
     * @author Tilt 
     * @param string 
     * @return string
     */ 
    function strip_tags_offset(&$string) {
        $string_without_tags=preg_replace_callback("`(<[^>]+>)`","callback_empty_tags",$string);
        return $string_without_tags;
    }
     function callback_empty_tags($in) {
        return str_pad("",strlen($in[1]));
    }
     /** 
     * Helper function: Search the next position of a regex in a string
     * @author Baptiste Doré 
     * @param string 
     * @param int 
     * @return int
     */ 
    function findSpaceFromPosition($string,$pos,$regex = "`[[:space:]]`",$lengthRegEx=1){
        preg_match_all($regex,$string,$result,PREG_OFFSET_CAPTURE);
        $j=0;
        foreach($result[0] as $space){
            if($pos > $result[$j][1] && $pos <= $space[1]){
                return $space[1]+$lengthRegEx;
            }
            $j++;
        }
       
    }
    /** 
     * Helper function: Clean an HTML text of all empty tags
     * @author Baptiste Doré 
     * @param string 
     * @return string
     */ 
    function cleanEmptyBalise($string){
        $string = eregi_replace("<[^/>]+>[[:space:]| ]*]+>", "", $string);
        return $string;

Comment supprimer des accents d'une string en PHP ?

Comment supprimer des accents d'une string en PHP ?

3 août 2011PHP, pense-bête, Regex

Bon on connait tous les méthode basic de str_replace(). Celle-ci fonctionnait pour moi dans quasiment tous es cas... quasi ... 

Je suis tombé sur un problème dernièrement. Impossible de supprimer ces foutues accents ! J'ai eu bon convertir les string avec iconv, decoder l'html en sortie de la base Mysql... rien à faire.

Du coup après une bonne heure je me suis dit bon je vais chercher un peu sur le net.
Evidemeent je tombe sur PHP.net. Et la dans les tréfonds des commentaires, une fonction attire mon attention !

{syntaxhighlighter brush:php}function getRewriteString($sString) {
     //Conversion des majuscules en minuscule
     $string = strtolower(htmlentities($sString)); 
     //Listez ici tous les balises HTML que vous pourriez rencontrer
     $string = preg_replace("/&(.)(acute|cedil|circ|ring|tilde|uml|grave);/", "$1", $string); 
     //Tout ce qui n'est pas caractère alphanumérique  -> _
     $string = preg_replace("/([^a-z0-9]+)/", "_", html_entity_decode($string)); 
     return $string;
}
{/syntaxhighlighter}

Et voilà un peu de regex et le tour est joué !

Drupal 6.x, Webform traitement des données avant Submit et enregistrement

Drupal 6.x, Webform traitement des données avant Submit et enregistrement

1 août 2011Drupal 6.x, PHP

Problème

Je souhaite ajouter un post traitement sur les données saisies par un utilisateur à travers un formulaire webform.

Ex : Vérifier les données saisies par un utilisateur et remplir un champ caché en fonction de ses choix fait avec les différents input.

Ce type de formulaire est très utile car il permet une mise en place très simple est rapide de formulaires. Seul inconvénient, lorsque vous désirez faire autre chose que ce qui est prévu, évidemment ça se complique.

Solution

Drupal est un outil très puissant qui permet d'insérer du code personnel dans ses fonctions grâce aux hook.

Nous allons donc en utiliser un très connu, hook_form_alter(&$form, &$form_state, $form_id).

Je considère dans cet article que vous avez déjà créér un module personnel à votre instance DRUPAL.

Le principe est simple, on insert une nouvelle étape de validation lors de la soumission du formulaire dasn laquelle on va modifier les valeurs qui nous intéresse ou faire un autre traitement, comme insérer dans une base de données ou envoyé un email.

Les valeurs saisies et envoyées lors du submit se trouvent dans les tableaux :

$form_state['values']
$form_state['clicked_button']['#post']['submitted']
{syntaxhighlighter brush: php}
<?php
/* Modification des formulaires */
function VOTREMODULE_form_alter(&$form, &$form_state, $form_id) {
        // Modifier tous les formulaires webform
        if (substr($form_id, 0, 20) == 'webform_client_form_') {
            //on ajoute une étape de validation aux formulaires webform
            array_unshift($form['#validate'],'VOTREMODULE_form_alter_webform_contact_validate');
        }
}
/* fonction permettant de modifier les  */
function VOTREMODULE_form_alter_webform_contact_validate($form, &$form_state) {
        //Insérez ici le code que vous désirez, ci dessous, j'ajoute juste un email dans un champs caché
        $form_state['values']['submitted']['email'] = "email@gmail.com";
        $form_state['clicked_button']['#post']['submitted']["email"] = "email@gmail.com";
}
?>
{/syntaxhighlighter}

 

Drupal Hook, autoriser des modules à utiliser _alter pour un composant

Drupal Hook, autoriser des modules à utiliser _alter pour un composant

1 août 2011Drupal 6.x, PHP

L'avantage évidemment de Drupal est de permettre de modifier le comportement d'un module ou du sytème, mais sans modifier le corps du moteur ou d'un module.

Vous pouvez par exemple modifier n'importe quel formulaire Drupal en utilisant le hook hook_form_alter().

Une fois que l'on a compris comment faire, on veut pouvoir le faire partout ^^

Cependant, encore faut-il que les développeurs d'un module que vous venez d'installer par exemple et que vous souhaitez modifier vous en aient laissé la possibilité...

Si ce n'est pas le cas, vous n'aurez pas d'autre solution que d'ajouter vous-même ce code afin de vous permettre d'utiliser un hook.

Voici un exemple concret pour le module uc_order.module.

Exemple

Vous souhaitez modifier le panel de facturation d'Ubercart. Mais voilà, impossible aucun hook n'a été prévu à cet effet.

A vous de trouver où insérer le code qu'il faudra pour vous laisser cette possibilité. Pour le module uc_order.mdule , je modifie la fonction _order_pane_list()

Juste après l'appel vers d'autres modules module_invoke_all(), insérez le code  :

<?php
$panes = module_invoke_all('order_pane', NULL);
//PATCH
drupal_alter('order_pane', $panes);
?>


Et voilà, vous pouvez désormais utiliser le hook_order_pane_alter($op,$arg1).

 

Drupal 7, db_query migration de la version 6 à la 7

Drupal 7, db_query migration de la version 6 à la 7

1 août 2011Drupal 6.x, Drupal 7.x, PHP

Et oui toute évolution de version apporte son lot de nouveautés.

Sur Drupal 7, la fonction db_query() a été revu et corrigé. Auparavant, pour exécuter une requête SQL, vous deviez écrire votre fonction comme suit :

{syntaxhighlighter brush: php}
$result = db_query("SELECT field FROM {table} WHERE field_int = %d AND field_text LIKE '%s'", $int_var, $text_var);
while ($row = db_fetch_object($result)) {
// Boucle sur les réultats de la recherche.
}
{/syntaxhighlighter}

Aujourdh'ui c'est sensiblement la même chose à deux trois choses prêts !

1. On utilise plus de boucle while, mais un foreach qui va parser le résultat directement

2. L'insertion des variables dans une requête a changé : on n'utilise plus les %d, ou %s, mais une autre syntaxe :nom ou :votre_var.
Et c'est là qu'il faut faire attanetion ! Avant pour insérer une chaîne de caractère, vous deviez protéger votre var '%s' par des guillemets, désormais ce n'est plus la peine, et surtout il ne faut plus le faire. Sinon quoi ? et bien cela ne fonctionne plus  du tout ^^

 

{syntaxhighlighter brush: php}
$result = db_query("SELECT field FROM {table} WHERE field_int = :intvar AND field_text LIKE :textvar ", array(':intvar' => $int_var, ':field_text' => $text_var));
foreach ($result as $row) {
// Boucle sur les réultats de la recherche.
}
{/syntaxhighlighter}

Et voilà !

Drupal 7 affichage des champs d'un template node--typeContent.tpl.php

Drupal 7 affichage des champs d'un template node--typeContent.tpl.php

1 août 2011PHP, Drupal 7.x

Vous savez certainement comment customiser vos propres contenus dans drupal 7.

Juste un petit rappel sur ce point :

Créer un dossier templates dans votre thème, et y insérer vos fichiers .tpl.php personnalisés.

Pour maitriser l'affichage des pages de base de drupal vous devrez donc créer un fichier node--page.tpl.php.

Jusque là il n'y a pas beaucoup de différences avec drupal 6 (à part le nommage des fichiers avec 2 tirets et le nouveau répertoire templates).

Cependant, lorsque vous allez vouloir afficher les champs qui composent votre page, un champ image, body, date ..., vous serez un peu déstabilisé si vous avez l'habitude avec drupal 6.

On utilise désormais la méthode render(). Ensuite, tous les champs de votre contenus se trouvent dans la variable $content.

<?php
print "<div class='imageHome'>";
print render($content['field_image']);
print "</div>";
print render($content['body']);
?>

Récupérer le contenu d'un field de votre node

Pour afficher un field sans passer par la fonction render de drupal est donc ne pas passer par le sytsème de templating intégré, vous devrez récupérer manuellement la value du field et afficher cette valuecomme vous le désirez.

//On récupère un tableau correspondant aux value de field_title
$yourTitle = field_get_items('node', $node, 'field_title');
//Ensuite on affiche la value souhaitée
print (yourTitle[0]["value"]); 

Ceci marche avec tous avec tous les field de vos nodes.

Pages

Subscribe to RSS - PHP