欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

自己动手开发模块 通过 system_settings_form 表单 来存取数据 有大用 有大大用

shiping1 的头像

自己动手开发模块

1)建一目录 sites/all/modules/test001
2)在其下建文件  
注意,模块名(以及钩子声明)必须是小写字母。
一,  test001.module  php文件
有一类似的ID标签。// $Id$
Drupal.org的版本控制系统能够通过修订信息和作者信息将CVS ID信息填满
按惯例都应该将该标签加在你的模块中
按照Drupal的 编码规范, 应该省略结束标签 ?>
在你的模块当中的所有函数,应该以{模块名}_{hook}的形式命名,
其中 hook 是指预先定义好的钩子函数的相应的后缀。
二,  test001.info     这个文件应该命名为test001.info
        该.info文件使用的是.ini格式,包含一个 ; $Id$ 可以使CVS插入相关文件ID信息。
通常格式
; $Id$
name = 模块名  (必须)  
     ;必须的 :仅仅第一个单词的第一个字母大写(例如应该"Example module")
description = 简单描述模块要做什么.  
                一行简短描述,用于在模块管理页面告诉管理员该模块做什么。记住,太长的描述并不是太好,所以请尽量简明;而且长度是限制在255字符的。
                注意,description中的特殊字符必须由相应的HTML来代替
        例如,使用 description = This is my "crazy@email.com" email address 来代替 description = This is my "crazy@email.com" email address 。
        如果描述中有单引号或撇号,你可以简单地将整个字符串放在双引号里面。例如, description = "Please don't use this unless you know what you are doing."
core (必须)
        从Drupal 6.x起,那些没有明确指明兼容Drupal哪个核心版本
                必须的
        从Drupal 6.x起,那些没有明确指明兼容Drupal哪个核心版本的模块,将不再起作用。
dependencies (可选)   ;模块依赖
            例: dependencies[] = taxonomy dependencies[] = comment
package (可选)
                如果一个模块的.info文件包括有一个'package'属性,
        那么在admin/build/modules页面,将会把具有相同'package'的模块列举在一起。
        如果没有'package'属性,那么该模块将列举在'Other'块里。
        一些建议使用的 'package' 例子:
        Audio, Bot, CCK, Chat E-Commerce, Event, Feed, Parser, Organic groups, Station, Video, Views,
        Voting (如果使用的VotingAPI)
        那么,现在你通过http://127.1/drupal/admin/build/module将可以看到我们所要创建的模块test001。
三, help钩子    帮助函数  {module}_help
        我们同样能够利用help钩子来提供一些关于我们模块的帮助和其他信息。
        由于我们前面所使用的.info文件,所以该钩子的实现并不是必须的。
        help钩子函数在 module文件里
        其中的 $path变量是指提供帮助的路径,通常用switch 语句来处理。
        function test001_help($path, $arg) {
            $output = ''; //declare your output variable
            switch ($path) {
            case "admin/help#test001":
            $output = '<p>'. t("Displays links to nodes created latest") .'</p>';
             break;
             }
             return $output;
        }
        当链接到主要帮助页面时(/admin/help 或者?q=admin/help).
        admin/help#modulename 将会被Drupal核心调用。看到帮助文档

        Hook_help()可以告诉drupal系统模块的信息以使模块在“模块”管理页面上列出来,
        这样用户就可以选择是否启用或禁用此模块了。
        模块一但被启用,模块文件里的全部代码都被包含到系统中,同时
        模块的函数也可以调用drupal的所有可用函数和访问所有可用变量了。

四, perm钩子 权限函数     {module}_perm
        这个函数是用来定义你的模块的权限名称的。
        它并不授予权限,仅仅指明什么权限对这个模块可用。
        基于这些权限的访问是定义在{module}_access函数中的。
        function test001_perm() {
            return array('access test001 content');
            //如果要更好的地控制权限的模块,你需要扩展这个权限设置,如下
            //return array('access test001 content', 'administer test001');
        }
        必须要开启test001模块,开发模块下(最好禁用缓存,才能更好的看到效果)
        这时你将会在http://127.1/drupal/admin/user/permissions 看到刚才所创建的权限:
        你的权限名称可以随意取的,但是每个名称必须独一无二
        权限名称应该包含你的模块名字,因为这样能够有效地避免命名冲突。
        建议的权限命名规则是"action_verb modulename".
        样例
        function newmodule_perm() {
        return array(
        'access newmodule', 'create newmodule', 'administer newmodule');
        } // function newmodule_perm
五,         你可能已经听说过这样一些模块类型,“区块模块”,
        主要是指那些创建区块内容的模块(例如菜单模块);
        “节点模块”,主要是指那些用于生成整页内容的模块(例如博客和论坛模块)
六, block钩子    {module}_block 创建区块
        function test001_block($op = 'list', $delta = 0, $edit = array()) {
        // 你的模块代码
        } // end function test001_block
        $op (或者 operation): 区块函数有四个不同的操作('list', 'view', 'save' 和 'form')
        $delta: 区块模块可以用来创建你所需要的那样多的不同的区块。
        delta是一个用在内部的数字,用以识别你的不同的区块。
        用户(user)模块就是一个有多个不同区块的模块例子:
        用户登陆区块,最新会员区块和在线会员区块。
        $edit: 仅仅和 "save" $op一起使用,稍微有些难处,我们暂不讨论。

        我们只有一个区块。首先,非常重要的一点就是,
        要定义在页面Administer -> Site Building -> Blocks 出现的内容。
        为了让你的区块能够被列举在管理页面,你必须为'list' $op定义输出。
        function test001_block($op = 'list', $delta = 0, $edit = array())
        {
            // list the blocks
            if ($op == "list") {
             $block[0]["info"] = t('Test001');
             return $block;
            }
        } // end test001_block
        添加了上面的代码到test001.module后,我们就能在区块列表页面admin/build/block看到该区块:
        $block - $block 是存储区块变量的变量。
        $block[0] - $block 是一个数组变量,数组中的每一项代表我们其中的一个区块。
        其中的“0”是 $delta 的值,
        因为我们这里只定义了一个区块,所以是“0”。
        如果我们需要定义更多的区块,则需要定义$block[0], $block[1], $block[2], 等等。
        $block[0]["info"] 代表区块的每个元素 (0, 1, 2)同样是一个 键=值 对数组。
        这些键包括有“info”,“cache”,“weight”,“status”等等。
        我们暂时只讨论“info”,这是在区块列表页面所显示的区块名称。
        所以,在Drupal内部,我们的区块名称是 $block[0],
        但是在管理页面,区块名称是Test001。在接下来这一步,我们将生成区块内容。
        function test001_block($op = 'list', $delta = 0, $edit = array())
        {
            // list the blocks
            if ($op == "list") {
             $block[0]["info"] = t('Test001');
             return $block;
            }
            else if ($op == 'view') {
                $block_content = '';
                $query = "SELECT nid, title, created FROM {node} ORDER BY created DESC  limit 0,10" ;
                $queryResult = db_query($query);
                while ($links = db_fetch_object($queryResult)) {
                 $block_content .= l($links->title, 'node/'.$links->nid) . '<br />';
                } if ($block_content == '') {
                    $block_content .= 'There is no content';
                 }
                $block['subject'] = 'Test001 Subject';
                $block['content'] = $block_content; return $block;
            }
        } // end test001_block
        使用db_query,db_fetch_object封装了所有的数据库操作 如mysql,postgres
        注意上面代码中的URL是包裹在函数l()里的,
        l()函数能够生成<a href=”link”>这样的链接。
        这里,我们同样返回了一个数组,包含元素”subject”和”content”。
        这其实也是Drupal核心所期望的区块函数所返回的值。
        如果你的区块函数返回值中没有将这两个元素都包含在里面,
        那么这个区块将不能正确呈现出来。
七)进行sql查询
        :表名称要包含在大括号里,例如{node}.这样做是必须的,
        以便让你的模块能够支持数据库表名前缀。
        你可以通过阅读Drupal站点上Drupal手册里的表前缀(以及多个站点共享数据表)
        获得更多信息。
        我们将使用SQL查询db_query()来获取记录(也就是数据库里的数据列表

八)    (a)模块安装,放在sites/all/modules/目录下
    必须test001文件夹,里面必须要含test001.module test001.info文件
    (b)启用 到管理=>站点构建=>模块  下启用 打上勾保存一下
    (c)配置 因它是区块模块,须要到区块管理页面将区块激活,为它指定一个显示的区域
        一定要注意,要选择你的主题中有显示的区域
        如果是节点模块可能需要,也可能并不需要更多的配置,这些都取决于模块
    (d)应该还有设置权限的吧 还要看看 权限 有没有开启吧!!

3)
    此时,要么用devel模块clear cache,
    要么浏览一下管理页面中的“菜单”页面就会刷新菜单路径缓存了。现在应该可以了

4)

前面所有的路径定义中access都为TRUE,但通常我们都希望对页面内容的访问作一些权限控制。此时我们需要在模块里实现hook_perm()函数:
function example_perm() {
  return array('access foo', 'access baz');
}

 现在,你在“访问控制”页面就可以分配这两个权限给指定的角色了。同时,你还要在hook_menu里这样定义'access':
'access' => user_access('access foo'),
 //这个不太懂 ,好像是不需要 ...在drupal 6 中
//好像是直接 'access arguments'=> array('access hellodrupal blocks'), //程序自动判断返回值  

 user_access()函数会访问$user全局变量和权限设定以确定访问页面的当前用户是否有'access foo'这个权限,有就返回TRUE,没有返回FALSE。用户ID为1的用户默认拥有任何权限,即user_access(‘任意值’)对他来说都会返 回TRUE;权限管理对他完全没用,乖乖。——所以,有特殊要求时,记得还要控制uid=1的用户。

 好了,我相信你已经能够用模块定义自己的页面了——虽然看似有些繁琐,但恭喜你已经迈出模块之旅的第一步。
//不是    钩子函数
function test001_admin() {
    $form['test001_maxdisp'] = array( '#type' => 'textfield',
     '#title' => t('Maximum number of links'),
     '#default_value' => variable_get('test001_maxdisp', 2),
     '#size' => 2, '#maxlength' => 2,
     '#description' => t("The maximum number of links to display in the block."),
     '#required' => TRUE );//required是什么意思 意思是必须要有值
    return system_settings_form($form);
 }

function test001_menu() {
        $items = array();
         $items['admin/settings/test001'] = array( 'title' => 'Test001 module settings',
         'description' => 'Description of your Test001 settings control',
         'page callback' => 'drupal_get_form',
         'page arguments' => array('test001_admin'),
         'access arguments' => array('access administration pages'),
         'type' => MENU_NORMAL_ITEM );
        return $items;
}

//这里好像是系统菜单 system_settings_form
与普通的菜单有点不一样

4)//不是    钩子函数
 function test001_all()
 {
 }
    如果你希望从另外的模块调用该函数,
    可以采用标准的命名方案:modulename_action,
    可以通过函数module_invoke()来调用。
  function test001_all()
  {
     // content variable that will be returned for display
      $page_content = '';
     $query = "SELECT nid, title, created FROM {node} ORDER BY created DESC";
     $queryResult = db_query($query);
     while ($links = db_fetch_object($queryResult))
    {
        $page_content .= l($links->title, 'node/'.$links->nid).'<br />';
    }
    // check to see if there was any content before
    // setting up the block
    if ($page_content == '')
    {
        // no content from a week ago, let the user know
        $page_content = "No events occurred on this site.";
    }
    return $page_content;
  }


   function test001_menu()
   {
        $items = array();
         $items['admin/settings/test001'] = array( 'title' => 'Test001 module settings',
         'description' => 'Description of your Test001 settings control',
         'page callback' => 'drupal_get_form',
         'page arguments' => array('test001_admin'),
         'access arguments' => array('access administration pages'),
         'type' => MENU_NORMAL_ITEM, );
        //this is added for this current tutorial.
        $items['test001'] = array( 'title' => 'Test001',
        'page callback' => 'test001_all',
        'access arguments' => array('access test001 content'),
        'type' => MENU_CALLBACK );
        return $items;
   }


function test001_block($op = 'list', $delta = 0, $edit = array())
{
    // list the blocks
    if ($op == "list") {
     $block[0]["info"] = t('Test001');
     return $block;
    }
    else if ($op == 'view') {
                $block_content = '';
                //$limitnum = variable_get('test001_maxdisp', 2);
                //$query = "SELECT nid, title, created FROM {node} ORDER BY created DESC limit 0,".limitnum ;
                //$queryResult = db_query($query);
                $limitnum = variable_get('test001_maxdisp', 2);
                $query = "SELECT nid, title, created FROM {node} ORDER BY created DESC ";
                $queryResult = db_query_range($query, 0, $limitnum);
                while ($links = db_fetch_object($queryResult)) {
                 $block_content .= l($links->title, 'node/'.$links->nid) . '<br />';
                } if ($block_content == '') {
                    $block_content .= 'There is no content';
                 } else {
                 //下面这个是增加"更多"链接
                    $options = array( "attributes" => array("title" => t("More events") ) );
                    $link = l( t("more…"), "test001", $options );
                    //看看 l 方法 $options参数 自己领会 就是a标签的属性吧
                    $block_content .= "<div class=\"more-link\">" . $link . "</div>";
                 }
                $block['subject'] = 'Test001 Subject';
                $block['content'] = $block_content;
                return $block;
    }
}

 

自己动手开发模块2

1)在 sites/all/modules/中
  建一文件夹 hellodrupal
2)在其内建 hellodrupal.info,hellodrupal.module
名称要一样
 <?php
; $Id$
name = Hellodrupal
description = List the latest content links
core = 6.x
packgage  = //未指定  ,放在other
dependencies  =
这里的结束 ?>一般没有 防止可能 空格 对 session,cookie有影响
3)http://api.drupal.org/api/function/hook_block/5
第五个版本 看到关于此hook_block函数的说明
4)http://api.drupal.org/api/group/database/5
第五个版本,看到关于操作数据库的函数
db_query 对应mysql_query()
db_query_range (返回一定条数的结果集) 相当于 limit 作用
pager_query  分页
db_query   
$query = select nid,title,created From {node}
where created >=%d and created <=%d
{node} 封装了前缀

 db_query_range($query, 0 ,10);//$query 是 $sql, limit 0,10
 $result = db_query_range('SELECT n.title, n.body, n.created
    FROM {node} n WHERE n.uid = %d', $uid, 0, 10);
theme('item_list', $links);//体会一下

表示 输出一个 ul 其 class='item_list'
其中 li 里面的东西就是 $links

_函数 表示是私有的
 

自己动手开发模块3

1)druapl创建的表单是安全的
  封装了表单的创建和存取
  它表单首先存储于数据库
  对表单进行缓存
  第二个用户 就不用生存 直接从数据库取(我觉得是从缓存取吧)
  每个表单有id 通过id取表单
2)drupal_get_form($from_id)
http://api.drupal.org/api/function/drupal_get_form/5
看到说明
根据某个表单构造函数,生成相应的表单,
某个表单构造函数 自己随便定义的函数,是不受任何钩子函数的回调
$from_id为表单的名字(唯一)
drupal_get_form("hello_form")
多个表单以向导的方式提交时,此函数可保存表单状态

function my_form()//my_form 就是 $form_id
{
    // 文本框  name是文本框的名称
    $form['name'] =  array(
    '#type' =>'textfield',//drupal 规定文本框用textfield来表示
    '#title'=>t('Your name'),//标题 显示在文本框前面
    '#description'=>t('Please input your name');//文本框下面的描述
   }
   //提交按钮  //
  $form['submit'] = array('#type'=>'submit','#value'=>t('Save'));
  return $form;
}

function hello_drupal_form(){
  return drupal_get_form('my_form');
}
表单元素有哪些
http://api.drupal.org/api/file/developer/topics/forms_api_reference.html/5
fieldset 将表单元素分组
属性
'#collapsible' => TRUE,  //是否可折叠
'#collapsed' => FALSE,  //默认是(false)打开 还是(true)关闭
function my_form()//my_form 就是 $form_id
{
    $form['basic'] = array(
        '#type'=>'fieldset',
        '#title'=>t('Basic information'),
        '#collspsiable'=>true,
        '#collapsed'=>false
        );

    // 文本框  name是文本框的名称
    $form['basic']['name'] =  array(
    '#type' =>'textfield',//drupal 规定文本框用textfield来表示
    '#title'=>t('Your name'),//标题 显示在文本框前面
    '#default_value'=>'hello world',
    '#description'=>t('Please input your name')//文本框下面的描述
    );
    $form['basic']['age'] =  array(
    '#type'=>'textfield',
    '#title'=>'Your age'
    );
   //提交按钮  //
  $form['submit'] = array('#type'=>'submit','#value'=>t('Save'));
  return $form;
}
item 可读的元素 纯文字的描述
3) t('Your name') 开发中文网站的时候 可以直接写
4) 验证类似于钩子函数 表单函数名_validate
//两个参数 必写
//$form_id表单id
//$form_values表单的相当于post,
但是作用比post大,它本质上是从db中取的
//此函数其实是可选的,可以不验证
//drupal 5
function test_form_validate($form_id,$form_values)
{
 form_set_error('',t(You must input your name'));
}
//drupal 6
/ * 表单验证
 * @param (array) &$form
 *  表单字段
 * @param (array) &$form_state
 *  表单值,用做判断表单的各种参数,包括用户提交的所有数据
 */
function myform_page_form_validate(&$form, &$form_state) {
 
  /**
   * 用户提交的所有数据在 $form_state['values'] 之中,相当于 $_POST
   * 根据需求,验证昵称是否少于 2 个字符,中英文均算一个字符
   * 可使用封装好的计算字符串长度函数:drupal_strlen
   */
  if (drupal_strlen($form_state['values']['name']) < 2) {
    /**
     * 如果少于 2 个字符,调用  form_set_error() 写入错误信息,系统将显示错误信息,同时阻止表单提交
     * form_set_error() 的格式,第一个参数:字段名称,第二个参数:用户将看到的错误信息
     */
    form_set_error('name', '昵称不能少于 2 个字符');
  } else if (drupal_strlen($form_state['values']['title']) > 255) {
    form_set_error('title', '标题长度不能大于 255 个字符');
  }
 
  // 如验证通过,将进入表单提交环节
}


5)submit 类似于钩子函数的回调函数
表单函数名_submit
表单提交处理函数
//drupal 5
function test_form_submit($form_id,$form_values)
{
 drupal_set_message(t('Your name is ').$form_values['name'].'    '.
 t('Your age is ').$form_values['age'];
}

//drupal 6
/**
 * 表单提交
 * @param (array) &$form
 * @param (array) &$form_state
 */
function myform_page_form_submit(&$form, &$form_state) {
  /**
   * 写入数据库
   */
  db_query("INSERT INTO {myform} (id, title, name, mail, timestamp, body)
  VALUES (null, '%s', '%s', '%s', %d, '%s')", $form_state['values']['title'],
  $form_state['values']['name'], $form_state['values']['mail'],
  $_SERVER['REQUEST_TIME'], $form_state['values']['body']);
 
  // 获取上一条 insert sql 返回的主键,以此判断是否执行成功
  if (db_last_insert_id('myform', 'id')) {
    
    /**
     * 执行成功了,到数据库去看看,是不是有这条记录了
     * 显示一条信息给用户
     */
    drupal_set_message('感谢您,反馈已经提交,我们将尽快和您取得联系');
    
    // 如果想将用户重定向到一个页面,可修改 $form['#redirect'] 值,如:
    
    $form['#redirect'] = 'test/abcde';
    
    /**
     * 这里也可以使用 drupal_goto 来重定向,但这并不是个好方法
     * 因为可能还有其它提交函数在 后面排队,被这儿一重定向,后面就没机会执行了
     */
    
  } else {
    
    // 数据写入失败了
    drupal_set_message('抱歉,遇到问题,提交失败了', 'error');
    
  }
 
}
















<?php

//帮助
function hellodrupal_help($path) {
            $output = ''; //declare your output variable
            switch ($path) {
            case "admin/help#hellodrupal":
            $output = '<p>'. t("第一个Drupal模块") .'</p>';
             break;
            }
             return $output;
}//function on this display help

function hellodrupal_block($op='list',$delta=0){
    
    switch ($op)
    {
        case 'list' :
        $block[0]['info'] = t('我的第一个drupal模块');
        $block[1]['info'] = t('我的第二个drupal模块');
        return $block;
        
        case 'view' :
          switch ($delta)
          {
             case 0 :
               $block['subject'] = '我的第一个block';
             $block['content'] = '欢迎访问我的站点';
             break;
             case 1 :
               //$block['subject'] = '我的第二个block';
             //$block['content'] = '欢迎再次访问我的站点';
             $query = "select nid,title,created from {node}";
             $queryResult = db_query_range($query, 0 ,10);
             $links = array();
             while ($node = db_fetch_object($queryResult))
             {
                 $links[] = l($node->title,'node/'.$node->nid);
             }
             $block['content'] = theme('item_list', $links);
             $block['subject'] = '我的第二个block';
             break;
          }
        return $block;
        break;
    }
}
function hellodrupal_menu() {
    $items = array();
    $items['hello'] = array(
    'title'=>t('hello drupal page'),
    'page callback'=>'hello_druapl_page',
    'page arguments' => array('hello','helloDrupal'),
    //'page arguments' => array(1,2),
    //它的优先级 大于 url传来的参数 也就是此时url如果放参数,参数不起作用
    //如果要默认值 就放在回调函数的形参上  (默认的时候要注意,第几个有默认值, page arguments=>array(......)) 中第几个元素就必须没有,假如有的话 虽不在url中赋值,但是是有值的 值为两个单或双引号括起来 
    //array(1,2)表示只取url前两个参数 array(1)表示只取url第一个参数
    //如果 把 'page arguments' 注释掉
    //那么 此时才取默值 ;;
    //否则的话 如果 取'page arguments' => array(1,2),
    //再如果 url 过来 没有传参的话 (其实是传两个 空值)
        //此时的话 参数就不是放在回调函数上的形参 而是两个空值
    'access arguments'=> array('access hellodrupal blocks')  
    );
    $items['helloform'] = array(
    'title'=>t('hello drupal page form'),
    'page callback'=>'hello_drupal_form',
    'page arguments' => array('page callback arguments'),
    'access arguments'=> array('access hellodrupal blocks')  
    );
    
    return $items;    

}


/*function hello_druapl_page()
{
  $output = 'hello drupal page';
  return $output;
}*/
function hello_druapl_page($name = null, $nickname = null)
{
      $output = '';
    if(empty($name)){
      $output = "hello andbody";
    }
    else {
      $output = "hello ".$name;
    }
    if(!empty($nickname)){
      $output .= ' your nick name is '.$nickname;
    }
    return $output;
}
//定义权限 仅仅指明什么权限对这个模块可用
function hellodrupal_perm(){
      return array('access hellodrupal blocks');
}

function hello_drupal_form(){
  return drupal_get_form('my_form');
}
/*function my_form()//my_form 就是 $form_id
{

    // 文本框  name是文本框的名称
    $form['name'] =  array(
    '#type' =>'textfield',//drupal 规定文本框用textfield来表示
    '#title'=>t('Your name'),//标题 显示在文本框前面
    '#description'=>t('Please input your name')//文本框下面的描述
   );
   //提交按钮  //
  $form['submit'] = array('#type'=>'submit','#value'=>t('Save'));
  return $form;
}*/
function my_form()//my_form 就是 $form_id
{
    $form['basic'] = array(
        '#type'=>'fieldset',
        '#title'=>t('Basic information'),
        '#collapsible'=>true,
        '#collapsed'=>false
        );

    // 文本框  name是文本框的名称
    $form['basic']['name'] =  array(
        '#type' =>'textfield',//drupal 规定文本框用textfield来表示
        '#title'=>t('Your name'),//标题 显示在文本框前面
        '#default_value'=>'hello world',
        '#description'=>t('Please input your name')//文本框下面的描述
    );
    $form['basic']['age'] =  array(
    '#type'=>'textfield',
    '#title'=>'Your age'
    );
   //提交按钮  //
  $form['submit'] = array('#type'=>'submit','#value'=>t('Save'));
  return $form;
}

//表单函数_validate 验证类似于钩子函数的回调函数
function my_form_validate(&$form, &$form_state)
{
    /**
   * 用户提交的所有数据在 $form_state['values'] 之中,相当于 $_POST
   */
    // form_set_error('',$form_values['name']);
  if($form_state['values']['name'] == '')
  {
    form_set_error('',t('You must input your name'));
  }
}
//表单函数_submit 提交函数
function my_form_submit(&$form, &$form_state)
{
     /**
       * 用户提交的所有数据在 $form_state['values'] 之中,相当于 $_POST
       */
     drupal_set_message(t('Your name is ').$form_state['values']['name'].'    '.
     t('Your age is ').$form_state['values']['age']);
}







自己动手开发模块4

一个模块 可以实现多处功能
一般情况下 只需要用 devel 清空缓存就可以了  
(也可以模块 先关闭 再开启 比较麻烦)
1)menu 菜单机制 模块管理机制
 它是导航系统
 所有的菜单 模块都是实现了 hook_menu 钩子函数
2)
http://api.drupal.org/api/function/hook_menu/5
实现菜单系统
只有一个入口 index.php
url->是否维护->否->get menu array
->q 后面参数 取过来->    看有调用无钩子函数  它会调用(回调函数)
->如果没有 调用回调函数->不同的主题模板 不同的节点类型 这个过程完成的
->如果有 调用回调函数->  看回调函数的定义是否存在
->如果不存在 回调函数的定义 ->返回 menu_not found
->如果存在 回调函数的定义 ->用户是否有权限(hook_perm)
->如果没有权限-> 返回  menu_access_denied(拒绝)
->如果有权限 根据url参数 和回调函数需要的参数进行处理->调用回调函数->生成页面
function hook_menu($may_cache) {
}
//drupal 6 是没有参数
//drupal 6

//type 菜单类型 最常用两种 MENU_NORMAL_ITEM (显示菜单项)
// MENU_CALLBACK(不显示菜单项)
//drupal 6 好像是没有采用 什么分缓存和不缓存了 全部缓存
function hook_menu() {
  $items = array();
  $items['example'] = array(
    'title' => 'Example Page', //必须
    'page callback' => 'example_page',
    'access arguments' => array('access content'),  //必须 // 要让所有可以访问,
   //'access arguments' =>true,
    'type' => MENU_SUGGESTED_ITEM,
  );
  $items['example/feed'] = array(
    'title' => 'Example RSS feed',
    'page callback' => 'example_feed',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

//这是 drupal5 不适用了
function hello_page_menu($may_cache) {
    $item = array();
    if ($may_cache) //有缓存的时候 把下面注册在菜单项中 $items就是菜单项
    {
//path url中路径 title 显示在菜单管理中,作为菜单项进行管理
//callback 指示 当访问 url时,执行哪个函数(它是回调函数,不是钩子,随便起什么名,不一定要 模块名_函数名()的格式),
//此函数里执行各种
//逻辑.输出html脚本,此函数也在本文件里实现

//access 访问权限  
//如果不设它 那会drupal 会提示 access 被拒绝(所有人都看不到)
//所以这是drupal一个bug 必须要写 只要写成跟 drupal 里的随便哪个权限一样就可以
//还要让这个权限对所有角色默认允许
//也可以自己定义一个权限
//如  funtion hello_page_perm(){
//      return array('access hellodrupal blocks');
//    }
//先这里是
        $items[] = array('path'=>'hello','title'=>t('hello'),
        'callback'=>'hello_page_test',
        //'access'=> user_access('access hello page'));
        'access'=> 'access hellodrupal blocks');
//path hello/sayhello 两层 自动把它注册为 hello的子菜单项
//type 告诉drupal 菜单项的类型 默认就是普通菜单项 可以在菜单中进行管理删除
        $items[] = array('path'=>'hello/sayhello','
        title'=>t('Say hello'),
        'callback'=>'hello_page2_test',
        'type'=> MENU_CALLBACK);
    }
    return $items;    

}
//drupal 5
$may_cache  //第一次访问 可以被缓存 它为true
//会调用两次   要注册的菜单 要么放在真下 要么放在假下,否则会出错
一)第一次为true
二)第一次为false  样式表文件等


//drupal 6
function your_module_menu() {
  $items['admin/settings/your_module'] = array(
    'title' => 'Your Module Settings',       // NOTE: t() not needed
    'description' => 'Menu description',     // ... for these elements
    'page callback' => 'page_callback_funtion',
    'page arguments' => array('page callback arguments'),//它的优先级 大于 url传来的参数我
//如果要默认值 就放在回调函数的形参上  (默认的时候要注意,第几个有默认值, page arguments=>array(......)) 中第几个元素就必须没有,假如有的话 虽不在url中赋值,但是是有值的 值为两个单或双引号括起来 
//它是默认参数的意思 //它是静态的 被存入缓存的
//'page arguments' => array(1,2),
    //它的优先级 大于 url传来的参数我
    //如果要默认值 就放在回调函数的形参上 放在page_callback_funtion函数的形参上
    //如果用array(1,2)表示只取url前两个参数 array(1)表示只取url第一个参数 ,

    'access callback' => 'user_access',                     // Check that the current user
    'access arguments' => array('Administer Your Module'),  // ... has this permission.
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}
//回调函数的参数 就是url/参数
多个参数 url/参数/参数
funtion hello_page_perm(){
      return array('access hellodrupal blocks');
}
funtion hello_page_test(){
     $output = 'hello drupal page';
      return $output;
}
funtion hello_page_test($name = null){
    $output = '';
    if(empty($name)){
      $output = "hello andbody";
    }
    else {
      $output = "hello ".$name;
    }
     return $output;
}
funtion hello_page_test($name = null, $nickname = null){
    $output = '';
    if(empty($name)){
      $output = "hello andbody";
    }
    else {
      $output = "hello ".$name;
    }
    if(!empty($nickname)){
      $output .= 'your nick name is ".$nickname;
    }
     return $output;
}
3)表单验证  表单名_validate
 function test001_admin_validate($form, &$form_state)
 {
     $maxdisp = $form_state['values']['test001_maxdisp'];
     if (!is_numeric($maxdisp))
     {
       form_set_error('test001_maxdisp', t('You must select a number for the maximum number of links.'));
       //第一个参数是字段名 ,,好像也可以为空
    }
     else if ($maxdisp <= 0) {
        form_set_error('test001_maxdisp', t('Maximum number of links must be positive.'));
     }
 }

 

 


自己动手开发模块5


1)http://hellodrupal.info/node/131   node_save
2)http://www.5iphp.com/drupal-hook_nodeapi drupal-hook_nodeapi
3)http://hellodrupal.info/node/31 drupal-hook_nodeapi
4)http://zhupou.cn/node/982  hook_user
5)http://blog.csdn.net/g089h515r806/article/details/2217658 hook_user 还要看
6)http://www.doooor.com/forum.php?mod=viewthread&tid=2382 hook_user  
7)http://drupaltaiwan.org/node/1181 user_save 还要看
8)http://www.trackself.com/archives/1352.html user_save 

 

 

 

 

普通分类: