之前我们讨论了如何控制区块中的选择器,现在让我们来学习如何用类似的技巧控制字段的选择器。
我们知道,字段是Drupal7建设网站的基石。字段包含着内容,内容为王!在我们学习控制字段的选择器之前,我们应该先搞清楚drupal是如何把字段渲染出来的。关于这个知识点,请看第二章第三节。
上次,我们从drupal核心复制了区块的模版文件blcok.tpl.php到自己的主题文件夹中,并进行了覆写,以达到掌控区块的主题层。对于字段来说,我们还是要使用类似的方法。字段在默认情况下是由主题函数theme_field()渲染的,所以为了改动这个函数,我们需要将它拷贝到自己主题文件夹中的template.php函数中进行覆写,将名字改为mytheme_field,这里的mytheme是自己的主题名称。
覆写后的新函数如下:
你会发现这段代码和核心中的theme_field(link is external)很类似,只改动了其中两处。我们在这里将包裹字段标签和字段内容的div的硬编码的class选择器给移除了。
然后,我们可以在template.php中为字段加上预处理函数:
/**
* Implements hook_preprocess_field()
*/
function mytheme_preprocess_field(&$vars) {
/* 先创建几个变量,这样可以少打几个字 */
$name = $vars['element']['#field_name'];
$bundle = $vars['element']['#bundle'];
$mode = $vars['element']['#view_mode'];
$classes = &$vars['classes_array'];
$title_classes = &$vars['title_attributes_array']['class'];
$content_classes = &$vars['content_attributes_array']['class'];
$item_classes = array();
$base_class = drupal_clean_css_identifier($field);
/* 字段的类选择器 */
$classes[] = 'field-wrapper';
$title_classes[] = 'field-label';
$content_classes[] = 'field-items';
$item_classes[] = 'field-item';
/* Uncomment the lines below to see variables you can use to target a field */
// print 'Name: ' . $name . '
';
// print 'Bundle: ' . $bundle . '
';
// print 'Mode: ' . $mode .'
';
/* 例子,为指定的字段加上特定的类选择器 */
switch ($mode) {
/* 所有的 teaser模式字段 */
case 'teaser':
switch ($name) {
/* Teaser read more links */
case 'node_link':
$item_classes[] = 'more-link';
break;
/* Teaser descriptions */
case 'body':
case 'field_description':
$item_classes[] = 'description';
break;
}
break;
}
/* 根据名称 */
switch ($name) {
case 'field_authors':
$title_classes[] = 'inline';
$content_classes[] = 'authors';
$item_classes[] = 'author';
break;
}
/* 添加奇偶类 */
foreach ($vars['items'] as $delta => $item) {
$vars['item_attributes_array'][$delta]['class'] = $item_classes;
$vars['item_attributes_array'][$delta]['class'][] = $delta % 2 ? 'even' : 'odd';
}
}
说了这么多,肯定还是会有很多人觉得很难控制Drupal输出的各种css选择器,是的,关于这一点,几乎每个themer都抱怨过:It sucks!
如果你发现有某个选择器你实在不知道如何控制,你还可以用一个比较迂回的办法,不过这需要你会用CSS预处理机制:比如sass中的@extend,这样你可以为自己需要的某个选择器写好样式,然后让drupal为你提供的选择器来extend这些样式。
ok,到此,虽然我们并没有完整的讲述在Drupal中各种改写选择器并实施SMACSS架构的方法,但是,至少证明这在一定程度上是可行的。
我们知道,开发者在开发Drupal7的时候,SMACSS之类的模块化CSS思想还没有出现。因此,正如前面所说的,Drupal7的CSS在构架方面存在着诸多弱点——虽然以当初的观点来看,大家都认为已经算是很不错的解决方案了。然而随着各方面经验的积累、大型实战项目的挑战及新兴观念和技术的普及,人们逐渐认识到这些问题,并尝试在自己的项目中,甚至新的Drupal8开发中加以改善。D8的整个前端构架都应用了SMACSS的思想,而我们在这几节中的讨论,则是试图改善D7中的问题。