0

I want to create a new selectable page template for users that will allow them to identify which pages on the site are "Service" pages (eg plumbing, gas fitting, etc). The template is an exact copy of page.php but includes some JSON LD (schema.org code) for "Service" pages on their website.

I really don't want a whole new servicepage.php file for this, that is just a carbon copy of page.php.

(How) Could I do this using only functions.php? Adding a new plugin is not currently an option.

4
  • "I want to create a new selectable page template" - it can be made selectable using the theme_page_templates hook, but I posted this as a comment because I don't get the "I really don't want a whole new servicepage.php file". Or that the hook I mentioned requires a template file.
    – Sally CJ
    Commented May 7, 2021 at 18:22
  • If servicepage.php is the same as page.php then there's no reason for it to be there as it will do exactly the same thing. If services are a custom post type then you should really create a template for that post type and keep all the content to a partial so that page.php and servicepage.php are minimal. single-POST_TYPE.php would be automatically used for any posts of that type so no need to manually select the template. Commented May 7, 2021 at 23:05
  • Hi Robert - I want to create a new page template that the user can select and when selected it will add some specific JSON LD (schema.org code). It is meant to the be the same as page.php, except with the added JSON. Does that make sense? I need some way for the user to indicate that it is a "Service" type page administratively...
    – Drewdavid
    Commented May 10, 2021 at 19:45
  • For now I decided to do it via a template php file and include page.php, as mentioned here: wordpress.org/support/topic/… but still interested to do it with a file-less solution if one presents itself that I can manage. =)
    – Drewdavid
    Commented May 10, 2021 at 22:04

1 Answer 1

1

Your previous question, Possible to create a "variant" page template that only contains differences and is therefore resilient to updates of original (ie page.php)?, provided nicely more context to this question.

As you Sally CJ noted in the comments you use theme_page_templates to add custom template to the template select list. To skip adding a separate file for the template, use template_include filter to select page.php as the actual template file. Target the template on the front end on template_redirect action with is_page_template() conditional to add data printing function to wp_head.

For example like this,

function my_service_template_slug() {
    return 'my-service-template.php';
}

function my_service_template_name() {
    return __( 'My Service Template', 'my-textdomain' );
}

// Add custom template to the template list
add_filter(
    'theme_page_templates',
    function( $page_templates, $theme, $post ){
        $page_templates[my_service_template_slug()] = my_service_template_name();
        return $page_templates;
    },
    11,
    3
);

// Use default page.php as servcie template
add_filter(
    'template_include',
    function( $template ) {
        return my_service_template_slug() === $template ? 'page.php' : $template;
    },
    11,
    1
);

// Add data to service template head
add_action(
    'template_redirect',
    function(){
        if ( is_page_template( my_service_template_slug() ) ) {
            add_action( 'wp_head', 'my_service_template_head_data');
        }
    }
);

function my_service_template_head_data() {
    // print something
}
4
  • Thanks Antti for answering my question! However I can't quite follow. My main point was that I was hoping to avoid needing a separate php file (ie, my-service-template.php)... if it is necessary, then I guess I can just add a template_include page.php + my custom JSON code and be done with it - without needing to involve function.php at all? I hope that made sense... thanks.
    – Drewdavid
    Commented May 10, 2021 at 19:50
  • @Drewdavid Yes, with the above code example you don't need to add a separate template file. But to make the "virtual" template appear in the template select list, you need to provide the related filter a file name even though the file doesn't exist in reality. This is what the first filter does in my example. Second filter is an explicit way of telling WP, which file to actually use for rendering the page when using the "virtual" template. I guess WP would figure this out by itself, based on template hierarchy, if doesn't find the custom template file, but I didn't double check this. Commented May 11, 2021 at 6:23
  • 1
    The template_redirect action is identifying pages using the "virtual" template so that you can add the required JSON LD only on those pages. The above code can be added to the functions.php file, to a custom plugin, or to one of those plugins that let you save php in the Dashboard. It just needs to go somewhere on your site to make it work. Commented May 11, 2021 at 6:26
  • 1
    Thanks Antti for your comments! I ended up using it as a simple plugin since I am including a couple data files so wanted a folder for them. So far it's working just perfectly and I'm learning something too haha. =)
    – Drewdavid
    Commented May 13, 2021 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.