Include pages by ID into front page


How can I call a specific page's content in the front page template of a Beans child theme?

I want to something like this in front-page.php:

add_action( 'beans_main_before_markup', 'mypage' );
  function mypage() {
      do_action( 'beans_content', 'pageID = 123' );
  }

beans_load_document();

so that in addition to whatever page I assign as the front page, it will aslo include the content of page 123.


Hi Jonathan and welcom to Beans Community!

I think what you are looking for is in this reply code snippet. Please let me know if this is not what your are looking for and I will gladly assist πŸ™‚

Happy coding,


That was Quick! Thank you Thierry. That almost did it. The title is the only thing that is not quite working.

this:

add_action( 'beans_main_after_markup', 'upholsterypage' );

function upholsterypage() {

    // Stop here if the post couldn't be fetched.
    if ( !$post = get_post( 23 ) )
        return;

    setup_postdata( $post );

    ?>
    <article class="uk-article uk-panel-box">
        <header>
            <h1 class="uk-article-title"><?php the_title(); ?></h1>
        </header>
        <div class="tm-article-content">
            <?php the_content(); ?>
        </div>
    </article>
    <?php

    wp_reset_postdata();

}

Returned with the proper PAGE content, but with the title of the first (Only) POST ("Hello World").

It's weird that the_content(); returns the content from the proper page but the_title(); returns the title of the Hello World post. OR If I assign a static front page, it returns the title of that page. For the moment, I have done this, which returns what I want, but I know it's not right:

add_action( 'beans_main_after_markup', 'upholsterypage' );

function upholsterypage() {

    // Stop here if the post couldn't be fetched.
    if ( !$post = get_post( 23 ) )
        return;

    setup_postdata( $post );

    ?>
    <article class="uk-article uk-panel-box">
        <header>
            <h1 class="uk-article-title">
              <?php 
                $id = 23; $p = get_page($id);
                echo apply_filters('the_title', $p->post_title); 
              ?>
            </h1>
        </header>
        <div class="tm-article-content">
            <?php the_content(); ?>
        </div>
    </article>
    <?php

    wp_reset_postdata();

}

Hi Jonathan,

Sorry, in this example you actually have to set the $post global as well which will fix the title issue etc. Find below the updated snippet:

add_action( 'beans_main_after_markup', 'upholsterypage' );

function upholsterypage() {

    global $post;

    // Stop here if the post couldn't be fetched.
    if ( !$get_post = get_post( 23 ) )
        return;

    // Setup post data.
    $post = $get_post;
    setup_postdata( $post );

    ?>
    <article class="uk-article uk-panel-box">
        <header>
            <h1 class="uk-article-title"><?php the_title(); ?></h1>
        </header>
        <div class="tm-article-content">
            <?php the_content(); ?>
        </div>
    </article>
    <?php

    wp_reset_postdata();

}

I have also updated the example on the other post previously mentioned.

Have fun,

PS: I removed previous unecessary replies and updated your code with the missing opening article markup πŸ™‚


That's awesome! Everything works perfecrtly now. I've got your update working now along with additional stuff. I used content.php for example code. So now I have this and it's working perfectly:

add_action( 'beans_main_after_markup', 'upholsterypage' );

function upholsterypage() {

    global $post;

    // Stop here if the post couldn't be fetched.
    if ( !$get_post = get_post( 23 ) )
        return;

    // Setup post data.
    $post = $get_post;
    setup_postdata( $post );

    $content_attributes = array(
    'class' => 'tm-content',
    'role' => 'section',
    'itemprop' => 'sectionEntityOfPage'
    );
    echo '<div class="tm-main uk-block machinepage"><div class="uk-container uk-container-center">';
    echo beans_open_markup( 'beans_content', 'section', $content_attributes );

    ?>
    <article class="uk-article uk-panel-box">
        <header>
            <h1 class="uk-article-title"><?php the_title(); ?></h1>
        </header>
        <div class="tm-article-content">
            <?php the_content(); ?>
        </div>
    </article>
    <?php
    echo beans_close_markup( 'beans_content', 'section' );
    echo '</div></div>';

    wp_reset_postdata();

}

Thank you so much for your help!


It is a pleasure πŸ™‚

If I may ask, why having tm-main again and why setting the_content markup using beans_open_markup and beans_close_markup? I just want to make sure I understand 100% correctly what you are trying to achieve and maybe help making the code the best it can. For example, would the code below fit your needs?

add_action( 'beans_main_after_markup', 'upholsterypage' );

function upholsterypage() {

    global $post;

    // Stop here if the post couldn't be fetched.
    if ( !$get_post = get_post( 23 ) )
        return;

    // Setup post data.
    $post = $get_post;
    setup_postdata( $post );

    ?>
    <section class="uk-block" role="section" itemprop="sectionEntityOfPage">
   <div class="uk-container uk-container-center">
      <article class="uk-article uk-panel-box">
         <header>
              <h1 class="uk-article-title"><?php the_title(); ?></h1>
         </header>
         <div class="tm-article-content">
              <?php the_content(); ?>
         </div>
      </article>
    </div>
  </section>
    <?php

    wp_reset_postdata();

}

Cheers,


I'll take a look at your suggestion, but my idea was only have to define the container once in CSS. I'm making a one-pager, using beans_main_after_markup functions several times for the home page. This way the surrounding html is identical for each, including the static front page, except for an additional class which I can use to assign backgrounds. So i End up with:

  • [header area with links to each section of this page]
  • [a hero banner]
  • [the assigned static fron page]
  • [a specific page's content that the client can easily find to edit]
  • [another specific page's content that the client can easily find to edit]
  • [another specific page's content that the client can easily find to edit]
  • [another specific page's content that the client can easily find to edit]
  • [footer area]

This means the client does not have to deal with widgets, though I did set it up to allow that as well for future-proofing.


Apologies for barging in, but would it not be more suitable to use custom fields? Perhaps I'm interpreting it not correctly, but I'm getting the idea that the client should be enabled to add his/her content not for one "traditional" content area, but multiple such sections, which to the front-end are displayed as a single page?

Also, @Thierry, I see

<div class="tm-article-content">
   <?php the_content(); ?>

and just prior

itemprop="sectionEntityOfPage"

I'd have expected the approach of articleBody, is there another approach to take with multiple content sections here (since we only get one articleBody, sadly)?


@j.C. Meijers,

Yes, you are probably right, however they want the exact simple interface they are familiar with. To them that means just the traditional content area. Nothing else.

Much of what seems obvious or intuitive to anyone used to working with WordPress, or indeed any CMS, is too much trouble to learn for someone who knows how to edit a simple WP page but is more used to working with machine shop tools.

This way, they go to the "page" they want to edit, edit the way they are used to, and don't affect any other section. It's more to do with familiarity than efficiency.


Hi Jonathan,

I completely understand what you are saying, that said it would be even less complicated with properly built admin fields which would avoid the client from going back and forth between pages. It is also our jobs to educate clients.

If it is more convenient for you and the client to use pages, then I would personally opt a more dynamic approach. For example, the client adds a parent page and all the children pages would represent the sections of the parent page (see here). Then in your child theme you would have a template file page.php which uses Beans loop to display the page as well as all its children. Your page.php whould look as such:

<?php

// Modify main loop.
add_filter( 'beans_loop_query_args', 'example_modify_posts_loop' );

function example_modify_posts_loop() {

  // Get current page and its children.
 $current = get_queried_object_id();
 $children = array_keys( get_children( array(
    'post_parent' => $current,
    'post_type' => 'page',
    'post_status' => 'publish',
   'orderby' => 'menu_order',
    'order' => 'ASC',
   'posts_per_page' => 10000
 ) ) );

  // WP_Query current page and its children.
  return array(
   'post_type' => 'page',
    'post__in' => array_merge( array( $current ), $children ),
    'orderby' => 'post__in',
    'posts_per_page' => 10000
 );

}

// Remove title link to avoid making the title clickable.
beans_remove_markup( 'beans_post_title_link' );

// Load document which is always needed at the bottom of template files.
beans_load_document();

See how we are grabing all children and adding it to the loop. From there we can start modifying the loop HTML according to your needs, for example changing the article markup to section, removing/adding classes etc. using Beans HTML API.

Let me know what you think and what would the ideal HTML be like πŸ˜‰


OK, now that looks like the way to go. I'll try it out and see if I can get it working for my purposes. That is cool!


Thank you Thierry. This worked out well. I do have a problem with scrollspy that still needs to be worked out - a matter of getting the code cleaned up rather than functionality, but I'll make another thread for that.

For this, I ended up using your child-page code in a front-page.php template so that single interior pages would still be possible. Using your code instead of my own first draft allowed me to remove unneed divs and still get full-width sections. I think I could have consolidated the remove_markup and replace_attribute lines but I must hhave made multiple syntax errors because I could not get that to work. Here is the template:

<?php
$id = get_the_ID();
// Remove the post title.
beans_remove_action( 'beans_post_title' );
beans_remove_markup( 'beans_fixed_wrap[_main]' );
beans_remove_markup( 'beans_main' );
beans_remove_markup( 'beans_main_grid' );
beans_modify_markup( 'beans_post', 'section' );
beans_replace_attribute( 'beans_post', 'class', 'uk-article', 'machinearticle'.$id );
beans_replace_attribute( 'beans_post', 'id', $id, 'machinesection'.$id );

// Modify main loop.
add_filter( 'beans_loop_query_args', 'add_children_posts_loop' );

function add_children_posts_loop() {
    // Get current page and its children.
    $current = get_queried_object_id();
    $children = array_keys( get_children( array(
        'post_parent' => $current,
        'post_type' => 'page',
        'post_status' => 'publish',
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'posts_per_page' => 10000
    ) ) );

    // WP_Query current page and its children.
    return array(
        'post_type' => 'page',
        'post__in' => array_merge( array( $current ), $children ),
        'orderby' => 'post__in',
        'posts_per_page' => 1000
    );

}

add_action( 'beans_post_prepend_markup', 'machine_post_wrap' );
  function machine_post_wrap() {
     echo '<article><div class="uk-container uk-container-center">';
  }
add_action( 'beans_post_append_markup', 'machine_end_post_wrap' );
  function machine_end_post_wrap() {
      echo '</div></article>';
  }

beans_load_document();

PS, I fully agree with you both. It would be better to do things in a better way and it's our job to educate the client. Unfortunatly, in this case the client has zero interest in being educated. Fortunatly, in most cases that is not true. I have had clients even go so far as reorganize thier entire business structucture due to education about how to organize and maintain their website. This has happened several times during a design phase, mostly over discussion about page and menu hierarchy and organization.


Hey Jonathan,

Great stuff πŸ™‚ Here is a little tip, Beans has functions to wrap markup and wrap inner markup instead of having to use prepend_markup and append_markup. Here is the code modifie using these two useful functions:

<?php

$id = get_the_ID();

// Modify markup.
beans_remove_markup( 'beans_fixed_wrap[_main]' );
beans_remove_markup( 'beans_main' );
beans_remove_markup( 'beans_main_grid' );

// Modify attribues.
beans_remove_action( 'beans_post_title' );
beans_remove_attribute( 'beans_post', 'class', 'uk-article' );

// Add markup.
beans_wrap_markup( 'beans_post', 'example_post_section', 'section', array(
  'id' => 'machinearticle'.$id, // Automatically escaped.
 'class' => 'machinearticle'.$id // Automatically escaped.
) );
beans_wrap_inner_markup( 'beans_post', 'example_post_container', 'div', array(
 'class' => 'uk-container uk-container-center'
) );

// Modify main loop.
add_filter( 'beans_loop_query_args', 'add_children_posts_loop' );

function add_children_posts_loop() {

    // Get current page and its children.
    $current = get_queried_object_id();
    $children = array_keys( get_children( array(
        'post_parent' => $current,
        'post_type' => 'page',
        'post_status' => 'publish',
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'posts_per_page' => 10000
    ) ) );

    // WP_Query current page and its children.
    return array(
        'post_type' => 'page',
        'post__in' => array_merge( array( $current ), $children ),
        'orderby' => 'post__in',
        'posts_per_page' => 1000
    );

}

// Load the document. Always Keep this at the bottom of the page template.
beans_load_document();

Note how it is wrapping the post with a section (with id and class) and wrapping the inner content with a div (with container class). Cool huh?

Have fun,

Code Reference:


Thanks you again. I was looking for exactly that (beans_wrap_markup) but missed it in the documentation.

Write a reply

Login or register to write a reply, it's free!