Answers:
想要使用tpl文件显示表单是完全合理的。您可以使用大量无关的CSS和#prefix
/ #suffix
属性来获得相似的结果,但是通过使用tpl,您不必使逻辑层和表示层的分离变得混乱,也不必像丑陋的CSS选择器那样定位#user-login label
。这是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); ?>
这是使用Foundation的,它为我们提供了这样的形式:
print drupal_render_children($form)
这使得表单实际上可以完成工作:)。
engine
,如果您使用的不是默认值,则需要另外指定。例如'engine' => 'twig'
。
user_profile_form
或的管理表单的主题,请记住user_register_form
。在这种情况下,您将需要a)在admin主题中进行主题化(如果无法更改基本admin主题,则以其为子主题)或b)将主题放入自定义模块中。否则将看不到您的主题。
您必须在模块或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',
),
);
}
然后添加带有以下代码的form--user_login.tpl.php模板以呈现表单:
<?php print drupal_render_children($form) ?>
#theme
属性是如此简单,并且在答案中第一次提到了它,这太奇怪了。这绝对是我最喜欢的方法。
即使您可能可以使用kiamlaluno的解决方案,但我个人不会。
您需要表单的模板文件的原因是什么?如果是因为您希望现有表单的标记稍有不同,该怎么办?如果是这样,则可以hook_form_alter()
在呈现表单之前先对其进行修改。使用Form 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中,该DIV具有内联样式,可将背景色变为红色。它还在表单的开头添加了一段帮助文本。
上面的代码加载后,这就是我的用户登录表单现在的样子:
有关更多信息,请参见Form API参考:Form API参考
实际上,我从来不需要为表单使用模板文件。
据我所知,当需要以特定方式呈现表单或表单的一部分时,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']
,则其值将在模板文件中以形式提供$field_1
。模板文件也将能够使用从传递的任何值template_preprocess_mymodule_form()
。
$form['#theme']
。
我将始终通过使用选择器添加到我的CSS文件中来进行样式设置,以标识要为核心登录表单设置样式的元素,如下所示
#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;
}
上面我简单地添加到 sites/all/themes/theme-name/css/theme-name.css
如果您需要样式的内容没有ID或没有足够准确的选择器,则有必要使用hook
修改HTML 的方法添加标识符。
IMO在使用内联元素风格是一个非常不好的做法,应该被淘汰,并通过使用替代class
和id
要为表单设置主题,可以使用自定义css,如在主题化Drupal 7表单(包括CSS和JS)中所述。
基本上,您需要执行以下步骤: