get_pages displays only parents instead of children

The problem here is twofold.

Firstly, you’re using 'parent' => $post->ID,. $post is a global variable, not a super global, so you have to state that you intend to use it before doing so with:

global $post;

But, as always, it’s easier to use the APIs than to go for the raw data, and you would be better off with:

'parent' => get_the_ID(),

Or even better, if we apply good coding practices, we get:

function display_child_pages( $post_id=0 ){
    ...
    'parent' => $post_id,

<?php display_child_pages( get_the_ID() ); ?>

Now the function declares clearly what it does, and can output the child pages of any page, not just the one we’re currently on. The function is also now significantly easier to write tests for thanks to the post_id argument.

Note that the above function should echo, not return the HTML, otherwise you end up encouraging early escaping and all the security issues that come with it.

Secondly, your query is doing exactly what you asked it to, but it’s more explicit than what you had in mind.

The query asks for all posts with the parent X, which in this case was 0 due to the error above. Child posts do not have that parent though, they have a different parent!

To get around this problem, you will need to recurse down the tree, running a query for each link to find its children, and a query for each child to find the grandchildren. parent only looks at the parent, it doesn’t go down multiple generations.

For example, “Parent 2” is not the parent of “Child 1a”. “Child 1” is the parent of “Child 1a”. This is why it wasn’t picked up by the query.

Additional Notes

  • Don’t use get_pages, use WP_Query instead and cut out the middle man, it’ll be a little faster, and all the parameters are the same
  • What happens if there are no children? There’s no check if get_pages actually found any pages
  • You use get_post_thumbnail_id but you never check if the page has a featured image, if there is no featured image it will be impossible to click the link or even see it!
  • What is this 'child_of' => $post->ID,? There is no child_of parameter, this looks like guesswork. Why guess when there’s a full list of all the supported options on the Codex under WP_Query?