jQuery与JSON在Drupal开发中的使用

为了要对代理商所在地进行选择,我需要做一个省和城市的级联选择功能。具体的功能是在省份的下拉列表(设为provinceList)中选中一个省 的时候,要在城市的下拉列表(设为cityList)中列出选中省份所对应的城市来。比如在省份列表中选择”广东省”后,城市列表应该是”肇庆市”、”广 州市”、”佛山市”……等。要实现这个功能,一般的WEB开发的方法有两个:

1.刷新网页方式
1)写一段provinceList的onchange事件处理脚本。
2)在provinceList的onchange事件中,把用户选择的省份提交到服务器。
3)服务器根据用户提交的省份参数。查找对应的城市列表,填充到cityList中去,重新呈现网页回送给客户端。
4)整个网页被再次程序给客户端。客户端在cityList中显示对应省份的城市列表。

这种方式的缺点非常明显:
首先,每次省份选择的改变都要服务器去做筛选参数,查找数据,填充数据,呈现网页等一通工作。开发和维护难度高。
其次,用户每改变一次省份选择,网页都要重新下载,客户体验不佳。

2.不刷新网页方式
1)网页第一次呈现的时候就把所有的省份和省市及其关联性的数据以网页脚本形式下载到客户端。
2)在provinceList的onchange事件中,脚本根据用户选择的省份以及在上一点提到的网页脚本中指定的省份与城市关系来填充cityList数据。
这种方式也有缺点:
在服务器端查询相关数据并生成客户端脚本来呈现和表示省份和城市及其关联性较为复杂。而在客户端,provinceList的onchange事件处理脚本也较为复杂。

而使用jQuery+JSON作为工具,在drupal平台上开发这个功能就简单得多了。
1.首先是开发一块网页客户端javascript代码(假设provinceList对应的下拉列表ID为search-province,而cityList对应的下拉列表控件ID为search-city),以下列出该块代码及其注释:

<?php
--------------------------------------------------------------------------
//document就绪后执行该代码块
$(function() {
//search-province的onchange事件处理代码
$("#search-province").change(function() {
//对请求网址'/ojcustom/getcitys/选中省份id'后drupal返回的JSON数据data进行处理的代码块
var getCitys = function (data) {
// 解析drupal返回的JSON数据data为javascript对象result,该对象包含了drupal返回的对应城市数组(array)
var result = Drupal.parseJson(data);
//填充城市列表之前,先清空现有的列表数据
$("#search-city").empty();
//针对返回的每一城市数据,一一填充到search-city的列表项中去
for(key in result) $("#search-city").append("");
}//getCitys()
//向网址'/ojcustom/getcitys/选中省份id '发送请求,请求参数为null,指定返回JSON数据的处理函数为getCitys
$.get('/ojcustom/getcitys/'+$("#search-province")[0].value, null,getCitys);
//结束事件处理代码
return
false;
});//change()
});//$(function())
---------------------------------------------------------------------------
 
?>

2.其次是在服务器端开发一块用来处理向网址’/ojcustom/getcitys/选中省份id ‘提交的请求的PHP代码:

<?php
---------------------------------------------------------------------------
//本函数通过用户在网址中提交的选中省份ID来获取相应城市列表,并且把列表数据转换成JSON数据返回给客户端
function get_citys_by_province_id(){
//用户提交网址中的第三个参数就是用户选中的省份ID
if (!is_numeric(arg(2))) exit;
//查找数据库得出相应城市列表
$result =db_query('select cid,name from {city} where pid='.arg(2));
//一一取出城市数据,并且把它们记录在一个数组(array)$options中
$options = array();
while ($term = db_fetch_object($result)) {
$choice = new stdClass();
$choice = array('value'=>$term->cid,'text' =>$term->name);
$options[] = $choice;
}
$options[] = array('value'=>'','text' =>'请选择');
//使用drupal内置的函数把城市数组转换成JSON数据,并且把它输出到客户端
print drupal_to_js($options);
//客户端输出结束
exit;
}
---------------------------------------------------------------------------
?>

这样,就完整完成了整个功能。
上面两段代码非常简单明了、易于控制,这个实现方法既没有第一个实现方法中的刷新网页问题和服务器端成本问 题,也没有第二种实现方法中的脚本生成难度和事件处理脚本难度的问题。通过本例子我们可以看出jQuery+JSON可以大大简化WEB开发的复杂度,而 druapl由于内置了jQuery与JSON,结合导drupal系统的其他优点,更加使得WEB开发变得可控和高效起来

Create .install file schema drupal 7

First we need to implement hook_schema() to define the table to store our entities. Drupal schema is an associated array representing the structure of database tables. During module installation, Drupal will call this hook automatically to install necessary tables. During module uninstallation, Drupal will remove the database tables defined in this hook. If there are no other installation procedure, hook_install() or hook_uninstall() does not need to be implemented. If the module implements hook_schema(), the database tables will be created before this hook_install() is fired.

The structure of client entity can be very basic, otherwise we could just use node instead.

$schema['client'] = array(
  'description' => 'The base table for client',
  'fields' => array(
    'cid' => array(
      'description' => 'The primary identifier for the client.',
      'type' => 'serial',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ),
    'type' => array(
      'description' => 'The {client_type}.type of this client.',
      'type' => 'varchar',
      'length' => 32,
      'not null' => TRUE,
      'default' => '',
    ),
    'name' => array(
      'description' => 'The name of the client.',
      'type' => 'varchar',
      'length' => 255,
      'not null' => TRUE,
      'default' => '',
    ),
  ),
  'primary key' => array('cid'),
  'indexes' => array(
    'type' => array('type'),
  ),
);

In this table, the type field indicates what type of client the entity is. If the entity only has one bundle, then we probably do not need this field. But since we would like to have many bundles with entity of client, we will need this field. This schema definition will create the following table shown in MySQL database:

mysql> DESC client;
+-------+------------------+------+-----+---------+----------------+
| FIELD | TYPE             | NULL | KEY | DEFAULT | Extra          |
+-------+------------------+------+-----+---------+----------------+
| cid   | INT(10) UNSIGNED | NO   | PRI | NULL    | AUTO_INCREMENT |
| TYPE  | VARCHAR(32)      | NO   | MUL |         |                |
| name  | VARCHAR(255)     | NO   |     |         |                |
+-------+------------------+------+-----+---------+----------------+

cid is the primary key and type is being indexed. Indexes are best used on columns that are frequently used in WHERE clauses, and in any kind of sorting, such as ORDER BY.

We also need a table to store different type of clients, or bundle definition table.

$schema['client_type'] = array(
  'description' => 'Stores information about all defined {client} types.',
  'fields' => array(
    'type' => array(
      'description' => 'The machine-readable name of this type.',
      'type' => 'varchar',
      'length' => 32,
      'not null' => TRUE,
    ),
    'name' => array(
      'description' => 'The human-readable name of this type.',
      'type' => 'varchar',
      'length' => 255,
      'not null' => TRUE,
      'default' => '',
      'translatable' => TRUE,
    ),
    'description' => array(
      'description' => 'A brief description of this type.',
      'type' => 'text',
      'size' => 'medium',
      'not null' => TRUE,
      'translatable' => TRUE,
    ),
    'help' => array(
      'description' => 'Help information shown to the user when creating a {client} of this type.',
      'type' => 'text',
      'size' => 'medium',
      'not null' => TRUE,
      'translatable' => TRUE,
    ),
  ),
  'primary key' => array('type'),
);

The MySQL database table for the above schema is:

mysql> DESC client_type;
+-------------+--------------+------+-----+---------+-------+
| FIELD       | TYPE         | NULL | KEY | DEFAULT | Extra |
+-------------+--------------+------+-----+---------+-------+
| TYPE        | VARCHAR(32)  | NO   | PRI | NULL    |       |
| name        | VARCHAR(255) | NO   |     |         |       |
| description | mediumtext   | NO   |     | NULL    |       |
| help        | mediumtext   | NO   |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+

Drupal7 修改系统tabs上显示的文字

系统tabs上默认显示的文字如 “view” 但有时根据项目的要求我们得把它改过,例如我们要将内容类型为 “product”的就要改为’Overivew’,而内容类型为”article”的要改为”View Article”,别的内容类型还是为默认的”view”.就可以用到以下的代码:

function hello_menu_alter(&$items) {
    unset($items['node/%node/view']['title']);
    $items['node/%node/view']['title callback'] = 'hello_view_tab_title';
    $items['node/%node/view']['title arguments'] = array(1);
}
 
function hello_view_tab_title($node) {
    if ($node->type == 'article') {
        return t('View Article');
    }
    if ($node->type == 'product') {
        return t('Overivew');
    }
    return t('View');
}

把以上代码加入到你的自定义module中,并把 “hello”替换成你的module名称.就可以实现了…

如何在Drupal中为节点增加一个Tab选项卡

将这段代码放在你自定义模块的hook_menu钩子函数中

$items['node/%node/new_tab']  = array( 
    'title' => 'New Tab', 
    'page callback' => 'mycallback', 
    'page arguments' => array(1), 
    'access callback'   => TRUE, 
    'type' => MENU_LOCAL_TASK 
)

这个Tab会显示在任意节点类型上,并且没有访问限制。
假如你需要这个Tab显示在一个特定节点类型上,那么看下面的代码,假设此节点类型的机器名是“custom_node”:
将这段代码放在你自定义模块的hook_menu钩子函数中:

$items['node/%custom_node/new_tab'] = array( 
    'title' => 'New Tab', 
    'page callback' => 'mycallback', 
    'page arguments' => array(1), 
    'access callback'   => TRUE, 
    'type' => MENU_LOCAL_TASK 
)

并且接着创建一个函数:

function custom_node_load($arg) { 
  $node = node_load($arg); 
  if($node->type == 'custom_node') 
    return $node; 
  return FALSE; 
}

Drupal 7生成带排序功能的表格

Drupal 7生成带排序功能的表格

/**
     * The "List nid" table
     * ----------------------------------------------------------------------
     */
    //$header = array('title', 'type', 'created', 'language');
    $header = array(
        array('data' => 'title', 'field' => 'title', 'sort' => 'ASC'),
        array('data' => 'type', 'field' => 'type', 'sort' => 'ASC'),
        array('data' => 'created', 'field' => 'created', 'sort' => 'ASC'),
        array('data' => 'language', 'field' => 'language'),
    );
 
    # set the database table
    $query = db_select('node', 'n')->extend('PagerDefault')->extend('TableSort');
 
    # get the desired fields from the database
    $query->condition('uid', 1)
            ->fields('n', array('title', 'type', 'created', 'language'))
            ->limit(6)
            ->orderByHeader($header)
            ->orderBy('created', 'DESC');
 
    # execute the query
    $results = $query->execute();
 
    # build the table fields
    $rows = array();
    foreach ($results as $row) {
        $rows[] = array($row->title,
            $row->type,
            $row->created,
            $row->language,
        );
    }
    $output = theme('table', array('header' => $header,
        'rows' => $rows));
 
    # add the pager
    $output .= theme('pager');
 
    return $output;

Drupal 7 生成表格

Drupal 7生成表格

$header = array('title', 'type', 'created', 'language');
 
        # set the database table
        $query = db_select('node', 'n')->extend('PagerDefault');
 
        # get the desired fields from the database
        $query->condition('uid',1)
                ->fields('n', array('title', 'type', 'created', 'language'))
                ->orderBy('created', 'DESC')
                ->limit(3);
 
        # execute the query
        $results = $query->execute();
 
        # build the table fields
        $rows = array();
        foreach ($results as $row) {
            $rows[] = array($row->title,
                $row->type,
                $row->created,
                $row->language,
            );
        }
        $output = theme('table', array('header' => $header,
            'rows' => $rows));
 
        # add the pager
        $output .= theme('pager');
 
        return $output;

Drupal7编辑器:用Wysiwyg安装TinyMCE,并用IMCE Wysiwyg bridge整合IMCE

CKEditor固然强大,但文件包也太大了,ckeditor_3.6.3_for_drupal_7.zip(4793K),相比之下TinyMCE就小多了,tinymce_3.5.2.zip(827K)。
TinyMCE官网下载:http://www.tinymce.com/download/download.php
1. 安装Wysiwyg模块:http://drupal.org/project/wysiwyg
2. 下载TinyMCE,解压缩到\sites\all\libraries目录下,以备Wysiwyg模块使用。
3. 打开Wysiwyg模块的“配置”页,在上方的Filtered HTML,Full HTML均启用TinyMCE。
4. 在TinyMCE后面的“编辑”中添加一些按钮。至此,TinyMCE已经可以使用了,但是没有图片浏览的按钮。所以需要安装IMCE
5. 安装IMCE模块:http://drupal.org/project/imce
6. 安装IMCE Wysiwyg bridge模块:http://drupal.org/project/imce_wysiwyg
7. 启用刚刚安装的两个模块。
8. 配置:admin/config/content/wysiwyg/profile/filtered_html/edit 添加IMCE按钮,嘿嘿,这个按钮是安装了上述两个模块后才出现的。
9. OVER