Support » Fixing WordPress » Getting page permalinks to not reflect page structure

  • Resolved eryanv


    My page/permalink structure currently looks like:

    PageA (/pagea)
    >> Page1 (/pagea/page1)
    >> Page2 (/pagea/page2)
    PageB (/pageb)
    >> Page3 (/pageb/page3)

    How can I get it to look like this?
    PageA (/pagea)
    >> Page1 (/page1)
    >> Page2 (/page2)
    PageB (/pageb)
    >> Page3 (/page3)

    Essentially I want to keep the structure for things like the navigation menu, but want to flatten the links for URLs.

    While I don’t think this makes a difference, I’m using the Month and Name Permalink structure.

Viewing 1 replies (of 1 total)
  • eryanv


    After a bit of digging I found the get_page_by_name function which helped me create these two functions which accomplish what I was looking to do.

    First is the function which alters the page links:

    //Removes top level directory unless it is the only part of the path
    add_action('page_link', i4kmh_page_link);
    function i4kmh_page_link( $url='', $id='' ) {
            $siteurl = get_bloginfo('siteurl');
            $siteurl = "/".preg_replace("/\//","\\\/",$siteurl)."/";
            $pathurl = preg_replace($siteurl, "", $url);
            $pages = explode('/',$pathurl);
            foreach($pages as $k=>$page) {
                    if($page == '') { unset($pages[$k]);}
                    elseif(!$firstcleared) { unset($pages[$k]); $firstcleared=true;}
            if(count($pages)==0) { return $url; } //If we've cleared out the only thing in the url, then it was top level or root level, so leave the url alone
                    foreach((array) $pages as $pathdir) {
                            $red_path .= '/' . sanitize_title($pathdir);
                    return get_bloginfo('siteurl').$red_path.'/';
            return $url;

    Second, the function which takes this normally bad links and finds the correct page for them:

    //Adds top level directory to pagename
    add_action('parse_request', i4kmh_pq);
    function i4kmh_pq($wpq = '') {
            global $wpdb;
                    $page_path = $wpq->query_vars['pagename'];
                    //Get a list of Top-Level menu items
                    $toppages = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_parent='0' and post_type='page'"),OBJECT_K);
                    if(empty($toppages)) { return $wpq; }
                    //Get first item in request
                    $page_path = rawurlencode(urldecode($page_path));
                    $page_path = str_replace('%2F', '/', $page_path);
                    $page_path = str_replace('%20', ' ', $page_path);
                    $page_paths = '/' . trim($page_path, '/');
                    $page_paths = explode('/', $page_paths);
                    //If first item is toplevel item return unchanged
                    foreach($toppages as $key => $obj) {
                            if($page_paths[1] == $obj->post_name) { return $wpq; }
                    $toplevelpage = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name= %s AND post_type='page'",$page_paths[1]));
                    if(count($toplevelpage) != 1) { // Too many to determine, or too few
                            return $wpq;
                    }else{ // Just the right amount, lookup the name and return the modified queryvar
                            foreach( (array) $page_paths as $pathdir)
                                    $full_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir);
                            $full_path = '/'.sanitize_title($toppages[$toplevelpage[0]->post_parent]->post_name).$full_path;
                            return $wpq;
            return $wpq;
Viewing 1 replies (of 1 total)
  • The topic ‘Getting page permalinks to not reflect page structure’ is closed to new replies.