如何使用模板文件来主题表单? -- forms 领域 和 theming 领域 drupal 相关 的问题

How to a use a template file to theme a form?


51
vote

问题

中文

虽然drupal中的节点,注释,块和许多其他东西使用主题模板文件(如node.tpl.php)主题,表单是一个不同的故事。表单没有主题模板文件。如何获得特定的表单来使用自定义主题模板?

英文原文

While nodes, comments, blocks and many other things in Drupal are themed using theme template files (like node.tpl.php), forms are a different story. There are no theme template files for forms. How can I get a particular form to use a custom theme template?

     

回答列表

75
 
vote
vote
最佳答案
 

要使用TPL文件来显示表单是完全合理的。您可以使用大量的外文CSS和 #prefix / #suffix 属性来实现类似的结果,但通过使用TPL,您不必杂乱逻辑和演示的分离图层,不必瞄准丑陋的CSS选择器,如 #user-login label 。这是Drupal 7 ...

中的一个例子

mytheme / template.php:

  template.php0  

custom_donate_form():

  template.php1  

mytheme / template / form / donate.tpl.php:

  template.php2  

这是使用 foundation ,它为我们提供了这样的形式:

输入图像描述

 

It's completely reasonable to want to use a tpl file to display a form. You can use lots of extraneous CSS and #prefix/#suffix properties to achieve similar results, but by using tpl's you don't have to clutter up the separation of your logic and presentation layers and don't have to target ugly CSS selectors like #user-login label. Here's an example in Drupal 7...

mytheme/template.php:

function mytheme_theme($existing, $type, $theme, $path) {     // Ex 1: the "story" node edit form.     $items['story_node_form'] = array(         'render element' => 'form',         'template' => 'node-edit--story',         'path' => drupal_get_path('theme', 'mytheme') . '/template/form',     );      // Ex 2: a custom form that comes from a custom module's "custom_donate_form()" function.     $items['custom_donate_form'] = array(         'render element' => 'form',         'template' => 'donate',         'path' => drupal_get_path('theme', 'mytheme') . '/template/form',     );      return $items; } 

custom_donate_form():

function custom_donate_form($form, &$form_state) {     $form['first_name'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('First name')),     );     $form['last_name'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('Last name')),     );     $form['address'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('Address')),     );     $form['city'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('City')),     );     $form['state'] = array(         '#type' => 'select',         '#options' => array(             'default' => 'State',             '...' => '...',         ),     );     $form['zip'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('Zip')),     );     $form['email'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('Email')),     );     $form['phone'] = array(         '#type' => 'textfield',         '#attributes' => array('placeholder' => t('Phone')),     );     $form['submit'] = array(         '#type' => 'submit',         '#value' => 'Submit',     );      return $form; } 

mytheme/template/form/donate.tpl.php:

<div class="row">     <div class="small-12 medium-12 large-8 columns">          <div class="row">             <div class="small-12 columns">                 <h5>Contact Information</h5>             </div>         </div>          <div class="row">             <div class="small-12 large-6 medium-6 columns">                 <?php print render($form['first_name']); ?>             </div>             <div class="small-12 large-6 medium-6 columns">                 <?php print render($form['last_name']); ?>             </div>         </div>          <div class="row">             <div class="small-12 medium-6 large-6 columns">                 <?php print render($form['address']); ?>             </div>              <div class="small-12 medium-6 large-6 columns">                 <?php print render($form['city']); ?>             </div>         </div>          <div class="row">             <div class="small-12 medium-3 large-3 columns">                 <?php print render($form['state']); ?>             </div>              <div class="small-12 medium-3 large-3 columns">                 <?php print render($form['zip']); ?>             </div>              <div class="medium-6 large-6 columns"></div>         </div>          <div class="row">             <div class="small-12 medium-6 large-6 columns">                 <?php print render($form['email']); ?>             </div>              <div class="small-12 medium-6 large-6 columns">                 <?php print render($form['phone']); ?>             </div>         </div>     </div>      <div class="row">         <div class="small-12 medium-12 large-8 large-offset-2 columns">             <?php print render($form['submit']); ?>         </div>     </div> </div>  <!-- Render any remaining elements, such as hidden inputs (token, form_id, etc). --> <?php print drupal_render_children($form); ?> 

This is using Foundation, which gives us a form like this:

enter image description here

 
 
         
         
18
 
vote

必须在模块或template.php中实现hook_form_alter()并设置表单的 #theme 属性:

  /**  * Implements hook_form_alter().  */ function hook_form_alter(&$form, &$form_state, $form_id) {   if ($form_id == 'user_login') {     $form['#theme'] = array('overwrite_user_login');   } }   

然后实现新主题:

  /**  * Implements hook_theme().  */ function hook_theme($existing, $type, $theme, $path){   return array(     'overwrite_user_login' => array(       'render element' => 'form',       'template' => 'form--user_login',       'path' => $path . '/templates',     ),   ); }   

然后添加表单 - user_login.tpl.php模板,并使用遵循代码呈现形式:

  <?php print drupal_render_children($form) ?>    
 

You have to implement hook_form_alter() in a module or template.php and set the form's #theme property:

/**  * Implements hook_form_alter().  */ function hook_form_alter(&$form, &$form_state, $form_id) {   if ($form_id == 'user_login') {     $form['#theme'] = array('overwrite_user_login');   } } 

Then implement new theme:

/**  * Implements hook_theme().  */ function hook_theme($existing, $type, $theme, $path){   return array(     'overwrite_user_login' => array(       'render element' => 'form',       'template' => 'form--user_login',       'path' => $path . '/templates',     ),   ); } 

And then add form--user_login.tpl.php template with follow code to render form:

<?php print drupal_render_children($form) ?>  
 
 
   
   
13
 
vote

即使您可以使用Kiammlaluno的解决方案,我个人不会。

您需要表单的模板文件是什么原因?如果是因为你想要现有形式的略微不同的标记?如果是这样,则可以使用 hook_form_alter() 在呈现之前修改表单。使用表单API您可以修改注入HTML元素等的所有表单字段等。

这是我创建的 hook_form_alter() 的一个例子,它会修改标准的drupal登录表单块:

  /**  * Implements hook_form_alter().  */ function MYMODULE_form_alter(&$form, &$form_state, $form_id) {    switch ($form_id) {     case 'user_login_block':        // Form modification code goes here.             $form['divstart'] = array(                 '#value' => '<div style="background-color: red;">',                 '#weight' => -1,             );              $form['instruct'] = array(                 '#value' => '<p>Enter your username and password to login</p>',                 '#weight' => 0,             );                        $form['divend'] = array(                 '#value' => '</div>',                 '#weight' => 4,                          );       break;   } }   

上面的示例在div中包装整个表单,它具有内联样式,将背景颜色变为红色。它还将帮助文本的段落添加到表单的开头。

这就是我的用户登录表单的样子,一旦加载上述代码:

自定义登录表单

有关详细信息,请参阅表单API参考:表单API参考

 

Even though you may be able to use kiamlaluno's solution I personally wouldn't.

What is your reason for needing a template file for a form? If it's because you want slightly different markup for an existing form? If so then you can use hook_form_alter() to modify the form before it is rendered. Using the Form API you you can modify all the form fields inject html elements etc.

Here is an example of hook_form_alter() that I've created that modifies the standard drupal login form block:

/**  * Implements hook_form_alter().  */ function MYMODULE_form_alter(&$form, &$form_state, $form_id) {    switch ($form_id) {     case 'user_login_block':        // Form modification code goes here.             $form['divstart'] = array(                 '#value' => '<div style="background-color: red;">',                 '#weight' => -1,             );              $form['instruct'] = array(                 '#value' => '<p>Enter your username and password to login</p>',                 '#weight' => 0,             );                        $form['divend'] = array(                 '#value' => '</div>',                 '#weight' => 4,                          );       break;   } } 

The above example wraps the entire form within a DIV which has an inline style to turn the background colour to red. It also adds a paragraph of help text to the beginning of the form.

This is what my user login form looks like now once the above code is loaded:

Customised login form

See the Form API reference for more information: Form API Reference

 
 
         
         
12
 
vote

我实际上从不需要使用模板文件来表格。
据我所知,Drupal核心代码使用主题函数,当需要以特定方式呈现形式或表单的一部分;调用 drupal_render()通常足够了目的。

要回复问题,为表单创建模板文件与创建不适用于表单的模板文件并不不同。

定义主题函数,使用主题函数函数表单构建器回调的名称。代码应类似于以下内容:

  /**  * Implementation of hook_theme().  */   function mymodule_theme() {    return array(      'mymodule_form' => array(        'template' => 'mymodule-form',        'file' => 'mymodule.admin.inc',        'arguments' => array('form' => NULL),      ),    );  }   

如果表单包含值 $form['field_1'] ,则其值将在模板文件中提供为 99887668 。模板文件也将能够使用从 template_preprocess_mymodule_form() 传递的任何值。

 

I have actually never needed to use a template file for a form.
As far as I can see, Drupal core code uses theme functions, when a form, or part of a form needs to be rendered in a particular way; a theme function that calls drupal_render() is normally enough for any purposes.

To reply to the question, creating a template file for a form is not different from creating a template file that is not for a form.

Define a theme function, using as theme function the name of the form builder callback. The code should be similar to the following:

/**  * Implementation of hook_theme().  */   function mymodule_theme() {    return array(      'mymodule_form' => array(        'template' => 'mymodule-form',        'file' => 'mymodule.admin.inc',        'arguments' => array('form' => NULL),      ),    );  } 

If the form contains the value $form['field_1'], its value will be available in the template file as $field_1. The template file will be also able to use any values passed from template_preprocess_mymodule_form().

 
 
     
     
1
 
vote

我将始终通过添加到我的CSS文件使用选择器来识别要样式的元素,如下用于核心登录表单

  /**  * Implements hook_theme().  */ function hook_theme($existing, $type, $theme, $path){   return array(     'overwrite_user_login' => array(       'render element' => 'form',       'template' => 'form--user_login',       'path' => $path . '/templates',     ),   ); } 0  

上面我只是添加到 /** * Implements hook_theme(). */ function hook_theme($existing, $type, $theme, $path){ return array( 'overwrite_user_login' => array( 'render element' => 'form', 'template' => 'form--user_login', 'path' => $path . '/templates', ), ); } 1

如果您需要的风格没有ID或足够准确的选择器,则必须使用 /** * Implements hook_theme(). */ function hook_theme($existing, $type, $theme, $path){ return array( 'overwrite_user_login' => array( 'render element' => 'form', 'template' => 'form--user_login', 'path' => $path . '/templates', ), ); } 2 方法来修改HTML TOOD标识符。

imo在元素上使用内联样式是非常糟糕的练习,应该被 /** * Implements hook_theme(). */ function hook_theme($existing, $type, $theme, $path){ return array( 'overwrite_user_login' => array( 'render element' => 'form', 'template' => 'form--user_login', 'path' => $path . '/templates', ), ); } 3 /** * Implements hook_theme(). */ function hook_theme($existing, $type, $theme, $path){ return array( 'overwrite_user_login' => array( 'render element' => 'form', 'template' => 'form--user_login', 'path' => $path . '/templates', ), ); } 4

 

I would always style by adding to my CSS file using selectors to identify the element to be styled as follows for the core login form

#user-login {    border:1px solid #888;    padding-left:10px;    padding-right:10px;    background-image: url(http://www.zaretto.com/images/zlogo_s.png);    background-repeat:no-repeat;    background-position:right; }  #user-login label {     display: inline-block; } 

The above I simply add to sites/all/themes/theme-name/css/theme-name.css

If what you need to style doesn't have an ID or a sufficiently accurate selector then it is necessary to use the hook approach to modify the HTML too add identifiers.

IMO using inline style on elements is a very bad practice that should be deprecated and replaced by use of class and id

 
 
0
 
vote

主题表单,您可以使用自定义CSS,如 主题drupal 7表格(包括CSS和JS)

基本上您需要执行以下步骤:

  1. 使用hook_menu()
  2. 注册到表单的路径
  3. 定义形式
  4. 使用hook_theme()
  5. 注册主题函数
  6. 写主题功能
  7. 创建CSS和JavaScript文件
 

To theme a form, you can use a custom css, as explained in Themeing Drupal 7 Forms (Including CSS and JS).

Basically you need to perform these steps:

  1. Register a path to the form using hook_menu()
  2. Define the form
  3. Register a theme function with hook_theme()
  4. Write the theme function
  5. Create the CSS and JavaScript files
 
 
-2
 
vote

我很确定你能够为表格使用模板,但你必须使用hook_theme首先注册模板。我有一个情况,表单真正需要是基于表而不是基于div,简单的#prefix和#suffix的变化并没有真正削减它。如果有兴趣,我可能会尝试挖掘一个例子。

 

I'm pretty sure you're able to use a template for forms, but you have to use hook_theme to register the template in the first place. I had a situation where the form really needed to be table based rather than div based and the simple #prefix and #suffix changes didn't really cut it. If interested I could probably try and dig up an example.

 
 

相关问题

6  应该使用“容器”表单元素时?  ( When should the container form element be used ) 
系统模块定义容器 form元素,但表单组件未以表单API参考文档记录。 什么时候应该使用该元素?它的目的是什么? ...

5  从Drupal表单字段/标签中删除冒号  ( Remove colons from drupal form fields labels ) 
如何删除:从使用Drupal形式API制作的表单后出现: ...

5  主题Drupal表单API复选框作为网格  ( Theme drupal form api checkboxes as a grid ) 
我有一个自定义表单,显示大约2多个复选框的表单元素。如果可能,我想在表中每行输出3个。我怎么能做到这一点? $form['preference'] = array( '#type' => 'checkboxes', '#default_value' => 1373, '#require...

19  形式的条件字段最简单的方法  ( Easiest method for conditional fields in a form ) 
获取基于另一个字段的值启用/禁用表单字段的javascript魔法最简单的方法是什么?这听起来像某个地方应该有一个助手,但我找不到它。我正在寻找一个不限于节点的解决方案。 ...

3  基于提交按钮值重定向节点形式  ( Node form redirect based on submit button value ) 
我已经读取并尝试了几种方法来重定向表单一旦提交。但是,如果操作是t("保存" ),我只想重定向节点表单。 如果我设置$ form ['#redirect'] = form_alter中的'blah',它将重定向所有类型的表单。如果我添加提交处理程序然后设置$ form_state ['重定向'],它只是被drupal...

6  我应该如何处理容器表单元素?  ( How should i handle container form elements ) 
我已将一些自定义字段添加到寄存器用户表单中,我发现它们被发送回,包装在"容器" 类型元素中。我的代码需要处理所有类型的自定义寄存器字段。 我该如何解析这些对象并从中提取字段?我应该调查阵列,我可以在那里找到什么? 我似乎无法在这些对象上找到任何好的文档。 编辑: 通过用户注册收到的常规字段可能如下所示: na...

7  如何将系统联系表单消息发送处理并改变生成的HTML?  ( How can i hook into the system contact form message sent process and alter the h ) 
我有一个drupal网站,我正在使用涉及范围的系统联系,以允许访问者向网站所有者发送消息。一旦访问者提交表单,用户将被重定向到主页,并且顶部读数出现粘性: 您的邮件已发送。 我的问题,是可以更改此消息并将一些HTML添加到输出吗?理想情况下,我会添加一些JavaScript来为Google Analytics帐户...

3  如何将表单元素值输出为文本?  ( How to output form element values as text ) 
在节点编辑表单上,我想使某些字段由所有用户不可编辑,但存储在其上的值在表单上可见。我的思想是要将它们作为文本而不是HTML表单元素打印出来。什么是完成此目的的最佳方式? 要提供一些上下文,这些值通过迁移填充,不应在网站上编辑。 ...

3  如何在Node-Add表单中展开FirdioSet?  ( How to expand the fieldsets in node add form ) 
当我通过 998876662 添加新节点时,有很多按组命令的设置:提交表单设置,工作流程设置,评论设置。但所有这些FirdioSet都默认折叠。 我的问题是:如何使它们默认扩展? ...

31  如何在“复选框”fapi元素中禁用一个复选框?  ( How can i disable a single checkbox in a checkboxes fapi element ) 
标题基本上说明了这一切,我想禁用一个复选框类型fapi元素的一个复选框。 我不想使用javascript,也不是从复选框到多个 checkbox 元素的选项,因为该元素由另一个模块提供。< / p> 思想? ...

6  如何将“传递给Drupal_Attributes()的参数1”解析为arrys_settings_form()上的array“错误?  ( How do i resolve the argument 1 passed to drupal attributes must be an array ) 
我通常不会在这样的特定问题上发布,并询问特定问题的帮助,但我在浪费时间的绳索结束时... 我有一个简单的d7模块如下所示,当我加载页面时(谁的菜单项正是我想要的地方)我收到以下错误: 可恢复的致命错误:传递给Drupal_Attributes()的参数1必须是阵列,在第3106行中调用/por/to/site/p...

13  如何将客户端表单验证添加到Drupal表单?  ( How do i add client side form validation to a drupal form ) 
如何将客户端表单验证添加到Drupal表单?例如,在评论模块中。如果Vistor不进入电子邮件地址,我想弹出一个说:"请输入电子邮件地址" 的窗口。 我希望有人能给我一个如何这样做的例子。 ...

2  如何通过drupal_get_form调用规则操作设置表单  ( How to call a rules action settings form via drupal get form ) 
所以,我正在尝试嵌入我在'/ admin / config / workflow / culs / comment / comment / commence_payment_paypal_wps / edit / 3'中找到的表单 - 其中包含paypal业务等的设置(来自commerce_paypal_wps .m...

7  如何覆盖搜索框?  ( How to overwrite the search box ) 
<div class="fr_search"> <form action="/" accept-charset="UTF-8" method="post" id="search-theme-form"> <input name="search_theme_form" id="edi...

3  如何为我的菜单添加额外的信息?  ( How can i add extra info to my menus ) 
我有一些在标准菜单模块中管理的菜单(Drupal 6,BTW)。我想在我编辑菜单项时添加一个复选框,以控制通过CSS的"新建" 横幅的显示(通过为打开复选框的项目添加类)。 我可以将我的复选框添加到形式,如下所示: function mymodule_form_menu_edit_item_alter(&$for...

4  将CSV文件发送到FAPI表单上的用户  ( Send a csv file to the user on fapi form submit ) 
我有一个fapi形式,可以从用户收集一些信息,然后生成csv文件。意图是当用户单击表单上的"导出" 时,CSV立即下载。 但是,当提交处理程序调用CSV生成函数时,表单只是重定向,而不是服务CSV。 是否有任何方法可以将此表单直接向用户提供服务,而不会生成临时文件? ...

9  表单API文件上传  ( Form api file upload ) 
我的表单中有以下代码。 $form['new']['upload'] = array( '#type' => 'file', '#title' => t(''), '#size' => 40, ); 在提交处理程序上,它返回文件名,但它不保存文件并返回文件对象。我还需要做什么? 我正在尝试做的是...

2  在哪里修改计算可折叠字段集的高度的逻辑?  ( Where to modify the logic that calculates the height of a collapsible fieldset ) 
我不确定这是否是一个主题问题,但我不断地获得可收缩的Firstalset是1-2扫描线太短,导致滚动条出现。 这个项目很重使用FAPI,有时在其他可折叠的仿古集中的可折叠仿真集,垂直滚动条正在吃太多的页面房地产。 我正在使用一个未修改的融合启动主题,如果有帮助。而且,我不是一个主题,但通常可以得到。 我会非常高兴修...

8  在“将文件推送”到用户之后是否可以重定向是可以重定向?  ( Is it possible to redirect after pushing a file to the user ) 
我有一个设置,其中一个网站生成有关站点使用情况的内部分析。用户能够请求下载其个人分析,因为此信息很敏感,我不创建任何文件,我在变量中生成CSV文件,然后将其"将其推送给用户: function _cex_download( $output, $filename ) { header("Pragma: pub...

1  即使第一个注册用户,最后表格验证函数也会传递错误  ( Last form validation function is passing an error even though the first one regi ) 
我写了一个自定义user_login表单验证函数,调用user_external_login_register()注册和登录用户,但表单调用form_set_error()的最后验证函数。 表单的#validate数组如下所示: validate (Array, 4 elements) * 0 (Str...




© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有


Licensed under cc by-sa 3.0 with attribution required.