WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.46k stars 4.18k forks source link

wp_insert_post( $args ) #17200

Open DietteJanssen opened 5 years ago

DietteJanssen commented 5 years ago

i have searched through the issues/related issues and i have been unable to find a solution... i need to include the gutenberg registered template when creating a new post programmatically.

i have registered a custom post type "credits" via php which includes the following arguments:

'show_in_rest'          => true, 
'rest_base'             => 'credits', 
'rest_controller_class' => 'WP_REST_Posts_Controller', 
'template' => array(
    array( 'core/image', array(
        'align' => 'left',
    ) ),
    array( 'core/heading', array(
        'placeholder' => 'Add Author...',
    ) ),
    array( 'core/paragraph', array(
        'placeholder' => 'Add Description...',
    ) ),
),

i am unable to programmatically add a new post which includes the gutenberg "template" array.

i have been able to output the following:

$post_content = '<!-- wp:paragraph --><p>Completed: '.$data['course']->post_title.'</p><!-- /wp:paragraph -->';

$my_post = array(
    'post_type'     => 'credits',
    'post_title'        => 'Course Completed',
    'post_content'      => $post_content,
    'post_status'       => 'publish',
    'meta_input'    => array(
        'credits_user_id' => $user_id,
        'credits_number_of_credits' => $course_points,
        'credits_approved' => true, 
    ),

wp_insert_post( $my_post );

... which pulls in the gutenberg paragraph block successfully (rather than pulling it into the "classic" editor). however, i need it to pull in the template of blocks the same way it does when adding a new post from the wordpress backend.

for context, using php i have hooked into learndash:

defined( 'ABSPATH' ) || exit;

if ( !class_exists( 'LearndashCourseCompletion' ) ) {

    class LearndashCourseCompletion {

        public function __construct() {

            /* functions
            -------------------------------------------------------------*/
            // register
            add_action( 'learndash_course_completed', array( $this, 'dj_learndash_course_completed' ));
        }

        public function dj_learndash_course_completed( $data ) {

            $user_id = $data['user']->data->ID;

            $course_id = $data['course']->ID; 
            $course_points = '';
            $args = array(
                'post_type' => 'sfwd-courses',
                'p'         => $course_id,
            );
            $loop = new WP_Query($args);

            if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();

                $course_points = get_post_meta( get_the_ID(), 'course_points', true );

                // Check if the custom field has a value.
                if ( ! empty( $course_points ) ) {

                    $post_content = '<!-- wp:paragraph --><p>Completed: '.$data['course']->post_title.'</p><!-- /wp:paragraph -->';

                    // Create post object

                    $my_post = array(
                        'post_type'     => 'credits',
                        'post_title'        => 'Course Completed',
                        'post_content'      => $post_content,
                        'post_status'       => 'publish',
                        'meta_input'    => array(
                            'credits_user_id' => $user_id,
                            'credits_number_of_credits' => $course_points,
                            'credits_approved' => true, 
                        ),
                    );

                    // Insert the post into the database
                    wp_insert_post( $my_post );
                }

            endwhile; else: 
            endif; 
            wp_reset_postdata(); 

        } // end function

    } // end class  
}

new LearndashCourseCompletion();   

... i need to find a solution to achieve this, even if it requires using a different method ( other than wp_insert_post ) to achieve the desired result. any help or direction would be appreciated.

linusx commented 4 years ago

+1

akaufman3 commented 4 years ago

+1

mwilliamson-creedinteractive commented 4 years ago

+1

bratvanov commented 4 years ago

+1

niklaspollonen commented 4 years ago

+1

chvillanuevap commented 4 years ago

+1

omarkasem commented 3 years ago

+1

omarkasem commented 3 years ago

Here's a dirty workaround that worked with my case. You create a page template and put your default template blocks in it. Then you do that

$query = new WP_Query(array(
        'meta_key' => '_wp_page_template',
        'meta_value' => 'template-defalut.php',
        'post_type' => 'page',
        'fields'=>'ids',
    ));
    $posts = $query->posts;
    if(empty($posts)){return;}
    $content = get_post_field('post_content', $posts[0]);
    wp_update_post(array(
      'ID'=>478,
      'post_content'=>$content
    ));

For me it worked as I wanted to publish many posts at once with a certain template blocks, I hope that would help until this feature is applied.

lunule commented 1 year ago

I didn't test it with core blocks, but the below method works fine with ACF blocks (so I would think it does with core stuff as well).

1. Post type registration

function cpt_mac_submenus() {

    $labels = array( //... );
    $args   = array(
        // ...
        'template' => array(
            array( 'acf/submenus--title-and-description', array(
                'lock' => array(
                    'move'   => true,
                    'remove' => true,
                ),
            ) ),
            array( 'acf/submenus--output-navigation', array(
                'lock' => array(
                    'move'   => true,
                    'remove' => true,
                ),
            ) ),
            array( 'acf/submenus--single-image', array(
                'lock' => array(
                    'move'   => true,
                    'remove' => true,
                ),
            ) ),
        ),
        'template_lock' => 'all',
    );

    register_post_type( 'mac-submenus', $args );

}
add_action( 'init', 'cpt_mac_submenus' );

2. Insert (custom post type) post with default content

$content = '<!-- wp:acf/submenus--title-and-description /--><!-- wp:acf/submenus--output-navigation /--><!-- wp:acf/submenus--single-image /-->';

$new_submenu_post_args_Arr = array(
    'post_title'    => $title,
    'post_type'     => 'mac-submenus',
    'post_status'   => 'draft',
    'post_author'   => 1,
    'post_content'  => $content,
);

wp_insert_post( $new_submenu_post_args_Arr );   

Basically, the $content variable should be set up with "blank" blocks, no content, no configuration, just the skeleton - as a result, the output is 100% the same thing configured in the register_post_type() arguments array.

chrillep commented 1 year ago

i believe wp_insert_post needs to be extended to have knowledge of the template. This is something the wp core team should do.

https://developer.wordpress.org/reference/functions/wp_insert_post/ the wp_insert_post has arg for page_template but this is not the same as a gutenberg template.

so either use the registered gutenberg template, if no content is inserted or add means to merge data with the blocks inside the gutenberg template :)

ref: