Clickez pour obtenir d'autres articles sur les thèmes suivant :
envoyer à un ami
Clickez ici pour envoyer ce papier à un ami (ou à un ennemi, selon votre état d'esprit).
Version imprimable
Clickez ici pour la version imprimable. Mais si vous aimez les arbres, préférez la version électronique (PDF) juste à côté...
Version PDF Amoureux de la nature, clickez-ici (ou scannez le QR code) obtenir une version PDF.
Version qrcode Scannez ce QR code pour lire cet article sur votre mobile.
Créer des handlers de menu
le lun, 21/12/2009 - 11:07 dans Drupal
PaperAirplaneDocs.png

Tout drupalien sait ce qu'est un "élément de menu" : un machin qui se colle dans un... menu, et qui apparaît quelque part sur l'interface graphique pour permettre l'affichage d'une page. Ces éléments de menu sont généralement crées à la mano en passant par le backoffice, via la section Construction du site puis Menus. Là on peut ajouter des associations entre un chemin valide et un titre de lien.

Ce "chemin valide" est systématiquement fournit par l'un des modules activé (ex. user/login issu modules/user). Mais alors comment créer ses propres chemins liés à ses propres pages ou actions, sans passer par d'inutile (pour cela) usines à gaz comme Panel ou Views ?

Le but de ce tutoriel est de démystifier ce passage obligé de la vie d'un module.

Les sources

L'ensemble des sources de ce tutoriel est disponible ici. Il s'agit d'un serveur Subversion, donc vous pouvez aussi directement récupérer les sources dans votre dossier site/all/modules par la commande suivante :

gaston$cd /var/www/drupal/site/all/modules
gaston$mkdir tutoriels
gaston$cd tutoriels
gaston$svn co http://www.arnumeral.fr/subversion/public/tutoriels_drupal/tutoriel_menus
...
gaston$ 

Cycle de vie d'un requete

Lorsqu'apache reçoit une requête, par exemple http://mon_site/mon-super-article, il commence par ré-écrire la partie "chemin" de l'URL de sorte à la rendre assimilable par Drupal. C'est le fameux système d'URL simplifiées (clean UEL). L'URL devient alors http://mon_site/index.php?q=mon-super-article, index.php étant le point d'entrée de Drupal.

La partie ?q=mon-super-article est donc une variable $_GET['q'] que va recevoir drupal pour effectuer une action. La première étape pour résoudre ce chemin, est de déterminer si le contenu de $_GET['q'] ne serait pas hasard pas un alias en cherchant une correspondance dans la table url_alias. L'exemple est bien choisi, il en trouvera un qui sera node/666. mon-super-article est donc le chemin, et node/666 le chemin dit "interne", celui que va réellement prendre en charge un module.

Et c'est effectivement la seconde étape de Drupal, trouver quel module est en charge du chemin interne node/666. Plus exactement, et attention il va y avoir risque de confusion de vocabulaire, Drupal va chercher quel "menu" est associé à ce chemin. Pour ne pas entretenir la confusion trop longtemps, un "menu" pour les modules, est une association entre un chemin interne (ici node/666), et un module (ici, le module modules/node). Pour simplifier le discours, j'appellerais cela un menu handler pour le différencier des éléments de menu qui eux, associent un lien à un chemin interne.

Si aucun handler n'est trouvé, Drupal renvoie le fameux 404 fichier non trouve. Si le handler existe bien mais que l'utilisateur qui cherche à le déclencher n'a pas les droits pour cela, il renverra un 401 Access denied. Enfin si le handler existe et que l'utilisateur a les droits, Drupal va transférer le traitement à une des fonctions du module qui a déclaré ce handler.

Cette fonction, appelée callback a plusieurs possibilités. Si le chemin interne correspond à une page (c'est le cas de node/666), la fonction callback va renvoyer, par son return, une chaîne de caractère qui correspondra au coeur de page (région content). Drupal va alors récupérer cette chaîne, la faire passer dans le thème, et ainsi produire la page correspondant au chemin interne. C'est ainsi que l'article http://mon_site/mon-super-article sera affiché.

Autre cas de figure, le chemin interne n'est pas une page, mais une action comme par exemple node/666/delete (suppression d'un article). Dans ce cas, la fonction callback n'a aucune raison de renvoyer une chaîne de caractère. Elle va simplement supprimer l'article, et terminer, sans return par un drupal_goto pour rediriger une un chemin interne d'atterrissage.

Enfin, dernier cas un peu moins usité, le chemin interne doit renvoyer des données, par exemple du code XML pour une procédure AJAX. Dans ce cas le code sera imprimé (print ou echo) directement dans la fonction de callback, qui se terminera par un très brutal exit();, coupant ainsi la chique à Drupal.

Implémentation de hook_menu

Maintenant que le sujet est un peu dégrossi, voyons comment faire déclarer un handler par un module. Pour commencer, il nous faut un construire un module de base (voir ce tutoriel) dans lequel nous allons implémenter un hook_menu. Ce hook permet à Drupal de récupérer l'ensemble des handlers de menu publiés par un module donné et son implémentation ressemble à ceci :

function tutoriel_menus_menu() {
  $items = array ();

  $items['tutoriels/menus/simple'] = array (
    'title' => 'Un menu simple',
    'description' => "Ceci est un menu simple",
    'page callback' => 'tutoriel_menus_simple_menu_callback',
    'file' => 'tutoriel_menus.pages.inc',
    'access arguments' => array (
      'access content'
    )
  );

  return $items;
}
implémentation d'un hook_menu

Chaque handler déclaré par le hook_menu est une entrée pour un tableau qui sera renvoyé en retour de la fonction. La clef utilisée par ce tableau est le chemin interne pris en charge par le handler, et sa valeur, une structure le décrivant. Dans cette structure nous avons des éléments simples à comprendre comme title ou description qui permettrons à Drupal de créer un élément de menu à partir de ce handler. Notez que ces deux chaînes ne doivent pas utiliser la fonction de traduction t(...).

Déclaration de la callback

page callback est l'élément fondamental de ce handler. Il s'agit de la fonction qui va être appelée par Drupal pour effectuer l'action associée au chemin interne. Le paramètre file définit quant à lui dans quel fichier PHP cette fonction se trouve. Cette astuce a permis à Drupal 6 d'améliorer grandement ses performances par rapport à Drupal 5. En effet, file permet de ne charger que les fichiers PHP utiles au traitement d'un chemin, sans charger tout le reste.

Si le paramètre file est omis (ce qui n'est pas conseillé), Drupal cherchera la fonction parmi celles déjà chargée en mémoire. Si ce paramètre est présent, le fichier correspondant sera cherché dans le dossier du module (utilisez le paramètre file path si le fichier se trouve hors de ce dossier). D'une manière général, les callbacks correspondant à des pages sont rangées dans un fichier mon_module.pages.inc. Celles correspondant à l'administration dans mon_module.admin.inc, etc.

Droits associés au handler

Le dernier paramètre, access argument, contient un tableau de permissions nécessaires à l'accès au menu. Ici access content désigne le droit d'accéder au contenu, ce que tout le monde peut généralement faire. Mais par exemple pour limiter aux seuls administrateur, nous aurions pu mettre administer site configuration.

Ce paramètre access argument est en réalité utilisé conjointement avec le paramètre access callback. Mais lorsque ce dernier est omis, Drupal utilise par défaut la valeur user_access. Ainsi vous comprenez que ces deux paramètres correspondent en réalité à un appel à la fonction user_access(array('access content')) qui renvoie vrai si l'utilisateur courant a les droits demandés. A titre d'exemple, vous auriez pu aussi utiliser pour access callback les fonctions is_anonymous_user ou user_is_logged_in, toute deux fournies par le module user. Comme elles ne prennent pas de paramètre, le paramètre access arguments peut dans ce cas être omis.

D'une manière générale, vous pouvez utiliser la fonction qui vous chante pour gérer les droits, pour peu qu'elle renvoie true si l'utilisateur est valide et false dans le cas contraire.

Implémentation de la callback

Il ne nous reste maintenant plus qu'à implémenter la callback, en commençant par créer un fichier tutoriel_menu.pages.inc et y placer une fonction comme celle-ci :

function tutoriel_menus_simple_menu_callback() {
  $output="Coeur de page associé à ce modeste menu";
  return $output;
}
tutoriel_menus.pages.inc - callback générique

Bon, un peu simpliste comme rendu, mais c'est juste pour l'exemple. Vous pouvez mettre dans $output tout ce qui vous chante, de simple messages à des tableaux triables.

Vidange du cache de menus

Il ne nous reste maintenant plus qu'à tester cela. Attention cependant, ce hook n'est, pour des raisons de performances, invoqué qu'à l'activation du module. C'est très bien pour la première fois, mais moins drôle lors des essais suivants. Pour régler ce problème, je vous conseille d'installer le module administration menu qui dans son menu déroulant de droite, dispose d'une action de vidange du cache des menus.

Une fois le module activé, vous devriez voir apparaître dans votre menu Navigation, le nouveau menu Un menu simple. En l'activant, dans le coeur de page, doit apparaître le retour de notre callback.

Des éléments menus arborescents

Il est possible de prolonger l'exemple précédent en créant une cascade de menu. Basiquement, une telle arborescence consiste simplement à créer un menu par niveau de chemin. Dans le chapitre précédent, le chemin était tutoriels/menus/simple. Pour rendre visible les deux niveaux précédents, il nous font donc créer deux menus respectivement pour tutoriels, puis tutoriels/menus.

$items['tutoriels'] = array (
  'title' => 'Les tutoriels',
  'page callback' => 'tutoriel_menus_tutoriels_callback',
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  ),
  'expanded'=>true  
);

$items['tutoriels/menus'] = array (
  'title' => 'Les menus',
  'description' => t("Tutoriel sur les menus"),
  'page callback' => 'tutoriel_menus_tutoriels_menu_callback',
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  ),
  'expanded'=>true  
);
Ajout de deux niveaux de menu

Notez la propriété expanded qui permettent d'auto-déployer les deux niveaux pour que tout soit visible par défaut. Enfin, comme nous utilisons deux nouvelles callback, il faut aussi les ajouter dans tutoriel_menu.pages.inc

function tutoriel_menus_tutoriels_callback() {
  return "Les tutoriels";
}

function tutoriel_menus_tutoriels_menus_callback() {
  return "Les tutoriels des menus";
}
Ajout des deux callback

Il suffit maintenant de reconstruire les menus et d'observer le résultat.

Choix du menu cible

Par défaut, nos éléments de menu sont intégrés par Drupal dans le menu administration si le chemin commence par admin/..., ou dans le menu navigation le cas échéant. Il est cependant possible d'ajouter nos handlers ailleurs en utilisant la propriété menu_name. Pour illustrer cette possibilité, nous allons ajouter aux liens primaires (un menu généralement affiché en haut à droite de chaque page), l'élément de menu A propos de nous :

$items['informations'] = array (
  'title' => 'A propos de nous',
  'page callback' => 'tutoriel_menus_a_propos_callback',
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  ),
  'menu_name' => 'primary-links'
);
Ajout d'un élément de menu dans le menu 'liens primaires'

Comme toujours, il nous faut une nouvelle callback :

function tutoriel_menus_a_propos_callback() {
  return "Bla bla bla...";
}
Callback pour l'élément de menu 'information'

Une fois le cache des menus reconstruit, si vous allez dans l'administration des menus, sur le menu Liens primaires, vous devriez voir apparaître le nouvel élément de menu. Et si votre thème l'affiche par défaut en haut à droite de la page, il y sera directement visible.

L'astuce ici consiste à savoir que le nom interne du menu liens primaires est primary-links. En utilisant ce nom pour la propriété menu_name, nous avons forcé l'ajout de ces menus aux liens primaires. Notez que c'est un ajout totalement dynamique, au sens où les menus ainsi créés disparaîtront d'eux même à la prochaine reconstruction des menus si vous les supprimez de votre hook. En somme une alternative intelligente pour déployer facilement des menus en production sans avoir à se refrapper une configuration manuelle, par exemple pour instancier toutes les sections d'un site sur le menu "liens secondaires".

Les onglets

Une autre manière de gérer les menus arborescents est de les afficher sous la forme d'onglet. Drupal permet en effet de gérer ainsi deux niveaux d'onglets (vous en avez un exemple dans la configuration d'un thème). Ces onglets sont très faciles à mettre en oeuvre pour peu d'en comprendre la logique.

$items['tutoriels/menus/simple/onglet-1'] = array (
  'title' => 'Onglet 1',
  'type' => MENU_DEFAULT_LOCAL_TASK,
  'access arguments' => array (
    'access content'
  )
);

$items['tutoriels/menus/simple/onglet-2'] = array (
  'type' => MENU_LOCAL_TASK,
  'title' => 'Onglet 2',
  'page callback' => 'tutoriel_menus_onglet2_callback',
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  )
);

$items['tutoriels/menus/simple/onglet-2/onglet-2-1'] = array (
  'title' => 'Onglet 2.1',
  'access arguments' => array (
    'access content'
  ),
  'type' => MENU_DEFAULT_LOCAL_TASK
);

$items['tutoriels/menus/simple/onglet-2/onglet-2-2'] = array (
  'title' => 'Onglet 2.2',
  'page callback' => 'tutoriel_menus_onglet22_callback',
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  ),
  'type' => MENU_LOCAL_TASK
);
Ajout d'onglets

Comme vous le voyez, nous sommes ici proche des menus arborescents. La nouveauté est tout d'abord l'utilisation du paramètre type indiquant à Drupal que nous définissons ici des onglets (appelés Tasks, ou tâches). MENU_LOCAL_TASK marque un onglet normal et MENU_DEFAULT_LOCAL_TASK marque l'onglet par défaut pour un niveau. Notez l'absence de callback pour les handlers marqués MENU_DEFAULT_LOCAL_TASK. En effet, la règle est que chaque niveau d'onglet doit disposer d'un MENU_DEFAULT_LOCAL_TASK, et que ce handler est automatiquement au chemin interne de son handler parent. En d'autres termes, si vous cliquez sur Onglet 1, c'est le chemin de notre menu simple qui s'affiche et son handler qui est utilisé. De même en cliquant sur Onglet 2.1, c'est le handler et donc le chemin et la callback de l'onglet 2 qui est utilisé. Du coup, nous n'avons que deux callback à ajouter

function tutoriel_menus_onglet2_callback() {
  return "Contenu de l'onglet 2";
}

function tutoriel_menus_onglet22_callback() {
  return "Contenu de l'onglet 22";
}
Callbacks pour les onglets

Les handlers \"cachés\"

Comme nous l'avons vu plus haut, nous fabriquons dans notre module des handlers de menu, et non des éléments de menus. Si jusqu'à maintenant nous avions une création automatique d'éléments de menu pour chacun de nos handlers, c'est soit que nous ométions le paramétrage type, qui a pour valeur par défaut MENU_NORMAL_ITEM (comprendre "un handler pour lequel drupal doit créer un élément de menu"), ou que nous voulions afficher des onglets avec MENU_LOCAL_TASK et MENU_DEFAULT_LOCAL_TASK.

Maintenant, dans de nombreux cas nos modules n'ont aucun besoin d'éléments de menu mais juste une URL associée à une page et/ou une action. C'est par exemple le cas si nous voulons créer une action d'ajout, ou dans l'exemple qui suit, un simple Hello World.

$items['tutoriels/menus/hello'] = array (
  'page callback' => 'tutoriel_menus_hello_callback',
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  ),
  'type'=>MENU_CALLBACK
);
Ajout d'un handler sans élément de menu

Et comme toujours, nous ajoutons la fonction callback associée

function tutoriel_menus_hello_callback() {
  return "Hello World";
}
Callback du handler sans élément de menu

Une fois le cache de menu reconstruit, vous constaterez que cette fois, aucun élément de menu n'a été rajouté par Drupal. Pour utiliser ce handler, il nous faut directement taper son URL (ou chemin interne) directement dans la zone d'adresse du navigateur, soit http://mon_site/tutoriels/menus/hello.

Les seules différences avec les handlers que nous avons créé jusqu'à maintenant sont que nous n'avons fournit à Drupal ni titre, ni description, et que nous avons en revanche spécifié MENU_CALLBACK comme paramètre type. Ce type permet juste de dire à Drupal qu'il n'est pas utile de cherche à créer un élément de menu.

Handlers paramétrés

Ce type de handler sans élément de menu est très utile pour créer des actions comme "ajouter", "supprimer", etc. Encore faut il pouvoir fournir des paramètres à ce menu de sorte à pouvoir indiquer, dans l'URL, la référence de l'objet à détruire.

Depuis la version 6, Drupal dispose d'un système très bien fait pour passer des paramètres au handler, basé sur le caractère %. Ainsi si nous ajoutons le menu suivant :

$items['tutoriels/menus/hello1/%'] = array (
  'page callback' => 'tutoriel_menus_hello1_callback',
  'page arguments' => array(3),
  'file' => 'tutoriel_menus.pages.inc',
  'access arguments' => array (
    'access content'
  ),
  'type'=>MENU_CALLBACK
);  
Ajout d'un handler paramétré

Et que nous ajoutons la callback suivante :

function tutoriel_menus_hello1_callback($message) {
  return "Hello $message";
}
Ajout d'une callback paramétrée

Après reconstruction du menu, nous constatons que l'URL http://mon_site/tutoriels/menus/hello1/gaston provoque l'affichage du message Hello gaston. Pour comprendre ce qui se passe, retournons sur la déclaration de notre handler.

D'abord, nous avons dans le chemin interne un symbole % qui indique à Drupal que cet élément de chemin est un paramètre et peut donc prendre n'importe quelle valeur (ici gaston). Ensuite nous avons un nouveau paramètre page arguments contenant un tableau. Le contenu de ce tableau sera transmis à la callback. Si un de ses éléments est un chiffre, il sera préalablement par l'élément de chemin de rang correspondant (qui commence à Innocent. Si l'élément du tableau n'est pas un chiffre, il sera transmis tel-quel à la fonction.

Dans le cas de notre chemin, nous demandons à Drupal de placer en seul paramètre de la callback l'élément de chemin de rang 3 (c'est à dire le 4ième). C'est pour cela que notre callback dispose d'un paramètre $message qui recevra cette valeur.

Il est possible d'avoir plusieurs paramètres à la callback dont l'ordre et le type sera spécifié par page arguments. Mais plus intéressant encore, il est aussi possible de passer en paramètre des objets préchargés par Drupal. Pour tester cela, ajoutons encore un nouvel handler et sa callback :

  $items['tutoriels/menus/hello2/%user'] = array (
    'page callback' => 'tutoriel_menus_hello2_callback',
    'page arguments' => array(3),
    'file' => 'tutoriel_menus.pages.inc',
    'access arguments' => array (
      'access content'
    ),
    'type'=>MENU_CALLBACK
  );  

  // callback associée  à mettre dans tutoriel_menus.pages.inc
function tutoriel_menus_hello2_callback($user) {
  return "Hello {$user->name}";
}
Ajout d'un handler paramétré avec objet

Reconstruisons le cache des menus et lançons l'URL http://mon_site/tutoriels/menus/hello2/1. Vous devriez alors voir apparaître un Hello administrateur (ou n'importe quel nom que vous aurez utilisé comme administrateur de votre site).

L'astuce ici tient à l'utilisation non plus du simple %, mais de %user. Ce dernier indique à Drupal de "charger en mémoire l'utilisateur aillant pour ID l'élément de chemin donné dans l'URL". C'est ainsi que notre callback hérite d'un objet $user chargé à partir de l'ID 1 (celui de l'administrateur).

Il est intéressant de comprendre comment le "magie" fonctionne ici. Lorsque Drupal rencontre un paramètre de handler de la forme %objet, il va chercher une fonction pré-existante de la forme objet_load. S'il la trouve (ici c'est le cas, il s'agit de user_load), il lui passe en paramètre l'élément de chemin (ici 1) correspondant. Les fonctions objet_load renvoient toujours l'objet chargé à partir du paramètre (ici $user=user_load(1)), et c'est cet objet qui est utilisé comme paramètre à la callback.

En standard, Drupal dispose de plusieurs fonctions de type objet_load. Citons par exemple node_load qui par un %node permet de passer un contenu en paramètre d'une callback.

Mais vous pouvez aussi créer la votre. En effet, si vous utilisez un élément de chemin %mon_objet comme ceci

  $items['tutoriels/menus/hello3/%mon_objet'] = array (
    'page callback' => 'tutoriel_menus_hello3_callback',
    'page arguments' => array(3),
    'file' => 'tutoriel_menus.pages.inc',
    'access arguments' => array (
      'access content'
    ),
    'type'=>MENU_CALLBACK
  );  

  // callback associée  à mettre dans tutoriel_menus.pages.inc
function tutoriel_menus_hello3_callback($mon_objet) {
  return "Hello {$mon_objet['name']}";
}
Utilisation d'un chargeur custom

Vous devez en outre ajouter une fonction de type object_load pour que Drupal puisse faire correspondre le paramètre de rang 3, à l'argument %mon_objet :
function mon_objet_load($id) {
  return array('name'=>"Objet[$id]");
}
Chargeur custom

Vous n'avez maintenant plus qu'à reconstruire les menus et tester http://mon_site/tutoriels/menus/hello3/12 pour voir apparaître "Hello Objet[12]".

Conclusion

Voilà, fin du "petit" tour d'horizon sur les menus. Comme vous l'avez vu, le sujet est pour le peu dense, à la mesure de la richesse du sujet. Ceci étant dit, nous n'avons ici qu'abordé l'essentiel, il reste encore beaucoup de choses à découvrir en explorant l'API des menus.

Les commentaires

Rdumas, le mar, 22/12/2009 - 13:07

Salut, je n'ai pas (encore) de remarque intelligente à te faire, je découvre Drupal car c'est la solution que j'ai choisi pour développer une appli web à destination d'entreprises?

1. (HS) Est ce que l'investissement dans l'apprentissage vaut la chandelle ou bien dois je rester avec mon PHP natif à coder dans mon coin (coin!) en réinventant la roue
Mes expériences en Appli Web sont du bête PHP/Mysql pour des carnets d'adresse, des gestion de bibli et de trajets.
Je demande conseil. Pourrions nous en discuter par mail ?

2. J'ai imprimé les articles que tu as récemment effacé sur les types de contenu,l AHAH et le schema API , est ce que tu les remettras en ligne ?

3. Ton menu haut déconne, les liens articles et tutorial disparaissent

Yoran, le mer, 23/12/2009 - 07:10

1. D'une manière générale j'aurais tendance à dire que oui, le jeu en vaut la chandelle car le niveau de technicité d'une application WEB de nos jours dépasse largement ce que l'on est capable de faire dans son coin. Ce qui ne veut pas dire que c'est impossible, loin de là, mais que c'est peut-être une perte de temps.

2. Ils reviendront lorsque je les aurais mis en cohérence avec le reste.

3. Hum, quel navigateur ? Je ne constate cela ni sous FF, ni sous chrome

Rdumas , le mer, 23/12/2009 - 15:49

1. Ok, je suis un peu effrayé car ce que je sais faire ce sont mes fichiers php qui s'appellent les uns les autres
Je suis venu à Drupal car je fais des sites web (d'une part) et il m'a semblé que CCK et Views me feraient mon application comme un RAD (genre Codecharge)
Maintenant que je suis convaincu (j'ai acheté le Pro Dev with Drupal, je l'attend incessamment) qu'il me faut créer mon appli comme un module (ou un ensemble de modules) de Drupal, je m'inquiète de voir arriver le jour où je commencerai à coder, disons que ton exemple d'application m'aiderait bien à comprendre ce que je dois faire pour gérer mes utilisateurs, mes pages de saisie d'info et le traitement de celles ci pour génerer plusieurs documents pdf (ou vues)
Bien sur j'ai commencé à voir dans tes tutos les facilités offertes par les API, ça me met l'eau à la bouche (rien que les connections à la bdd)

2. ok merci

3. FF 3.5.6 et IE8
En fait, le curseur est un peu foufou et en se deplaçant, il efface Tutoriel, Articles, Société et au bout de quelques allez retour erratiques, il ne reste que Accueil
Sous IE8 on voit mieux que les items ainsi disparus sont en fait decalés une ligne plus bas mais comme ils sont blanc sur fond blanc ....

Yoran, le jeu, 24/12/2009 - 07:00

1. Perso je ne suis pas un fanatique de views, je n'en vois en fait pas trop l'intérêt pour qui sait coder une requête SQL. Ceci étant dit, ne t'embarque pas trop vite sur des tonnes de modules custom. D'expérience, tu arrives à construire une appli web à 80% avec ce qui est fourni en standard + une poignée de modules vitaux.

3. Yep, c'est réglé, j'ai trouvé le fautif Wink

capoucho, le mer, 23/12/2009 - 15:42

Salut,

Super ces petits tutos !

En attendant que vous remettiez aussi le tuto sur la liste des courses que j'avais ajouté dans mes favoris et que je ne vois plus !
Mais j'ai bien compris que c'était le grand ménage d'hiver... Smile

Bonne chance, et merci, car grâce à vous j'ai pu enfin comprendre comment personnaliser son appli web avec Drupal, comme un vrai développeur web finalement !! Quand on peut éviter de passer par une admin qui produit du mauvais code, autant le faire à la main...

Timos , le mer, 23/12/2009 - 23:37

Hello

Merci à nouveau pour ce tuto, je n'ai pas encore tout suivi mais c'est super instructif.

Deux questions et une remarque :

  • tout d'abord ta remarque concernant la non-utilisation de la fonction de traduction t() dans les paramètres "title" et "description" est-elle vraiment valable pour "description" ? Dans tes sources tu l'utilises et du coup j'ai testé... il semblerait que ça marche
  • pour vidanger le cache des menus, la commande drush cache clear est-elle valable ? si oui quand je teste les menus en arborescences, le premier menu du tuto ne se place pas dans l'arborescence prévue... est-ce normal ?

Et ma remarque : je constate le même phénomène que Rdumas à propos de ton menu, je suis sous une Ubuntu 8.10 avec FF 3.5.5.

Merci encore pour tous ces tutaux

Yoran, le jeu, 24/12/2009 - 07:01

Oui, désolé, c'est une erreur, j'ai enlevé le t(...). La doc de hook_menu spécifie bien que dans les deux cas (title et description) ce sont les chaînes non traduites qui doivent être fournies.

Timos , le jeu, 24/12/2009 - 12:00

Oui, j'ai été voir la doc. Bon j'imagine que cela doit avoir une incidence sur le bon fonctionnement du truc, mais en ce qui concerne la description, ça avait l'air de fonctionner avec la chaîne passée dans la fonction t().

J'ai vu également l'on pouvait customiser le titre en utilisant une fonction callback avec un

'title callback' => 'mon_menu_title_callback'

Bon à savoir pour la traduction du titre : Si cette fonction n'est pas spécifiée, par défaut Drupal considère que c'est la fonction t() qui est passée en paramètre. Du coup le titre reste traduisible.

Je ne sais pas ce que cela donne pour la description.

Bon sur ce, je break et je vais préparer mon chapon Wink

gagarine , le jeu, 07/01/2010 - 14:36

Bravo pour ce tuto, bien que je connaissais le domaine je l'ai lut avec plaisir et le recommande!

J'utilise souvent views pour ces facilités de thème. Mais c'est vrais que niveau performance c'est pas toujours la joie. Cependant, c'est un bon modeleur de requête qui permet de voir rapidement quelles tables/champs doivent être chargés ensuite rien n'empêche de copier cette requête dans un module (et nettoyer le code SQL).

Yoran, le dim, 21/02/2010 - 22:30

Le problème c'est que pour bon nombre de site que j'ai pu avoir entre les mains, le travail d'optimisation que tu évoques a bien souvent été, comment dire, évité ? Wink

Mais je suis absolument d'accord sur l'aspect "modeleur" de views, même si avec le temps, on fini par avoir le schéma de la base bien en tête et du coup ne plus trop avoir besoin de cela.

capoucho, le lun, 04/01/2010 - 12:10

Bonjour,

Serait-il possible que vous remettiez en place le tutoriel sur la liste des courses ?

J'avais complètement oublié de télécharger les sources, et du coup ça fait deux semaines que j'attends de les revoir. J'ai bien compris que vous faisiez le ménage pour tout remettre en ordre, mais pensez-vous le remettre prochainement en ligne ? Ou peut-être un accès temporaire aux sources serait-il envisageable ??

Merci d'avance pour votre réponse...

Timos , le lun, 04/01/2010 - 16:32

Hello capoucho
les sources (code) pour les tutos sont toujours disponibles sur le serveur svn si je ne m'abuse
A+
Tim

capoucho, le lun, 04/01/2010 - 18:03

Salut Timos,

Alors à ce compte là, je veux bien que tu me donnes l'adresse sur le serveur svn... Smile Car je ne la retrouve pas pour la liste des courses.

Merci !

Timos , le lun, 04/01/2010 - 21:52

ouaip, désolé :
http://arnumeral.fr/subversion/public/tutoriels_drupal/tutoriel_listes/

bon, en même temps je n'avais pas fais ce tuto (j'attendais la refonte) donc je ne suis pas sûr que cela corresponde à ce que tu cherches.

Yoran, le dim, 21/02/2010 - 22:32

Non, désolé les sources ne sont plus sur le dépôt mais maintenant cela devrait vite arriver. Entre temps j'ai mon petit qui est arrivé et qui m'a pris pas mal de temps (et c'est bien normal Wink.

Idéalement, dans le procesus de reconstruction des tutoriaux, j'aimerais caser un intercalaire sur les formulaires (FormAPI) qui permettrait d'aborder sereinement la création d'un type de contenu custom.

Publier un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement. Si vous avez un compte gravatar, l'utilisez pour afficher votre avatar.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <br> <p> <img> <sup> <a>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Every instance of custom tags in the input text will be replaced with a specific tool shortcut.
  • Textual smileys will be replaced with graphical ones.

Plus d'informations sur les options de formatage