You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ACF字段更新自动管理SCSS文件及重命名问题

问题描述

我在WordPress中用ACF(高级自定义字段)的灵活内容字段搭建页面构建器,之前手动为每个组件创建_component-name.scss文件并导入主SCSS文件,这种方式容易出错。于是尝试利用acf/update_field过滤器,在灵活内容字段更新时遍历layouts数组自动生成对应SCSS文件,创建功能已经实现,但遇到一个问题:重命名布局时无法获取原名称,没法同步重命名对应的SCSS文件。

以下是当前的实现代码:

add_filter('acf/update_field', 'create_css_files', 10, 1);

/**
 * When ACF Fields are saved, check to see if it was the page builder,
 * if it was, attempt to create a new scss file for any new elements within our page builder.
 * Note that get_stylesheet_directory gets the root of the current theme.
 *
 * @param [type] $field
 *
 * @return void
 */
function create_css_files($field)
{
    if ($field['name'] == 'page_builder_elements') {
        foreach ($field['layouts'] as $layout) {
            $name = $layout['name'];

            // Only allow letters, numbers, hyphens and underscores
            $clean_name = preg_replace('/[^A-Za-z0-9_\-]/', '', $name);

            // Replace underscores with hyphens in the layout name
            $clean_name = str_replace('_', '-', $clean_name);

            $file_path = get_stylesheet_directory() . '/resources/styles/scss/_' . $clean_name . '.scss';

            $directory = dirname($file_path);

            if (!file_exists($directory)) {
                mkdir($directory, 0755, true);
            }

            if (!file_exists($file_path)) {
                $file_handle = fopen($file_path, 'w');
                fclose($file_handle);
            }

            $import_directive = "@import 'scss/$clean_name';" . "\n";

            $base_stylesheet_path = get_stylesheet_directory() . '/resources/styles/app.scss';

            file_put_contents($base_stylesheet_path, $import_directive, FILE_APPEND);
        }
    }

    return $field;
}
解决方案

要解决重命名布局时同步SCSS文件的问题,核心是获取布局更新前的原始名称。由于acf/update_field仅提供更新后的字段数据,需要借助acf/prepare_field过滤器先缓存原始布局信息,再在更新时对比新旧名称。

步骤1:缓存原始布局数据

添加acf/prepare_field过滤器,在字段加载时缓存原始布局的key与name映射关系:

add_filter('acf/prepare_field', 'cache_original_layouts', 10, 1);

function cache_original_layouts($field) {
    if ($field['name'] == 'page_builder_elements') {
        $original_layouts = [];
        foreach ($field['layouts'] as $layout) {
            $original_layouts[$layout['key']] = $layout['name'];
        }
        wp_cache_set('acf_page_builder_original_layouts', $original_layouts, 'acf');
    }
    return $field;
}

步骤2:更新时对比新旧名称并同步文件

修改原有create_css_files函数,取出缓存数据对比布局新旧名称,实现文件重命名与导入语句更新:

add_filter('acf/update_field', 'create_css_files', 10, 1);

function create_css_files($field) {
    if ($field['name'] != 'page_builder_elements') {
        return $field;
    }

    $original_layouts = wp_cache_get('acf_page_builder_original_layouts', 'acf');
    $scss_dir = get_stylesheet_directory() . '/resources/styles/scss/';
    $app_scss_path = get_stylesheet_directory() . '/resources/styles/app.scss';
    $existing_imports = file_get_contents($app_scss_path);

    foreach ($field['layouts'] as $layout) {
        // 处理新名称的清理逻辑
        $new_name = $layout['name'];
        $clean_new_name = preg_replace('/[^A-Za-z0-9_\-]/', '', $new_name);
        $clean_new_name = str_replace('_', '-', $clean_new_name);
        $new_file_path = $scss_dir . '_' . $clean_new_name . '.scss';

        // 处理重命名逻辑
        if ($original_layouts && isset($original_layouts[$layout['key']])) {
            $old_name = $original_layouts[$layout['key']];
            $clean_old_name = preg_replace('/[^A-Za-z0-9_\-]/', '', $old_name);
            $clean_old_name = str_replace('_', '-', $clean_old_name);
            $old_file_path = $scss_dir . '_' . $clean_old_name . '.scss';

            if ($clean_old_name != $clean_new_name && file_exists($old_file_path)) {
                // 重命名SCSS文件
                rename($old_file_path, $new_file_path);
                // 更新app.scss中的导入语句
                $old_import = "@import 'scss/$clean_old_name';";
                $new_import = "@import 'scss/$clean_new_name';";
                $existing_imports = str_replace($old_import, $new_import, $existing_imports);
            }
        }

        // 保留原有新布局文件创建逻辑
        $directory = dirname($new_file_path);
        if (!file_exists($directory)) {
            mkdir($directory, 0755, true);
        }
        if (!file_exists($new_file_path)) {
            fclose(fopen($new_file_path, 'w'));
        }

        // 避免重复追加导入语句
        $new_import = "@import 'scss/$clean_new_name';";
        if (strpos($existing_imports, $new_import) === false) {
            $existing_imports .= $new_import . "\n";
        }
    }

    // 写入更新后的app.scss
    file_put_contents($app_scss_path, $existing_imports);
    // 清理缓存避免残留旧数据
    wp_cache_delete('acf_page_builder_original_layouts', 'acf');

    return $field;
}

额外优化说明

  1. 修复了原有代码中每次更新重复追加导入语句的问题,现在会先检查语句是否已存在。
  2. 用布局的key作为唯一标识(创建后不会改变),比name更可靠。
  3. 操作完成后清理缓存,避免影响后续字段更新操作。

内容的提问来源于stack exchange,提问作者Jesse Luke Orange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:53:14