0

I'm using the plugin homepage control in many projects and really like what it does. I can create custom sections for my static homepage and can sort them in the customizer. In my recent client project, I thought it would be a good idea to create this kind of sections according to the subpages of my homepage. -I totally failed. First I tried to use variable function names but I wasn't able to access the functions with add_action. Then I tried to use an anonymous function within the add_action call, but now I'm not able to pass my content variables into it.

Maybe my whole approach is going the wrong direction, has someone a hint or better solution for me?

Thanks in advance.

if ( ! function_exists( 'homepage_content' )  ) {
    function homepage_content() {

        $the_id = 5;
        $item = get_post( $the_id );

        $page_tree_array = get_pages( array(
            'child_of' => $the_id
        ) );

        foreach( $page_tree_array as $item ) {

            $id = $item->ID;
            $slug = $item->post_name;
            $title = apply_filters( 'the_title', $item->post_title );
            $content = apply_filters( 'the_content', $item->post_content );

            $function_name = 'homepage_section_' . $slug;

            add_action( 'homepage', function() {
                ?>
                <article id="post-<?php echo $id; ?>" <?php post_class( 'homepage-content' ); ?>>

                    <h1><?php echo $title; ?></h1>
                    <?php echo $content; ?>

                </article>

                <?php
            }, 60 );

        }

    }
}

1 Answer 1

1

The use of add_action() seems backwards to me. A better approach would be to hook homepage_content() into the homepage hook and then just output each section within the one hook:

function homepage_content() {
    $the_id = 5;
    $item = get_post( $the_id );

    $page_tree_array = get_pages( array(
        'child_of' => $the_id
    ) );

    foreach( $page_tree_array as $item ) {
        $id = $item->ID;
        $slug = $item->post_name;
        $title = apply_filters( 'the_title', $item->post_title );
        $content = apply_filters( 'the_content', $item->post_content );
        ?>

        <article id="post-<?php echo $id; ?>" <?php post_class( 'homepage-content' ); ?>>
            <h1><?php echo $title; ?></h1>
            <?php echo $content; ?>
        </article>

        <?php
    }
}
add_action( 'homepage', 'homepage_content' );

There's some other changes you could make that would help too, but I left out to focus on the use of add_action():

  • Get the homepage ID dynamically with get_option( 'page_on_front' ).
  • Setting $item to the get_post() value for the ID seems unnecessary, since you never use it.
  • Use setup_postdata() for each section so that you can use template tags like the_title() and the_content().
  • Using setup_postdata() also means you could put the homepage section template into a separate file and call it with get_template_part().

Taking all that into account and your homepage_content() function would look like this:

function homepage_content() {
    global $post;

    $child_pages = get_pages( array(
        'child_of' => get_option( 'page_on_front' ),
    ) );

    foreach ( $child_pages as $post ) {
        setup_postdata( $post );
        get_template_part( 'partials/homepage-content' );
    }

    wp_reset_postdata();
}
add_action( 'homepage', 'homepage_content' );

Then create partials/homepage-content.php as the template for each section. Since setup_postdata() was used you can use the proper template tags:

<article id="post-<?php the_ID(); ?>" <?php post_class( 'homepage-content' ); ?>>
    <h1><?php the_title(); ?></h1>
    <?php the_content(); ?>
</article>
2
  • Hello @JacobPeattie, thank you for this. There is a lot of enhancement in your comment, especially using setup_postdata and get_template_part. This will indeed work like a charm, unfortunately, I'll lose the possibility to order each part via the plugin 'homepage controll'. But if there's no possibility to use add_action from inside the foreach, I'm pretty sure I can handle the displayed order by WordPress' page order functionality.
    – chrisbergr
    Commented May 7, 2018 at 18:59
  • Yes, adding 'sort_column' => 'menu_order' to the settings array for get_pages gives me the desired order. I think I can accept this as the correct answer :)
    – chrisbergr
    Commented May 7, 2018 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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