Bien que cela puisse paraître compliqué de l’extérieur, créer et modifier des contenus Drupal sans l’aide de l’interface d’administration est une chose relativement simple lorsque l’on s’est déjà confronté au problème. Néanmoins il faut être prudent avec ce que vous voulez sauvegarder, puisqu’en outrepassant le système naturel de création de contenus via l’interface d’admin vous avez la possibilité de faire tout et n’importe quoi et d’empêcher les autres modules de fonctionner correctement.

Créer des nodes programmaticalement
©copyright

Voici donc un poste très simple sur la création de nodes via la programmation.


1.1 Initialisation de l’objet node

$node = new stdClass(); // Création d’un nouvel objet
$node->type = "article"; // Spécification du type de contenu à créer
$node->title = "Le titre de votre nouveau node";
$node->language = LANGUAGE_NONE; // Définition de la langue du contenu.
$node->uid = 1; // Ajout de l’auteur du node
$node->path = array('alias' => 'article/chuck-norris-is-a-jedi'); // Ajout de l’url du contenu
node_object_prepare($node); // Création des valeurs par défaut.

// Do your stuff

$node = node_submit($node); // Prépare le node avant l’enregistrement (date + auteur) si les champs sont vides.
node_save($node); // Enregistrement du node.

Notes :
- Définition de la langue : Si le module Locale n’est pas activé sur votre site, utilisez la constante LANGUAGE_NONE afin de ne pas spécifier de langue en particulier à votre contenu, sinon insérez la langue désirée.
- Node_object_prepare() : remplit par défaut certaines valeurs telles que le statut, la promotion en page d’accueil, les commentaires ou encore le sticky.

1.2 Ajout du champ body

Au passage, depuis cette dernière version le champ body n’est plus obligatoire et peut être supprimé/caché depuis l’interface de gestion des champs.

$body_text = 'Chuck Norris donne fréquemment du sang à la Croix-Rouge. Mais jamais le sien.';
$node->body[$node->language][0]['value'] = $body_text; // Votre texte
$node->body[$node->language][0]['summary'] = text_summary($body_text); // Résumé de votre champ body si vous en voulez un.
$node->body[$node->language][0]['format'] = 'filtered_html'; // Format d’entrée du champ.

Notez ici la réutilisation du champ $node->language défini à l’étape précédente, cette variable vous servira souvent pour récupérer les informations de vos champs.

1.3 Remplissez vos champs

Rien de compliqué puisque la manip’ est la même que pour le champ body, il suffit d’ajouter la valeur désirée dans le champ voulu.

$node->field_text_list[$node->language][0]['value'] = 'Pomme';

Par contre certain champ ont besoin de plus d’informations comme le champ texte à qui il faut renseigner le format d’entrée.

$node->field_custom_name[$node->language][0]['value'] = 'Texte dans mon champ custom';
$node->field_custom_name[$node->language][0]['format']  = 'text_format'; // Si votre champ à un format d’entrée n’oubliez pas  de le renseigner.

1.4 Renseigner un champ nodereference

Si vous utilisez le module nodereference pour lier vos contenus, il vous suffit simplement d’indiquer le nid du node dans le champ pour que cela fonctionne.

$node->field_nodereference[$node->language][]['nid'] = 12;

1.5 Insérer un terme à votre node

Si votre terme existe déjà, ajoutez simplement l’Id de celui-ci à votre champ.

$node->field_tags[$node->language][]['tid'] = 8; // field_tags, correspond au nom du champ et 8 à son id

Sinon, si vous voulez en créer un nouveau procédez comme suit :

$node->field_tags[$node->language][] = array (
  'vid' => 1,  // Id du vocabulaire
  'tid' => 'autocreate',
  'name' => 'Mon term', // Votre term
  'vocabulary_machine_name' => 'tags'
);

1.6 Ajouter un fichier

Le nouveau système de fichier mérite un post à lui tout seul pour bien le comprendre et s’en servir, du coup je vous livre toute faite la solution pour ajouter un fichier déjà présent sur votre site à votre contenu.

$filepath = drupal_realpath('misc/druplicon.png');  // Création du chemin du fichier
// Création de l’objet contenant les propriétés du fichier.
$file = (object) array(
  'uid' => 1,
  'uri' => $filepath,
  'filemime' => file_get_mimetype($filepath),
  'status' => 1,
);
$file = file_copy($file, 'public://'); // On déplace le fichier à la racine du système de fichiers
$node->field_image[LANGUAGE_NONE][0] = (array)$file; // On assigne le fichier au champ

2 Mise à jour du contenu

$nid = 1;
$node = node_load($nid);
$node->title = 'Mise à jour du titre';
node_save($node);

On charge le node avec un id, on met à jour le champ qui nous intéresse et on le sauvegarde. Si vous avez plusieurs nodes à mettre à jour, utilisez la fonction node_load_multiple() qui vous évitera de faire plusieurs requêtes sur la base de données.



Voilà, j’espère que cet article et les quelques liens ci-dessous vous permettront de vous aider. Il y a pas mal de modules qui font de la création de nodes comme ça. En trouver un et le décortiquer reste la meilleure solution pour apprendre. Si toutefois vous avez plus d’informations, je suis preneur :)

Voici les quelques sources qui m’ont aidées à comprendre les changements de cette nouvelle version:

7 Responses to Comment créer et mettre à jour un node par la programmation

Avatar

Cyprien PROUVOT

août 18th, 2011 at 22 h 31 min

Très synthétique et indispensable pour bien débuter la manipulation des nodes sur Drupal.

Juste une question : le $node->language est indispensable à chaque fois? Et à quoi correspond le tableau [0] qui suit?

Avatar

Julien

août 19th, 2011 at 8 h 42 min

Si ton site ne gère pas de multi-lingue tu peux très bien utiliser la constante LANGUAGE_NONE à la place de $node->language, mais il te faudra obligatoirement y mettre une valeur, c’est comme cela qu’est définie la structure d’un champ créé par la field api.

Chaque field peut être un champ multiple, d’où le tableau à la fin. Par exemple, si tu as autorisé 4 champs de saisies tu pourrais aller jusqu’à la valeur [3] pour récupérer une info. Effectivement si tu ne proposes qu’un champ de saisie simple, ça peut paraitre inutile de devoir faire cela. Or s’il n’y avait pas cette possibilité, tu ne pourrais pas transformer ton champ simple en un champ multiple puisque tu n’aurais pas la même structure. En plus, ça permet de garder une homogénéité du code et donc pas besoin de se casser la tête pour récupérer une valeur.

Avatar

Cyprien PROUVOT

août 19th, 2011 at 9 h 51 min

Effectivement çà parait logique présenté comme çà. Merci pour cet éclaircissement!

Avatar

Jérôme

août 20th, 2011 at 21 h 50 min

Je n’ai pas testé mais je sens que ça va m’être utile à l’avenir. Donc je garde le lien dans un coin :)
J’avais simplement une question de version, est-ce que ça fonctionne pour Drupal 6 et Drupal 7 ? Ou est-ce limité à Drupal 7 ?
Merci.

Avatar

Julien

août 21st, 2011 at 17 h 49 min

Non il est tout à fait possible de faire la même chose avec Drupal 6. Le code est juste un peu différent.

Avatar

Jérôme

août 21st, 2011 at 22 h 31 min

Merci pour l’info.

Avatar

Gilles

décembre 21st, 2011 at 14 h 57 min

Merci pour cet article très intéressant.
Je m’intéresse à l’externalisation de la saisi pour faciliter la prise en main de contributeurs non expérimentés.
Avez-vous essayez de créer du contenu sans l’administration Drupal et sans code, mais avec word par exemple ? Je pense à MetaWeblog API comme dans cet article : http://www.sysarchitects.com/node/64 ?

Comment Form



About me

about me

Bienvenue sur mon blog. Sur cet espace j’essaie de partager au mieux ma passion pour le web et actuellement mon engouement pour Drupal. Vous trouverez ici mes découvertes, mes problématiques et les solutions rencontrées.

I am going to DrupalCon London!

Commentaires

  • zanane: Merci Julien ! Bravo pour ton site et ton esprit de partage [...]
  • vikin: Bonjour Julien. Cela fait quelques temps que je souhaite créer un blog en utilisant Drupal. Cer [...]
  • Julien Desrosiers: Bonne idée! Ça me fait penser à The Daily WordPress Reference, qui est un peu comme ça mais q [...]
  • fofiedelly: merci pour les astuces!! en passant ton blog tombe à l'heure meme où je me met sous drupal et il e [...]
  • Julien: Bonjour Non il n'y aura pas de version Française de [...]