WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

My client was editing pages in the admin area of their site, which is currently being hosted on my server. Two of them were logged in simultaneously, but that shouldn't matter.

We're using a child theme of a premium theme. I'm a developer. I hadn't touched any files in hours and was not even around when they were editing.

All of a sudden they say, all posts and pages were rearranged. Custom post type "portfolio" suddenly got moved to the regular post type (the blog), all pages disappeared (and thus caused 404s), etc. But upon inspecting the database, all is fine.

I deactivated every plugin and the problem persisted. But then I switched the theme to twentyfourteen and the problem was GONE! I switched to the parent theme, the problem is also not there either, everything is in order.

I repaired tables, I deleted and reuploaded the child theme, nothing is fixing it.

On my local server, the problem does not exist with the child theme. I checked the functions.php, but how can anything be amiss there if it's working fine locally?

So I am at a loss as to what could have possibly happened, but ironically, we were planning to launch the site tomorrow or the day after.

Nothing like this has ever happened to me before, so I hope someone can help. Thank you so much!

EDIT: I've identified that it is something in the functions.php of the child theme that is causing the problem, because if I delete the child functions.php, the problem resolves. But I'm stumped as to why this isn't a problem locally, and why the problem started hours after last editing code? If posting the code to the functions.php would help, I can do that. I also copied some of the code to the parent theme's functions, and there was no problem.

EDIT: To add the code. Another developer suspects that custom_pre_get_posts was the problem. He commented out the code, and yes, that does fix the problem, but the client really needs the /portfolio-item/ slug to be dropped from the urls. I wonder if this part is conflicting only with the hidden-pages code I added? Either way, it is still a mystery why this code would function for weeks and suddenly break.


function evol_child_scripts() {
wp_enqueue_style( 'style', get_stylesheet_directory_uri() .    
'/stylesheets/css/style.css' ); 

add_action( 'wp_enqueue_scripts', 'evol_child_scripts' );

/*function codex_custom_init() {
$args = array(
  'public' => true,
  'label'  => 'Hidden Pages'
register_post_type( 'hidden', $args );
add_action( 'init', 'codex_custom_init' );

 * Register a custom post type but don't do anything fancy
register_post_type( 'hidden', array( 'label' => 'Hidden Pages', 'public' =>    
true, 'capability_type' => 'post',  'show_ui' => true, 'query_var' => true,   
'supports' => array( 'title', 'editor', 'thumbnail' ) ) );
 * Remove the slug from published post permalinks. Only affect our CPT  though.
function vipx_remove_cpt_slug( $post_link, $post, $leavename ) {

if ( ! in_array( $post->post_type, array( 'hidden' ) ) 
    || 'publish' != $post->post_status )
    return $post_link;

$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );

return $post_link;
add_filter( 'post_type_link', 'vipx_remove_cpt_slug', 10, 3 );

 * Some hackery to have WordPress match postname to any of our public 
 * post types. All of our public post types can have /post-name/ as 
 * the slug, so they better be unique across all posts. Typically core 
 * only accounts for posts and pages where the slug is /post-name/
function vipx_parse_request_tricksy( $query ) {

// Only noop the main query
if ( ! $query->is_main_query() )

// Only noop our very specific rewrite rule match
if ( 2 != count( $query->query )
    || ! isset( $query->query['page'] ) )

// 'name' will be set if post permalinks are just post_name, 
// otherwise the page rule will match
if ( ! empty( $query->query['name'] ) )
    $query->set( 'post_type', array( 'post', 'hidden', 'page' ) );
add_action( 'pre_get_posts', 'vipx_parse_request_tricksy' );

function remove_search_filter () {
remove_filter( 'pre_get_posts', 'tr_search_filter' );
add_action( 'init', 'remove_search_filter');

function remove_icons() {
wp_dequeue_style( 'icons' );

add_action( 'wp_enqueue_scripts', 'remove_icons' );

function tr_widgets_init_2() {

if ( ot_get_option( 'tr_sidebars' ) ) :
    $tr_sidebars = ot_get_option( 'tr_sidebars' );
    foreach ( $tr_sidebars as $tr_sidebar ) {
        register_sidebar( array(
            'id' => $tr_sidebar["id"],
            'name' => $tr_sidebar["title"],
            'before_widget' => '<div class="widget %2$s">',
            'after_widget' => '</div>',
            'before_title' => '<h6 class="widget-title">',
            'after_title' => '</h6>',
add_action( 'widgets_init', 'tr_widgets_init_2' );

add_filter('post_type_link','custom_post_type_link', 10, 3); 
function custom_post_type_link($permalink, $post, $leavename) { 

    $url_components = parse_url($permalink); 
    $post_path = $url_components['path']; 
    $post_name = end(explode('/', trim($post_path, '/'))); 

    if(!empty($post_name)) { 
        switch($post->post_type) { 
            case 'portfolio': 
                $permalink = str_replace($post_path, '/' . $post_name . '/',     
    return $permalink; 

function custom_pre_get_posts($query) { 
    global $wpdb; 

    if(!$query->is_main_query()) { 

    $post_name = $query->get('name'); 
    $post_type = $wpdb->get_var( $wpdb->prepare( 'SELECT post_type FROM ' .     
$wpdb->posts . ' WHERE post_name = %s LIMIT 1', $post_name ) ); 

    switch($post_type) { 
        case 'portfolio': 
            $query->set('portfolio', $post_name); 
            $query->set('post_type', $post_type); 
            $query->is_single = true; 
            $query->is_page = false; 

    return $query; 


function fb_add_search_box ( $items, $args ) {

// only on primary menu
if( 'primary' === $args -> theme_location )
    $items .= '<li class="menu-item menu-item-search">' . get_search_form(     
FALSE ) . '</li>';

return $items;
 add_filter( 'wp_nav_menu_items', 'fb_add_search_box', 10, 2 );

// Callback function to insert 'styleselect' into the $buttons array
function my_mce_buttons_2( $buttons ) {
array_unshift( $buttons, 'styleselect' );
return $buttons;
// Register our callback to the appropriate filter
add_filter('mce_buttons_2', 'my_mce_buttons_2');

// Callback function to filter the MCE settings
function my_mce_before_init_insert_formats( $init_array ) {  
// Define the style_formats array
$style_formats = array(  
    // Each array child is a format with it's own settings
        'title' => 'Image Text', 
        'block' => 'p',  
        'classes' => 'image-text',     
        'title' => 'Image Text no Overlay', 
        'block' => 'p',  
        'classes' => 'image-text-2',     
         'title' => 'w/ gray background', 
        'inline' => 'span',  
        'exact' => true,    
         'classes' => 'gray-background', 
         'title' => 'w/ white background', 
        'inline' => 'span',  
        'exact' => true,    
         'classes' => 'white-background', 
        'title' => 'Image Text no Indent', 
        'block' => 'p',  
        'classes' => 'image-text-3',     
         'title' => 'Button', 
        'inline' => 'a',  
        'exact' => true,    
         'classes' => 'button small', 
        'title' => 'Blog Image Caption', 
        'block' => 'p',  
        'classes' => 'caption',     
         'title' => 'Signature', 
        'inline' => 'span',  
        'exact' => true,    
         'classes' => 'sign', 
// Insert the array, JSON ENCODED, into 'style_formats'
$init_array['style_formats'] = json_encode( $style_formats );  

return $init_array;  

// Attach callback to 'tiny_mce_before_init' 
add_filter( 'tiny_mce_before_init', 'my_mce_before_init_insert_formats' );  
share|improve this question
Please show the code for functions.php; maybe the problem will be easily spotted. – Douglas.Sesar May 30 '14 at 2:57
I added it above! – Alicia May 30 '14 at 3:30
What is $query->set('portfolio', $post_name); used for? Maybe try to comment that out once – Douglas.Sesar May 30 '14 at 3:59
Are you using the same version of WordPress on your dev server and local machine? That could be the reason why it's working in one environment and not the other. – markcbain May 30 '14 at 5:34
1. Anything that calls 'portfolio' in this bit of code is attempting to rewrite the portfolio custom post type from a slug of /portfolio-item/ to none (so just domain.com/page-name). 2. Yeah, same version. However, I just had a thought! My local server (through MAMP) seems to be running PHP 5.5.3, whereas my host recently upgraded from PHP 5.3 (or something lower) to 5.4. Could that cause it? I can try reverting the PHP version, but I've never done this before and do not know if its just a matter of clicking the button or if I have to rebuild anything? – Alicia May 30 '14 at 14:47

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.