Правильная обработка $_GET-запроса

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

Аватар пользователя lena_elena4 lena_elena4 16 марта 2009 в 15:55

Ссылки в меню - термины одного словаря.
При нажатии на ссылку должны вывести "подтермины", родитель которых - пункт меню.
Не пойму, почему у меня не показывается страница, на которой должны появиться "подтермины".
Я так думаю, причина в неправильной передаче $_GET-параметров.

//Меню
function library_menu() {
  $items = array();
  $items['taxonomy/term/%term'] = array(
  'title' => t('Литература'),
  'description' => t('Выводим все ссылки'),
  'page callback' => 'author',
  'access callback' => TRUE,
  'type' => MENU_CALLBACK
  );
return $items;
}

//callback-функция
function author() {
$term = isset($term) ? intval(arg(2)) : 0;
  $page_content = '';
  $content = db_query("SELECT td.name FROM {term_data} td
    INNER JOIN {term_hierarchy} th
        ON td.tid = th.tid WHERE th.parent = $term"
);
  if(!$result) _db_error_page($error = 'Error in $sql');
  while ($links = db_fetch_object($content))
   $page_content .= l(htmlspecialchars($links->title),"node/$links->nid") . '<br />';
  //проверяем, есть ли контент
  if ($page_content != ''){
  //отобразить страницу
  return $page_content;
  }
}

Комментарии

Аватар пользователя lena_elena4 lena_elena4 16 марта 2009 в 16:36

Только что увидела. Вот это:
if(!$result) _db_error_page($error = 'Error in $sql');
поменять на:
if(!$content) _db_error_page($error = 'Error');

Но вопрос остается открытым.

Аватар пользователя goodboy goodboy 16 марта 2009 в 16:02

Запрос возвращает ведь td.name, а вы выводите title,nid
Посмотрите структуру объекта $links при помощи print_r( $links )

Также непонятна проверка на $result

Аватар пользователя lena_elena4 lena_elena4 16 марта 2009 в 16:09

это да, исправила.
Запрос теперь SELECT td.tid,td.name FROM {term_data} td
INNER JOIN {term_hierarchy} th
ON td.tid = th.tid WHERE th.parent = $term
подставляю конкретное значение $term, проверяю в самой базе, запрос результат возвращает, но страница все равно пустая.

Аватар пользователя goodboy goodboy 16 марта 2009 в 19:12

1. Проверьте, чему равно значение $term внутри функции и результирующий запрос.

$content = db_query("SELECT td.name FROM {term_data} td INNER JOIN {term_hierarchy} th ON td.tid = th.tid WHERE th.parent = $term");

я бы переписал для начала в виде
$content = db_query("SELECT td.name FROM {term_data} td INNER JOIN {term_hierarchy} th ON td.tid = th.tid WHERE th.parent = %d", $term);

2. Выясните, что возвращает $links while ($links = db_fetch_object($content))

Ведь, если написано l(htmlspecialchars($links->title),"node/$links->nid") . '<br />';,
то $links должен содержать title и nid. Но в запросе ведь другие поля!

Правильней будет написать l(htmlspecialchars($links->name),"node/$links->tid") . '<br />';

Посмотрите также статью http://www.drupal.ru/node/25211

Аватар пользователя zhylik zhylik 16 марта 2009 в 20:54

Попробуйте что-то вроде этого:

function library_menu() {
  $items['taxonomy/term/%'] = array(
    'title' => 'Литература',
    'description' => 'Выводим все ссылки',
    'page callback' => 'library_author',
    'page arguments' => array(2),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK
  );
  return $items;
}

function library_author($tid) {
  $tid = (int)$tid;
  if ($tid == 0) return drupal_not_found();

  $result = db_query("
    SELECT td.name, td.tid
    FROM {term_data} td
    INNER JOIN {term_hierarchy} th ON td.tid = th.tid
    WHERE th.parent = %d"
,
    $tid
  );
  if(!$result) return drupal_not_found();

  $page_content = '';
  while ($term = db_fetch_object($result)) {
   $page_content .= l($term->name,"taxonomy/term/$term->tid") . '<br />';
  }

  return !empty($page_content) ? $page_content : t('No terms were founded.');
}

1. 'taxonomy/term/%term'
"%term" нельзя использовать в качестве пласехолдера в пути, т.к. нет ф-ии term_load(), которая бы превращала переданный аргумент в объект-термин (как "%node", "%taxonomy_vocabulary" и т.п.). Оставляйте просто процент, который свидетельствует о том, что на его месте должен быть аргумент.

2. Для "description" и "title" в массиве, описывающем меню в 6 друпале не надо писать t().

3. 'page callback' => 'library_author', function library_author($tid) {
Для любой модульной ф-ии крайне желателен префикс (library_).

4. 'page arguments' => array(2)
В функцию обратного вызова можно передавать параметры таким способом.

5. htmlspecialchars() в l() можно не использовать. Она там все равно запускается.

6. "taxonomy/term/$term->tid"
Указываемый путь должен ссылаться на термин, а не на ноду ("node/$links->tid" - не правильная ссылка)

7. При использовании такой ф-ии, при открытии странички термина будет отображен только список терминов-детей, а ноды, которые принадлежат данному термину не выведутся (как это делалось обычно)

8. Строчка "if(!$result) return drupal_not_found();" меня вообще смущает... яб ее убрал...

Аватар пользователя lena_elena4 lena_elena4 17 марта 2009 в 23:29

Времени все не было, работы много. Добралась наконец-то сюда.
Спасибо за помощь и потраченное на меня время. Я когда-нибудь тоже буду вам помогать.
Все равно при нажатии на пункт меню страница пустая.
Мне кажется, что-то у меня с путями. Не могу понять, как Друпал строит пути.
У меня есть блок ссылок, который выводит из одного словаря список терминов (жанры книг - фантастика, история и т.д.) Сейчас блок так выглядит:

function library_block($op='list', $delta=0) {
  $num = variable_get('library_maxdisp', 6);
  $block_content = ''; //контент блока

 //показать блок на странице блоков
 if($op=='list'){
  $block[0]["info"] = t("library");
  return $block;
 }
  //показать контент блока
  else if ($op == 'view') {
    $vid = 9; // идентификатор (vid) словаря
    $result = db_query("SELECT td.tid, td.name FROM {term_data} td
              INNER JOIN {term_hierarchy} th
                  ON td.tid = th.tid
                  WHERE td.vid = %d AND th.parent = 0 ORDER BY td.weight"
,$vid);
                  if(!$result) return drupal_not_found();
      while($term = db_fetch_object($result))
      $block_content .= l($term->name,"taxonomy/term/$term->tid") . "<br>";    
        if($block_content==''){
        //проверяем, пустой ли блок
        return;
        }else{ 
        //отобразить блок
        $block['subject'] = 'Читателям';
        $block['content'] = $block_content;
        return $block;
        }
  }  
}

При нажатии на ссылку, выводятся "подтермины" - авторы книг определенного жанра.
Здесь я использую код меню и callback-функции, который мне переделал zhylik.
Дальше я хочу, чтобы при нажатии на "подтермин"(=автор), выводились все его книги - это ноды.
Еще раз, структура того, что хочу сделать, в двух словах такая: термин-подтермин-ноды этого подтермина.
Как здесь построить связи, чтобы переходить от ссылки к ссылке?