我使用webpack捆绑我的文件。我想添加一个脚本,使我能够动态更改自定义程序中的设置。
我创建了一个包含所有自定义程序功能的类
<?php
/**
* The Customizer specific functionality.
*
* @since 1.0.0
* @package mytheme
*/
namespace MyTheme\Customizer;
use MyTheme\Helpers as Helpers;
/**
* Class Customizer
*/
class Customizer {
/**
* Global theme name
*
* @var string
*
* @since 1.0.0
*/
protected $theme_name;
/**
* Global theme version
*
* @var string
*
* @since 1.0.0
*/
protected $theme_version;
/**
* Initialize class
*
* @param array $theme_info Load global theme info.
* @param Helpers\General_Helper $helpers Instance of the General Helpers object.
*
* @since 1.0.0
*/
public function __construct( $theme_info = null, Helpers\General_Helper $helpers ) {
$this->theme_name = $theme_info['theme_name'];
$this->theme_version = $theme_info['theme_version'];
$this->helpers = $helpers;
}
/**
* Register customizer settings
*
* @see add_action('customize_register',$func)
* @param \WP_Customize_Manager $wp_customize WP Customize object.
* @since 1.0.0
*/
public function register_customizer_settings( \WP_Customize_Manager $wp_customize ) {
// Abort if selective refresh is not available.
if ( ! isset( $wp_customize->selective_refresh ) ) {
return;
}
/**
* Footer section
*/
$wp_customize->add_section( 'footer_section', array(
'title' => esc_html__( 'Footer', 'mytheme' ),
'priority' => 100,
) );
/**
* Copyright notice
*/
$wp_customize->add_setting( 'footer_copyright', array(
'default' => '',
'type' => 'theme_mod',
'transport' => 'postMessage',
'sanitize_callback' => 'wp_kses_post',
) );
$wp_customize->add_control( 'footer_copyright', array(
'label' => esc_html__( 'Footer Copyright Text', 'mytheme' ),
'section' => 'footer_section',
'type' => 'text',
) );
}
/**
* Enqueue live preview script
*
* @since 1.0.0
*/
public function live_preview_enqueue() {
$customizer_script = '/skin/public/scripts/customizer.js';
wp_register_script( $this->theme_name . '-customizer', get_template_directory_uri() . $customizer_script, array(), $this->helpers->get_assets_version( $customizer_script ) );
wp_enqueue_script( $this->theme_name . '-customizer', array( 'jquery', 'customize-preview' ), false );
}
}
在另一个我加载动作的课程中,我有
private function define_customizer_hooks() {
$customizer = new Customizer\Customizer( $this->get_theme_info(), new Helpers\General_Helper() );
$this->loader->add_action( 'customize_register', $customizer, 'register_customizer_settings', 11 );
$this->loader->add_action( 'customize_preview_init', $customizer, 'live_preview_enqueue' );
}
现在,我可以看到我的设置很好。 Footer section
正在显示。但是我的控制台出错了
jQuery.Deferred异常:wp.customize不是函数TypeError:wp.customize不是函数
customizer.js 看起来像这样
/* global wp */
$(function() {
wp.customize('footer_copyright', (value) => {
value.bind((newval) => {
if ($('.footer__copyright').length) {
if (newval !== '') {
if ($('.footer__copyright').hasClass('hide')) {
$('.footer__copyright').removeClass('hide').text(newval);
} else {
$('.footer__copyright').text(newval);
}
} else {
$('.footer__copyright').addClass('hide');
}
} else {
$('.footer__container').append(`<div class="footer__copyright">${newval}</div>`);
}
});
});
});
我的 webpack.config.js 看起来像这样:
/* global process __dirname */
const DEV = process.env.NODE_ENV !== 'production';
const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const appPath = `${path.resolve(__dirname)}`;
// Dev Server
const proxyUrl = 'mytheme.test';
// Theme
const themeName = 'mytheme';
const themePath = `/wp-content/themes/${themeName}/skin`;
const themeFullPath = `${appPath}${themePath}`;
const themePublicPath = `${themePath}/public/`;
const themeEntry = `${themeFullPath}/assets/application.js`;
const themeAdminEntry = `${themeFullPath}/assets/application-admin.js`;
const themeGutenbergEntry = `${themeFullPath}/assets/application-gutenberg.js`;
const themeCustomizerEntry = `${themeFullPath}/assets/customizer.js`;
const themeOutput = `${themeFullPath}/public`;
// Outputs
const outputJs = 'scripts/[name].js';
const outputCss = 'styles/[name].css';
const outputFile = '[name].[ext]';
const outputImages = `images/${outputFile}`;
const outputFonts = `fonts/${outputFile}`;
const allModules = {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.json$/,
exclude: /node_modules/,
use: 'file-loader',
},
{
test: /\.(png|svg|jpg|jpeg|gif|ico)$/,
exclude: [/fonts/, /node_modules/],
use: `file-loader?name=${outputImages}`,
},
{
test: /\.(eot|otf|ttf|woff|woff2|svg)$/,
exclude: [/images/, /node_modules/],
use: `file-loader?name=${outputFonts}`,
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader', 'postcss-loader', 'sass-loader',
],
},
],
};
const allPlugins = [
new MiniCssExtractPlugin({
filename: outputCss,
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
// Use BrowserSync For assets
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
proxy: proxyUrl,
files: [
{
match: ['wp-content/themes/**/*.php', 'wp-content/plugins/**/*.php'],
},
],
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
},
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
];
const allOptimizations = {
runtimeChunk: false,
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
};
// Use only for production build
if (!DEV) {
allOptimizations.minimizer = [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true,
uglifyOptions: {
output: {
comments: false,
},
compress: {
warnings: false,
drop_console: true, // eslint-disable-line camelcase
},
},
}),
];
allPlugins.push(new CleanWebpackPlugin([themeOutput]));
}
module.exports = [
// Theme Skin
{
context: path.join(__dirname),
entry: {
application: [themeEntry],
applicationAdmin: [themeAdminEntry],
themeGutenberg: [themeGutenbergEntry],
customizer: [themeCustomizerEntry],
},
output: {
path: themeOutput,
publicPath: themePublicPath,
filename: outputJs,
library: ['wp', '[name]'],
libraryTarget: 'var',
},
externals: {
wp: 'wp',
},
optimization: allOptimizations,
mode: 'production',
module: allModules,
plugins: allPlugins,
devtool: DEV ? '#inline-source-map' : '',
},
];
和 package.json 是
{
"name": "mytheme",
"version": "1.0.0",
"author": "dingo_d",
"private": true,
"main": "",
"scripts": {
"__sassUnusedTheme": "sass-unused \"wp-content/themes/init_theme_name/**/*.scss\"",
"__eslintTheme": "eslint wp-content/themes/init_theme_name/skin/assets/",
"__stylelintTheme": "stylelint \"wp-content/themes/init_theme_name/**/*.scss\" --syntax scss",
"precommitCss": "npm run __stylelintTheme",
"precommitCssUnused": "npm run __sassUnusedTheme",
"precommitJs": "npm run __eslintTheme",
"precommit": "npm run precommitJs && npm run precommitCss && npm run precommitCssUnused",
"start": "webpack --progress --watch --display-error-details --display-reasons",
"build": "NODE_ENV=production webpack --progress"
},
"devDependencies": {
"@infinumjs/eslint-config": "^1.1.0",
"@infinumjs/stylelint-config": "^1.0.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-preset-env": "^1.6.1",
"browser-sync": "^2.24.1",
"browser-sync-webpack-plugin": "^2.2.2",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.5.1",
"css-loader": "^0.28.11",
"eslint": "^4.19.1",
"eslint-plugin-import": "^2.11.0",
"expose-loader": "^0.7.5",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.11",
"imports-loader": "^0.8.0",
"mini-css-extract-plugin": "^0.4.0",
"node-sass": "^4.9.0",
"postcss-cssnext": "^3.1.0",
"postcss-loader": "^2.1.4",
"precss": "^3.1.2",
"sass-loader": "^7.0.1",
"style-loader": "^0.21.0",
"stylelint": "^9.2.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.6.0",
"webpack-cli": "^2.1.2"
},
"dependencies": {
"autoprefixer": "^8.4.1",
"babel-polyfill": "^6.26.0",
"bugsnag-js": "^4.6.0",
"css-mqpacker": "^6.0.2",
"cssnano": "^3.10.0",
"jquery": "^3.3.1",
"jquery-match-height": "^0.7.2",
"layzr.js": "^2.2.2",
"media-blender": "^2.1.0",
"normalize.css": "^8.0.0",
"npm": "^6.0.0",
"postcss-font-magician": "^2.1.1",
"slick-carousel": "^1.8.1",
"whatwg-fetch": "^2.0.4"
},
"browserslist": [
"android >= 4.2",
"not ie < 11",
"last 2 versions",
"Safari >= 8"
]
}
困扰我的是我基本上使用(和修改)了我的代码,该代码在没有所有花哨的构建工具(https://themes.svn.wordpress.org/expire/1.0.9/inc/customizer/js/customizer.js)的情况下构建的主题中工作
我试过
/* global wp */
(function(api) {
api('footer_copyright', (value) => {
value.bind((newval) => {
if ($('.footer__copyright').length) {
if (newval !== '') {
if ($('.footer__copyright').hasClass('hide')) {
$('.footer__copyright').removeClass('hide').text(newval);
} else {
$('.footer__copyright').text(newval);
}
} else {
$('.footer__copyright').addClass('hide');
}
} else {
$('.footer__container').append(`<div class="footer__copyright">${newval}</div>`);
}
});
});
})(wp.customize);
但是,我得到了
未捕获的ReferenceError:未定义wp
在检查器中,可能在加载完所有内容后wp.customize
可用(ƒ (){return f.instance.apply(f,arguments)}
)。
我遵循了使用网络包的Gutenberg小组给出的建议,但我不确定我是否做得对。
答案 0 :(得分:1)
Not sure if this is the best solution but I decided to add a dependency in my wp_enqueue_script
call. For example I initially had:
wp_enqueue_script('scripts/admin/remove_category.js', asset_path('scripts/admin/remove_category.js'));
But then I had a search through the WordPress JS files to see which ones used wp
, I figured I could pick an arbitrary one of these to use as a dependency and subsequently ensure wp
is available inside my script, like this:
wp_enqueue_script('scripts/admin/remove_category.js', asset_path('scripts/admin/remove_category.js'), ['wp-util']);
答案 1 :(得分:0)
wp.customize
对象已在全局范围内可用。来自WordPress&#39; JavaScript Reference/wp:
window.wp对象用于命名多个有用的Javascript WordPress管理员的类对象。
将window.wp.customize
更改为class Expense extends Model
{
protected $dates = ['date', 'another_date_field'];
//other stuff
}
应该可以解决问题。
答案 2 :(得分:0)
定制器有一些用于排队脚本的有用操作:
customize_controls_enqueue_scripts
。customize_preview_init
。所以我认为在您的情况下,您应该使用 customize_controls_enqueue_scripts
将脚本与 wp_enqueue_script
函数排入队列。