20、Drupal模块部署与更新全攻略

Drupal模块部署与更新全攻略

在Drupal开发中,模块的部署、安装、更新和卸载是非常重要的环节。本文将详细介绍如何通过 .info .install 文件来实现这些功能,并以天气信息模块为例进行说明。

1. .info 文件配置

在Drupal中, .info 文件是模块的重要配置文件,它包含了模块的基本信息,如名称、描述、依赖项等。以下是 .info 文件的一些关键配置项:
- features[] :例如 features[] = comment_user_verification
- settings[] :这是一个可选的键值数组,用于向主题传递信息。类似于 .NET 应用配置框架中的 <add key="mykey" value="myvalue" /> ,在 .info 文件中可以写成 settings[mykey] = myvalue ,主题模块可以使用 theme_get_setting() 函数获取这些设置。
- engine :该必填字段指定主题使用的主题引擎。如果未提供,主题将被视为独立主题,即使用 .theme 文件实现。大多数主题应使用 phptemplate 作为默认引擎。
- screenshot :这是一个可选字段,指示Drupal主题页面引擎在哪里可以找到主题的缩略图。如果 .info 文件中省略此键,Drupal将使用主题目录中的 screenshot.png 文件。

.info 文件的行可以按任意顺序排列(除了 $Id$ 行),但大多数用户会将名称和描述放在首位,以便于阅读和更新。需要注意的是, .info 文件的内容会被缓存到数据库中,因此Drupal不会注意到任何更改。要清除缓存,可以点击“Configuration➤Performance”中的“Clear all caches”按钮。

2. .install 文件的作用

如果模块需要新的内容类型、自定义数据库或对环境进行其他更改,如创建目录结构,就需要包含一个 .install 文件。该文件的名称与模块名称相同,扩展名为 .install .install 文件的作用是为模块的安装和卸载提供支持,确保用户在使用和卸载模块时不会留下任何痕迹。

3. 构建 .install 文件

.install 文件与Drupal的钩子系统一起工作,最常见的用途是创建数据库表。以天气信息模块为例,我们需要创建一个表来跟踪用户输入的天气位置信息。以下是创建表的 schema 钩子函数:

function weather_info_schema() {
  $schema['weather_info'] = array(
    'description' => 'Weather information history.',
    'fields' => array(
        'hid' => array(
          'type' => 'serial',
          'unsigned' => TRUE,
          'not null' => TRUE,
          'description' => 'Primary Key: Unique history entry ID.',
          ),
        'location' => array(
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
          'default' => '',
          'description' => 'Weather location.',
          ),
        'units' => array(
          'type' => 'text',
          'length' => 50,
          'not null' => TRUE,
          'description' => 'Weather unit system.',
          ),
        'language' => array(
          'type' => 'text',
          'length' => 50,
          'not null' => TRUE,
          'description' => 'Language in which weather is displayed.',
          ),
        'uid' => array(
          'type' => 'int',
          'not null' => TRUE,
          'default' => '0',
          'description' => 'The uid of the user making the entry.',
          ),
        'timestamp' => array(
          'type' => 'int',
          'not null' => TRUE,
          'default' => '0',
          'description' => 'A unix timestamp indicating the time the entry was made.',
          ),
        ),
      'primary key' => array('hid'),
      'indexes' => array(
        'list' => array('location'),
        ),
      );

  return $schema;
}

在这个函数中,首先定义了表的字段,然后可选地定义了键和索引。数组的第一维是要创建的表的名称,这里是 weather_info 。通过返回 $schema ,Drupal模块安装函数会自动处理数据库表的创建。

4. 启用和安装钩子

在Drupal中,模块可以被启用、安装、禁用或卸载。当管理员在模块管理页面勾选模块并点击“Save configuration”按钮时,安装程序会查找 .install 文件中的某些钩子。首先处理 schema 钩子创建数据库表,然后如果模块尚未安装(或已卸载),安装程序引擎会查找 install 钩子并执行它(如果存在),最后执行 enable 钩子。

4.1 Install 钩子

以下是天气信息模块的 install 钩子示例:

function weather_info_install() {
  global $user;
  // Insert a default weather_info category.
  db_insert('weather_info')
    ->fields(array(
        'location' => 'Manchester, NH',
        'units' => 'F',
        'language' => 'en',
        'uid' => $user->uid,
        'timestamp' => REQUEST_TIME,
        ))
    ->execute();
  drupal_set_message(st('Weather information table has been created.'));
}

在这个钩子中,使用 db_insert() 函数插入一条初始记录。同时,还需要使用Fields API创建模块依赖的字段,例如天气位置、语言和单位字段:

// Weather location field
$field = array(
  'field_name' => 'field_weather_location',
  'type' => 'text',
  'translatable' => TRUE,
  );
$instance = array(
  'field_name' => 'field_weather_location',
  'entity_type' => 'user',
  'bundle' => 'user',
  'label' => 'Weather location',
  'widget' => array(
      'type' => 'text_textfield',
      'weight' => '15',
      ),
    'description' => st('Enter a location on earth for which you would like '
      . 'to see weather information presented.'),
    );

// Create the field and instance.
field_create_field($field);
field_create_instance($instance);

// Weather language field
$field = array(
  'field_name' => 'field_weather_language',
  'type' => 'list_text',
  'translatable' => TRUE,
  'settings' => array(
      'allowed_values' => "en|English\nes|Spanish\nde|German\ntr|Turkish\nfr|French\n",
      'allowed_values_function' => '',
      ),
    );
$instance = array(
  'field_name' => 'field_weather_language',
  'entity_type' => 'user',
  'bundle' => 'user',
  'label' => 'Weather language',
  'widget' => array(
      'type' => 'options_select',
      'weight' => '16',
      ),
    'description' => st('Enter the language in which you would like to see '
      . 'weather information presented.'),
    'default_value' => array(
      array(
        'value' => 'en',
        ),
      ),
    );
field_create_field($field);
field_create_instance($instance);

// Weather units field
$field = array(
  'field_name' => 'field_weather_unit',
  'type' => 'list_text',
  'translatable' => TRUE,
  'settings' => array(
      'allowed_values' => "F|Fahrenheit\nC|Celsius\nK|Kelvin\nR|Rankine",
      'allowed_values_function' => '',
      ),
    );
$instance = array(
  'field_name' => 'field_weather_unit',
  'entity_type' => 'user',
  'bundle' => 'user',
  'label' => 'Weather units',
  'widget' => array(
      'type' => 'options_select',
      'weight' => '17',
      ),
    'description' => st('Enter the measurement unit with which you would like '
      . 'to see weather information presented.'),
    'default_value' => array(
      array(
        'value' => 'F',
        ),
      ),
    );

field_create_field($field);
field_create_instance($instance);
4.2 Enable 钩子

enable 钩子的作用是设置模块依赖的系统变量:

function weather_info_enable() {
  variable_set('default_location', 'Manchester, NH');
  variable_set('default_units', 'F');
  variable_set('default_language', 'en');
  variable_set('current_location', variable_get('default_location'));
  drupal_set_message(st('Weather information default variables have been set.'));
}
5. 模块更改与历史记录插入

创建天气信息历史表后,我们可以添加功能来利用这个新表。每次用户更改其个人资料信息时,插入一条记录到历史表中:

function weather_info_insert_history($location, $language, $unit, $weather) {
  global $user;
    $fields = array(
      'location' => $location,  
      'language' => substr($language, 0, 2),
      'units' => substr($unit, 0, 1),
      'uid' => $user->uid,
      'timestamp' => REQUEST_TIME,
      );
    $options = array('return' => Database::RETURN_STATEMENT);
    $returned = db_insert('weather_info', $options)
      ->fields($fields)
      ->execute();
}

function weather_info_profile_weather_location_validate($element, &$form_state) {
  $location = $form_state['values']['field_weather_location']['und'][0]['value'];
  $language = $form_state['values']['field_weather_language']['und'][0]['value'];
  $unit = $form_state['values']['field_weather_unit']['und'][0]['value'];
  if (variable_get('default_location') != $location) {
    $weather = weather_info_get_weather($location, 'en');
    if ($weather) {
      weather_info_insert_history($location, $language, $unit, $weather);
    }
    else {
      form_set_error('field_weather_location[und][0][value]', t('Cannot get weather for %location.',  
        array('%location' => $location)));  
    }
  }
}
6. 禁用和卸载钩子

禁用和卸载钩子用于撤销启用和安装钩子所做的环境更改,特别是卸载钩子可以删除模块正常使用时生成的信息。

6.1 Disable 钩子

当模块在模块页面上被取消勾选并提交页面时,执行 disable 钩子:

function weather_info_disable() {
  variable_del('default_location');
  variable_del('default_units');
  variable_del('default_language');
  variable_del('current_location');
}

这个函数只是从变量表中删除系统变量,虽然不是必需的,但清理是一个好习惯。

6.2 Uninstall 钩子

当模块在卸载页面上被勾选并提交页面时,执行 uninstall 钩子:

function weather_info_uninstall() {
  field_delete_field('field_weather_location');
  field_delete_field('field_weather_language');
  field_delete_field('field_weather_unit');

  // Flush the cache to get rid of the user profile page entry
  drupal_flush_all_caches();
}

在卸载模块时,需要删除所有创建的字段,并清除缓存。如果使用 schema 钩子创建了表,卸载引擎会自动处理这些表的删除。

在交付模块之前,需要将 .install 文件添加到 .info 文件中,让Drupal知道它的存在:

; $Id$
name = Weather information
description = A block that shows current weather for a particular location.
package = Cool stuff from Brian
core = 7.x
files[] = weather_info.module
files[] = weather_info.inc
files[] = weather_info.install
files[] = tests/weather_info.test
dependencies[] = blocks
configure = /admin/config/weather_info/settings
version = 7.x-1.x

通过以上步骤,我们可以完成Drupal模块的部署、安装、更新和卸载。在后续的开发中,还需要考虑模块的更新问题,确保用户能够方便地升级到新版本。

Drupal模块部署与更新全攻略

7. 更新钩子与模块更新

随着模块的开发,我们肯定会对其进行改进。Drupal有一个更新管理器,它会定期检查Drupal社区网站(drupal.org),查看特定系统上加载的所有模块是否有可用更新。如果你的模块托管在drupal.org上并发布了新版本,所有启用该模块的系统上的更新管理器都会通知管理员有新版本可用。

当你对模块进行功能添加或删除,且只影响模块本身时,只需将新的模块文件放在项目目录中即可。但如果添加的功能影响到系统的其他部分,就需要使用更新钩子,让安装程序引擎知道如何处理新代码。

更新钩子可用于处理多种情况,例如添加新的数据库字段以捕获更多信息、修复错误指定的数据库表、创建存储特定信息的新目录或更改角色权限等。

Drupal的更新引擎会读取 .install 文件,查找需要应用的更新。它会记录每个已安装模块的当前更新版本。当有新的更新可用时,安装程序会查找具有特定名称的更新钩子,该名称遵循以下规则:
- 第1位数字表示Drupal核心兼容性。
- 第2位数字表示模块的主要版本号(例如,模块是7.x - 1. 系列还是7.x - 2. 系列)。
- 后2位数字是从00开始的顺序计数。

以下是一些更新钩子名称的示例:
| 更新钩子名称 | 说明 |
| — | — |
| weather_info_update_7100() | 这是使数据库准备好运行天气信息模块7.x - 1. 版本的第一次更新。 |
| weather_info_update_7000() | 假设模块有一个在Drupal 6下运行的版本,这是将其升级到与Drupal核心API 7.x兼容所需的更新。 |
| weather_info_update_7200() | 这是使数据库准备好运行天气信息模块7.x - 2.
版本的第一次更新。 |
| weather_info_update_7201() | 这是使数据库准备好运行天气信息模块7.x - 2.* 版本的第二次更新。 |

8. 创建更新示例

以天气信息模块为例,我们希望保存用户选择新位置时返回的XML流,并将数据库表名改为更具描述性的名称。以下是实现这一目标的步骤:

首先,修改写入数据库的函数:

function weather_info_insert_history($location, $language, $unit, $weather) {
  global $user;
  $fields = array(
    'location' => $location,  
    'language' => substr($language, 0, 2),
    'units' => substr($unit, 0, 1),
    'uid' => $user->uid,
    'timestamp' => REQUEST_TIME,
    'xml' => $weather->asXML(),
    );
  db_insert('weather_info_history')
    ->fields($fields)
    ->execute();
}

这里使用了 asXML() 方法将XML天气对象序列化,并将 db_insert() 函数中的表名改为 weather_info_history

接下来,创建更新钩子函数:

/**
 * Rename {weather_info} table to {weather_info_history} and add a field to capture  
 * raw XML data from the weather service.
 */
function weather_info_update_7100() {
  db_rename_table('weather_info', 'weather_info_history');
  db_add_field('weather_info_history', 'xml',  
    array(
      'type' => 'text',
      'size' => 'normal',
      'description' => 'Raw weather XML returned.',
    )
  );

  // update all existing records
  $result = db_select('weather_info_history', 'h')
    ->fields('h', array('hid', 'location', 'language'))
    ->execute();
  foreach ($result as $record) {
    $weather = weather_info_get_weather($record->location, $record->language);
    if ($weather) {
      db_update('weather_info_history')
        ->fields(array(
            'xml' => $weather->asXML())
            )
        ->condition('hid', $record->hid, '=')
        ->execute();
    }
  }
}

这个函数首先重命名表,然后添加一个新字段,最后读取现有记录并使用天气服务生成的XML更新每条记录。

9. 更新系统的操作步骤

完成 .install 文件的更新后,我们需要将更新后的包交付给用户。具体操作步骤如下:
1. 更新 .info 文件 :由于我们有了新版本的程序,需要更新版本号。新的 .info 文件如下:

; $Id$
name = Weather information
description = A block that shows current weather for a particular location.
package = Cool stuff from Brian
core = 7.x
files[] = weather_info.module
files[] = weather_info.inc
files[] = weather_info.install
files[] = tests/weather_info.test
dependencies[] = profile
configure = /admin/config/weather_info/settings
version = 7.x-1.0
  1. 放置新模块文件 :将新的模块文件放在项目目录中。
  2. 触发更新流程
    • 访问配置页面,更新管理器会检测到有新的模块版本,并显示错误消息。
    • 点击“status report”可获取更多信息。
    • 点击“database update script”启动更新程序,会出现更新向导。
    • 点击“Continue”,会显示所有可用的更新信息,包括 .install 文件中的注释和更新编号(如7100)。
    • 点击“Apply pending updates”,更新程序会运行所有可用的更新函数(这里只有一个),过程中会显示进度条。
    • 更新完成后,会显示状态屏幕。

以下是更新流程的mermaid流程图:

graph LR
    A[放置新模块文件] --> B[访问配置页面]
    B --> C{检测到新模块版本?}
    C -- 是 --> D[点击status report]
    D --> E[点击database update script]
    E --> F[更新向导]
    F --> G[点击Continue]
    G --> H[显示可用更新信息]
    H --> I[点击Apply pending updates]
    I --> J[更新进行中]
    J --> K[更新完成,显示状态屏幕]
    C -- 否 --> L[无更新]

通过以上步骤,我们可以确保用户能够方便地将模块更新到新版本,同时保证系统的稳定性和数据的完整性。在开发Drupal模块时,合理使用 .info .install 文件,以及各种钩子函数,可以有效地管理模块的部署、安装、更新和卸载过程。

基于NSGA-III算法求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文围绕基于NSGA-III算法的微电网多目标优化调度展开研究,重点介绍了如何利用该先进多目标进化算法解决微电网系统中多个相互冲突的目标(如运行成本最小化、碳排放最低、供电可靠性最高等)的协同优化问题。文中结合Matlab代码实现,详细阐述了NSGA-III算法的基本原理、在微电网调度模型中的建模过程、约束条件处理、目标函数设计以及仿真结果分析,展示了其相较于传统优化方法在求解高维、非线性、多目标问题上的优越性。同时,文档还提供了丰富的相关研究案例和技术支持背景,涵盖电力系统优化、智能算法应用及Matlab仿真等多个方面。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事能源优化领域的工程技术人员;尤其适合正在进行微电网调度、多目标优化算法研究或撰写相关论文的研究者。; 使用场景及目标:①掌握NSGA-III算法的核心思想及其在复杂能源系统优化中的应用方式;②学习如何构建微电网多目标调度模型并利用Matlab进行仿真求解;③为科研项目、毕业论文或实际工程提供算法实现参考和技术支撑。; 阅读建议:建议读者结合文中提供的Matlab代码实例,逐步调试运行并深入理解算法流程模型构建细节,同时可参考文档中列出的其他优化案例进行横向对比学习,以提升综合应用能力。
内容概要:本文深入探讨了YOLOv11目标检测模型在计算机竞赛中的应用价值,介绍了其作为实时目标检测前沿技术的核心原理,即通过单次前向传播实现目标分类定位,具备高精度高速度的优势。文章阐述了YOLOv11基于深度学习和卷积神经网络的特征提取机制,并重点分析了在竞赛中提升性能的关键技巧,包括数据集精细化管理、针对性数据增强策略(如光照调整)、模型结构选择学习率调度优化。结合自动驾驶、医疗影像分析和环境监测等实际应用场景,展示了其广泛适用性。并通过一段完整的代码实例,详细解析了模型加载、图像预处理、推理、后处理及结果可视化的全流程。最后展望了YOLOv11未来在硬件加速、多模态融合及模型可解释性方面的演进趋势。; 适合人群:具备一定深度学习基础,参计算机视觉相关竞赛的高校学生、研究人员及算法工程师;熟悉Python和PyTorch框架的技术人员。; 使用场景及目标:①掌握YOLOv11在各类计算机竞赛中的实际部署方法;②学习如何针对特定任务优化模型性能;③理解从数据处理到结果可视化的完整目标检测流程;④为参赛项目提供高效、可靠的解决方案。; 阅读建议:建议结合代码实例动手实践,复现检测流程,并根据具体竞赛需求调整数据增强策略模型参数,同时关注模型轻量化推理效率的平衡。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值