@@ -45,7 +45,9 @@ function gutenberg_maintain_templates_routes() {
4545 // templates controller, so we need to check if the id is an
4646 // integer to make sure it's the proper post type endpoint.
4747 if ( ! is_int ( $ post_arr ['id ' ] ) ) {
48- return null ;
48+ // See _build_block_template_result_from_file, registered
49+ // templates always set the theme to the active theme.
50+ return get_stylesheet ();
4951 }
5052 $ terms = get_the_terms ( $ post_arr ['id ' ], 'wp_theme ' );
5153 if ( is_wp_error ( $ terms ) || empty ( $ terms ) ) {
@@ -524,3 +526,270 @@ function gutenberg_migrate_existing_templates() {
524526
525527 update_option ( 'active_templates ' , $ active_templates );
526528}
529+
530+ add_action ( 'save_post_wp_template ' , 'gutenberg_maybe_update_active_templates ' );
531+ function gutenberg_maybe_update_active_templates ( $ post_id ) {
532+ $ post = get_post ( $ post_id );
533+ $ is_inactive_by_default = get_post_meta ( $ post_id , 'is_inactive_by_default ' , true );
534+ if ( $ is_inactive_by_default ) {
535+ return ;
536+ }
537+ $ active_templates = get_option ( 'active_templates ' , array () );
538+ $ active_templates [ $ post ->post_name ] = $ post ->ID ;
539+ update_option ( 'active_templates ' , $ active_templates );
540+ }
541+
542+ add_action ( 'pre_get_block_template ' , 'gutenberg_get_block_template ' , 10 , 3 );
543+
544+ ///////////////////////////////////////////////////////////////////////
545+ // This function is a copy of core's, except for the marked section. //
546+ ///////////////////////////////////////////////////////////////////////
547+ function gutenberg_get_block_template ( $ output , $ id , $ template_type ) {
548+ if ( 'wp_template ' !== $ template_type ) {
549+ return $ output ;
550+ }
551+ $ parts = explode ( '// ' , $ id , 2 );
552+ if ( count ( $ parts ) < 2 ) {
553+ return null ;
554+ }
555+ list ( $ theme , $ slug ) = $ parts ;
556+
557+ //////////////////////////////
558+ // START CORE MODIFICATIONS //
559+ //////////////////////////////
560+ $ active_templates = get_option ( 'active_templates ' , array () );
561+
562+ if ( ! empty ( $ active_templates [ $ slug ] ) ) {
563+ if ( is_int ( $ active_templates [ $ slug ] ) ) {
564+ $ post = get_post ( $ active_templates [ $ slug ] );
565+ if ( $ post && 'publish ' === $ post ->post_status ) {
566+ $ template = _build_block_template_result_from_post ( $ post );
567+
568+ if ( ! is_wp_error ( $ template ) && $ theme === $ template ->theme ) {
569+ return $ template ;
570+ }
571+ }
572+ } elseif ( false === $ active_templates [ $ slug ] ) {
573+ return null ;
574+ }
575+ }
576+ ////////////////////////////
577+ // END CORE MODIFICATIONS //
578+ ////////////////////////////
579+
580+ $ wp_query_args = array (
581+ 'post_name__in ' => array ( $ slug ),
582+ 'post_type ' => $ template_type ,
583+ 'post_status ' => array ( 'auto-draft ' , 'draft ' , 'publish ' , 'trash ' ),
584+ 'posts_per_page ' => 1 ,
585+ 'no_found_rows ' => true ,
586+ 'tax_query ' => array (
587+ array (
588+ 'taxonomy ' => 'wp_theme ' ,
589+ 'field ' => 'name ' ,
590+ 'terms ' => $ theme ,
591+ ),
592+ ),
593+ );
594+ $ template_query = new WP_Query ( $ wp_query_args );
595+ $ posts = $ template_query ->posts ;
596+
597+ if ( count ( $ posts ) > 0 ) {
598+ $ template = _build_block_template_result_from_post ( $ posts [0 ] );
599+
600+ //////////////////////////////
601+ // START CORE MODIFICATIONS //
602+ //////////////////////////////
603+ // Custom templates don't need to be activated, so if it's a custom
604+ // template, return it.
605+ if ( ! is_wp_error ( $ template ) && $ template ->is_custom ) {
606+ return $ template ;
607+ }
608+ ////////////////////////////
609+ // END CORE MODIFICATIONS //
610+ ////////////////////////////
611+ }
612+
613+ $ block_template = get_block_file_template ( $ id , $ template_type );
614+
615+ /**
616+ * Filters the queried block template object after it's been fetched.
617+ *
618+ * @since 5.9.0
619+ *
620+ * @param WP_Block_Template|null $block_template The found block template, or null if there isn't one.
621+ * @param string $id Template unique identifier (example: 'theme_slug//template_slug').
622+ * @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
623+ */
624+ return apply_filters ( 'get_block_template ' , $ block_template , $ id , $ template_type );
625+ }
626+
627+ add_action ( 'pre_get_block_templates ' , 'gutenberg_get_block_templates ' , 10 , 3 );
628+
629+ ///////////////////////////////////////////////////////////////////////
630+ // This function is a copy of core's, except for the marked section. //
631+ ///////////////////////////////////////////////////////////////////////
632+ function gutenberg_get_block_templates ( $ output , $ query = array (), $ template_type = 'wp_template ' ) {
633+ if ( 'wp_template ' !== $ template_type ) {
634+ return $ output ;
635+ }
636+
637+ $ post_type = isset ( $ query ['post_type ' ] ) ? $ query ['post_type ' ] : '' ;
638+ $ wp_query_args = array (
639+ 'post_status ' => array ( 'auto-draft ' , 'draft ' , 'publish ' ),
640+ 'post_type ' => $ template_type ,
641+ 'posts_per_page ' => -1 ,
642+ 'no_found_rows ' => true ,
643+ 'lazy_load_term_meta ' => false ,
644+ 'tax_query ' => array (
645+ array (
646+ 'taxonomy ' => 'wp_theme ' ,
647+ 'field ' => 'name ' ,
648+ 'terms ' => get_stylesheet (),
649+ ),
650+ ),
651+ );
652+
653+ if ( ! empty ( $ query ['slug__in ' ] ) ) {
654+ $ wp_query_args ['post_name__in ' ] = $ query ['slug__in ' ];
655+ $ wp_query_args ['posts_per_page ' ] = count ( array_unique ( $ query ['slug__in ' ] ) );
656+ }
657+
658+ // This is only needed for the regular templates/template parts post type listing and editor.
659+ if ( isset ( $ query ['wp_id ' ] ) ) {
660+ $ wp_query_args ['p ' ] = $ query ['wp_id ' ];
661+ } else {
662+ $ wp_query_args ['post_status ' ] = 'publish ' ;
663+ }
664+
665+ //////////////////////////////
666+ // START CORE MODIFICATIONS //
667+ //////////////////////////////
668+ $ active_templates = get_option ( 'active_templates ' , array () );
669+ ////////////////////////////
670+ // END CORE MODIFICATIONS //
671+ ////////////////////////////
672+
673+ $ template_query = new WP_Query ( $ wp_query_args );
674+ $ query_result = array ();
675+ foreach ( $ template_query ->posts as $ post ) {
676+ $ template = _build_block_template_result_from_post ( $ post );
677+
678+ if ( is_wp_error ( $ template ) ) {
679+ continue ;
680+ }
681+
682+ if ( $ post_type && ! $ template ->is_custom ) {
683+ continue ;
684+ }
685+
686+ if (
687+ $ post_type &&
688+ isset ( $ template ->post_types ) &&
689+ ! in_array ( $ post_type , $ template ->post_types , true )
690+ ) {
691+ continue ;
692+ }
693+
694+ //////////////////////////////
695+ // START CORE MODIFICATIONS //
696+ //////////////////////////////
697+ if ( $ template ->is_custom || isset ( $ query ['wp_id ' ] ) ) {
698+ // Custom templates don't need to be activated, leave them be.
699+ // Also don't filter out templates when querying by wp_id.
700+ $ query_result [] = $ template ;
701+ } elseif ( isset ( $ active_templates [ $ template ->slug ] ) && $ active_templates [ $ template ->slug ] === $ post ->ID ) {
702+ // Only include active templates.
703+ $ query_result [] = $ template ;
704+ }
705+ ////////////////////////////
706+ // END CORE MODIFICATIONS //
707+ ////////////////////////////
708+ }
709+
710+ if ( ! isset ( $ query ['wp_id ' ] ) ) {
711+ /*
712+ * If the query has found some user templates, those have priority
713+ * over the theme-provided ones, so we skip querying and building them.
714+ */
715+ $ query ['slug__not_in ' ] = wp_list_pluck ( $ query_result , 'slug ' );
716+ /*
717+ * We need to unset the post_type query param because some templates
718+ * would be excluded otherwise, like `page.html` when looking for
719+ * `page` templates. We need all templates so we can exclude duplicates
720+ * from plugin-registered templates.
721+ * See: https://github.com/WordPress/gutenberg/issues/65584
722+ */
723+ $ template_files_query = $ query ;
724+ unset( $ template_files_query ['post_type ' ] );
725+ $ template_files = _get_block_templates_files ( $ template_type , $ template_files_query );
726+ foreach ( $ template_files as $ template_file ) {
727+ // If the query doesn't specify a post type, or it does and the template matches the post type, add it.
728+ if (
729+ ! isset ( $ query ['post_type ' ] ) ||
730+ (
731+ isset ( $ template_file ['postTypes ' ] ) &&
732+ in_array ( $ query ['post_type ' ], $ template_file ['postTypes ' ], true )
733+ )
734+ ) {
735+ $ query_result [] = _build_block_template_result_from_file ( $ template_file , $ template_type );
736+ } elseif ( ! isset ( $ template_file ['postTypes ' ] ) ) {
737+ // The custom templates with no associated post types are available for all post types as long
738+ // as they are not default templates.
739+ $ candidate = _build_block_template_result_from_file ( $ template_file , $ template_type );
740+ $ default_template_types = get_default_block_template_types ();
741+ if ( ! isset ( $ default_template_types [ $ candidate ->slug ] ) ) {
742+ $ query_result [] = $ candidate ;
743+ }
744+ }
745+ }
746+
747+ if ( 'wp_template ' === $ template_type ) {
748+ // Add templates registered in the template registry. Filtering out the ones which have a theme file.
749+ $ registered_templates = WP_Block_Templates_Registry::get_instance ()->get_by_query ( $ query );
750+ $ matching_registered_templates = array_filter (
751+ $ registered_templates ,
752+ function ( $ registered_template ) use ( $ template_files ) {
753+ foreach ( $ template_files as $ template_file ) {
754+ if ( $ template_file ['slug ' ] === $ registered_template ->slug ) {
755+ return false ;
756+ }
757+ }
758+ return true ;
759+ }
760+ );
761+
762+ $ matching_registered_templates = array_map (
763+ function ( $ template ) {
764+ $ template ->content = apply_block_hooks_to_content (
765+ $ template ->content ,
766+ $ template ,
767+ 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata '
768+ );
769+ return $ template ;
770+ },
771+ $ matching_registered_templates
772+ );
773+
774+ $ query_result = array_merge ( $ query_result , $ matching_registered_templates );
775+ }
776+ }
777+
778+ /**
779+ * Filters the array of queried block templates array after they've been fetched.
780+ *
781+ * @since 5.9.0
782+ *
783+ * @param WP_Block_Template[] $query_result Array of found block templates.
784+ * @param array $query {
785+ * Arguments to retrieve templates. All arguments are optional.
786+ *
787+ * @type string[] $slug__in List of slugs to include.
788+ * @type int $wp_id Post ID of customized template.
789+ * @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only).
790+ * @type string $post_type Post type to get the templates for.
791+ * }
792+ * @param string $template_type wp_template or wp_template_part.
793+ */
794+ return apply_filters ( 'get_block_templates ' , $ query_result , $ query , $ template_type );
795+ }
0 commit comments