跳转到主要内容

6.12 在主题中应用smacss(3)

之前我们讨论了如何控制区块中的选择器,现在让我们来学习如何用类似的技巧控制字段的选择器。

我们知道,字段是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中的问题。