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 使用节点