Добавление материала прямо из раздела, в котором находиться пользователь.

Главные вкладки

Аватар пользователя Wet Wet 9 апреля 2008 в 0:00

Проблема такова:
Некоторым моим пользователям сайта неудобно добавлять контент только через одно место (ссылка Создать -> "Тип материала..."). Необходимо сделать так, что бы пользователь мог добавлять новый материал прямо из категории, в которой он (пользователь) находится. То есть нужно реализовать ссылку добавления так, как например в модуле Форум ("Начать новое обсуждение.").
Дополнительного модуля, реализующего эту функцию, не нашел. Прошу помощи у друпаловцев.

Комментарии

Аватар пользователя J. Bravo J. Bravo 9 апреля 2008 в 0:50

А что используется для вывода материалов по категориям? Если views, то достаточно разместить ссылку типа /node/add/mytype в заголовке view. Собственно, такую ссылку можно разместить в любом месте, откуда пользователям удобно размещать материалы.

Аватар пользователя gorr gorr 9 апреля 2008 в 1:16

Неплохая у Вас получилась фраза:"Некоторым моим пользователям сайта неудобно добавлять контент только через одно место" Smile

Аватар пользователя Wet Wet 9 апреля 2008 в 10:24

Да, с юмором написано Smile Но в каждой шутке есть доля правды: юзабилити в друпале не очень хорошо продуман. Сами разработчики это уже поняли.
С view все ясно, а как тогда быть с taxonomy/term/id.
Да и еще проблема в том, что бы при создании автоматически выбирался термин в выподающем списке словаря. Тут я чувствую придется лопатить код...

Аватар пользователя Химический Али Химический Али 9 апреля 2008 в 10:48

//возвращает TRUE только если выводится узел определенного типа (gift)
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
return ($node->nid && $node->type == 'gift'); //gift заменить на нужный тип материала
}

Отсюда ($node->type) получаете тип материала. По нему формируете ссылку вида node/add/$node->type

Аватар пользователя Wet Wet 9 апреля 2008 в 11:46

Спасибо! Но вот только термин будет выбираться автоматически? Да и ссылка должна быть в таксономии, а не в ноде.

Аватар пользователя gorr gorr 9 апреля 2008 в 12:08

Это в блоке:
if(arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2))) {
$output = l(t('create YOUR_NODE_TYPE'), node/add/'YOUR_NODE_TYPE'/arg(2));
}

А в модуле вставляем хук
YOUR_MODULE_form_alter ,в котором правим форму добавления нода вашего типа
при условии, что существует и является целым arg(3)
Изменяем именно поля таксономии, так, чтобы по дефолту выбирался терм с ключом arg(3)
Таксономия для нового нода выдаст пустые поля, поэтому перекрываем в нашем случае.

Аватар пользователя Wet Wet 9 апреля 2008 в 12:19

Спасибо, все в принципе понятно. Вот только вопрос... Хук как я понял прописывать в модуле taxonomy. А можно как-н. избежать этого и прописать код в отдельном файле, что бы потом не мучиться с обновлением системы.

Аватар пользователя gorr gorr 9 апреля 2008 в 12:34

/**
* Implementation of hook_form_alter().
* Generate a form for selecting terms to associate with a node.
*/
function taxonomy_form_alter($form_id, &$form) {
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
$node = $form['#node'];

if (!isset($node->taxonomy)) {
if ($node->nid) {
$terms = taxonomy_node_get_terms($node->nid);
}
else {
$terms = array();
}
}
else {
$terms = $node->taxonomy;
}

$c = db_query(db_rewrite_sql("SELECT v.* FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $node->type);

while ($vocabulary = db_fetch_object($c)) {
if ($vocabulary->tags) {
$typed_terms = array();
foreach ($terms as $term) {
// Extract terms belonging to the vocabulary in question.
if ($term->vid == $vocabulary->vid) {

// Commas and quotes in terms are special cases, so encode 'em.
if (strpos($term->name, ',') !== FALSE || strpos($term->name, '"') !== FALSE) {
$term->name = '"'.str_replace('"', '""', $term->name).'"';
}

$typed_terms[] = $term->name;
}
}
$typed_string = implode(', ', $typed_terms) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL);

if ($vocabulary->help) {
$help = $vocabulary->help;
}
else {
$help = t('A comma-separated list of terms describing this content. Example: funny, bungee jumping, "Company, Inc.".');
}
$form['taxonomy']['tags'][$vocabulary->vid] = array('#type' => 'textfield',
'#title' => $vocabulary->name,
'#description' => $help,
'#required' => $vocabulary->required,
'#default_value' => $typed_string,
'#autocomplete_path' => 'taxonomy/autocomplete/'. $vocabulary->vid,
'#weight' => $vocabulary->weight,
'#maxlength' => 255,
);
}
else {
// Extract terms belonging to the vocabulary in question.
$default_terms = array();
foreach ($terms as $term) {
if ($term->vid == $vocabulary->vid) {
$default_terms[$term->tid] = $term;
}
}
$form['taxonomy'][$vocabulary->vid] = taxonomy_form($vocabulary->vid, array_keys($default_terms), $vocabulary->help);
$form['taxonomy'][$vocabulary->vid]['#weight'] = $vocabulary->weight;
$form['taxonomy'][$vocabulary->vid]['#required'] = $vocabulary->required;
}
}
if (is_array($form['taxonomy']) && !empty($form['taxonomy'])) {
if (count($form['taxonomy']) > 1) { // Add fieldset only if form has more than 1 element.
$form['taxonomy'] += array(
'#type' => 'fieldset',
'#title' => t('Categories'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
}
$form['taxonomy']['#weight'] = -3;
$form['taxonomy']['#tree'] = TRUE;
}
}
}

Вставляете в свой модуль такую же, только подправленную как следует в вашем случае.

Аватар пользователя gorr gorr 9 апреля 2008 в 12:43

То есть там в начале функции проверяем наличие arg(3) и если он задан, то меняем дефолтные установки на терм с таким tid.
Кстати код для блока я тоже бы в этот модуль вынес в хуке YOUR_MODULE_block()

Аватар пользователя Wet Wet 9 апреля 2008 в 12:46

Вобщем я сделал комбинацию.
Блок +

if (is_numeric(arg(3))) {
   $form['taxonomy'][$vocabulary->vid]['#default_value'] = arg(3);
} 

в taxonomy_form_alter.

Всем спасибо!

Аватар пользователя Wet Wet 9 апреля 2008 в 15:03

Создаешь блок, записываешь в него PHP-код.

<?php
if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)))
{
$voc = taxonomy_get_vocabulary(arg(2));
foreach($voc->nodes as $type) {
echo l(t('Create '.$type) . " ", "node/add/$type/".arg(2));
}
}

В taxonomy.module находишь 745-ую строку и вставляешь туда следующий код:

if (is_numeric(arg(3))) {
 $form['taxonomy'][$vocabulary->vid]['#default_value'] = arg(3);
}

Актуально для Drupal версии 5.7.

Аватар пользователя Wet Wet 9 апреля 2008 в 20:20

Вот только возникла странная ошибка. Почему-то на некоторых терминах в коде блока выдается ошика.

taxonomy_get_vocabulary(arg(2)); ничего не возвращает например по taxonomy/term/42