Drupal 7: Программное изменение страницы просмотра и формы редактирования типа контента


Новичок в Drupal пытается создать свой первый модуль для Drupal 7.

На своем сайте я создал новый тип контента (имя машины: аннотация) из интерфейса администратора сайта. Пользователь может добавить новый экземпляр этого типа контента, используя форму, которую я определил с помощью FAPI. В функции отправки этой формы я делаю следующее:

function form_add_abstract_submit($form, &$form_state) {

  global $user;

  $node = new stdClass();
  $node->type = 'abstract';
  node_object_prepare($node);

  $node->title = $form_state['values']['abstract_title'];
  $node->language = LANGUAGE_NONE;
  $node->uid = $user->uid;

  // ... fill the rest of the node's fields here [...]

  if($node = node_submit($node)) {
    node_save($node);
    // Not sure about this way of defining the path to the created node
    $path = 'abstract/' . $node->nid;
    $node->path = array('alias' => $path);
    node_save($node);
    drupal_set_message(t('Abstract submitted');
  } else {
    form_set_error('description', t('ERROR'));
  }

  $form_state['redirect'] = 'index.php';
}

Как показано выше, я определяю путь к этим узлам как "абстрактный/[его идентификатор узла]". Затем, когда пользователь посещает этот URL-адрес, я бы хотелось бы показать две вкладки, одна из которых позволяет пользователю видеть поля узла, а другая - ссылку на форму для ее редактирования. Я попытался реализовать это, добавив следующие три пункта меню в свою функцию hook_menu:

$items['abstract/%'] = array(
      'title callback' => 'abstract_page_title',
      'title arguments' => array(1),
      'page callback' => 'abstract_page_view',
      'page arguments' => array(1),
      'access callback' => TRUE,
      'type' => MENU_CALLBACK,
  );

  $items['abstract/%/view'] = array(
      'title' => 'View',
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
  );

  $items['abstract/%/edit'] = array(
      'title' => 'Edit',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('my_module_form_abstract_edit', 1),
      'access callback' => TRUE,
      'file' => 'my_module_forms.inc',
      'type' => MENU_LOCAL_TASK,
  );

Однако, если я посещаю abstract/[идентификатор узла], моя функция abstract_page_view не вызывается, и отображается представление по умолчанию для отображения моего типа контента. Вкладка "Редактировать" в этом представлении также ссылается на абстрактный/[идентификатор узла]#наложение=узел/[идентификатор узла]/редактирование, а не на аннотация/[идентификатор узла]/отредактируйте, как я хотел бы.

Что я делаю не так? Должен ли я программно определять свой тип контента вместо того, чтобы делать это из серверной части администратора, или моя проблема в другом месте?

Author: tomurillo, 2013-02-01

1 answers

Если я понимаю, что вы пытаетесь сделать, вы хотите настроить страницу добавления/редактирования узла и страницу просмотра узла для вашего "абстрактного" типа контента.

Похоже, вы пытаетесь повторить то, что drupal уже делает для вас без видимой причины. Ваш код, похоже, на самом деле не делает ничего такого, чего drupal уже не делает для вас (из предоставленного вами примера кода). (В качестве примечания, чего вы на самом деле пытаетесь достичь?)

Если бы это было так, я бы не создавал полностью настраиваемые страницы. Drupal предоставляет вам крючки, чтобы вы могли изменять то, что он дает вам по умолчанию.

Например, страница добавления/редактирования узла (узел/добавить/аннотация и узел/[nid]/редактировать) может быть изменена с помощью hook_form_base_form_id_alter() или hook_form_FORM_ID_alter(). При изменении этих форм вы можете добавить свои собственные функции проверки и отправки, если вам нужно выполнить дополнительную отправку.

Для псевдонимов путей используйте модуль pathauto, который позволит вы должны установить псевдоним пути для своей страницы в abstract/[nid] - хотя, как правило, вам было бы лучше сделать что-то вроде abstract/[title] ради SEO и большего удобства для пользователей.

Для страницы добавления узла вы можете добавить псевдоним пути, перейдя в раздел администратор/конфигурация/поиск/путь. Затем вы можете сделать это чем-то вроде абстрактного/добавить вместо узла/добавить/абстрактный.

Поля Drupal должны быть способны обрабатывать практически любые данные, которые вы хотите обработать, особенно с помощью модулей как дата, ссылка, электронная почта и многое-многое другое.

Теперь, когда я знаю, что вы хотите сохранить некоторые данные узла во внешней базе данных, эта следующая часть представляет для вас интерес. Эти крючки узлов позволяют подключаться к системе CRUD узлов:

Если вам действительно действительно нужны дополнительные данные (не так часто, обычно вы можете делать то, что вам нужно, с полями), например, данные, которые вы храните в отдельной таблице базы данных, вы можете использовать крючки hook_node_view() для отображения пользовательских данных на странице просмотра узла, hook_node_load() для загрузки пользовательских данных в объект узла при каждой его загрузке, hook_node_delete() для удаления пользовательских данных при удалении узла, hook_node_insert() для вставки пользовательских данных при создании узла, hook_node_update() для обновления пользовательских данных при сохранении узла.

Есть и другие крючки, например, связанные с ревизией, если вы используете версии и связанные с индексом поиска, для добавления данных в индекс поиска и результаты поиска. Смотрите их здесь - http://api.drupal.org/api/search/7/hook_node_

Кроме того, если вы добавляете данные в узлы из своей внешней базы данных, которые не находятся в полях drupal, вас также могут заинтересовать API-интерфейсы, предоставляемые модулем Сущности. В частности, вы можете определить свои данные как свойства сущности, чтобы их можно было легко обрабатывать с помощью таких модулей, как правила и api поиска (и другие модули, использующие api сущности). См. http://drupal.org/node/1021466

Если вы действительно должны сделать это таким образом, у вашего hook_menu() также есть некоторые проблемы: Символы % в путях меню действительно следует заменить на %node, который затем вызовет node_load и правильно проверит nid в пути. См. http://drupal.org/node/224170 для получения дополнительной информации о загрузчиках подстановочных знаков меню.

Аннотация/% также не должна быть MENU_CALLBACK, она должна будьте MENU_NORMAL_ITEM.

В принципе, вы пытаетесь скопировать страницы узла/% узла/%/просмотра узла/%/редактирования, поэтому вам следует попробовать скопировать то, что есть в модуле узла в node_menu() для этих элементов, но просто измените путь. Затем вы можете сделать так, чтобы ваши новые пути выполняли то, что делал бы модуль узла в узле/% узел/%/просмотр и узел/%/редактирование. Однако затем у вас возникнут проблемы с другими модулями, которые добавляют пути узла/%/что-то (если вы используете какие-либо такие модули). В этом случае эти дополнительные вкладки на странице узла не будет присутствовать на ваших страницах, потому что их пути не будут совпадать.

Поэтому, если вам действительно не нужно иметь abstract/%/edit, я бы оставил меню в покое и просто использовал автоматический путь, чтобы иметь abstract/[nid] или abstract/[название] и оставил страницы редактирования как узел/[nid]/редактировать.

Альтернативное решение, в зависимости от того, лучше ли оно подходит для вашего варианта использования, состоит в том, чтобы вообще не использовать систему узлов и создать свой собственный пользовательский тип сущности. Таким образом, у вас будет абстрактный тип сущности, как пользователь, узел и термин таксономии.

Если вы на самом деле не используете какие-либо функции, предоставляемые системой узлов, это может быть лучшим решением. Это относительно просто, но недостатком является то, что многие существующие модули contrib работают только с узлами, а не с другими типами сущностей. Таким образом, те дополнительные функции, которые вам могут потребоваться, вам также придется кодировать самостоятельно. Таким образом, это зависит от того, есть ли у вас время для выполнения требуемой дополнительной пользовательской работы или если вы лучше использовать узлы, так что вы получаете совместимость из коробки.

 2
Author: rooby, 2013-02-04 10:51:12