I'm working on a new content type. Let's call it hotel rooms (it is not but the similarities are good enough).
Now, for each room, I will have a title and a description but I will also have a lot of metadata - beds, sea view, room number, size, summer price, winter price, and so on.
I would like my custom type to work on any theme. That means I need to provide a way to layout the post for index.php
, single.php
, and so forth. Obviously, presenting metadata is a large part of this.
How do I do this?
I'm working on a new content type. Let's call it hotel rooms (it is not but the similarities are good enough).
Now, for each room, I will have a title and a description but I will also have a lot of metadata - beds, sea view, room number, size, summer price, winter price, and so on.
I would like my custom type to work on any theme. That means I need to provide a way to layout the post for index.php
, single.php
, and so forth. Obviously, presenting metadata is a large part of this.
How do I do this?
Share Improve this question asked Jan 15, 2020 at 16:55 Matthew Brown aka Lord MattMatthew Brown aka Lord Matt 1,0683 gold badges13 silver badges34 bronze badges2 Answers
Reset to default 2I assume that you're making your custom post type in a plugin if you mean for it to work with any theme.
In that case, I would suggest building your templates in your plugin, and call all your meta data there.
Example:
/* Filter the single_template with our custom function*/
add_filter('single_template', 'my_custom_template');
function my_custom_template($single) {
global $post;
/* Checks for single template by post type */
if ( $post->post_type == 'POST TYPE NAME' ) {
if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
return PLUGIN_PATH . '/Custom_File.php';
}
}
return $single;
}
You can refine that further and add a function to check to see if the theme has single-yourposttype.php and to use that one if it exists instead of your plugin version, allowing for easy overrides by developers. Example:
$themeurl = get_theme_file_path("/single-yourposttype.php");
$pluginurl = plugin_dir_path( dirname( __FILE__ ) ) . 'single-yourposttype.php';
if( file_exists( $themeurl ) ) {
include( $themeurl );
} elseif( file_exists( $pluginurl ) ) {
require "$pluginurl";
}
I hope that helps.
I'd suggest to not add layout, but MarkUp and offer an option to override it. The best way to do this would be to add to a hook that your users can add to their themes templates.
// Theme template file
do_action( 'hotel_rooms' );
// Your plugin hooks in there:
add_action( 'hotel_rooms', 'callback' );
function callback() {
echo "I am displaying details about a hotel room";
}
You could also make this a two step process to offer more refined control:
// Themes template or another (child?) plugin
// [] is an array and the default.
$data = add_filter( 'hotel_room_data', [] );
// Plugin
apply_filters( 'hotel_room_data', …etc. );
Two stepped: Eat your own dog food and apply the filter to your own loops and MarkUp as well.
add_action( 'hotel_rooms', 'callback' );
function callback() {
$data = apply_filters( 'hotel_room_data', …etc. );
foreach ( $data as $room ) {
print $room['size'];
}
}