paged > max_num_pages won't throw 404

I've created new page in WP administration called Blog and created custom page template for it. In the template, I have a simple paged custom query.

$query = new WP_Query(array( 'post_type' = 'post', 'posts_per_page' = 1, 
'paged' = $paged ));

Everything seems to look ok, except when I manually type bigger page number than is available after the '/page/' part of url. The page won't throw a 404 error but will render the page as normal without the custom loop. Is it normal behaviour? If so, how should I throw the 404 template page?

Also, I have one sub question:

Is it possible, to create custom theme page, without the need to create the page in the wordpress adminstration? In most cases I don't even use the content of the page and leave it empty. Then if someone will delete the page, or change the page slug, part of website can be broken.

Is there more fool proof and more administrator friendly solution?

PS: here is the full page-blog.php source code:

div id="primary" class="content-area"
    main id="main" class="site-main"

        h1?=get_theme_mod('crochelou-blog-main-headline') ?span class="sub-headline"?=get_theme_mod('crochelou-blog-sub-headline') ?/span/h1
        section id="page-container"
        nav id="blog-nav-wrapper"?php
            wp_nav_menu( array(
                'menu_id'        = 'category-menu',
                'menu' = 'category-menu'
            ) );
        ?/nav
            ?php

            $query = new WP_Query(array( 'post_type' = 'post', 'posts_per_page' = 1, 'paged' = $paged )); ?


            section id="main-blog-loop"?php
                if($paged  1){ ?
                    a href="?= get_pagenum_link($paged - 1) ?" class="pagination-arrow arrow left arrow-left prev"/a
                ?php }

                ?div class="wrapper articles"
                    ?php 
                    while($query-have_posts()): $query-the_post(); ?

                    article class="crochelou-card blog"
                        div class="blog image" style="background-image: url('?=esc_url(the_post_thumbnail_url('medium'))  ?')"/div
                        div class="categories"?php
                            $categories = get_the_category();
                             foreach($categories as $category){ 
                                 $name = $category-name;
                                 $link = get_category_link($category-term_id); ?
                                 a href="?= $link ?" class="catgory"?= $name ?/a
                            ?php
                             }
                        ?/div
                        span class="date"?= get_the_date('d') . '\\' . get_the_date('m') . '\\' . get_the_date('Y') ?/span
                        h4 class="headline blog"a href="?= get_the_permalink() ?"?= get_the_title() ?/a/h4
                        div class="perex excerpt"?php the_excerpt(); ?/div
                        a class="link read-more" href="?= get_the_permalink() ?" číst../a
                    /article



                    ?php endwhile;
                    ?
                /div?php
                if($paged  $query-max_num_pages){ ?
                    a href="?= get_pagenum_link($paged + 1) ?" class="pagination-arrow arrow right arrow-right right"/a
                ?php }

                ?
            /section



                ?php if($paged  $query-max_num_pages){  ?
                    div id="blog-pagination"
                        nav class="pagination"
                            ul
                                ?php 
                                for($i=1; $i = $query-max_num_pages; $i++){

                                    if($i === $paged){ ?

                                    span class="current"?= $i ??php if($i  $query-max_num_pages){ echo ','; } ?/span

                                    ?php }else{ ?

                                    a href="?= get_pagenum_link($i) ?"?= $i ??php if($i  $query-max_num_pages){ echo ','; } ?/a

                                    ?php }

                                }
                                ?
                            /ul
                        /nav
                    /div
               ?php     }       


            ?
            !-- THIS WILL JUST RENDER 'ABOUT ME' TEST FROM ADMINISTRATION --
            div class="separator"/div
            ?php $page = get_page_by_path( 'o-mne' ); ?
            article id="about"
                h3 class="title"?= $page-post_title ?/h3
                ?php 
                $content = $page-post_content;
                $content = apply_filters('the_content', $content);
                $content = str_replace(']]', ']]gt;', $content);
                ?
                div id="about-content"?= $content ?/div
            /article



        /section
    /main!-- #main --
/div!-- #primary --

Topic paged loop pagination 404-error theme-development Wordpress

Category Web


You won't get a 404 because WP can find the page, and it then delegates the request to the template file where you added your own logic.

You could build your own 404 handling in that file, but a better way is to use a the archive.php (or archive-post.php for just this post type) to render the output, and use the pre_get_posts action to manipulate the WP_Query that is used to find posts (customize page size). If you're doing it that way, you'll find that WP will trigger a 404 correctly if the requested page is greater than the last available page.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.