template_redirect
概述
template_redirect 是一个 WordPress 动作钩子,在确定加载哪个模板之前触发。它主要用于在完全了解查询内容后执行重定向操作。
关键要点
- template_redirect 钩子在 WordPress 决定加载哪个模板页面前执行,适合用于基于查询内容的重定向。
- 不应使用此钩子来加载不同模板,因为这可能中断后续钩子运行,导致网站功能损坏。
- 如需加载替代模板,应使用 template_include 过滤器钩子返回新模板路径,以避免干扰 WordPress 加载过程。
- 使用 wp_redirect() 后必须调用 exit() 或 die() 以确保重定向生效。
- 移除 template_redirect 钩子中的回调函数时,需注意优先级和注册时机,可通过在更高优先级钩子中调用 remove_action() 实现。
代码示例
// 重定向特定页面示例
function custom_redirects() {
if ( is_front_page() ) {
wp_redirect( home_url( '/dashboard/' ) );
die;
}
if ( is_page('contact') ) {
wp_redirect( home_url( '/new-contact/' ) );
die;
}
}
add_action( 'template_redirect', 'custom_redirects' );
// 重定向未登录用户示例
function my_page_template_redirect() {
if ( is_page( 'goodies' ) && ! is_user_logged_in() ) {
wp_redirect( home_url( '/signup/' ) );
exit();
}
}
add_action( 'template_redirect', 'my_page_template_redirect' );
// 移除 template_redirect 钩子回调示例
add_action( 'template_redirect', 'remove_my_action', 5 );
function remove_my_action(){
remove_action('template_redirect', 'function_to_remove', 10 );
}注意事项
- 避免在 template_redirect 钩子中加载不同模板,应使用 template_include 过滤器。
- 重定向后务必调用 exit() 或 die(),否则可能导致意外行为。
- 移除钩子回调时,需确保回调已注册但未触发,可通过调整优先级实现。
Fires before determining which template to load.
Description
This action hook executes just before WordPress determines which template page to load.
It is a good hook to use if you need to do a redirect with full knowledge of the content that has been queried.
Note: Loading a different template is not a good use of this hook. If you include another template and then use exit() or die(), no subsequent template_redirect hooks will be run, which could break the site’s functionality. Instead, use the ‘template_include’ filter hook to return the path to the new template you want to use. This will allow an alternative template to be used without interfering with the WordPress loading process.
Source
do_action( 'template_redirect' );
Changelog
| Version | Description |
|---|---|
| 1.5.0 | Introduced. |
Skip to note 4 content
Rami Yushuvaev
Redirect existing pages to other pages:
function custom_redirects() { if ( is_front_page() ) { wp_redirect( home_url( '/dashboard/' ) ); die; } if ( is_page('contact') ) { wp_redirect( home_url( '/new-contact/' ) ); die; } } add_action( 'template_redirect', 'custom_redirects' );Skip to note 5 content
Steven Lin
Example migrated from Codex:
Following example will redirect all non-authenticated users to a custom ‘signup’ page when trying to visit the ‘goodies’ page.
function my_page_template_redirect() { if ( is_page( 'goodies' ) && ! is_user_logged_in() ) { wp_redirect( home_url( '/signup/' ) ); exit(); } } add_action( 'template_redirect', 'my_page_template_redirect' );Don’t forget to call exit() ( or die() ) after a wp_redirect() .
Skip to note 6 content
Andrew Lima
If you need to remove a template_redirect from within a custom plugin, simply using
remove_action( 'template_redirect', 'function_to_remove' );won’t cut it.As a workaround, what you can do is create a function to hook into template_redirect action earlier and then remove the redirect you are trying to remove.
// remove a template redirect from within a custom plugin. add_action( 'template_redirect', 'remove_my_action', 5 ); function remove_my_action(){ remove_action('template_redirect', 'function_to_remove', 10 ); }remove_my_action()function at a higher priority than when thefunction_to_remove()function is registered. It’s recommended to hook yourremove_my_action()function to an action hook that fires aftertemplate_redirect. For example, you can hook it to theafter_setup_themeaction.wporg_plugin_init()fires oninitaction, registering thetemplate_redirectcallback (at default priority10), 2)wporg_theme_template_redirect()fires ontemplate_redirectwith priority5, removing the registered callback (set to fire on priority10), and 3) actiontemplate_redirectwith priority10is running, but because the callback has been removed, it doesn’t run. Because the plugin’s callback is set to run at priority10during theinitaction, by hooking intotemplate_redirectat an earlier priority, the callback has been registered, and has not yet fired, so it can be removed. Hope that’s helpful.