I realise Wordpress questions are hard to answer, given the plethora of plugins and complications out there.

We've been having some trouble on our Wordpress page where virtual pages will populate their submenu with all the pages that don't have an explicit parent(Parent: (no parent)).

I've isolated the offending code to this piece of code in the header:

<!-- Secondary Nav -->
<!-- Show Secondary Menu if the page is a child or has children -->
<?php global $post; $children = get_pages( array( 'child_of' => $post->ID ) );

    if ( is_page() && $post->post_parent  || count( $children ) > 0 ) : ?>

        <div class="row subnav">
            <div class="container">
                <div class="columns large-12">
                        <?php wp_list_pages( array('title_li'=>'','depth'=>1,'child_of'=>get_post_top_ancestor_id()) ); ?>

    <?php else : ?>
    <!--This is a parent page without children -->

    <?php endif; ?>

Research has indicated that virtual pages are usually made as a page with children, as opposed to a page without children.

How does Wordpress handle virtual pages with regards to page... childing? This bahaves as expected on normal pages, it gets a list of affiliated menu items.

I've seen the same behaviour on buddypress, and this is currently happening with coursepress.

I guess more importantly, is there a way to separate virtual pages from normal pages in this if statement so it doesn't generate submenus for them?

Here's a couple image examples:

Example slug designation

Course page

  • Hi, welcome to WPSE. I don't quite get the meaning of virtual page ... can you please explain this?
    – Jack Johansson
    May 19 '17 at 2:22
  • If I knew what a virtual page was in wordpress I wouldn't be asking this question. It's the best term I could find for a page that technically doesn't exist. Like... it's all code, you can't add it to the pages list and edit it there. I've added images to show what I'm talking about
    – Mugluck
    May 19 '17 at 2:54
  • If Frank's answer solved your problem in a better way, please consider marking his answer as accepted.
    – Jack Johansson
    May 19 '17 at 16:36
  • Frank's answer is trying to solve a different problem, not the one I asked. So I can't do that.
    – Mugluck
    May 22 '17 at 2:16
  • Anyway you wish sir. By the way if you haven't figured to solve the issue yet, you can ask a new more-accurate question based on the explanations in our answers, so we can help you out in a better way.
    – Jack Johansson
    May 22 '17 at 3:46

The WordPress, just like any other CMS, relies on generating content based on the user's request and then outputting it to the browser as an HTML page. What you asked can have a very long answer, but here is a simple explanation to what you asked.

We begin with the file named .htaccess, which is a server file. This is what is inside an .htaccess file ( that is generated by WordPress when you activate pretty permalinks):

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

The code simply tells the server to:

If the requested URL is not a file or directory, then send the request to index.php, which is the place when WordPress is told what to load and view.

When you are trying to access a post's content, for example by visiting http://example.com/my-category/my-first-post, WordPress checks the URL and notices that you have tried to access a single post's content. It then will try and generate the content for that particular page.

Every page in WordPress has it's own template, which is like a blank form that is going to be filled with data. For example, the template file for a single post, is called single.php and is located in the root of your templates directory. So, when you try to visit a post, the code inside that template part will be run.

To have a better understanding of templates hierarchy, take a look into the below picture:

WordPress template hierarchy

So, how do we target these pages? The first approach is to find the proper template file and directly edit it. This is not recommended as the template file may be overridden in the future by updates.

Another approach is to find the proper hook to change what we need to change. For example if you want to change the WordPress's title, you can hook into wp_title hook:

add_filter( 'wp_title', 'my_wp_title', 10, 2 );
function my_wp_title(){
    return 'Hello!';

This will set the title of your WordPress to Hello!. As i mentioned, your question is broad and the answer to it can be very long. If you exactly specify your problem, i can post a more accurate answer.

I hope this helped you out with understanding of how WordPress (or any other CMS) renders it's content.

  • 1
    Hmmm. I thought I had made a specific question. But now you make me realise it wasn't. Thank you for the answer, that does help. I'll research the hooks.
    – Mugluck
    May 19 '17 at 3:13
  • @Jack: your answer, as nice as it is, does not provide a solution, nor explanation, to the problem, which is clearly shown by pictures, added to his question. May 19 '17 at 7:19
  • @FrankP.Walentynowicz Unfortunately the images were added after i posted my answer, or didn't load for me, since i noticed the images now. I don't quite understand the terms such as virtual page, but if you do, please help him solve his issue.
    – Jack Johansson
    May 19 '17 at 15:58
  • @JackJohansson I think, virtual pages, he meant, are pages not listed in Pages -> All pages, like front page displaying all posts. The problem was, that he created a real page 'Courses' to display all courses, which is not needed, as CoursePress creates an archive container 'Courses' to display them. May 19 '17 at 16:11

Problem Explanation

The only problems are menu settings, and your menu structure. There is no need for any custom code, or searching for any 'hooks'. In last section, I'll explain why pages ( custom post types ), created by CoursePress plugin, are not being displayed in Pages -> All pages list.


Go to Appearance -> Menus and select your menu for editing. Deselect Automatically add new top-level pages to this menu box in Menu Settings -> Auto add pages option. This step is very important. If the box, mentioned above, is checked, every time you create a new course, its title will be added as top level menu item. Now, you can rearrange, by dragging and dropping menu items, your menu structure, to get something like that:

Courses ( Post Type Archive )
    ├─── Course 1 ( Course )
    ├─── Course 2 ( Course )
    └─── Course 3 ( Course )

Press Save Menu button. All done. The rest is being handled by CoursePress plugin.

Pages vs Custom Post Types

The 'course' is a custom post type, created by CoursePress plugin. This plugin creates a top level admin menu CoursePress and, as one of its sub menus, Courses. This is where you get a list of virtual pages ( as you call it ). They are not listed by Pages -> All pages, because their 'post_type' is not 'page' but 'course'.

  • Thanks for that advice, you outlined it well, though Auto adding pages to the menu is already off.This particular auto-add is via the submenu code in my post, which for some reason, on the 'courses' page, treats all the unParented pages as being its parents
    – Mugluck
    May 19 '17 at 7:19
  • @Mugluck: maybe, the box was checked when you started adding courses. The code from your question has nothing to do with courses being children or having children. The 'course' defined in CoursePress plugin is top level, it is not a child, nor it has any children. The comments, on top of the code provided, state it clearly. I've tested the plugin, and it dit not create any secondary menus. May 19 '17 at 7:46
  • @Mugluck: what is the source of this code? Sorry, I forgot to ask in my previous comment. May 19 '17 at 7:54
  • @Mugluck: Ok. I understand. You've created actual page 'Courses' to display your courses, created by CoursePress. Delete this page, because you don't need it. Now add 'Courses' from CoursePress group of items, to your menu. If you don't see it, click on 'View All' link in this group.Then, add all courses from the same group as children of just inserted 'Courses'. That's all. May 19 '17 at 8:56
  • Wow. This is an amazing amount of response Frank, completely didn't expect it when I punched out for the weekend. The source code I referenced above is a part of the custom theme the company I work for had built. It handles populating the submenus for their navigation which is separate from the core wordpress navigation. So solutions have to target that code, as the core wordpress navigation doesn't affect it. Like I said, I isolated the problem to there. It's necessary for normal site operation, so I can't remove it.
    – Mugluck
    May 22 '17 at 2:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.