以下是Scott Fennell的来宾帖子。 斯科特(Scott)最近在CSS-Tricks上看到了一篇有关WordPress中类名的帖子,并对使用控制而不是保持原样有自己的一些想法。 他的想法是在可能的情况下实施更SMASMA风格的哲学。
我喜欢这个领域的最近一篇有关了解WordPress CSS类的文章 。 作者指出:
@carlosinho
我已经掌握了一些这样做的技巧,并希望与您分享这些技巧。
我喜欢SMACSS书 。 在这里推荐的所有出色实践中,我最喜欢的是类名的规则 。 冒着蒙上许多光彩的风险,我将提炼出一个例子:
<div class="pod">
<h3 class="pod-header">heading</h3>
<ul class="pod-items">
<li class="pod-item"><a class="pod-item-link" href="#">Click me</a></li>
<li class="pod-item"><a class="pod-item-link" href="#">Click me</a></li>
</ul>
</div>
这并不是SMACSS书中的逐字记录,但是它代表了SMACSCS在我的工作流程中的含义。 注意:
- .pod每个组件都可以通过以pod-为前缀的css类进行pod- 。
- 具有父对多子关系的组件采用单/复数命名方案,如pod-item和pod-items.
这或多或少是我用CSS定位HTML的理想设置。 这是我在本文中要争取的模型。 不幸的是,WordPress并非那样。
让WordPress遵循这种格式需要采取四种广泛的方法:
- 真正快速简便的过滤器,仅需几行代码即可更改WordPress的输出。
- 告诉WordPress将某些类应用于我们注册的对象。
- 在我们自己的自定义函数(plugin东西或functions.php)中养成习惯,以便他们可以轻松且可管理地接受定制类。
- 相对较大的WordPress核心替代可能最终不值得付出努力。
它应该不用说(但可以说):实际上,修改WordPress核心文件不是一种选择。
修改WordPress附带的许多类的最简单方法是过滤。 假设我们有大量数据。 它可以是帖子标题(字符串)或帖子类别数组。 这些数据可能正在某个地方(从数据库到浏览器)显示在前端,或者可能正在从后期编辑器到要存储在数据库中的数据库。 多次将数据从一个地方移动到另一个地方时,我们可以使用过滤器进行更改。 这是使用应用于body标签的类的示例:
/**
* Extends the default WordPress body class.
*
* @param array $classes An array of css classes.
* @return array The array of css classes, filtered.
*/
function sjf_body_class( $classes ) {
// If the current post has a post thumbnail, append a body class.
if ( is_singular() && has_post_thumbnail() ) {
$classes[] = 'body-has-post-thumbnail';
}
return $classes;
}
// Apply these classes to the body tag.
add_filter( 'body_class', 'sjf_body_class' );
请注意,只有这是一篇带有精选图片的帖子,我们才有条件执行此操作。 无论该条件的结果如何,我们都必须返回$classes数组,这一点很重要, 否则我们所有其他模板都将没有body类! 将这一点视为O'Reilly动物书籍中的“陷阱”图标。
我们可以将所需的任何字符串添加到classes数组,但是,如果要获取未进行硬编码的任何内容,则应首先使用sanitize_html_class()对其进行清理 。 例如,我们可能想添加一些post_meta值,也许如果该帖子已经根据艺术进行了特殊的配色:
/**
* Extends the default WordPress body class to include the accent color for this post.
*
* @param array $classes An array of css classes.
* @return array The array of css classes, plus a new class for accent-color.
*/
function sjf_body_class( $classes ) {
// If the current post has an accent color, append a body class.
if ( is_singular() ) {
$accent_color = get_post_meta( get_the_ID(), 'sjf_accent_color', TRUE );
$accent_color = sanitize_html_class( $accent_color );
if( ! empty( $accent_color ) ) {
$classes[] = "body-$accent_color";
}
}
return $classes;
}
// Apply these classes to the body tag.
add_filter( 'body_class', 'sjf_body_class' );
我们可以以几乎完全相同的方式修改应用于循环中的帖子的类的数组。 唯一的区别是,不是将函数添加到body_class过滤器,而是将其添加到post_class :
/**
* Extends the default WordPress post class to include the accent color for this post.
*
* @param array $classes An array of css classes.
* @return array The array of css classes, plus a new class for accent-color.
*/
function sjf_post_class( $classes ) {
// If the current post has an accent color, append a post class.
if ( is_singular() ) {
$accent_color = get_post_meta( get_the_ID(), 'sjf_accent_color', TRUE );
$accent_color = sanitize_html_class( $accent_color );
if( ! empty( $accent_color ) ) {
$classes[] = "sjf-body-$accent_color-post";
}
}
return $classes;
}
// Apply these classes to the post tag.
add_filter( 'post_class', 'sjf_post_class' );
像这样还有更多的钩子。 请参阅亚当·布朗的清单,并搜索“班级”以获取更多想法。 一些额外课程的最佳人选是:
- nav_menu_css_class
- get_image_tag_class
- comment_class
请注意,我对SMACSS的解释表明我的帖子类别与我的身体类别相同,仅在其后缀-post 。 多亏了current_filter()函数,我们实际上可以使用完全相同的函数来运行我们的主体类和我们的帖子类,并使我们的代码保持干燥:
function sjf_body_post_class( $classes ) {
// If the current post has an accent color, add a class.
if ( is_singular() ) {
$accent_color = get_post_meta( get_the_ID(), 'sjf_accent_color', TRUE );
$accent_color = sanitize_html_class( $accent_color );
if( ! empty( $accent_color ) ) {
// If we are on the post_class filter, tack on a '-post'.
$suffix = '';
if( current_filter() == 'post_class' ) { $suffix = '-post'; }
$classes[] = "sjf-body-$accent_color$suffix";
}
}
return $classes;
}
// Apply these classes to the body tag.
add_filter( 'body_class', 'sjf_body_post_class' );
// Apply these classes to the post tag.
add_filter( 'post_class', 'sjf_body_post_class' );
过滤器是将新类应用于WordPress生成的项目的强大而简单的工具。 但是WordPress为响应主题或注册该项目的插件而生成的项目又如何呢?
考虑以下代码,用于注册侧边栏 :
function sjf_widgets_init() {
register_sidebar( array(
'name' => __( 'Main Sidebar', 'sjf' ),
'id' => 'sjf-main-widgets',
'description' => __( 'Widgets in this area will be shown on all posts and pages.', 'sjf' ),
'before_title' => '<h1>',
'after_title' => '</h1>',
) );
}
add_action( 'widgets_init', 'sjf_widgets_init' );
漂亮又简单。 但是,如果我们的目标是将SMACSS样式的类应用于尽可能多的元素,那是一个浪费的机会! 在这里有很多地方可以插入类,尽管与之前处理类数组的过滤器不同,这种情况需要一个简单的类名称字符串。 对于此示例,假设设计根据登录状态要求不同的窗口小部件样式。 这是我们可以做的:
function sjf_widgets_init() {
$slug = 'sjf-main';
if( is_user_logged_in() ) {
$logged = 'logged-in';
} else {
$logged = 'logged-out';
}
register_sidebar( array(
'name' => __( 'Main Sidebar', 'theme-slug' ),
'id' => "$slug-widgets",
'description' => __( 'Widgets in this area will be shown on all posts and pages.', 'sjf' ),
'before_widget' => "<div id='%s' class='widget $slug-widget $slug-widget-$logged_in $slug-widget-%s'>",
'after_widget' => '</div>',
'before_title' => "<h1 class='widget-title $slug-widget-title $slug-widget-title-$logged_in'>",
'after_title' => '</h1>',
) );
}
add_action( 'widgets_init', 'sjf_widgets_init' );
发生了几件事:
- 用户数据。 使用$logged我们可以运行较早的旧技巧,看看这篇文章是否已被艺术指导成一种特殊的配色方案。
- sprintf() 。 使用%s ,我们提示WordPress用这种类型的小部件的副词名替换该小块。 诸如widget_search或widget_text类的东西。
- 排列。 为了支持SMACSS,我们不只是添加$color_class类或$id类并将其命名为好。 我们考虑了可能需要的不同组合。 例如,如果我们需要将搜索表单定位在主边栏中的带红色重音的页面上,则可以使用单个CSS类sjf-main-widget-red-widget_search 。
需要明确的是,我从先前的post_meta示例中移开的原因之一是因为在注册小部件时尚未公开发布数据。
某些设计可能细微到足以证明小部件的更详细类的合理性。 .org存储库中有一些插件,可以对每个小部件进行快速分类: 每个小部件 分类 。
在介绍了对WordPress生成的元素进行分类的一些方法之后,我们现在来看一下自己的自定义元素。
无论是在我们的functions.php中还是在我们的插件文件中,我们无疑都会注册许多我们自己的函数。 我想出了使SMACSS就绪的例程。 考虑一下此函数,它只返回hello world :
function sjf_hello() {
return '<span class="sjf-hello">hello world</span>';
}
完全不支持SMACSS。 如果我们希望能够以符合SMACSS的方式定位此元素,我们将需要更多。 例如,如果从本文开始在我们的.pod示例中使用了此元素,我们希望它包含.pod-sjf-hello类的类。 无论哪种情况,我们都希望能够根据需要方便地注入mnay类。 这是我的工作:
/**
* Get the string "hello world", wrapped and classed.
*
* @param array $classes An array of CSS classes.
* @return string The "hello world" string, wrapped and classed.
*/
function sjf_hello( $classes = array() ) {
// The namespace for this element.
$slug = 'sjf-hello';
// Prepend the slug to each class name, convert to a string.
$classes_str = sjf_prepend_slug( $classes, $slug );
return "<span class='$slug $classes_str'>hello world</span>";
}
注意,我的函数现在为$classes接受一个arg,它需要一个css类名数组。 如果我要传递大量的类给我,我就不必担心提前给它们sjf_prepend_slug()前缀,因此可以使用第二个函数sjf_prepend_slug()在这些函数中给它们sjf_prepend_slug()前缀:
/**
* Prepend a string to each member of an array.
*
* @param array $classes An array of CSS classes.
* @param string $slug A namespace to prepend to each class.
* @return string The $classes array, cleaned, slugged, and imploded.
*/
function sjf_prepend_slug( $classes, $slug ) {
$cleaned = array();
foreach( $classes as $class ) {
$cleaned []= sanitize_html_class( $slug . '-' . $class );
}
// Convert the array to a string, with a space between each class name.
$classes_str = implode( ' ', $cleaned );
return $classes_str;
}
该功能还可以完成所有类的清理工作。 我们可以将其用于主题或插件中的所有模板标签。
这个简单的例程可以帮助我们以最少的额外代码使所有自定义函数保持SMACSS就绪状态。
到目前为止,我们讨论的所有技术在代码:收益率方面都非常有效。 就是说,我们用很少的代码就获得了很多SMACSS优势,这就是促使我写这篇文章的原因。 但是,我们可以采取另一种方法,即用我们自己的方法覆盖核心功能,并在此过程中添加SMACSS类。
我可能不建议这样做只是添加SMACSS类,因为它可能是很多代码,更多代码意味着更多错误。 相反,如果默认WordPress输出中的某些元素已经需要为我们的项目进行修改(也许是出于设计或功能方面的原因),我们应该抓住这个机会对其进行分类。
搜索表单是主题开发人员涉足的第一个替代项。 这样做的方法是将一个新的搜索表单添加到我们的主题中,该文件的保留名称为`searchform.php`。 但是,我希望能够在其他地方重用我的自定义搜索表单,并且我不想在`functions.php`之外定义函数,所以我的`searchform.php`看起来像这样:
/**
* sjf search form.
*
* @package WordPress
* @subpackage sjf
* @since sjf 1.0
*/
echo sjf_get_search_form();
我的sjf_get_search_form()生活在functions.php中,看起来像这样:
/**
* Returns a WordPress search form.
*
* Accepts arguments to inject CSS classes into the form, which this theme uses
* in order to comply with SMACSS. Passing dynamic class values for each
* instance would not be possible with the normal use of searchform.php.
*
* @param array $classes CSS classes for the form.
* @return string A search form.
*
* @since anchorage 1.0
*/
if( ! function_exists( 'sjf_get_search_form' ) ) {
function sjf_get_search_form( $classes = array() ) {
$slug = 'sjf-searchform';
// An array of CSS classes for the search form.
$classes = sjf_prepend_slug( $classes, $slug );
// Grab the search term to use as a watermark.
$placeholder = esc_attr__( 'Search', 'sjf' );
if( get_query_var( 's' ) ) {
$placeholder = esc_attr( get_query_var( 's' ) );
}
$action = esc_url( home_url( '/' ) );
$search_for = esc_html__( 'Search for:', 'sjf' );
$search_for_attr = esc_attr__( 'Search for:', 'sjf' );
$submit = esc_html__( 'Submit', 'sjf' );
$out ="
<form action='$action' class='$classes $slug sjf-form' method='get' role='search'>
<label class='$classes-label $slug-label sjf-label' for='s'><span class='screen-reader-text'>$search_for</span></label>
<input id='s' type='search' title='$search_for_attr' name='s' value='$placeholder' class='$classes-input $slug-input sjf-input'>
<input type='submit' value='$submit' class='$classes-submit $slug-submit sjf-submit'>
</form>
";
return $out;
}
}
那是一种经典的形式! 表单本身和其中的每个元素都可以通过我喜欢的SMACSS-y方法访问。 我认为大多数开发人员都习惯于替换默认格式,因此在此过程中使用某些类来实现它可能不会有太多麻烦。
对于其他组件,不一定必须说相同的话。 我对整个评论模板进行了类似的工作,后来又出现了500行。 可行,但不一定值得。
正如我之前提到的,应用于导航菜单项的类需要进行过滤,但是如果我们想要更精细的控制,则可以将类应用于链接本身,子菜单,或者我们选择的图标解决方案中的某些字形,WordPress具有我们深入学习的一种方式。 沃克类是令人头疼的东西,可能需要专门的教程。 在线上有一些 很好的 例子 ,只是知道这是将CSS类应用到菜单中的最可行的途径。
我发现随着时间的推移,保持整洁的项目最困难的部分是样式表。 函数,页面模板和侧边栏可能会来来去去,但样式表似乎永远存在,杂乱无章! 我认为,预先投资一些课室对于使事情在将来可以维护很重要。
翻译自: https://css-tricks.com/smacss-press/