워드 프레스 API 메뉴 / 하위 메뉴 순서


11

내가 사용하여 어린이 테마 개발하고 있어요 워드 프레스 3.4.2 과의 개발 버전 옵션 프레임 워크 에 의해 데이비드 가격 . 이것은 나의 첫 번째 주제이며 나는 이것에 대해 비교적 새로운 것이기 때문에 Wordpress Codex를 살펴보고 항목을 API에 등록하는 것을 확인했습니다.

테마 외부의 외부 파일을 변경하지 않고 테마 옵션 페이지가 모양 메뉴 의 계층 내에서 위치 를 다시 정렬하는 방법이 있는지 궁금했습니다. 따라서 테마가 활성화되면 위치가 다릅니다 첫 번째 이미지이지만 두 번째 이미지와 같습니다.

낡은새로운

메뉴 ( 모양 탭, 플러그인 , 사용자 등) 또는 하위 메뉴 ( 테마 , 위젯 , 메뉴 등)를 만들 수는 있지만 하위 메뉴 설정 방법은 두 번째입니다. 위에서?

내가 수집 한 것에서 어딘가에 주문이 있고 functions.php파일 내의 다른 추가 페이지 가 그 뒤에 배치됩니까?

내 functions.php 파일에서 :

// Add our "Theme Options" page to the Wordpress API admin menu.
if ( !function_exists( 'optionsframework_init' ) ) {
    define( 'OPTIONS_FRAMEWORK_DIRECTORY', get_template_directory_uri() . '/inc/' );
    require_once dirname( __FILE__ ) . '/inc/options-framework.php';
}

감사.


업데이트 된 기능을 사용해 보셨습니까?
Adam

@userabuser에게 다시 연락해 주셔서 감사합니다. 업데이트 된 스크립트를 복사하여 붙여 넣었으며 다른 항목을 재정의하지 않고 목록을 위아래로 이동하는 것처럼 보이지만 새 업데이트로 위젯 메뉴 에 여전히 몇 가지 오류가 발생 합니다. Warning: Invalid argument supplied for foreach() in /wp-content/themes/mythemename/functions.php on line 1444 1444 행 : foreach ($submenu[$menus] as $index => $value){Warning: ksort() expects parameter 1 to be array, null given in /wp-content/themes/mythemename/functions.php on line 1468 1468 행 : ksort($submenu[$menus]);
user1752759

이것에 대해 살펴볼 수 있다면 좋을 것입니다.
user1752759

답변:


3

다음은 예입니다.

배열 키를 기반으로 하위 메뉴 항목의 순서를 먼저 파악 var_dump하려면 $ submenu 전역 변수에 대해 다음을 출력 할 수 있습니다 .

(예를 들어 게시물 메뉴와 하위 메뉴를 사용하고 있습니다)

  //shortened for brevity....

  ["edit.php"]=>
  array(6) {
    [5]=>
    array(3) {
      [0]=> string(9) "All Posts"
      [1]=> string(10) "edit_posts"
      [2]=> string(8) "edit.php"
    }
    [10]=>
    array(3) {
      [0]=> string(7) "Add New"
      [1]=> string(10) "edit_posts"
      [2]=> string(12) "post-new.php"
    }
    [15]=>
    array(3) {
      [0]=> string(10) "Categories"
      [1]=> string(17) "manage_categories"
      [2]=> string(31) "edit-tags.php?taxonomy=category"
    }
    [17]=>
    array(3) {
      [0]=> string(14) "Sub Menu Title"
      [1]=> string(10) "edit_posts"
      [2]=> string(17) "sub_menu_page.php"
    }
  }

하위 항목이 기본 항목 다음에 17 키로 배열에 추가 된 것을 볼 수 있습니다.

예를 들어 모든 게시물 하위 메뉴 항목 바로 뒤에 하위 메뉴 항목을 추가 하려면 배열 키를 6, 7, 8 또는 9로 설정해야합니다 (각각 5, 10, 10 이전).

이것이 당신이하는 방법입니다 ...

function change_submenu_order() {

    global $menu;
    global $submenu;

     //set our new key
    $new_key['edit.php'][6] = $submenu['edit.php'][17];

    //unset the old key
    unset($submenu['edit.php'][17]);

    //get our new key back into the array
    $submenu['edit.php'][6] = $new_key['edit.php'][6];


    //sort the array - important! If you don't the key will be appended
    //to the end of $submenu['edit.php'] array. We don't want that, we
    //our keys to be in descending order
    ksort($submenu['edit.php']);

}

결과,

  ["edit.php"]=>
  array(6) {
    [5]=>
    array(3) {
      [0]=> string(9) "All Posts"
      [1]=> string(10) "edit_posts"
      [2]=> string(8) "edit.php"
    }
    [6]=>
    array(3) {
      [0]=> string(14) "Sub Menu Title"
      [1]=> string(10) "edit_posts"
      [2]=> string(17) "sub_menu_page.php"
    }
    [10]=>
    array(3) {
      [0]=> string(7) "Add New"
      [1]=> string(10) "edit_posts"
      [2]=> string(12) "post-new.php"
    }
    [15]=>
    array(3) {
      [0]=> string(10) "Categories"
      [1]=> string(17) "manage_categories"
      [2]=> string(31) "edit-tags.php?taxonomy=category"
    }
  }

... 한번 시도해 보시고 어떻게하는지 알려주세요!

업데이트 1 :

functions.php 파일에 추가하십시오;

function change_post_menu_label() {

    global $menu;
    global $submenu;

    $my_menu  = 'example_page'; //set submenu page via its ID
    $location = 1; //set the position (1 = first item etc)
    $target_menu = 'edit.php'; //the menu we are adding our item to

    /* ----- do not edit below this line ----- */


    //check if our desired location is already used by another submenu item
    //if TRUE add 1 to our value so menu items don't clash and override each other
    $existing_key = array_keys( $submenu[$target_menu] );
    if ($existing_key = $location)
    $location = $location + 1;

    $key = false;
    foreach ( $submenu[$target_menu] as $index => $values ){

        $key = array_search( $my_menu, $values );

        if ( false !== $key ){
            $key = $index;
            break;
        }
    }

     $new['edit.php'][$location] = $submenu[$target_menu][$key];
     unset($submenu[$target_menu][$key]);
     $submenu[$target_menu][$location] = $new[$target_menu][$location];

    ksort($submenu[$target_menu]);

}

내 업데이트에는 메뉴 위치 설정을 처리하는 약간 더 쉬운 방법이 포함되어 있으므로 하위 메뉴 페이지의 이름과 메뉴 내에서 원하는 위치 만 지정하면됩니다. 그러나 $location기존 키와 동일한 하위 메뉴 페이지를 선택하면 해당 키가 사용자 키로 대체되므로 메뉴 항목이 해당 메뉴 항목과 함께 사라집니다. 이 경우 메뉴를 올바르게 주문하려면 숫자를 늘리거나 줄이십시오. 마찬가지로 누군가가 동일한 메뉴 영역에 영향을 미치고 $location하위 메뉴 항목 과 동일한 플러그인을 설치 하면 동일한 문제가 발생합니다. 이를 피하기 위해 Kaiser의 예제는이를위한 기본적인 검사를 제공합니다.

업데이트 2 :

배열에있는 기존의 모든 키를 원하는대로 검사하는 추가 코드 블록을 추가 $location했으며 일치하는 것이 있으면 메뉴 항목이 서로 재정의되는 것을 피하기 위해 $location값을 증가시킵니다 1. 이것은 그것을 담당하는 코드입니다.

   //excerpted snippet only for example purposes (found in original code above)
   $existing_key = array_keys( $submenu[$target_menu] );
   if ($existing_key = $location)
   $location = $location + 1;

업데이트 3 : (여러 하위 메뉴 항목을 정렬 할 수 있도록 스크립트 수정)

add_action('admin_init', 'move_theme_options_label', 999);

function move_theme_options_label() {
    global $menu;
    global $submenu;

$target_menu = array(
    'themes.php' => array(
        array('id' => 'optionsframework', 'pos' => 2),
        array('id' => 'bp-tpack-options', 'pos' => 4),
        array('id' => 'multiple_sidebars', 'pos' => 3),
        )
);

$key = false;

foreach ( $target_menu as $menus => $atts ){

    foreach ($atts as $att){

        foreach ($submenu[$menus] as $index => $value){

        $current = $index;  

        if(array_search( $att['id'], $value)){ 
        $key = $current;
        }

            while (array_key_exists($att['pos'], $submenu[$menus]))
                $att['pos'] = $att['pos'] + 1;

            if ( false !== $key ){

                if (array_key_exists($key, $submenu[$menus])){
                    $new[$menus][$key] = $submenu[$menus][$key];
                    unset($submenu[$menus][$key]);
                    $submenu[$menus][$att['pos']] = $new[$menus][$key];

                } 
            }
        }
    }
}

ksort($submenu[$menus]);
return $submenu;

}

위의 예 $target_menu에서 다차원 값 배열을 보유하는 변수 내에서 매개 변수를 적절하게 설정하여 여러 하위 메뉴 및 하위 메뉴 당 여러 항목을 대상으로 지정할 수 있습니다 .

$target_menu = array(
//menu to target (e.g. appearance menu)
'themes.php' => array(
    //id of menu item you want to target followed by the position you want in sub menu
    array('id' => 'optionsframework', 'pos' => 2),
    //id of menu item you want to target followed by the position you want in sub menu
    array('id' => 'bp-tpack-options', 'pos' => 3),
    //id of menu item you want to target followed by the position you want in sub menu
    array('id' => 'multiple_sidebars', 'pos' => 4),
    )
 //etc....
);

이 수정은 존재하지 않는 사용 가능한 키 (위치)를 찾을 때까지 순환하므로 하위 메뉴 항목이 동일한 키 (위치)를 갖는 경우 서로 덮어 쓰는 것을 방지합니다.


빠른 응답 userabuser에 감사드립니다. 그러나 나는이 모든 것에 상당히 익숙하지 않습니다. 위의 스크립트 / 코드를 구현하는 방법과 간결한 작성 방법으로 인해 어떤 파일을 배치해야하는지 잘 모르겠습니다. 정교하게 작성하십시오. 이 예제가 작동하고 필요한 수를 출력하는 경우 ... 사용자가 나중에 플러그인을 설치하여 내부에 몇 가지 하위 레벨 (예 : 전자 상거래 솔루션)이있는 추가 최상위 메뉴를 만든 경우 배열 키에 영향을 미치며 제동을 시작하십시오.
user1752759

1
@Rob 메뉴 항목이 서로 재정의되는 상황을 피하는 데 도움이되도록 약간 조정했습니다.
Adam

@ user1752759 위와 어떤 관련이 있습니까? 위의 주석에서 제공하는 functions.php 파일의 전체 경로는 무엇입니까? 해당 파일 내의 코드는 무엇입니까? 마지막 대화에서 이것은 당신을 위해 일했습니다. 그것은 또한 나를 위해 작동합니다. 그래서 지난번에 두 번의 코드 스 니펫을 복제하고 함수 주위에 올바른 중괄호가없는 것을 올바르게 기억한다면 여기에 다른 것이 코드 내에서 누락 될 수 있다고 의심됩니다.
Adam

@userabuser에게 다시 연락해 주셔서 감사합니다. 업데이트 된 스크립트를 복사하여 붙여 넣었으며 다른 항목을 재정의하지 않고 목록을 위아래로 이동하는 것처럼 보이지만 새 업데이트로 위젯 메뉴에 여전히 몇 가지 오류가 발생합니다. Warning: Invalid argument supplied for foreach() in /wp-content/themes/mythemename/functions.php on line 1444 1444 행 : foreach ($submenu[$menus] as $index => $value){Warning: ksort() expects parameter 1 to be array, null given in /wp-content/themes/mythemename/functions.php on line 1468 1468 행 : ksort($submenu[$menus]);
user1752759

이것에 대해 살펴볼 수 있다면 좋을 것입니다.
user1752759

2

관리 메뉴 (및 문제)

관리 메뉴에는 후크와 공용 API가 심각하지 않기 때문에 (항목을 이동할 수 있도록) 몇 가지 해결 방법을 사용해야합니다. 다음 답변은 미래에 무엇을 기다리고 있으며 현재 핵심 상태를 유지하는 한 어떻게 해결할 수 있는지 보여줍니다.

먼저, scribu는 훨씬 쉽게 처리 할 수 있는 관리자 메뉴 패치를 개발 하고 있습니다. 현재 구조가 엉망 이되어서 곧 구식이 될 기사를 작성했습니다 . WP 3.6이 완전히 변경 될 것으로 예상합니다.

그런 다음 더 이상 테마에 옵션 페이지를 사용해서는 안된다는 요점이 있습니다. 현재는 »테마 맞춤 설정 도구« 가 있습니다.

플러그인

TwentyEleven / Ten 옵션 페이지의 기본 "테마 옵션"페이지에서이를 테스트하는 플러그인을 작성했습니다. 보시다시피 어떤 위치를 허용하는 실제 API는 없습니다. 그래서 우리는 세계를 가로 채야합니다.

한마디로 : 주석을 따르고 약간의 디버그 출력을 제공하기 위해 추가 한 관리자 알림을 살펴보십시오.

<?php
/** Plugin Name: (#70916) Move Submenu item */

add_action( 'plugins_loaded', array( 'wpse70916_admin_submenu_items', 'init' ) );

class wpse70916_admin_submenu_items
{
    protected static $instance;

    public $msg;

    public static function init()
    {
        is_null( self :: $instance ) AND self :: $instance = new self;
        return self :: $instance;
    }

    public function __construct()
    {
        add_action( 'admin_notices', array( $this, 'add_msg' ) );

        add_filter( 'parent_file', array( $this, 'move_submenu_items' ) );
    }

    public function move_submenu_items( $parent_file )
    {
        global $submenu;
        $parent = $submenu['themes.php'];

        $search_for = 'theme_options';

        // Find current position
        $found = false;
        foreach ( $parent as $pos => $item )
        {
            $found = array_search( $search_for, $item );
            if ( false !== $found )
            {
                $found = $pos;
                break;
            }
        }
        // DEBUG: Tell if we didn't find it.
        if ( empty( $found ) )
            return $this->msg = 'That search did not work out...';

        // Now we need to determine the first and second item position
        $temp = array_keys( $parent );
        $first_item  = array_shift( $temp );
        $second_item = array_shift( $temp );

        // DEBUG: Check if it the item fits between the first two items:
        $distance = ( $second_item - $first_item );
        if ( 1 >= $distance )
            return $this->msg = 'We do not have enough space for your item';

        // Temporary container for our item data
        $target_data = $parent[ $found ];

        // Now we can savely remove the current options page
        if ( false === remove_submenu_page( 'themes.php', $search_for ) )
            return $this->msg = 'Failed to remove the item';

        // Shuffle items (insert options page)
        $submenu['themes.php'][ $first_item + 1 ] = $target_data;
        // Need to resort the items by their index/key
        ksort( $submenu['themes.php'] );
    }

    // DEBUG Messages
    public function add_msg()
    {
        return print sprintf(
             '<div class="update-nag">%s</div>'
            ,$this->msg
        );
    }
} // END Class wpse70916_admin_submenu_items

행운을 빌고 재미있게 보내.


2

맞춤 필터

이를 달성 할 수있는 또 다른 가능성이 있습니다. 내가 왜 그것에 대해 먼저 생각하지 않았는지 묻지 마십시오. 어쨌든, 사용자 정의 메뉴 순서 전용 필터가 있습니다. true맞춤 주문을 허용하도록 설정하면됩니다 . 그런 다음 주 메뉴 항목을 주문하는 두 번째 후크가 있습니다. 거기에서 우리는 단지 인터셉트 global $submenu하고 하위 메뉴 항목을 전환합니다.

여기에 이미지 설명을 입력하십시오

이 예는 이동 메뉴 항목을 위젯 항목 의 기능을 보여줍니다. 원하는대로 조정할 수 있습니다.

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (#70916) Custom Menu Order
 * Description: Changes the menu order of a submenu item.
 */

// Allow a custom order
add_filter( 'custom_menu_order', '__return_true' );
add_filter( 'menu_order', 'wpse70916_custom_submenu_order' );
function wpse70916_custom_submenu_order( $menu )
{
    // Get the original position/index
    $old_index = 10;
    // Define a new position/index
    $new_index = 6;

    // We directly interact with the global
    $submenu = &$GLOBALS['submenu'];
    // Assign our item at the new position/index
    $submenu['themes.php'][ $new_index ] = $submenu['themes.php'][ $old_index ];
    // Get rid of the old item
    unset( $submenu['themes.php'][ $old_index ] );
    // Restore the order
    ksort( $submenu['themes.php'] );

    return $menu;
}

PHP @kaiser를 사용할 때 확신이 없지만 메뉴 위 뿐만 아니라 테마를function wpse70916_custom_submenu_order( $menu ) 다시 정렬하기 위해 동일한 스크립트 내에 여러 항목을 포함하도록 위의 스크립트를 구현하는 방법을 알고 있습니까? 옵션 , 위젯 , 편집기 등이 매우 유연하고 항목이 서로 재정의되지 않도록합니까? 감사합니다.
user1752759

@ user1752759 플러그인에는 이미 이러한 유연성이 있습니다. 충돌 안전 (재정의를 피하는 것)은 또 다른 문제입니다. 마지막으로 작업을 할당 할 수 없으므로 100 % 시나리오에서는 불가능합니다. 나중에 실행할 수있는 것이 항상 있습니다. 어쨌든 : 새로운 질문을 열고이 질문에 링크하십시오.
카이저

카이저 감사합니다. 너무 많이 묻지 않으면 위의 스크립트를 업데이트하여 여러 항목이 수행되는 방법 (예 : 메뉴위젯 )을 표시 할 수 있습니까? PHP를 처음 접했기 때문에 아마도 숫자 때문에 올바르게하고 있다고 생각하지 않습니다. 건배
1752759

새로운 질문을하고이 질문에 링크하십시오. 감사.
카이저
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.