Wordpress profile page tabbed interface

I have some trouble with situation in admin Wordpress. What I want is create tabbed interface in user edit section. I dont have experience with dommanipulation, so I dont know, what is best solution for this. Now I have ok code with preg_replace function, but I need in multilangual admin area order some section by custom function. Thank you

$html = '<div id="container">';
$html = '<h2>TAB1</h2>';
$html .= '<table><tr><td>SECTION1</td></tr></table>';
$html .= '<h2>TAB2</h2>';
$html .= '<table><tr><td>SECTION2</td></tr></table>';
$html .= '<h2>TAB3</h2>';
$html .= '<table><tr><td>SECTION3</td></tr></table>';
$html .= '<h2>TAB4</h2>';
$html .= '<table><tr><td>SECTION4</td></tr></table>';
$html .= '<hr>';
$html .= 'some content append to last section';
$html .= '</div>';

/*
WHAT I NEED
<div id="container">
    <div class="tabs">
        <a href="" class="active">TAB2</a>
        <a href="">TAB1</a>
        <a href="">TAB3</a>
        <a href="">TAB4</a>
    </div>

    <section>
        <table><tr><td>SECTION2</td></tr></table>
    </section>
    <section class="hidden">
        <table><tr><td>SECTION1</td></tr></table>
    </section>
    <section class="hidden">
        <table><tr><td>SECTION3</td></tr></table>
    </section>
    <section class="hidden">
        <table><tr><td>SECTION4</td></tr></table>
        <hr>
        some content append to last section
    </section>
</div>
*/

$dom = new DOMDocument();
$dom->strictErrorChecking = false;
$dom->preserveWhiteSpace = true; 
$dom->loadHTML(mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($dom);

$tab = array();
foreach ($xpath->query('//h2') as $e) {
    $parent_cat = $xpath->query('following-sibling::*[1]');
    $tab[] = array(trim($e->nodeValue) => $parent_cat);
    $e->parentNode->removeChild($e);
}

$order = array(1,0,2);
uksort($tab, function($key1, $key2) use ($order) {
    $a = array_search($key1, $order);
    $b = array_search($key2, $order);
    if($a === false && $b === false) return 0;
    else if ($a === false) return 1;
    else if ($b === false) return -1;
    else return $a - $b;
});

print_r($tab);

Answers


Ok i found it. This is create tabbed interface in Wordpress administration in section of editing users profiles. But, I now, that quality of code is not so good, but it works :)

add_action( 'current_screen', array( 'change_profile_page' );
function change_profile_page(){
    $screen = get_current_screen();
    if ( 'user-edit' === $screen->base || 'profile' === $screen->base){
        add_action( 'admin_head', 'change_profile_page_start' );
        add_action( 'admin_footer', 'change_profile_page_end' );
    }
}


function tabify_profile_options( $html ) {
    $dom = new DOMDocument();
    $dom->strictErrorChecking = false;
    $dom->preserveWhiteSpace = true;
    libxml_use_internal_errors(true);
    $dom->loadHTML(mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8'));
    libxml_clear_errors();
    $xpath = new DOMXPath($dom);

    $tab = array();
    foreach ($xpath->query('//form[@id="your-profile"]//h2 | //form[@id="your-profile"]//h3') as $e) {
        $parent = $xpath->query('following-sibling::table', $e);
        if ($parent->length > 0) {
            $tab[] = array( 'title' => trim($e->nodeValue), 'content' => $parent);
            $e->parentNode->removeChild($e);
            $parent->item(0)->parentNode->removeChild($parent->item(0));
        }
    }

    $order = apply_filters( 'profile_options_order', array(1,4,2));
    uksort($tab, function($key1, $key2) use ($order) {
        $a = array_search($key1, $order);
        $b = array_search($key2, $order);
        if($a === false && $b === false) return 0;
        else if ($a === false) return 1;
        else if ($b === false) return -1;
        else return $a - $b;
    });

    $i = 0;
    $tabs = '';
    $content = '';
    $more = '';
    foreach($tab as $value){
        $tabs .= '<a href="javascript:;" class="nav-tab' . ($i==0 ? " nav-tab-active" : "" ) . '">' . apply_filters( 'profile_options_title', apply_filters( 'profile_options_' . ($i+1) . '_title', $value['title'] ) ) . '</a>';

        if ($i == 1) {
            foreach ($xpath->query('//form[@id="your-profile"]//label[@for="send_password"]/ancestor::table[1]') as $e) {
                $more .= $e->ownerDocument->saveHTML( $e );
                $e->parentNode->removeChild($e);
            }
        }
        $content .= '<section' . ($i!=0 ? ' class="hidden"' : '' ) . '>' . apply_filters( 'profile_options_' . ($i+1) . '_content' , $dom->saveHTML( $value['content']->item(0) ) . $more ) . '</section>';
        $more = '';
        $i++;
    }

    $rest = '';
    $submit = '';
    foreach ($xpath->query('//form[@id="your-profile"]/*') as $e) {
        if ( $e->getAttribute('class') != 'submit' ) {
            $rest .= $e->ownerDocument->saveHTML( $e );
        } else {
            $submit .= $e->ownerDocument->saveHTML( $e );
        }
        $e->parentNode->removeChild($e);
    }

    $content = preg_replace('~>\s+<~', '><', $content);
    $content = preg_replace('/(\<input type="text" name="user_login"[^>]+)(disabled)([^>]+)(>)(\<span+)(.*?)<\\/span>/', '${1}${3}${4}', $content);

    $rest = str_replace('<hr><hr>', '', $rest);

    $html = '
        <h2 class="nav-tab-wrapper">' . $tabs . '<a href="javascript:;" class="nav-tab">' . __('Další nastavení', 'core') . '</a></h2>'
         . $content . '
        <section class="hidden">' . $rest . '</section' . $submit ."
        <script>
            (function($) {
                $(document).on( 'click', '.nav-tab-wrapper a', function() {
                    $('section').hide();
                    $('section').eq($(this).index()).show();
                    $(this).addClass('nav-tab-active').delay(50).queue(function() {
                        $(this).siblings('.nav-tab').removeClass('nav-tab-active');
                        $(this).dequeue();
                    });
                    return false;
                })
            })( jQuery );
        </script>";

    $frag = new DomDocument();
    $frag->strictErrorChecking = false;  
    $frag->validateOnParse = true;
    $frag->loadHTML(mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8'));
    $target = $dom->getElementById('your-profile');
    foreach($frag->getElementsByTagName('body')->item(0)->childNodes as $node){ 
        $target->appendChild($dom->importNode($node,true));
    }

    return $dom->saveHTML();
}

function change_profile_page_start() {
    ob_start( 'tabify_profile_options' );
}

function change_profile_page_end() {
    ob_end_flush();
}

// example of filter
add_filter('profile_options_order', function($args) { return array(5); });
add_filter( 'profile_options_title', function($args) { return str_replace('Yoast ', '', $args); } );

Need Your Help

How to get Filename/File Contents as key/value input for MAP when running a Hadoop MapReduce Job?

java hadoop mapreduce distributed-system

I am creating a program to analyze PDF, DOC and DOCX files. These files are stored in HDFS.

aasm after callback with argument

ruby-on-rails ruby ruby-on-rails-4 aasm acts-as-state-machine

I'm using the aasm (formerly acts_as_state_machine) gem in my rails 4 application. I have something like this on my Post model