在 Drupal 7 中使用表单

Posted

技术标签:

【中文标题】在 Drupal 7 中使用表单【英文标题】:Working with forms in Drupal 7 【发布时间】:2015-01-16 17:22:28 【问题描述】:

我有保存图片的节点。有一项任务是提供在每个节点中选择图片的类型和大小以进一步下载到最终用户设备的能力。 为此,我想在每个节点下附加一个表单,以允许用户选择他们需要的类型和大小。用户选择它并放置提交按钮后,我想处理用户的请求,在服务器端生成他们需要的图片,并以某种方式让他的浏览器下载它。但我不知道如何实现这一点,因为我不了解 Drupal 7 中的客户端-服务器交换机制。我知道基本的 Form API,但它对我没有帮助。 那么,你有什么建议?

编辑 1

这是我的模块testmodule.module的源代码

<?php
function testmodule_custom_form($form, &$form_state) 
    $form=array();
    $form['image_types'] = array(
        '#type' => 'radios',
        '#title' => t('Select image type to download'),
        '#options' => array(0 => t('SVG'), 1 => t('PNG'), 2 => t('ICON')),
    );
    $form['image_sizes'] = array(
        '#type' => 'radios',
        '#title' => t('Select image size'),
        '#options' => array(0 => t('100x100'), 1 => t('200x200')),
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Download'),

    );
    return $form;


function testmodule_custom_form_submit($form, &$form_state) 
    drupal_set_message('IT WORKS!!!');


function testmodule_node_view($node, $view_mode, $langcode) 
    if($node->type === 'article') 
        $my_form = drupal_get_form('testmodule_custom_form', $node);
        $node->content['attached_form'] = array(
            '#markup' => drupal_render($my_form),
            '#weight' => 99,
        );
    


function testmodule_node_presave($node) 
    $node->body[$node->language][0]['format']  = 'full_html';
    if ($node->field_image_svg[$node->language])
    
        $file = file_load($node->field_image_svg[$node->language][0]['fid']);
        $image = new Imagick(drupal_realpath($file->uri));
        $image->setImageFormat("png");
        $destination = 'public://pngimages/'.$file->filename.'.png';
        $image->writeImage(drupal_realpath($destination)); 
        $data = file_get_contents(drupal_realpath($destination));
        $file = file_save_data($data, $destination, FILE_EXISTS_REPLACE);
        $node->field_image[$node->language][0] = (array)$file;  
    

?>  

【问题讨论】:

【参考方案1】:

我通常更喜欢的另一种方法是使用带有默认值的程序块。

我已经在你的代码中实现了一个并清理了一些项目以更好地符合编码标准。

/**
 * Implements hook_form().
 */
function testmodule_custom_form($form, &$form_state) 
  $form = array();
  $form['image_types'] = array(
    '#type' => 'radios',
    '#title' => t('Select image type to download'),
    '#options' => array(0 => t('SVG'), 1 => t('PNG'), 2 => t('ICON')),
  );
  $form['image_sizes'] = array(
    '#type' => 'radios',
    '#title' => t('Select image size'),
    '#options' => array(0 => t('100x100'), 1 => t('200x200')),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Download'),

  );
  return $form;


/**
 * Implements hook_form_submit().
 */
function testmodule_custom_form_submit($form, &$form_state) 
  drupal_set_message('IT WORKS!!!');


/**
 * Implements hook_block_info().
 */
function testmodule_block_info() 
  $blocks = array();

  $blocks['image_download'] = array(
    'info' => t('Node - Image download'),
    'status' => 1,
    'region' => 'content',
    'visibility' => BLOCK_VISIBILITY_LISTED,
    'pages' => 'node/*',
    'cache' => DRUPAL_CACHE_PER_PAGE,
    'weight' => 1,
  );

  return $blocks;


/**
 * Implements hook_block_view().
 */
function testmodule_block_view($delta = '') 
  $n = menu_get_object();
  if (!$n || $n->type != 'only_particular_content_type') 
    return FALSE;
  

  if ($delta == 'image_download') 
    return array(
      'content' => drupal_get_form('testmodule_custom_form'),
    );
  

  return FALSE;


/**
 * Implements hook_node_presave().
 */
function testmodule_node_presave($node) 
  $node->body[$node->language][0]['format']  = 'full_html';
  $field_image_svg = field_get_items('node', $node, 'field_image_svg');
  if (!$field_image_svg) 
    return;
  

  $file = file_load($field_image_svg[0]['fid']);
  $image = new Imagick(drupal_realpath($file->uri));
  $image->setImageFormat("png");
  $destination = 'public://pngimages/'.$file->filename.'.png';
  $image->writeImage(drupal_realpath($destination));
  $data = file_get_contents(drupal_realpath($destination));
  $file = file_save_data($data, $destination, FILE_EXISTS_REPLACE);
  $node->field_image[$node->language][0] = (array)$file;


【讨论】:

也谢谢你。但我还不熟悉块的处理。我是初学者,积木是需要进一步研究的主题之一。 如果你被他们困住了,只要把任何问题都扔掉。看看:hook_block_info()。钩块视图()。钩块配置()。钩块保存()。 api.drupal.org/api/drupal/modules%21block%21block.api.php/7 好的,我一定会考虑的。那么在 Drupal 7 中使用链接呢?你能给点建议吗?我在hook_form_submit() 中使用drupal_goto(base_path().'/sites/default/files/tempimages/name.ext');,但它只在同一个选项卡中打开一个图像,我想让它至少在一个新选项卡中打开,或者,最好是开始下载到用户驱动器。跨度> 我会使用 $form_state['redirect'] 而不是 drupal_goto。如果表单上有任何其他提交处理程序,这很有用。在您的情况下,这不太可能。您正在寻找将标题内容配置设置为附件以强制自动“另存为”实现。您通常可以使用 php (header('Content-Disposition: attachment; filename="downloaded.pdf"');) 中的 'header' 函数执行此操作,但是当您直接下载时,您应该更改 .htaccess 文件:***.com/questions/14388994/…【参考方案2】:

一种方法是创建一个带有表单回调函数的自定义模块。

代码示例:

function YOUR_MODULE_custom_form($form, &$form_state) 
    // your form controls and inputs go here


function YOUR_MODULE_custom_form_submit($form, &$form_state) 
    // your form submission handler.
    // your image resizing logic and any other logic should go here

然后为了将此表单附加到节点,创建一个hook_node_view 实现。

function YOUR_MODULE_node_view($node, $view_mode, $langcode)

    if($node->type === 'YOUR_CONTENT_TYPE') 
        $my_form = drupal_get_form('YOUR_MODULE_custom_form', $node);
        $node->content['your_attached_form'] = array(
            '#markup' => drupal_render($my_form),
            '#weight' => 99,
        );
    

希望这能让你开始。我强烈建议您花时间熟悉 Drupal 表单 API 并创建自定义模块,这将使您的生活更轻松:)。

【讨论】:

感谢您的回答,Muhammad,但我尝试了这种方法,但没有奏效。这就是我想知道的原因。我什至在我的模块中复制了您的代码(当然,进行了更正),但它不再起作用。我的节点中甚至没有表格。你有什么想法为什么?附:几分钟后我会在这里添加我的代码。如果你有时间,请看一下。 我清除了缓存,现在它可以工作了!!!难以置信...我只需要清除缓存...该死的注意力不集中。 :)

以上是关于在 Drupal 7 中使用表单的主要内容,如果未能解决你的问题,请参考以下文章

Drupal 7 - 自定义模块:在节点提交中使用自定义表单输入

在 Drupal 7 中向表单添加文本(只是文本!)[关闭]

无法在 Drupal 7 中保留依赖选择框的值

在drupal 7中,由于多个附件,将表单添加到视图会产生多个相同的表单,如何只保留一个?

如何在drupal Web表单中的选择选项中填充动态内容

需要在每个节点可以提交一次的内容类型的每个实例中都有一个表单 - Drupal 7