Làm thế nào để chặn các tập lệnh đã được bản địa hóa


10

Nếu một plugin sử dụng một số tập lệnh (ví dụ nổi bật: Datepicker UI UI), nhưng bạn không hài lòng với cách tập lệnh kết xuất đầu ra, thì có hai khả năng:

1. Hủy đăng ký tập lệnh> Thêm phiên bản của riêng bạn

Vì vậy, đầu tiên bạn cần phải kiểm tra xử lý, sau đó tìm ra ưu tiên và móc ( wp_enqueue_scripts, login_enqueue_scripts, vv) ... Bạn có biết cuộc tập trận.

2. Thay đổi các tham số plugin jQuery

Thông thường - nếu plugin không tào lao - nó sẽ đẩy các tham số từ PHP sang JS bằng cách sử dụng

wp_localize_script( $handle, $object_name, array( 
    // data
) );

Bây giờ đây là một cách thông minh để thêm dữ liệu của bạn vào tập lệnh JS, nhưng ... theo mặc định nó không thể lọc được. Cả WP_Scriptscũng không WP_Dependenciescung cấp bất kỳ người sử dụng bộ lọc sau này có thể sử dụng

Câu hỏi: Làm thế nào chúng ta có thể lọc các đối số / tham số được chuyển từ PHP sang Javascript bằng cách sử dụng wp_localize_script?

Câu trả lời:


9

wp_localize_script()gọi phương thức localize()trên biến toàn cục $wp_scripts. Chúng ta có thể đặt biến này thành một thể hiện của một lớp con gồm WP_Scripts:

class Filterable_Scripts extends WP_Scripts
{
    function localize( $handle, $object_name, $l10n )
    {
        $l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
        return parent::localize($handle, $object_name, $l10n);
    }
}

add_action( 'wp_loaded', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
});

Tùy biến chủ đề không sử dụng điều đó, nó tạo ra một thể hiện riêng của WP_Scripts(xem wp-admin/customize.php). Cũng có thể thay thế điều đó:

add_action( 'customize_controls_init', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
    $GLOBALS['wp_scripts']->registered = $GLOBALS['registered'];
});

Không ai trong số này đã được thử nghiệm, chỉ là một ý tưởng.


Bạn có thể vui lòng chỉ định $ l10n là gì không? Tôi hiểu việc chuyển nó qua tay cầm và đối tượng, nhưng không phải $ l10n. Cảm ơn.
Eric Leroy

1
@EricLeroy Đây là tham số thứ ba của wp_localize_script(): một mảng đơn hoặc đa chiều .
fuxia

Việc triển khai này giúp tôi rất nhiều, nhưng tôi muốn cảnh báo bạn rằng nó đã làm rối các tập lệnh quản trị của tôi, ACF đã ngừng hoạt động vì các javascripts không được in do giải pháp trên. Tôi chưa có bản sửa lỗi, nhưng tôi đang tìm kiếm nó ngay bây giờ.
Ogier Schelvis

3

@toscho thực hiện tuyệt vời. Đã thử nghiệm và sự thật. Đây là một phiên bản sửa đổi một chút , cũng vượt qua $ xử lý và $ object_name để bạn chỉ có thể lọc khi cần.

class Filterable_Scripts extends WP_Scripts
{
    function localize( $handle, $object_name, $l10n )
    {
        $l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
        return parent::localize($handle, $object_name, $l10n);
    }
}

add_action( 'init', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
});

add_filter('script_l10n', 'se108362_example_filter', 10 , 3);

// Example
function se108362_example_filter($l10n, $handle, $object_name ) {
    if('js-handle' == $handle && 'jsVariable' == $object_name) {
       return 'Something Else';
    }
    return $l10n;
}

1

Câu trả lời được chấp nhận là tuyệt vời! Nhưng tôi gặp phải một vấn đề là Trường tùy chỉnh nâng cao đã ngừng hoạt động trong phần phụ trợ do lỗi javascript. Sau khi đào được vài giờ, tôi đã đi đến kết luận rằng đối tượng Filterable_Scripts bị thiếu các tệp javascript được đăng ký bởi plugin ACF. Tôi không biết chính xác lý do tại sao nó làm điều này, nhưng tôi đã tìm thấy một giải pháp thích hợp cho vấn đề này nếu bạn gặp phải vấn đề tương tự.

Các $GLOBALS['wp_scripts']may mắn thay vẫn chứa các kịch bản thích hợp. Vì vậy, tôi đã làm như sau trong add_action:

add_action( 'wp_loaded', function() {
    $fscripts = new Filterable_Scripts();

    $missing_scripts = array_diff_key( $GLOBALS['wp_scripts']->registered, $fscripts->registered);
    foreach($missing_scripts as $mscript){
        $fscripts->registered[$mscript->handle] = $mscript;
    }

    $GLOBALS['wp_scripts'] = $fscripts;
});

Vì đối tượng chứa một mảng gồm tất cả các tập lệnh đã đăng ký và các thẻ điều khiển cũng là các khóa mảng, nên tôi có thể sử dụng Array_diff_key để xác định tập lệnh nào bị thiếu trong đối tượng mở rộng và thêm lại chúng. Tôi đã làm điều này và không chỉ

$fscripts->registered = $GLOBALS['wp_scripts']->registered;

bởi vì tôi không muốn ghi đè lên bất kỳ thay đổi nào được thực hiện bởi đối tượng mở rộng.


1
Tôi có một cách khác để làm điều này, đó là thêm lưu hai thẻ script acf $acf_field_group = $GLOBALS['wp_scripts']->registered['acf-field-group'];(cũng acf-input) và sau đó thêm chúng vào ví dụ của WP_Scriptsthẻ mở rộng : $GLOBALS['wp_scripts']->registered['acf-field-group'] = $acf_field_group, sau đó nhận ra rằng ACF chỉ sử dụng các tập lệnh trong Admin và tôi chỉ l10nở phía trước vì vậy chỉ cần bọc hành động và lọc trong một !is_adminbài kiểm tra.
MikeiLL

Điểm tốt, hiệu suất khôn ngoan giải pháp của bạn hoạt động tốt hơn. Tôi cũng đang thêm kiểm tra is_admin vào phiên bản mã cá nhân này. Điều tôi vẫn thích mặc dù về cách tiếp cận của mình là nếu id của các tập lệnh sẽ thay đổi trong tương lai hoặc có các tập lệnh mới bị thiếu trong các phiên bản sau của plugin ACF (hoặc các plugin khác), tôi không phải thay đổi mã.
Ogier Schelvis

Vâng, điều đó có ý nghĩa với tôi là tốt. Tôi không chắc có cần thiết không nếu bạn chỉ chạy hành động ở mặt trước.
MikeiLL

Hừm .. cảm động. Tôi đoán đôi khi tôi bị cuốn vào quá nhiều trong việc tìm ra giải pháp hoàn hảo đến nỗi tôi quên mất vấn đề ban đầu thực sự là gì. Tuy nhiên, nếu nhu cầu về nó trong quản trị viên có thể thay đổi, chúng tôi đã thực hiện phép toán ;-)
Ogier Schelvis

Ở đây cũng vậy, bạn ạ, nhưng đó là tất cả về học tập, phải không?
MikeiLL
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.