Drupal灵活的节点类型,对应Drupal7专业开发指南 第三版的的七章源码:
job_post.info
name = Job Post description = A job posting content type package = Pro Drupal Development core = 7.x files[] = job_post.install files[] = job_post.module
job_post.install
<?php
/**
* @file
* Install file for Job Post module.
*/
/**
* Implements hook_install().
* - Add the body field.填充body字段
* - Configure the body field.配置body 字段
* - Create the company name field.创建公司名称字段
*/
function job_post_install()
{
// 更新 节点类型的数据库缓存.在写一个新的模块的是时候,若要涉及到节点类型的创建,这个函数必须要调用一下.
node_types_rebuild();
// 获取所有可用的节点类型
$types = node_type_get_types();
// add the body field to the node type
// 为一个内容类型增加一个body 字段
node_add_body_field($types['job_post']);
// Load the instance definition for our content type's body
// Returns an array of instance data for a specific field and bundle.
// 返回字段在数据库中的实例
$body_instance = field_info_instance('node', 'body', 'job_post');
// Configure the body field
// 配置body字段
$body_instance['type'] = 'text_summary_or_trimmed';
// Save our changes to the body field instance.
// 保存修改
field_update_instance($body_instance);
// Create all the fields we are adding to our content type.
// 创建这个类容类型
foreach(_job_post_installed_fields() as $field)
{
field_create_field($field);
}
// Create all the instances for our fields.
// 创建实例
foreach(_job_post_installed_instances() as $instance)
{
$instance['entity_type'] = 'node';
$instance['bundle'] = 'job_post';
field_create_instance($instance);
}
}
/**
* Return a structured array defining the fields created by this content type.
* For the job post module there is only one additional field – the company name
* Other fields could be added by defining them in this function as additional
* elements
* in the array below
* 返回字段数组
*/
function _job_post_installed_fields()
{
// 返回值是翻译函数的名字。get_t()函数常用于Drupal安装期间所使用的钩子hook_install(),也可以在安装模块时使用。
$t = get_t();
return array(
'job_post_company' => array(
'field_name' => 'job_post_company',
'label' => $t('Company posting the job listing'),
'type' => 'text'
)
);
}
/**
* Return a structured array defining the field instances associated with this
* content type.
* 返回实例数组
*/
function _job_post_installed_instances()
{
$t = get_t();
return array(
'job_post_company' => array(
'field_name' => 'job_post_company',
'type' => 'text',
'label' => $t('Company posting the job listing'),
'widget' => array(
'type' => 'text_textfield'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Company posting the job listing'),
'type' => 'text'
)
)
)
);
}
/**
* Implements hook_uninstall().
* 卸载
*/
function job_post_uninstall()
{
// Gather all the example content that might have been created while this
// module was enabled.
// 收集所有可能创建的类容
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(
':type' => 'job_post'
));
$nids = array();
foreach($result as $row)
{
$nids[] = $row->nid;
}
// Delete all the nodes at once
// 删除所有节点
node_delete_multiple($nids);
// Loop over each of the fields defined by this module and delete
// all instances of the field, their data, and the field itself.
// 遍历所有模块定义的字段然后删除之
foreach(array_keys(_job_post_installed_fields()) as $field) // 函数返回包含数组中所有键名的一个新数组。
{
field_delete_field($field); // 通过fieldname指定一个字段的实例和数据以供删除
}
// Loop over any remaining field instances attached to the job_post
// content type (such as the body field) and delete them individually.
// 删除与其有关的类容类型然后单独删除它们
$instances = field_info_instances('node', 'job_post');
foreach($instances as $instance_name=>$instance)
{
field_delete_instance($instance); // 通过instance指定一个字段的实例和数据以供删除
}
// Delete our content type
// 删除类容类型
node_type_delete('job_post');
// Purge all field infromation
// 批量删除,最大大小1000
field_purge_batch(1000);
}
job_post.module
<?php
/**
* @file
* This module provides a node type called job post
*/
/**
* Implements hook_node_info() to provide our job_post type.
* 当Drupal查找可用可用的节点类型时用到
*/
function job_post_node_info() {
return array(
'job_post' => array(
'name' => t('Job Post'),
'base' => 'job_post',
'description' => t('Use this content type to post a job.'),
'has_title' => TRUE,
'title_label' => t('Job Title'),
'help' => t('Enter the job title, job description, and the name of the company that posted the job'),
),
);
}
/**
* Implements hook_menu_alter().
* 实现只有站点管理员才能使用这项功能
*/
function job_post_menu_alter(&$callbacks)
{
// If the user does not have 'administer nodes' permission,
// disable the job_post menu item by setting its access callback to FALSE.
// 如果没有权限,通过禁用回调来禁用这个功能
if(!user_access('administer nodes'))
{
$callbacks['node/add/job_post']['access callback'] = FALSE;
// Must unset access arguments or Drupal will use user_access()
// as a default access callback.
//
unset($callbacks['node/add/job_post']['access arguments']);
}
}
/**
* Implements hook_permission().
* 定义权限,其实drupal自己就做了这一步,这里的反而没有用处
*/
function job_post_permission()
{
return array(
'create job post' => array(
'title' => t('Create a job post'),
'description' => t('Create a job post')
),
'edit own job post' => array(
'title' => t('Edit own job post'),
'description' => t('Edit your own job posting')
),
'edit any job post' => array(
'title' => t('Edit any job post'),
'description' => t('Edit any job posting')
),
'delete own job post' => array(
'title' => t('Delete own job post'),
'description' => t('Delete own job posting')
),
'delete any job post' => array(
'title' => t('Delete any job post'),
'description' => t('Delete any job posting')
)
);
}
/**
* Implements hook_node_access().
* 实现权限管理
*/
function job_node_access($op, $node, $account)
{
// 这个够简洁
$is_author = $account->uid == $node->uid;
switch ($op)
{
case 'create' :
// Allow if user's role has 'create joke' permission.
// 检查是否有创建权限
if(user_access('create job', $account))
{
return NODE_ACCESS_ALLOW;
}
case 'update' :
// Allow if user's role has 'edit own joke' permission and user is
// the author; or if the user's role has 'edit any joke' permission.
if(user_access('edit own job', $account) && $is_author || user_access('edit any job', $account))
{
return NODE_ACCESS_ALLOW;
}
case 'delete' :
// Allow if user's role has 'delete own joke' permission and user is
// the author; or if the user's role has 'delete any joke' permission.
if(user_access('delete own job', $account) && $is_author || user_access('delete any job', $account))
{
return NODE_ACCESS_ALLOW;
}
}
}
/**
* Implement hook_form() with the standard default form.
* 渲染页面
*/
function job_post_form($node, $form_state)
{
return node_content_form($node, $form_state);
}
/**
* Implements hook_validate().
* 数据校验
*/
function job_post_validate($node)
{
// Enforce a minimum character count of 2 on company names.
// 公司名至少2个字
// 测试一下und是个什么东西
// print_r($node);
// form_set_error('job_post_company', t('只是测试一下.'), $limit_validation_errors = NULL);
if(isset($node->job_post_company) && strlen($node->job_post_company['und'][0]['value']) < 2)
{
form_set_error('job_post_company', t('The company name is too short. It must be atleast 2 characters.'), $limit_validation_errors = NULL);
}
}
/**
* Implements hook_insert().
* base key才会被hook
*/
function job_post_insert($node)
{
// log details of the job posting to watchdog
// 在日志里记录
watchdog('job post', 'A new job post titled: ' . $node->title . ' for company: ' . $node->job_post_company['und'][0]['value'] . ' was added by UID: ' . $node->uid, $variables = array(), WATCHDOG_NOTICE, $link = 'node/' . $node->nid);
}
/**
* Implements hook_update().
* 在修改的时候被调动
*/
function job_post_update($node)
{
// log details of the job posting to watchdog
watchdog('job post', 'A job post titled: ' . $node->title . ' for company: ' . $node->job_post_company['und'][0]['value'] . ' was updated by UID: ' . $node->uid, $variables = array(), WATCHDOG_NOTICE, $link = 'node/' . $node->nid);
}
/**
* Implements hook_delete().
* 只有base key相符才会hook
*/
function job_post_delete($node)
{
// log details of the job posting to watchdog
watchdog('job post', 'A job post titled: ' . $node->title . ' for company: ' . $node->job_post_company['und'][0]['value'] . ' was deleted by UID: ' . $node->uid, $variables = array(), WATCHDOG_NOTICE, $link = 'node/' . $node->nid);
}
/**
* Implements hook_load().
* 在构建节点对象时向对象中添加你自定义的节点属性
*/
function job_post_load($nodes)
{
// Add a new element to the node at load time for storing the
// job posting sponsor information
//
foreach($nodes as $node)
{
$node->sponsor = "ACME Career Services, Your Source for Drupal Jobs";
}
return $node;
}
/**
* Implement hook_view().
*/
function job_post_view($node, $view_mode)
{
// Add and theme the sponsor so it appears when the job post is displayed
// 显示新加入的赞助商字段
if($view_mode == 'full')
{
$node->content['sponsor'] = array(
'#markup' => theme('sponsor', array(
'sponsor' => $node->sponsor,
'sponsor_id' => $node->nid
)),
'#weight' => 100
);
}
return $node;
}
/**
* Implements hook_theme().
* 上一个函数的#markup字段指定了使用theme函数渲染
* 而theme函数则构成了一个job_post_theme的函数名并且调用它
*/
function job_post_theme()
{
// define the variables and template associated with the sponsor field
// The sponsor will contain the name of the sponsor and the sponsor_id
// will be used to create a unique CSS ID
return array(
'sponsor' => array(
'variables' => array(
'sponsor' => NULL,
'sponsor_id' => NULL
),
'template' => 'sponsor'
)
);
}
sponsor.tpl.php
<?php
/**
* @file
* Default theme implementation for rendering job post sponsor information
*
* Available variables:
* - $sponsor_id: the node ID asociated with the job posting
* - $sponsor: the name of the job post sponsor
*/
?>
<div id="sponsor-<?php print $sponsor_id ?>" class="sponsor">
<div class="sponsor-title">
<h2>Sponsored by</h2>
</div>
<div class="sponsored-by-message">
This job posting was sponsored by: <?php print $sponsor; ?>
</div>
</div>
关于base键在数据库的位置:

知识共享署名-非商业性使用-相同方式共享:码农场 » Chapter 07: Working with Nodes 使用节点
码农场