6.12 在主题中应用smacss(3)——Apply SMACSS in Drupal theme(3)
之前我们讨论了如何控制区块中的选择器,现在让我们来学习如何用类似的技巧控制字段的选择器。
我们知道,字段是Drupal7建设网站的基石。字段包含着内容,内容为王!在我们学习控制字段的选择器之前,我们应该先搞清楚drupal是如何把字段渲染出来的。关于这个知识点,请看第二章第三节。
上次,我们从drupal核心复制了区块的模版文件blcok.tpl.php到自己的主题文件夹中,并进行了覆写,以达到掌控区块的主题层。对于字段来说,我们还是要使用类似的方法。字段在默认情况下是由主题函数theme_field()渲染的,所以为了改动这个函数,我们需要将它拷贝到自己主题文件夹中的template.php函数中进行覆写,将名字改为mytheme_field,这里的mytheme是自己的主题名称。
覆写后的新函数如下:
/** * Overrides theme_field() */ function mytheme_field($variables) { $output = ''; // Render the label, if it's not hidden. if (!$variables['label_hidden']) { $output .= '<div ' . $variables['title_attributes'] . '>' . $variables['label'] . ': </div>'; } // Render the items. $output .= '<div ' . $variables['content_attributes'] . '>'; foreach ($variables['items'] as $delta => $item) { $output .= '<div ' . $variables['item_attributes'][$delta] . '>' . drupal_render($item) . '</div>'; } $output .= '</div>'; // Render the top-level DIV. $output = '<div class="' . $variables['classes'] . '"' . $variables['attributes'] . '>' . $output . '</div>'; return $output; }
你会发现这段代码和核心中的theme_field很类似,只改动了其中两处。我们在这里将包裹字段标签和字段内容的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 '<strong>Name:</strong> ' . $name . '<br/>'; // print '<strong>Bundle:</strong> ' . $bundle . '<br/>'; // print '<strong>Mode:</strong> ' . $mode .'<br/>'; /* 例子,为指定的字段加上特定的类选择器 */ 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中的问题。
(无主题)