_wp_to_kebab_case()
云策文档标注
概述
_wp_to_kebab_case() 函数旨在在服务器端模拟 lodash 库的 kebabCase 功能,确保客户端和服务器端处理字符串时输出一致,主要用于生成预设类名等场景。由于向后兼容性要求,服务器端必须与客户端行为保持一致,函数更新需遵循客户端逻辑。
关键要点
- 函数目的:将输入字符串转换为 kebab-case 格式,以匹配 lodash 的 kebabCase 行为,确保跨环境输出一致性。
- 参数:接受一个必需字符串参数 $input_string,返回 kebab-cased 字符串。
- 兼容性考虑:因 lodash 输出已保存在文章内容中,无法更新客户端库,故服务器端需模拟其行为,函数变更应与客户端同步。
- 实现细节:使用正则表达式处理 Unicode 字符,移除了 lodash 版本中的非字母数字字符和撇号相关组,变量命名保持与 lodash 一致以便比较和移植。
代码示例
function _wp_to_kebab_case( $input_string ) {
// 变量命名与 lodash 保持一致,便于比较和更新
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
// 定义 Unicode 字符范围
$rsLowerRange = 'a-zxdf-xf6xf8-xff';
$rsNonCharRange = 'x00-x2fx3a-x40x5b-x60x7b-xbf';
$rsPunctuationRange = 'x{2000}-x{206f}';
$rsSpaceRange = ' tx0bfxa0x{feff}nrx{2028}x{2029}x{1680}x{180e}x{2000}x{2001}x{2002}x{2003}x{2004}x{2005}x{2006}x{2007}x{2008}x{2009}x{200a}x{202f}x{205f}x{3000}';
$rsUpperRange = 'A-Zxc0-xd6xd8-xde';
$rsBreakRange = $rsNonCharRange . $rsPunctuationRange . $rsSpaceRange;
// 构建捕获组
$rsBreak = '[' . $rsBreakRange . ']';
$rsDigits = 'd+';
$rsLower = '[' . $rsLowerRange . ']';
$rsMisc = '[^' . $rsBreakRange . $rsDigits . $rsLowerRange . $rsUpperRange . ']';
$rsUpper = '[' . $rsUpperRange . ']';
// 组合正则表达式
$rsMiscLower = '(?:' . $rsLower . '|' . $rsMisc . ')';
$rsMiscUpper = '(?:' . $rsUpper . '|' . $rsMisc . ')';
$rsOrdLower = 'd*(?:1st|2nd|3rd|(?![123])dth)(?=b|[A-Z_])';
$rsOrdUpper = 'd*(?:1ST|2ND|3RD|(?![123])dTH)(?=b|[a-z_])';
$regexp = '/' . implode(
'|',
array(
$rsUpper . '?' . $rsLower . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper, '$' ) ) . ')',
$rsMiscUpper . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper . $rsMiscLower, '$' ) ) . ')',
$rsUpper . '?' . $rsMiscLower . '+',
$rsUpper . '+',
$rsOrdUpper,
$rsOrdLower,
$rsDigits,
)
) . '/u';
// 执行匹配并返回结果
preg_match_all( $regexp, str_replace( "'", '', $input_string ), $matches );
return strtolower( implode( '-', $matches[0] ) );
// phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
}注意事项
- 函数自 WordPress 5.8.0 版本引入,用于处理主题 JSON、字体集合等场景中的字符串转换。
- 相关函数包括 WP_Theme_JSON_Resolver::inject_variations_from_block_style_variation_files()、WP_Font_Collection::get_sanitization_schema() 等,具体用途见文档。
原文内容
This function is trying to replicate what lodash’s kebabCase (JS library) does in the client.
Description
The reason we need this function is that we do some processing in both the client and the server (e.g.: we generate preset classes from preset slugs) that needs to create the same output.
We can’t remove or update the client’s library due to backward compatibility (some of the output of lodash’s kebabCase is saved in the post content).
We have to make the server behave like the client.
Changes to this function should follow updates in the client with the same logic.
Parameters
$input_stringstringrequired-
The string to kebab-case.
Source
function _wp_to_kebab_case( $input_string ) {
// Ignore the camelCase names for variables so the names are the same as lodash so comparing and porting new changes is easier.
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
/*
* Some notable things we've removed compared to the lodash version are:
*
* - non-alphanumeric characters: rsAstralRange, rsEmoji, etc
* - the groups that processed the apostrophe, as it's removed before passing the string to preg_match: rsApos, rsOptContrLower, and rsOptContrUpper
*
*/
/** Used to compose unicode character classes. */
$rsLowerRange = 'a-z\xdf-\xf6\xf8-\xff';
$rsNonCharRange = '\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf';
$rsPunctuationRange = '\x{2000}-\x{206f}';
$rsSpaceRange = ' \t\x0b\f\xa0\x{feff}\n\r\x{2028}\x{2029}\x{1680}\x{180e}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}\x{200a}\x{202f}\x{205f}\x{3000}';
$rsUpperRange = 'A-Z\xc0-\xd6\xd8-\xde';
$rsBreakRange = $rsNonCharRange . $rsPunctuationRange . $rsSpaceRange;
/** Used to compose unicode capture groups. */
$rsBreak = '[' . $rsBreakRange . ']';
$rsDigits = '\d+'; // The last lodash version in GitHub uses a single digit here and expands it when in use.
$rsLower = '[' . $rsLowerRange . ']';
$rsMisc = '[^' . $rsBreakRange . $rsDigits . $rsLowerRange . $rsUpperRange . ']';
$rsUpper = '[' . $rsUpperRange . ']';
/** Used to compose unicode regexes. */
$rsMiscLower = '(?:' . $rsLower . '|' . $rsMisc . ')';
$rsMiscUpper = '(?:' . $rsUpper . '|' . $rsMisc . ')';
$rsOrdLower = '\d*(?:1st|2nd|3rd|(?![123])\dth)(?=\b|[A-Z_])';
$rsOrdUpper = '\d*(?:1ST|2ND|3RD|(?![123])\dTH)(?=\b|[a-z_])';
$regexp = '/' . implode(
'|',
array(
$rsUpper . '?' . $rsLower . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper, '$' ) ) . ')',
$rsMiscUpper . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper . $rsMiscLower, '$' ) ) . ')',
$rsUpper . '?' . $rsMiscLower . '+',
$rsUpper . '+',
$rsOrdUpper,
$rsOrdLower,
$rsDigits,
)
) . '/u';
preg_match_all( $regexp, str_replace( "'", '', $input_string ), $matches );
return strtolower( implode( '-', $matches[0] ) );
// phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
}
Changelog
| Version | Description |
|---|---|
| 5.8.0 | Introduced. |