web-dev-qa-db-fra.com

Affichage d'une page d'édition de nœud avec drupal_get_form () et hook_menu ()

J'utilise drupal 7 et je suis bloqué sur un problème très basique. Je voudrais simplement montrer la page d'édition à un identifiant de nœud connu. Je sais qu'il existe des articles similaires, mais ils ne l'ont pas non plus travailler ou je n'ai pas compris le thème. Mon module ressemble à ceci:

<?php
/*
 * Show the edid page to a specific nid.
 */

function control_center_menu() {
  $items = array();
  module_load_include('inc', 'node', 'node.pages');
  $nid = '4';
  $node = node_load($nid);
  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('page_node_form', $node),
    'access callback' => TRUE,
  );
  return $items;
}

Cependant, lors de test/test, je reçois un tas d'erreurs:

Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'node_form' not found or invalid function name in drupal_retrieve_form() (line 795 of /home/christian/workspace/gigs/includes/form.inc).
Notice: Undefined index: #node in menu_form_node_form_alter() (line 629 of /home/christian/workspace/gigs/modules/menu/menu.module).
Notice: Trying to get property of non-object in menu_form_node_form_alter() (line 629 of /home/christian/workspace/gigs/modules/menu/menu.module).
Notice: Undefined index: #node in menu_form_node_form_alter() (line 630 of /home/christian/workspace/gigs/modules/menu/menu.module).
Notice: Trying to get property of non-object in menu_form_node_form_alter() (line 630 of /home/christian/workspace/gigs/modules/menu/menu.module).

Et au lieu de la forme du trou, je ne reçois que la case à cocher Paramètres du menu et les paramètres du chemin URL.

Qu'est-ce que je fais mal? J'ai essayé dur de trouver un exemple amical de noob mais je n'en ai pas trouvé ... Merci beaucoup à l'avance!

6
user8878

hook_menu() n'est évalué que lorsque les caches sont reconstruits, donc l'appel à module_load_include() ne sera pas appelé lorsque le chemin sera réellement visité.

Ce hook est uniquement destiné à déclarer des éléments de menu, s'il y a une logique à ajouter pour un chemin, cela devrait se produire dans le rappel d'accès/rappel de page comme ceci:

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

  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'control_center_test_callback',
    'page arguments' => array('page_node_form', $node),
    'access callback' => TRUE,
  );
  return $items;
}

function control_center_test_callback() {
  module_load_include('inc', 'node', 'node.pages');
  $nid = '4';
  $node = node_load($nid);

  return drupal_get_form('page_node_form', $node);
}

Puisque vous transférez vers une page d'édition de noeud statique, il peut être plus facile de simplement définir le rappel de la page sur drupal_goto() et de coder en dur l'URL:

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

  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'drupal_goto',
    'page arguments' => array('node/4/edit'),
    'access callback' => TRUE,
  );
  return $items;
}
7
Clive

Vous devez définir le rappel de menu comme dans le code suivant.

  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('page_node_form', $node),
    'file path' => drupal_get_path('module', 'node'),
    'file' => 'node.pages.inc',
    'access callback' => TRUE,
  );

N'oubliez pas qu'une implémentation de hook_menu() n'est invoquée que lorsque les menus sont reconstruits, pas chaque fois qu'une nouvelle page est demandée à Drupal. Par conséquent, le formulaire obtiendrait un objet de nœud mis à jour uniquement lorsque votre module est installé ou lorsque les menus sont en cours de reconstruction; dans d'autres cas, le formulaire obtiendra une copie statique de l'objet nœud, qui ne reflète pas l'objet nœud réel.

Il serait préférable de faire tester/tester un alias de chemin pour node/4/edit. De cette façon, le formulaire obtiendrait à chaque fois un objet de nœud mis à jour.

3
kiamlaluno

J'ai utilisé le code comme suit:

function mymodule_menu() {

  $items = array();

  $items['user/%user/firm'] = array(
    'title' => 'Firm',
    'page callback' => 'firm_callback',
    'page arguments' => array(1),
    'access callback' => 'user_check',
    'access arguments'  => array(1),
    'type' => MENU_LOCAL_TASK,
  );

  return $items;
}

function firm_callback($userobj) {
    ....

    if ( isset($node) ) { // existed node

        $form_state['build_info']['args'] = array($node);
        form_load_include($form_state, 'inc', 'node', 'node.pages');
        $form = drupal_build_form('firm_node_form', $form_state);
        return $form;

    } else { // new node

        module_load_include('inc', 'node', 'node.pages');
        $form = node_add('firm');
        return drupal_render($form);

    }
}    

function mymodule_form_firm_node_form_alter(&$form, &$form_state, $form_id) {
  form_load_include($form_state, 'inc', 'node', 'node.pages');
}
0
Dimetry