Reputation: 847
A while ago i started a new Wordpress project. But i got into an issue. Since there are multiple designs i need to create multiple templates for pages, posts and text format outputs for on the different page-templates.
So since the're are so many template files i wanted to create some subdirectory's. i know that since Wordpress 3.4 and higher you're able to use the subdirectory name page-templates
for all the page templates but how could i use that for the format files and for the post files.
Yes i did try to add functions like:
get_template_part('/template-parts/page-templates' , 'page');
And
require( get_template_directory() . '/template-parts/template-tags.php' );
The ideal directory structure i would like to create is as follows:
wp-content/themes/mytheme
- archive
- 404
- CSS
- JS
- Images
- template-parts (dir)
-- page-templates (dir for page-template files.)
-- format-templates (dir for format-templates.)
-- post-templates (dir for post-templates.)
- header
- footer
So to be clear. I want to create the structure for template files like above. Don't mind the folders like CSS
etc. Those are set the correct way. The intention is, after i've succesfully created the structure, to be able to select the templates like a page temple from the /wp-admin
edit page section.
Upvotes: 10
Views: 6571
Reputation: 1588
wrapping up the accepted answer in a working piece of code :
<?php
/* Pages templates in sub folders */
/* --------------------------------------------------------------------------------- */
add_filter('theme_page_templates', function($post_templates) {
$directories = glob(get_template_directory() . '/pages/*' , GLOB_ONLYDIR);
foreach ($directories as $dir) {
$templates = glob($dir.'/*.php');
foreach ($templates as $template) {
if (preg_match('|Template'.' '.'Name: (.*)$|mi', file_get_contents($template), $name)) {
$post_templates['/pages/'.basename($dir).'/'.basename($template)] = $name[1];
}
}
}
return $post_templates;
});
This could be enhanced with a recursive function, for now it only adds :
./pages/\*/\*.php
Upvotes: 0
Reputation: 86
I know this is an old question that already has an answer but it wasn't the solution I was looking for. Adding another option in case anyone else is searching for a way to move all WordPress template files to a subfolder. Found this code for changing the default folder for WordPress template files on Reddit and made a few small adjustments. This code can be placed in the functions.php of your theme or child theme.
/**
* Tell WordPress that we have moved default template files to the page-templates folder.
* Based on code from: https://www.reddit.com/r/Wordpress/comments/ffhjvw/moving_wordpress_theme_template_files_to/
*
* Related posts with other solutions:
* https://stackoverflow.com/questions/60589503/moving-wordpress-theme-template-files-to-subdirectory
* https://wordpress.stackexchange.com/questions/17385/custom-post-type-templates-from-plugin-folder
* https://wordpress.stackexchange.com/questions/291725/store-page-template-files-in-a-subfolder
* https://wordpress.stackexchange.com/questions/312159/how-to-move-page-template-files-like-page-slug-php-to-a-sub-directory/312611#312611
*
* Template hierarchy info:
* https://developer.wordpress.org/reference/hooks/type_template_hierarchy/
* https://core.trac.wordpress.org/browser/tags/5.8.1/src/wp-includes/template.php
* https://developer.wordpress.org/themes/basics/organizing-theme-files/#page-templates-folder
*
* @param array $templates A list of candidates template files.
* @return string Full path to template file.
*/
function change_template_path($templates) {
// The custom sub-directory for page templates in your theme.
$custom_sub_dir = 'page-templates';
// Don't use the custom template directory in unexpected cases.
if(empty($templates) || ! is_array($templates)) {
return $templates;
}
$page_template_id = 0;
$count = count( $templates);
if($templates[0] === get_page_template_slug()) {
// if there is a custom template, then our page-{slug}.php template is at the next index
$page_template_id = 1;
}
// The last one in $templates is page.php, single.php, or archives.php depending on the type of template hierarchy being read.
// Paths of all items starting from $page_template_id will get updated
for($i = $page_template_id; $i < $count ; $i++) {
$templates[$i] = $custom_sub_dir . '/' . $templates[$i];
}
return $templates;
}
// Add filters to override the path for each WP template hierarchy.
// These are all the template hierarchy filters. You should probably only override the ones you need.
add_filter('404_template_hierarchy', 'change_template_path');
add_filter('archive_template_hierarchy', 'change_template_path');
add_filter('attachment_template_hierarchy', 'change_template_path');
add_filter('author_template_hierarchy', 'change_template_path');
add_filter('category_template_hierarchy', 'change_template_path');
add_filter('date_template_hierarchy', 'change_template_path');
add_filter('embed_template_hierarchy', 'change_template_path');
add_filter('frontpage_template_hierarchy', 'change_template_path');
add_filter('home_template_hierarchy', 'change_template_path');
// If you override the index hierarchy, be sure to add an index.php template in your custom template folder.
add_filter('index_template_hierarchy', 'change_template_path');
add_filter('page_template_hierarchy', 'change_template_path');
add_filter('paged_template_hierarchy', 'change_template_path');
add_filter('privacypolicy_template_hierarchy', 'change_template_path');
add_filter('search_template_hierarchy', 'change_template_path');
add_filter('single_template_hierarchy', 'change_template_path');
add_filter('singular_template_hierarchy', 'change_template_path');
add_filter('tag_template_hierarchy', 'change_template_path');
add_filter('taxonomy_template_hierarchy', 'change_template_path');
Upvotes: 2
Reputation: 373
WP_Theme
class contains the method get_page_templates()
that offers this filter:
apply_filters( "theme_{$post_type}_templates", $post_templates, $this, $post, $post_type );
line 1103 of class-wp-theme.php
Keeping in mind that in wordpress post
and page
are post_type
s,
add_filter( "theme_post_templates", ...
and add_filter( "theme_page_templates",...
should be valid.
Under the codex's "Used By" section for that method, it states:
wp-admin/includes/template.php: page_template_dropdown()
wp-admin/includes/meta-boxes.php: page_attributes_meta_box()
Which leads me to believe it would make them available on the /wp-admin/
edit page section.
Info from core files regarding the filter:
* Filters list of page templates for a theme.
*
* The dynamic portion of the hook name, `$post_type`, refers to the post type.
* @since 4.7.0 Added the `$post_type` parameter.
*
* @param array $post_templates Array of page templates. Keys are filenames,
* values are translated names.
* @param WP_Theme $this The theme object.
* @param WP_Post|null $post The post being edited, provided for context, or null.
* @param string $post_type Post type to get the templates for.
I'm unsure if a relative uri works here or if you need get_theme_file_path()
, but am assuming the former.
function deep_templates( $post_templates, $theme, $post, $post_type )
$post_templates['/folder/folder/folder/file.php'] = "Page Style One";
$post_templates['/folder/other-folder/file.php'] = "Page Style Two";
return $post_templates;
add_filter( 'theme_page_templates', 'deep_templates' );
AND/OR
add_filter( 'theme_post_templates', 'deep_templates' );
add_filter( 'theme_my-custom-cpt_templates', 'deep_templates' );
Upvotes: 8
Reputation: 9
You need to create a Template file(inside "page-templates" directory) for each diferent design you will have.
For creating a template file accessible from de Backend(wp-admin) you need to add:
<?php
/*
Template Name: TEMPLATE-NAME
*/
?>
in the top of each file(template). Then inside each file, you can add the blocks or modules of the design using get_template_part() function.
Upvotes: -1
Reputation: 3461
Here is an example of what you need to do.
- directory1 (dir)
-- directory2 (dir)
--- template-file.php
To access this template with get_template_part
you would do this:
get_template_part( 'directory1/directory2/template', 'file' );
'directory1/directory2
defines the directory structure.
template'
is the string before the -
in the template name.
'file' is the string after the dash
in the template name.
So in your case if you had a template file called page-contact.php
in your page-templates
directory, you would use.
get_template_part('template-parts/page-templates/page' , 'contact');
Upvotes: 4
Reputation: 75
get_template_part will only work as part of a WordPress THEME.
What you'll want to do is create your own WordPress theme, (which lives in wp-content/themes/ ) which you can then use for any PHP templates, CSS resources etc. that you want.
You can check out how to build a WordPress theme and include everything in the codex here.
Upvotes: -1