By Devport Team | Last updated: 2025-07-12 | 14 min read

How to Create Custom Page Templates in a Full-Site Editing Theme

Custom page templates have always been a cornerstone of WordPress theme development. With Full-Site Editing (FSE), creating these templates has become more intuitive and powerful than ever. Instead of writing PHP files with mixed logic and presentation, you now work with visual blocks and clean HTML markup.

This guide will walk you through everything you need to know about creating custom page templates in FSE themes, from understanding the new template hierarchy to building complex layouts for specific use cases.

Table of Contents

  1. Template Hierarchy in FSE
  2. Creating Templates via Site Editor
  3. Code-Based Template Creation
  4. Template Parts Strategy
  5. Conditional Template Logic
  6. Portfolio and Landing Page Examples

Template Hierarchy in FSE

Understanding the New Hierarchy

FSE maintains WordPress's traditional template hierarchy but implements it through HTML files instead of PHP. Understanding this hierarchy is crucial for creating templates that WordPress will automatically use for specific content.

Template Priority Order

Single Post View:
1. templates/single-{post-type}-{slug}.html
2. templates/single-{post-type}.html
3. templates/single.html
4. templates/singular.html
5. templates/index.html

Page View:
1. templates/page-{slug}.html
2. templates/page-{id}.html
3. templates/page.html
4. templates/singular.html
5. templates/index.html

Archive View:
1. templates/category-{slug}.html
2. templates/category-{id}.html
3. templates/category.html
4. templates/archive.html
5. templates/index.html

File Structure for Templates

block-theme/
├── templates/
│   ├── index.html           # Fallback template
│   ├── front-page.html      # Homepage
│   ├── single.html          # Single posts
│   ├── page.html            # Static pages
│   ├── archive.html         # Archive pages
│   ├── search.html          # Search results
│   ├── 404.html            # Error page
│   ├── single-product.html  # Custom post type
│   └── page-custom.html     # Custom page template
└── parts/
    ├── header.html
    ├── footer.html
    └── sidebar.html

Template Registration in theme.json

{
  "version": 2,
  "customTemplates": [
    {
      "name": "page-no-title",
      "title": "Page (No Title)",
      "postTypes": ["page"]
    },
    {
      "name": "page-sidebar",
      "title": "Page with Sidebar",
      "postTypes": ["page"]
    },
    {
      "name": "page-full-width",
      "title": "Full Width Page",
      "postTypes": ["page", "post"]
    },
    {
      "name": "portfolio-item",
      "title": "Portfolio Item",
      "postTypes": ["portfolio"]
    }
  ]
}

Creating Templates via Site Editor

Step-by-Step Visual Creation

1. Access the Site Editor

Navigate to Appearance → Editor or use the admin bar when viewing your site.

2. Navigate to Templates

Click on Templates in the navigation sidebar to view all available templates.

3. Create New Template

Click Add New and choose: - Template type (Page, Post, Archive, etc.) - Specific page/post to create template for - Or create a generic template

4. Design Your Template

Basic Page Template Structure:

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
    <!-- wp:post-title {"level":1} /-->
    <!-- wp:post-content {"layout":{"type":"constrained"}} /-->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Advanced Template Patterns

Hero Page Template

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:cover {"url":"featured-image","dimRatio":50,"minHeight":500,"align":"full"} -->
<div class="wp-block-cover alignfull" style="min-height:500px">
    <div class="wp-block-cover__inner-container">
        <!-- wp:post-title {"level":1,"textAlign":"center","style":{"color":{"text":"#ffffff"}}} /-->
    </div>
</div>
<!-- /wp:cover -->

<!-- wp:group {"style":{"spacing":{"padding":{"top":"4rem","bottom":"4rem"}}}} -->
<div class="wp-block-group" style="padding-top:4rem;padding-bottom:4rem">
    <!-- wp:post-content {"layout":{"type":"constrained"}} /-->
</div>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Two-Column Layout Template

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:columns {"align":"wide","style":{"spacing":{"margin":{"top":"4rem","bottom":"4rem"}}}} -->
<div class="wp-block-columns alignwide" style="margin-top:4rem;margin-bottom:4rem">
    <!-- wp:column {"width":"70%"} -->
    <div class="wp-block-column" style="flex-basis:70%">
        <!-- wp:post-title {"level":1} /-->
        <!-- wp:post-content /-->
    </div>
    <!-- /wp:column -->

    <!-- wp:column {"width":"30%"} -->
    <div class="wp-block-column" style="flex-basis:30%">
        <!-- wp:template-part {"slug":"sidebar"} /-->
    </div>
    <!-- /wp:column -->
</div>
<!-- /wp:columns -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Code-Based Template Creation

Creating Template Files Directly

Basic Template Structure

File: templates/page-landing.html

<!-- wp:template-part {"slug":"header-minimal","tagName":"header"} /-->

<!-- wp:group {"align":"full","layout":{"type":"default"}} -->
<div class="wp-block-group alignfull">
    <!-- wp:pattern {"slug":"theme-name/hero-section"} /-->

    <!-- wp:group {"style":{"spacing":{"padding":{"top":"0","bottom":"0"}}}} -->
    <div class="wp-block-group" style="padding-top:0;padding-bottom:0">
        <!-- wp:post-content {"layout":{"type":"constrained"}} /-->
    </div>
    <!-- /wp:group -->

    <!-- wp:pattern {"slug":"theme-name/cta-section"} /-->
</div>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer-minimal","tagName":"footer"} /-->

Dynamic Content Templates

Portfolio Grid Template

File: templates/archive-portfolio.html

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","style":{"spacing":{"padding":{"top":"4rem","bottom":"4rem"}}}} -->
<main class="wp-block-group" style="padding-top:4rem;padding-bottom:4rem">
    <!-- wp:group {"layout":{"type":"constrained"}} -->
    <div class="wp-block-group">
        <!-- wp:heading {"textAlign":"center","level":1} -->
        <h1 class="has-text-align-center">Our Portfolio</h1>
        <!-- /wp:heading -->

        <!-- wp:paragraph {"align":"center"} -->
        <p class="has-text-align-center">Explore our latest projects and creative work</p>
        <!-- /wp:paragraph -->
    </div>
    <!-- /wp:group -->

    <!-- wp:query {"queryId":1,"query":{"perPage":9,"postType":"portfolio","order":"desc","orderBy":"date"},"displayLayout":{"type":"flex","columns":3},"align":"wide"} -->
    <div class="wp-block-query alignwide">
        <!-- wp:post-template -->
            <!-- wp:group {"style":{"spacing":{"padding":"0"}},"className":"portfolio-item"} -->
            <div class="wp-block-group portfolio-item" style="padding:0">
                <!-- wp:post-featured-image {"isLink":true,"aspectRatio":"16/9"} /-->

                <!-- wp:group {"style":{"spacing":{"padding":"1rem"}}} -->
                <div class="wp-block-group" style="padding:1rem">
                    <!-- wp:post-title {"level":3,"isLink":true} /-->
                    <!-- wp:post-excerpt {"moreText":"View Project →"} /-->
                </div>
                <!-- /wp:group -->
            </div>
            <!-- /wp:group -->
        <!-- /wp:post-template -->

        <!-- wp:query-pagination {"layout":{"type":"flex","justifyContent":"center"}} -->
            <!-- wp:query-pagination-previous /-->
            <!-- wp:query-pagination-numbers /-->
            <!-- wp:query-pagination-next /-->
        <!-- /wp:query-pagination -->
    </div>
    <!-- /wp:query -->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Template with Custom Blocks

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main"} -->
<main class="wp-block-group">
    <!-- wp:acf/hero-block {
        "name": "acf/hero-block",
        "data": {
            "field_hero_title": "",
            "field_hero_subtitle": "",
            "_field_hero_title": "field_123456",
            "_field_hero_subtitle": "field_789012"
        }
    } /-->

    <!-- wp:post-content {"layout":{"type":"constrained"}} /-->

    <!-- wp:my-plugin/related-posts {
        "numberOfPosts": 3,
        "displayFeaturedImage": true
    } /-->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Template Parts Strategy

Creating Reusable Template Parts

Header Variations

File: parts/header-minimal.html

<!-- wp:group {"style":{"spacing":{"padding":{"top":"1rem","bottom":"1rem"}}},"backgroundColor":"white","className":"header-minimal"} -->
<div class="wp-block-group header-minimal has-white-background-color has-background" style="padding-top:1rem;padding-bottom:1rem">
    <!-- wp:group {"layout":{"type":"flex","justifyContent":"space-between"},"align":"wide"} -->
    <div class="wp-block-group alignwide">
        <!-- wp:site-logo {"width":120} /-->
        <!-- wp:navigation {"layout":{"type":"flex","justifyContent":"right"},"style":{"spacing":{"blockGap":"2rem"}}} /-->
    </div>
    <!-- /wp:group -->
</div>
<!-- /wp:group -->

File: parts/header-centered.html

<!-- wp:group {"style":{"spacing":{"padding":{"top":"2rem","bottom":"2rem"}}},"className":"header-centered"} -->
<div class="wp-block-group header-centered" style="padding-top:2rem;padding-bottom:2rem">
    <!-- wp:group {"layout":{"type":"constrained"}} -->
    <div class="wp-block-group">
        <!-- wp:site-logo {"width":150,"align":"center"} /-->
        <!-- wp:site-title {"textAlign":"center","style":{"spacing":{"margin":{"top":"1rem"}}}} /-->
        <!-- wp:site-tagline {"textAlign":"center"} /-->

        <!-- wp:navigation {"layout":{"type":"flex","justifyContent":"center"},"style":{"spacing":{"margin":{"top":"2rem"}}}} /-->
    </div>
    <!-- /wp:group -->
</div>
<!-- /wp:group -->

Conditional Template Parts

While FSE doesn't support PHP conditions directly, you can create variations:

Different Headers for Different Templates

In theme.json:

{
  "templateParts": [
    {
      "area": "header",
      "name": "header",
      "title": "Header Default"
    },
    {
      "area": "header",
      "name": "header-minimal",
      "title": "Header Minimal"
    },
    {
      "area": "header",
      "name": "header-transparent",
      "title": "Header Transparent"
    }
  ]
}

Then use specific headers in different templates:

<!-- For landing pages -->
<!-- wp:template-part {"slug":"header-minimal","tagName":"header"} /-->

<!-- For regular pages -->
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

Conditional Template Logic

Working Around PHP Limitations

Since FSE templates are HTML-based, traditional PHP conditionals aren't available. Here are strategies to achieve conditional behavior:

1. Query Block Conditions

<!-- Show content only if posts exist -->
<!-- wp:query {"query":{"perPage":1,"postType":"announcement"}} -->
<div class="wp-block-query">
    <!-- wp:post-template -->
        <!-- wp:group {"style":{"spacing":{"padding":"1rem"}},"backgroundColor":"accent"} -->
        <div class="wp-block-group has-accent-background-color has-background" style="padding:1rem">
            <!-- wp:heading {"level":4} -->
            <h4>Latest Announcement</h4>
            <!-- /wp:heading -->
            <!-- wp:post-title {"isLink":true} /-->
        </div>
        <!-- /wp:group -->
    <!-- /wp:post-template -->
</div>
<!-- /wp:query -->

2. Block Visibility Controls

Use plugins or block supports for conditional display:

<!-- wp:group {"metadata":{"showOnlyOn":"desktop"}} -->
<div class="wp-block-group">
    <!-- Desktop-only content -->
</div>
<!-- /wp:group -->

3. Custom Block Solutions

Create a custom block for complex conditions:

register_block_type('mytheme/conditional-content', array(
    'render_callback' => function($attributes) {
        if (is_user_logged_in()) {
            return $attributes['loggedInContent'];
        }
        return $attributes['loggedOutContent'];
    }
));

Portfolio and Landing Page Examples

Complete Portfolio Template

File: templates/single-portfolio.html

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","align":"full"} -->
<main class="wp-block-group alignfull">
    <!-- Hero Section with Featured Image -->
    <!-- wp:cover {"useFeaturedImage":true,"dimRatio":30,"minHeight":600,"align":"full"} -->
    <div class="wp-block-cover alignfull" style="min-height:600px">
        <div class="wp-block-cover__inner-container">
            <!-- wp:group {"layout":{"type":"constrained"}} -->
            <div class="wp-block-group">
                <!-- wp:post-title {"level":1,"textAlign":"center","style":{"color":{"text":"#ffffff"}}} /-->

                <!-- wp:group {"layout":{"type":"flex","justifyContent":"center"},"style":{"spacing":{"margin":{"top":"2rem"}}}} -->
                <div class="wp-block-group" style="margin-top:2rem">
                    <!-- wp:post-terms {"term":"portfolio-category","style":{"color":{"text":"#ffffff"}}} /-->
                </div>
                <!-- /wp:group -->
            </div>
            <!-- /wp:group -->
        </div>
    </div>
    <!-- /wp:cover -->

    <!-- Project Details -->
    <!-- wp:group {"style":{"spacing":{"padding":{"top":"4rem","bottom":"2rem"}}}} -->
    <div class="wp-block-group" style="padding-top:4rem;padding-bottom:2rem">
        <!-- wp:columns {"align":"wide"} -->
        <div class="wp-block-columns alignwide">
            <!-- wp:column {"width":"30%"} -->
            <div class="wp-block-column" style="flex-basis:30%">
                <!-- wp:heading {"level":3} -->
                <h3>Project Details</h3>
                <!-- /wp:heading -->

                <!-- wp:group {"className":"project-meta"} -->
                <div class="wp-block-group project-meta">
                    <!-- Custom fields would go here -->
                    <!-- Client, Date, Technologies, etc. -->
                </div>
                <!-- /wp:group -->
            </div>
            <!-- /wp:column -->

            <!-- wp:column {"width":"70%"} -->
            <div class="wp-block-column" style="flex-basis:70%">
                <!-- wp:post-content /-->
            </div>
            <!-- /wp:column -->
        </div>
        <!-- /wp:columns -->
    </div>
    <!-- /wp:group -->

    <!-- Related Projects -->
    <!-- wp:group {"style":{"spacing":{"padding":{"top":"4rem","bottom":"4rem"}}},"backgroundColor":"light-gray"} -->
    <div class="wp-block-group has-light-gray-background-color has-background" style="padding-top:4rem;padding-bottom:4rem">
        <!-- wp:heading {"textAlign":"center"} -->
        <h2 class="has-text-align-center">Related Projects</h2>
        <!-- /wp:heading -->

        <!-- wp:query {"queryId":2,"query":{"perPage":3,"postType":"portfolio","exclude":[0],"orderBy":"rand"}} -->
        <div class="wp-block-query">
            <!-- Query content here -->
        </div>
        <!-- /wp:query -->
    </div>
    <!-- /wp:group -->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Landing Page Template

File: templates/page-landing.html

<!-- wp:template-part {"slug":"header-transparent","tagName":"header","className":"site-header-transparent"} /-->

<!-- wp:group {"tagName":"main","align":"full","className":"landing-page"} -->
<main class="wp-block-group alignfull landing-page">
    <!-- Hero Section -->
    <!-- wp:pattern {"slug":"mytheme/hero-landing"} /-->

    <!-- Features Section -->
    <!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"5rem","bottom":"5rem"}}}} -->
    <div class="wp-block-group alignfull" style="padding-top:5rem;padding-bottom:5rem">
        <!-- wp:group {"layout":{"type":"constrained"}} -->
        <div class="wp-block-group">
            <!-- wp:heading {"textAlign":"center"} -->
            <h2 class="has-text-align-center">Why Choose Us</h2>
            <!-- /wp:heading -->

            <!-- wp:columns {"align":"wide","style":{"spacing":{"margin":{"top":"3rem"}}}} -->
            <div class="wp-block-columns alignwide" style="margin-top:3rem">
                <!-- Feature columns -->
            </div>
            <!-- /wp:columns -->
        </div>
        <!-- /wp:group -->
    </div>
    <!-- /wp:group -->

    <!-- Testimonials -->
    <!-- wp:pattern {"slug":"mytheme/testimonials-carousel"} /-->

    <!-- CTA Section -->
    <!-- wp:pattern {"slug":"mytheme/cta-download"} /-->

    <!-- Content Section -->
    <!-- wp:group {"style":{"spacing":{"padding":{"top":"4rem","bottom":"4rem"}}}} -->
    <div class="wp-block-group" style="padding-top:4rem;padding-bottom:4rem">
        <!-- wp:post-content {"layout":{"type":"constrained"}} /-->
    </div>
    <!-- /wp:group -->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer-minimal","tagName":"footer"} /-->

Best Practices for Custom Templates

1. Template Organization

templates/
├── Core Templates/
│   ├── index.html
│   ├── single.html
│   └── page.html
├── Custom Page Templates/
│   ├── page-no-title.html
│   ├── page-sidebar.html
│   └── page-landing.html
└── Post Type Templates/
    ├── single-portfolio.html
    └── archive-portfolio.html

2. Naming Conventions

3. Performance Optimization

<!-- Optimize images -->
<!-- wp:post-featured-image {"sizeSlug":"large","isLink":false} /-->

<!-- Lazy load content below fold -->
<!-- wp:group {"metadata":{"loading":"lazy"}} -->

<!-- Use constrained layouts -->
<!-- wp:post-content {"layout":{"type":"constrained"}} /-->

4. Accessibility Considerations

<!-- Proper heading hierarchy -->
<!-- wp:post-title {"level":1} /-->

<!-- Semantic HTML -->
<!-- wp:group {"tagName":"main"} -->
<!-- wp:group {"tagName":"article"} -->

<!-- Skip links in header -->
<!-- wp:skip-link {"target":"main"} /-->

Conclusion

Creating custom page templates in FSE represents a significant evolution in WordPress theme development. The visual approach combined with clean markup makes template creation more accessible while maintaining the flexibility developers need.

Key takeaways: - Understand the template hierarchy for automatic template selection - Use the Site Editor for quick visual template creation - Leverage template parts for reusable components - Create multiple template variations for different use cases - Optimize for performance and accessibility

As you become comfortable with FSE templates, you'll find that complex layouts that once required extensive PHP can now be created visually, making WordPress development faster and more enjoyable.


Want to learn more about modern WordPress development? Check out our comprehensive Ultimate Guide to Gutenberg and Full-Site Editing for advanced techniques and best practices.