เพิ่มไดเรกทอรีปลั๊กอินหลายรายการ


39

งาน

คุณสามารถลงทะเบียนเพิ่มไดเรกทอรีธีมเพิ่มเติมโดยใช้register_theme_directory()สำหรับการติดตั้ง WP ของคุณ น่าเศร้าหลักไม่ได้ส่งมอบด้วยฟังก์ชั่นเดียวกันสำหรับปลั๊กอิน เรามี MU-Plugin, Drop-Ins, Plugins และ Themes อยู่แล้ว แต่เราต้องการมากขึ้นสำหรับองค์กรไฟล์ที่ดีกว่า

นี่คือรายการงานที่ต้องทำให้สำเร็จ:

  • เพิ่มไดเรกทอรีปลั๊กอินเพิ่มเติม
  • สำหรับแต่ละไดเรกทอรีปลั๊กอินจำเป็นต้องมี "แท็บ" ใหม่ดังที่แสดงไว้ที่นี่[1]
  • ไดเรกทอรีเพิ่มเติมจะมีฟังก์ชั่นเช่นเดียวกับไดเรกทอรีปลั๊กอินเริ่มต้น

มีอะไรในนั้น?

คำตอบที่ดีที่สุดและสมบูรณ์ที่สุดจะได้รับรางวัล


[1] แท็บเพิ่มเติมสำหรับโฟลเดอร์ปลั๊กอิน / ไดเรกทอรีใหม่


3
เนื่องจากโครงสร้างไดเรกทอรีนั้นเชื่อมโยงกับค่าคงที่ไดเรกทอรีฉันจึงสงสัยว่าการทำเช่นนี้ในระดับระบบไฟล์นั้นเป็นไปได้จริง เลเยอร์เสมือนจริงขององค์กรในผู้ดูแลระบบอาจทำได้ง่ายกว่าในระดับส่วนขยาย
Rarst

@Rarst ซึ่งไม่ควรจะถือคุณกลับมาจากการเพิ่มความคิดของคุณ :)
Kaiser

นี่จะเป็นคุณสมบัติที่ยอดเยี่ยม
ltfishie

คุณสมบัติฟังดูดี เพียงแค่ต้องย้อนกลับวิศวกรหลักคิดออกว่าควรจะทำอย่างไร (วิธี WP) แล้วส่งแพทช์ไปยัง Devs ... คุณต้องการดู register_theme_directory () - search_theme_directories () - get_raw_theme_roots () - get_theme_roots () - get_theme_roots () () - get_theme () - get_themes ()
Sterling Hamilton

2
ชาย: ส่งสิ่งที่ ? นี่เป็นคำถามไม่ใช่คำตอบที่มีรหัสเป่าเต็ม :) FYI: ตั๋วใหม่บน trac เพื่อเขียนใหม่get_themes()ในชั้นเรียน
ไกเซอร์

คำตอบ:


28

โอเคฉันจะแทงนี่สิ ข้อ จำกัด บางประการที่ฉันพบระหว่างทาง:

  1. ไม่มีตัวกรองจำนวนมากในคลาสย่อยของ WP_List_Table อย่างน้อยก็ไม่มีที่ที่เราต้องการให้เป็น

  2. เนื่องจากขาดตัวกรองเราจึงไม่สามารถรักษารายการประเภทปลั๊กอินที่ถูกต้องที่ด้านบน

  3. นอกจากนี้เรายังต้องใช้จาวาสคริปต์ที่ยอดเยี่ยม (อ่าน: สกปรก) เพื่อแสดงปลั๊กอินว่าใช้งานได้

ฉันห่อรหัสพื้นที่ผู้ดูแลของฉันไว้ในชั้นเรียนดังนั้นชื่อฟังก์ชั่นของฉันจึงไม่ได้ขึ้นหน้า คุณสามารถดูทั้งหมดของรหัสนี้ที่นี่ กรุณาช่วย!

API กลาง

ฟังก์ชั่นง่ายๆที่ตั้งค่าตัวแปรทั่วโลกซึ่งจะมีไดเรกทอรีปลั๊กอินของเราในอาเรย์แบบเชื่อมโยง $keyเป็นไปได้บางสิ่งบางอย่างใช้ภายในเพื่อดึงข้อมูลปลั๊กอิน ฯลฯ$dirเป็นทั้งเส้นทางหรือบางสิ่งบางอย่างเต็มรูปแบบเมื่อเทียบกับwp-contentไดเรกทอรี $labelจะเป็นสำหรับการแสดงผลของเราในพื้นที่ผู้ดูแลระบบ (เช่นสตริงที่แปลได้)

<?php
function register_plugin_directory( $key, $dir, $label )
{
    global $wp_plugin_directories;
    if( empty( $wp_plugin_directories ) ) $wp_plugin_directories = array();

    if( ! file_exists( $dir ) && file_exists( trailingslashit( WP_CONTENT_DIR ) . $dir ) )
    {
        $dir = trailingslashit( WP_CONTENT_DIR ) . $dir;
    }

    $wp_plugin_directories[$key] = array(
        'label' => $label,
        'dir'   => $dir
    );
}

แน่นอนว่าเราต้องโหลดปลั๊กอิน ขอความช่วยเหลือจากplugins_loadedสายและผ่านปลั๊กอินที่ใช้งานอยู่โหลดแต่ละครั้ง

เขตการปกครอง

มาตั้งค่าฟังก์ชั่นของเราในชั้นเรียนกัน

<?php
class CD_APD_Admin
{

    /**
     * The container for all of our custom plugins
     */
    protected $plugins = array();

    /**
     * What custom actions are we allowed to handle here?
     */
    protected $actions = array();

    /**
     * The original count of the plugins
     */
    protected $all_count = 0;

    /**
     * constructor
     * 
     * @since 0.1
     */
    function __construct()
    {
        add_action( 'load-plugins.php', array( &$this, 'init' ) );
        add_action( 'plugins_loaded', array( &$this, 'setup_actions' ), 1 );

    }

} // end class

เรากำลังจะเข้าหาplugins_loadedแต่เนิ่นๆและตั้งค่า "การกระทำ" ที่เราอนุญาตให้ใช้ สิ่งเหล่านี้จะจัดการกับการเปิดใช้งานปลั๊กอินและการปิดการใช้งานเนื่องจากฟังก์ชั่นในตัวไม่สามารถทำได้กับไดเรกทอรีที่กำหนดเอง

function setup_actions()
{
    $tmp = array(
        'custom_activate',
        'custom_deactivate'
    );
    $this->actions = apply_filters( 'custom_plugin_actions', $tmp );
}

load-plugins.phpจากนั้นก็มีฟังก์ชั่นลงในติดยาเสพติด มันทำเรื่องสนุกได้ทุกประเภท

function init()
{
    global $wp_plugin_directories;

    $screen = get_current_screen();

    $this->get_plugins();

    $this->handle_actions();

    add_filter( 'views_' . $screen->id, array( &$this, 'views' ) );

    // check to see if we're using one of our custom directories
    if( $this->get_plugin_status() )
    {
        add_filter( 'views_' . $screen->id, array( &$this, 'views_again' ) );
        add_filter( 'all_plugins', array( &$this, 'filter_plugins' ) );
        // TODO: support bulk actions
        add_filter( 'bulk_actions-' . $screen->id, '__return_empty_array' );
        add_filter( 'plugin_action_links', array( &$this, 'action_links' ), 10, 2 );
        add_action( 'admin_enqueue_scripts', array( &$this, 'scripts' ) );
    }
}

มาดูทีละอย่างกัน get_pluginsวิธีการเป็นห่อหุ้มรอบฟังก์ชันอื่น มันเติมคุณลักษณะที่pluginsมีข้อมูล

function get_plugins()
{
    global $wp_plugin_directories;
    foreach( array_keys( $wp_plugin_directories ) as $key )
    {
       $this->plugins[$key] = cd_apd_get_plugins( $key );
    }
}

cd_apd_get_pluginsเป็นของget_pluginsฟังก์ชั่นในตัวที่ไม่มีฮาร์ดโค้ดWP_CONTENT_DIRและpluginsธุรกิจ โดยทั่วไป: รับไดเรกทอรีจาก$wp_plugin_directoriesทั่วโลกเปิดค้นหาไฟล์ปลั๊กอินทั้งหมด เก็บไว้ในแคชไว้ใช้ภายหลัง

<?php
function cd_apd_get_plugins( $dir_key ) 
{
    global $wp_plugin_directories;

    // invalid dir key? bail
    if( ! isset( $wp_plugin_directories[$dir_key] ) )
    {
        return array();
    }
    else
    {
        $plugin_root = $wp_plugin_directories[$dir_key]['dir'];
    }

    if ( ! $cache_plugins = wp_cache_get( 'plugins', 'plugins') )
        $cache_plugins = array();

    if ( isset( $cache_plugins[$dir_key] ) )
        return $cache_plugins[$dir_key];

    $wp_plugins = array();

    $plugins_dir = @ opendir( $plugin_root );
    $plugin_files = array();
    if ( $plugins_dir ) {
        while ( ( $file = readdir( $plugins_dir ) ) !== false ) {
            if ( substr($file, 0, 1) == '.' )
                continue;
            if ( is_dir( $plugin_root.'/'.$file ) ) {
                $plugins_subdir = @ opendir( $plugin_root.'/'.$file );
                if ( $plugins_subdir ) {
                    while (($subfile = readdir( $plugins_subdir ) ) !== false ) {
                        if ( substr($subfile, 0, 1) == '.' )
                            continue;
                        if ( substr($subfile, -4) == '.php' )
                            $plugin_files[] = "$file/$subfile";
                    }
                    closedir( $plugins_subdir );
                }
            } else {
                if ( substr($file, -4) == '.php' )
                    $plugin_files[] = $file;
            }
        }
        closedir( $plugins_dir );
    }

    if ( empty($plugin_files) )
        return $wp_plugins;

    foreach ( $plugin_files as $plugin_file ) {
        if ( !is_readable( "$plugin_root/$plugin_file" ) )
            continue;

        $plugin_data = get_plugin_data( "$plugin_root/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached.

        if ( empty ( $plugin_data['Name'] ) )
            continue;

        $wp_plugins[trim( $plugin_file )] = $plugin_data;
    }

    uasort( $wp_plugins, '_sort_uname_callback' );

    $cache_plugins[$dir_key] = $wp_plugins;
    wp_cache_set('plugins', $cache_plugins, 'plugins');

    return $wp_plugins;
}

ถัดไปเป็นธุรกิจที่น่ารำคาญของการเปิดใช้งานและปิดการใช้งานปลั๊กอิน ในการทำเช่นนี้เราใช้handle_actionsวิธีการ นี่คืออีกครั้ง ripped ออกมาโจ๋งครึ่มจากด้านบนของwp-admin/plugins.phpไฟล์หลัก

function handle_actions()
{
    $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';

    // not allowed to handle this action? bail.
    if( ! in_array( $action, $this->actions ) ) return;

    // Get the plugin we're going to activate
    $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false;
    if( ! $plugin ) return;

    $context = $this->get_plugin_status();

    switch( $action )
    {
        case 'custom_activate':
            if( ! current_user_can('activate_plugins') )
                    wp_die( __('You do not have sufficient permissions to manage plugins for this site.') );

            check_admin_referer( 'custom_activate-' . $plugin );

            $result = cd_apd_activate_plugin( $plugin, $context );
            if ( is_wp_error( $result ) ) 
            {
                if ( 'unexpected_output' == $result->get_error_code() ) 
                {
                    $redirect = add_query_arg( 'plugin_status', $context, self_admin_url( 'plugins.php' ) );
                    wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'plugin-activation-error_' . $plugin ), $redirect ) ) ;
                    exit();
                } 
                else 
                {
                    wp_die( $result );
                }
            }

            wp_redirect( add_query_arg( array( 'plugin_status' => $context, 'activate' => 'true' ), self_admin_url( 'plugins.php' ) ) );
            exit();
            break;
        case 'custom_deactivate':
            if ( ! current_user_can( 'activate_plugins' ) )
                wp_die( __('You do not have sufficient permissions to deactivate plugins for this site.') );

            check_admin_referer('custom_deactivate-' . $plugin);
            cd_apd_deactivate_plugins( $plugin, $context );
            if ( headers_sent() )
                echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />";
            else
                wp_redirect( self_admin_url("plugins.php?deactivate=true&plugin_status=$context") );
            exit();
            break;
        default:
            do_action( 'custom_plugin_dir_' . $action );
            break;
    }

}

ฟังก์ชั่นที่กำหนดเองสองสามที่นี่อีกครั้ง cd_apd_activate_plugin(คัดลอกมาจากactivate_plugin) และcd_apd_deactivate_plugins(ฉีกออกจากdeactivate_plugins) ทั้งสองอย่างนั้นเหมือนกับฟังก์ชั่น "พาเรนต์" ตามลำดับโดยไม่มีไดเรกทอรีฮาร์ดโค้ด

function cd_apd_activate_plugin( $plugin, $context, $silent = false ) 
{
    $plugin = trim( $plugin );

    $redirect = add_query_arg( 'plugin_status', $context, admin_url( 'plugins.php' ) );
    $redirect = apply_filters( 'custom_plugin_redirect', $redirect );

    $current = get_option( 'active_plugins_' . $context, array() );

    $valid = cd_apd_validate_plugin( $plugin, $context );
    if ( is_wp_error( $valid ) )
        return $valid;

    if ( !in_array($plugin, $current) ) {
        if ( !empty($redirect) )
            wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); // we'll override this later if the plugin can be included without fatal error
        ob_start();
        include_once( $valid );

        if ( ! $silent ) {
            do_action( 'custom_activate_plugin', $plugin, $context );
            do_action( 'custom_activate_' . $plugin, $context );
        }

        $current[] = $plugin;
        sort( $current );
        update_option( 'active_plugins_' . $context, $current );

        if ( ! $silent ) {
            do_action( 'custom_activated_plugin', $plugin, $context );
        }

        if ( ob_get_length() > 0 ) {
            $output = ob_get_clean();
            return new WP_Error('unexpected_output', __('The plugin generated unexpected output.'), $output);
        }
        ob_end_clean();
    }

    return true;
}

และฟังก์ชั่นปิดการใช้งาน

function cd_apd_deactivate_plugins( $plugins, $context, $silent = false ) {
    $current = get_option( 'active_plugins_' . $context, array() );

    foreach ( (array) $plugins as $plugin ) 
    {
        $plugin = trim( $plugin );
        if ( ! in_array( $plugin, $current ) ) continue;

        if ( ! $silent )
            do_action( 'custom_deactivate_plugin', $plugin, $context );

        $key = array_search( $plugin, $current );
        if ( false !== $key ) {
            array_splice( $current, $key, 1 );
        }

        if ( ! $silent ) {
            do_action( 'custom_deactivate_' . $plugin, $context );
            do_action( 'custom_deactivated_plugin', $plugin, $context );
        }
    }

    update_option( 'active_plugins_' . $context, $current );
}

นอกจากนี้ยังมีcd_apd_validate_pluginฟังก์ชั่นที่validate_pluginไม่ได้ใช้งานโดยไม่มีขยะที่เข้ารหัสยาก

<?php
function cd_apd_validate_plugin( $plugin, $context ) 
{
    $rv = true;
    if ( validate_file( $plugin ) )
    {
        $rv = new WP_Error('plugin_invalid', __('Invalid plugin path.'));
    }

    global $wp_plugin_directories;
    if( ! isset( $wp_plugin_directories[$context] ) )
    {
        $rv = new WP_Error( 'invalid_context', __( 'The context for this plugin does not exist' ) );
    }

    $dir = $wp_plugin_directories[$context]['dir'];
    if( ! file_exists( $dir . '/' . $plugin) )
    {
        $rv = new WP_Error( 'plugin_not_found', __( 'Plugin file does not exist.' ) );
    }

    $installed_plugins = cd_apd_get_plugins( $context );
    if ( ! isset($installed_plugins[$plugin]) )
    {
        $rv = new WP_Error( 'no_plugin_header', __('The plugin does not have a valid header.') );
    }

    $rv = $dir . '/' . $plugin;
    return $rv;
}

เอาล่ะออกไปให้พ้น เราสามารถเริ่มพูดคุยเกี่ยวกับการแสดงตารางรายการ

ขั้นตอนที่ 1: เพิ่มมุมมองของเราไปยังรายการที่ด้านบนของตาราง สิ่งนี้ทำได้โดยการกรองviews_{$screen->id}ภายในinitฟังก์ชั่นของเรา

add_filter( 'views_' . $screen->id, array( &$this, 'views' ) );

จากนั้นฟังก์ชั่น hooked ที่แท้จริงจะวน$wp_plugin_directoriesซ้ำผ่าน หากหนึ่งในไดเรกทอรีที่ลงทะเบียนใหม่มีปลั๊กอินเราจะรวมไว้ในจอแสดงผล

function views( $views )
{
    global $wp_plugin_directories;

    // bail if we don't have any extra dirs
    if( empty( $wp_plugin_directories ) ) return $views;

    // Add our directories to the action links
    foreach( $wp_plugin_directories as $key => $info )
    {
        if( ! count( $this->plugins[$key] ) ) continue;
        $class = $this->get_plugin_status() == $key ? ' class="current" ' : '';
        $views[$key] = sprintf( 
            '<a href="%s"' . $class . '>%s <span class="count">(%d)</span></a>',
            add_query_arg( 'plugin_status', $key, 'plugins.php' ),
            esc_html( $info['label'] ),
            count( $this->plugins[$key] )
        );
    }
    return $views;
}

สิ่งแรกที่เราต้องทำถ้าเรากำลังดูหน้าไดเรกทอรีปลั๊กอินที่กำหนดเองคือการกรองมุมมองอีกครั้ง เราต้องกำจัดinactiveจำนวนเพราะมันจะไม่แม่นยำ ผลที่ตามมาของการไม่มีตัวกรองที่เราต้องการให้เป็น ขออีกครั้ง ...

if( $this->get_plugin_status() )
{
    add_filter( 'views_' . $screen->id, array( &$this, 'views_again' ) );
}

และไม่มีการตั้งค่าอย่างรวดเร็ว ...

function views_again( $views )
{
    if( isset( $views['inactive'] ) ) unset( $views['inactive'] );
    return $views;
}

ถัดไปลองกำจัดปลั๊กอินที่คุณจะเห็นเป็นอย่างอื่นในตารางรายการและแทนที่ด้วยปลั๊กอินที่กำหนดเองของเรา all_pluginsขอเข้าสู่

if( $this->get_plugin_status() )
{
    add_filter( 'views_' . $screen->id, array( &$this, 'views_again' ) );
    add_filter( 'all_plugins', array( &$this, 'filter_plugins' ) );
}

เนื่องจากเราได้ตั้งค่าปลั๊กอินและข้อมูลของเราแล้ว (ดูsetup_pluginsด้านบน) filter_pluginsวิธีการเพียง (1) จะบันทึกจำนวนในปลั๊กอินทั้งหมดในภายหลังและ (2) แทนที่ปลั๊กอินในตารางรายการ

function filter_plugins( $plugins )
{
    if( $key = $this->get_plugin_status() )
    {
        $this->all_count = count( $plugins );
        $plugins = $this->plugins[$key];
    }
    return $plugins;
}

และตอนนี้เราจะฆ่าการกระทำเป็นกลุ่ม ฉันสามารถรองรับสิ่งเหล่านี้ได้อย่างง่ายดายใช่ไหม?

if( $this->get_plugin_status() )
{
    add_filter( 'views_' . $screen->id, array( &$this, 'views_again' ) );
    add_filter( 'all_plugins', array( &$this, 'filter_plugins' ) );
    // TODO: support bulk actions
    add_filter( 'bulk_actions-' . $screen->id, '__return_empty_array' );
}

ลิงก์การกระทำของปลั๊กอินเริ่มต้นจะไม่ทำงานสำหรับเรา ดังนั้นเราต้องตั้งค่าของเราเอง (ด้วยการกระทำที่กำหนดเอง ฯลฯ ) ในinitฟังก์ชั่น

if( $this->get_plugin_status() )
{
    add_filter( 'views_' . $screen->id, array( &$this, 'views_again' ) );
    add_filter( 'all_plugins', array( &$this, 'filter_plugins' ) );
    // TODO: support bulk actions
    add_filter( 'bulk_actions-' . $screen->id, '__return_empty_array' );
    add_filter( 'plugin_action_links', array( &$this, 'action_links' ), 10, 2 );
}

สิ่งเดียวที่ได้รับการเปลี่ยนแปลงที่นี่คือ (1) เรากำลังเปลี่ยนการกระทำ (2) การรักษาสถานะปลั๊กอินในและ (3) การเปลี่ยนชื่อ nonce เล็กน้อย

function action_links( $links, $plugin_file )
{
    $context = $this->get_plugin_status();

    // let's just start over
    $links = array();
    $links['activate'] = sprintf(
        '<a href="%s" title="Activate this plugin">%s</a>',
        wp_nonce_url( 'plugins.php?action=custom_activate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . esc_attr( $context ), 'custom_activate-' . $plugin_file ),
        __( 'Activate' )
    );

    $active = get_option( 'active_plugins_' . $context, array() );
    if( in_array( $plugin_file, $active ) )
    {
        $links['deactivate'] = sprintf(
            '<a href="%s" title="Deactivate this plugin" class="cd-apd-deactivate">%s</a>',
            wp_nonce_url( 'plugins.php?action=custom_deactivate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . esc_attr( $context ), 'custom_deactivate-' . $plugin_file ),
            __( 'Deactivate' )
        );
    }
    return $links;
}

และในที่สุดเราก็ต้องจัดคิว JavaScript เพื่อปิดมัน ในinitฟังก์ชั่นอีกครั้ง (พร้อมกันในเวลานี้)

if( $this->get_plugin_status() )
{
    add_filter( 'views_' . $screen->id, array( &$this, 'views_again' ) );
    add_filter( 'all_plugins', array( &$this, 'filter_plugins' ) );
    // TODO: support bulk actions
    add_filter( 'bulk_actions-' . $screen->id, '__return_empty_array' );
    add_filter( 'plugin_action_links', array( &$this, 'action_links' ), 10, 2 );
    add_action( 'admin_enqueue_scripts', array( &$this, 'scripts' ) );
}

ในขณะที่จัดคิว JS ของเราเราจะใช้wp_localize_scriptเพื่อรับค่าการนับ "ปลั๊กอินทั้งหมด" ทั้งหมด

function scripts()
{
    wp_enqueue_script(
        'cd-apd-js',
        CD_APD_URL . 'js/apd.js',
        array( 'jquery' ),
        null
    );
    wp_localize_script(
        'cd-apd-js',
        'cd_apd',
        array(
            'count' => esc_js( $this->all_count )
        )
    );
}

และแน่นอนว่า JS เป็นเพียงแฮ็คที่ดีในการทำให้ปลั๊กอินรายการใช้งาน / ไม่ใช้งานเพื่อแสดงตารางอย่างถูกต้อง นอกจากนี้เราจะติดจำนวนที่ถูกต้องของปลั๊กอินทั้งหมดกลับเข้าไปในAllลิงค์

jQuery(document).ready(function(){
    jQuery('li.all a').removeClass('current').find('span.count').html('(' + cd_apd.count + ')');
    jQuery('.wp-list-table.plugins tr').each(function(){
        var is_active = jQuery(this).find('a.cd-apd-deactivate');
        if(is_active.length) {
            jQuery(this).removeClass('inactive').addClass('active');
            jQuery(this).find('div.plugin-version-author-uri').removeClass('inactive').addClass('active');
        }
    });
});

สรุป

การโหลดไดเรกทอรีปลั๊กอินเพิ่มเติมที่เกิดขึ้นจริงนั้นค่อนข้างน่าตื่นเต้น รับตารางรายการเพื่อแสดงอย่างถูกต้องเป็นส่วนที่ยากขึ้น ฉันยังคงไม่พอใจอย่างสมบูรณ์กับวิธีการที่ปรากฏออกมา แต่บางทีบางคนสามารถปรับปรุงรหัสได้


1
ที่น่าประทับใจ! ทำงานได้ดีจริงๆ ฉันจะใช้เวลาช่วงวันหยุดเพื่อศึกษารหัสของคุณ หมายเหตุ: __return_empty_array()มีฟังก์ชั่นคือ
fuxia

ขอบคุณ! ข้อเสนอแนะยินดีต้อนรับเสมอ รวม__return_empty_arrayฟังก์ชั่น!
chrisguitarguy

1
คุณควรรวบรวมรายชื่อของสถานที่ทั้งหมดที่ตัวกรองหลักแบบง่ายจะช่วยคุณแยกฟังก์ชั่น แล้ว…ส่งตั๋ว Trac
fuxia

อันนี้ยอดเยี่ยมจริงๆ มันจะยิ่งเย็นลงถ้าเราสามารถทำสิ่งนี้เป็นห้องสมุดในธีม (ดูความคิดเห็นของฉันใน Github: github.com/chrisguitarguy/WP-Plugin-Directories/issues/4 )
julien_c

1
+1 ไม่อยากจะเชื่อเลยว่าฉันจะพลาดคำตอบนี้ดีมาก! ฉันจะดูรหัสของคุณในรายละเอียดมากขึ้นในช่วงสุดสัปดาห์ :) @Julien_c - ทำไมคุณต้องใช้สิ่งนี้ในธีม
Stephen Harris

2

ฉันไม่มีความสนใจส่วนตัวในการปรับเปลี่ยน UI แต่ฉันชอบรูปแบบระบบไฟล์ที่จัดระเบียบมากขึ้นด้วยเหตุผลหลายประการ

ด้วยเหตุนี้แนวทางอื่นก็คือการใช้ symlink

wp-content
    |-- plugins
        |-- acme-widgets               -> ../plugins-custom/acme-widgets
        |-- acme-custom-post-types     -> ../plugins-custom/acme-custom-post-types
        |-- acme-business-logic        -> ../plugins-custom/acme-business-logic
        |-- google-authenticator       -> ../plugins-external/google-authenticator
        |-- rest-api                   -> ../plugins-external/rest-api
        |-- quick-navigation-interface -> ../plugins-external/quick-navigation-interface
    |-- plugins-custom
        |-- acme-widgets
        |-- acme-custom-post-types
        |-- acme-business-logic
    |-- plugins-external
        |-- google-authenticator
        |-- rest-api
        |-- quick-navigation-interface

คุณสามารถตั้งค่าปลั๊กอินแบบกำหนดเองplugins-customซึ่งอาจเป็นส่วนหนึ่งของที่เก็บข้อมูลการควบคุมเวอร์ชันของโครงการของคุณ

จากนั้นคุณสามารถติดตั้งการอ้างอิงของบุคคลที่สามลงในplugins-external(ผ่านนักแต่งเพลงหรือ submodules Git หรือสิ่งที่คุณต้องการ)

จากนั้นคุณสามารถมีสคริปต์ Bash แบบง่าย ๆ หรือคำสั่ง WP-CLI ที่สแกนไดเรกทอรีเพิ่มเติมและสร้าง symlink pluginsสำหรับแต่ละโฟลเดอร์ย่อยที่พบ

pluginsจะยังคงรก แต่มันจะไม่เป็นเรื่องเพราะคุณจะต้องเท่านั้นที่จะมีปฏิสัมพันธ์กับและplugins-customplugins-external

การขยายไปยังnไดเร็กทอรีเพิ่มเติมจะทำตามกระบวนการเดียวกันกับสองรายการแรก


-3

หรือคุณสามารถใช้ COMPOSER กับเส้นทางไดเรกทอรีที่กำหนดเองที่กำหนดให้ชี้ไปที่โฟลเดอร์ wp-content หากไม่ใช่คำตอบที่ตรงกับคำถามของคุณเป็นวิธีคิด wordpress ใหม่ให้ไปที่นักแต่งเพลงก่อนที่จะทำให้คุณหมดแรง


เสร็จสิ้นการย้ายไปยังนักแต่งเพลงเมื่อนานมาแล้ว โปรดดูวันที่ของคำถามนี้ นอกจากนั้น: นี่ไม่ใช่คำตอบจริงๆ อาจแสดงวิธีตั้งค่านี้จริงหรือ
ไกเซอร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.