gpt4 book ai didi

php - Wordpress add_rewrite_tag()、add_rewrite_rule() 和 post_link()

转载 作者:可可西里 更新时间:2023-10-31 23:10:53 25 4
gpt4 key购买 nike

我正在尝试执行以下操作:

重写我的 WordPress 安装的 URL 结构,以便在其中包含语言字段。例如http://www.mydomain.com/lang/

然后我想从/lang/获取输入并使用它来显示适当的内容。例如如果 lang 是“en”,我将采用英文自定义字段并以英文显示主题。

这是我到目前为止所拥有的:

<?php
function add_directory_rewrite() {
global $wp_rewrite;
add_rewrite_tag('%lang%', '(.+)');
add_rewrite_rule('^/(.+)/', 'index.php?p=$matches[1]&lang=$matches[2]', 'top');
add_permastruct('lang', '%lang%');

}
add_action( 'init', 'add_directory_rewrite' );
?>

这在获取语言方面有效,但我现在面临的问题是 the_permalink() 有“/%lang%/”,其中/en/应该是或/fr/或/de/或任何语言。为了添加更多细节,我的永久链接结构是/%lang%/%category%/%postname%/并且假设我有一个名为 food 的类别和一个标题为鸡的帖子,the_permalink 将生成 http://www.mydomain.com/%lang%/food/chicken/

知道我做错了什么吗?干杯。

最佳答案

您还需要添加一个函数,该函数将采用包含错误“/%lang%/”段的永久链接,并将其替换为帖子的适当默认语言。通常,您可以通过 'pre_post_link' 执行此操作过滤器,或 'post_link'过滤。如果您使用前者,您将从头开始创建永久链接(完全自定义的 url,不使用核心 WP 必须提供的任何内容)。如果使用后者,则可以过滤永久链接 WP 已经完成了它的魔法,但在它被用于网站之前。下面是一个例子:

function lou_rewrite_lang_in_permalink($permalink, $post, $leavename) {
// find the default post language via a function you have created to
// determine the default language url. this could be based on the current
// language the user has selected on the frontend, or based on the current
// url, or based on the post itself. it is up to you
$default_post_language = get_default_post_lang($post);

// once you have the default language, it is a simple search and replace
return str_replace('%lang%', $lang, $permalink);
}
add_filter('post_link', 'lou_rewrite_lang_in_permalink', 11, 3);

你不提,我就提。使用您原来的独奏功能,如果它是独立的,您将很难过。原因是,尽管您告诉重写器存在新的 url 段,但您没有告诉 WordPress 将其作为 url 参数。因此,即使您有一些花哨的代码来重写 url 并告诉 WordPress 花哨的 lang 参数,WordPress 也不知道它应该寻找它,因此忽略了它。你需要添加这样的东西来纠正:
function lou_add_lang_query_var($vars) {
// tell WP to expect the lang query_var, which you can then later use
$vars[] = 'lang';

// return the new list of query vars, which includes our lang param
return array_unique($vars);
}
add_filter('query_vars', 'lou_add_lang_query_var', 10, 1);

这将告诉 WP()它需要接受 'lang' 的类而不是跳过它。然后你可以做这样的事情来确定当前页面发送的是它的语言:
function lou_somefunction() {
// do stuff
...

// access the $wp object
global $wp;

// determine the language from the query_vars of the current page
$lang = $wp->query_var['lang'];

// do other stuff with $lang
...
}

希望这会有所帮助。

编辑

首先我想说的是,WordPress 本身并不支持语言网址,这绝对是一种讽刺。老实说,我从来不需要这样做,但我的大多数客户都不是具有国际需求的国际公司。我将在以后的版本中以代码形式向 WordPress 提交一些东西来解决这个问题,但到目前为止,你需要一个像我在下面创建的插件。

所以我做了很多调查来实现这一点。与提问者简短交谈后,如果发现我的解决方案不完整。自然而然地,我开始挖掘。看起来应该是一项平庸的任务,结果却是一项非常不平庸的任务。简短的版本是,WordPress 只是不希望您在每个 url 上的 url 中间或开头插入 url 的额外部分。您可以使用上面的代码轻松地使用帖子网址完成此操作,但更多内容(页面、附件、作者页面等)您必须做一些特别的事情。您还可以在 url 的末尾添加部分(端点),但即使这样也很复杂。

我过去和现在都与 WordPress 重写器进行过广泛的合作,并且我拥有关于该主题的专家知识。尽管如此,我还是花了 4-5 个小时来编写一些内容,让您可以在所有 url 之前添加语言指示符,然后可以使用它来确定页面应该以哪种语言显示,而不管页面类型如何。有一个问题,我认为是可以接受的。您必须确切地知道并指定要支持的语言前缀。我不认为这对任何会使用它的人来说是一个问题,但尽管如此,它仍然是一个限制,仅仅是因为重写引擎的工作方式。

终于,这里有一个插件,您可以使用它来完成此操作。我在一个准系统 WP 安装上工作,使用 WooTheme作为主题。如果您安装了其他第三方插件,则这可能不适用于他们的所有 url,具体取决于他们如何添加重写规则。在短期内,我可能会将其转换为 WP 的插件,并在 Wordpress.org 上发布它,但至少还有几天的时间。这是插件形式的代码的工作原型(prototype)。在您的插件文件夹中创建一个新目录(类似于/wp-content/plugins/lou-lang),然后将此代码粘贴到该文件夹​​内的 php 文件中(类似于/wp-content/plugins/lou-lang/lou -lang.php)。然后通过您的管理仪表板激活插件,该插件将标记为“Loushou Language URLs”。

代码:
<?php (__FILE__ == $_SERVER['SCRIPT_FILENAME']) ? die(header('Location: /')) : null;
/**
* Plugin Name: Loushou Language URLs
* Plugin URI: http://quadshot.com/
* Description: Adding the ability to have language support in your frontend urls.
* Version: 0.1-beta
* Author: Loushou
* Author URI: http://quadshot.com/
*/

class lou_rewrite_takeover {
protected static $add_rules = array();

public static function pre_init() {
// debug
add_action('admin_footer-options-permalink.php', array(__CLASS__, 'qsart_rewrite_debug'));

// add rw tag
add_action('init', array(__CLASS__, 'add_directory_rewrite'));

// rw rule adds
add_filter(is_admin() ? 'setup_theme' : 'do_parse_request', array(__CLASS__, 'do_parse_request'), 0);
add_filter('post_rewrite_rules', array(__CLASS__, 'post_rewrite_rules'));
add_filter('date_rewrite_rules', array(__CLASS__, 'date_rewrite_rules'));
add_filter('root_rewrite_rules', array(__CLASS__, 'root_rewrite_rules'));
add_filter('comments_rewrite_rules', array(__CLASS__, 'comments_rewrite_rules'));
add_filter('search_rewrite_rules', array(__CLASS__, 'search_rewrite_rules'));
add_filter('author_rewrite_rules', array(__CLASS__, 'author_rewrite_rules'));
add_filter('page_rewrite_rules', array(__CLASS__, 'page_rewrite_rules'));
add_filter('rewrite_rules_array', array(__CLASS__, 'final_rules_correction'), PHP_INT_MAX, 1);

// query vars
add_filter('query_vars', array(__CLASS__, 'add_lang_query_var'), 10, 1);
add_filter('request', array(__CLASS__, 'default_language'), 9);

// fix permalinks
$link_filters_needing_rewrite = array(
'post_link',
'post_type_link',
'page_link',
'attachment_link',
'search_link',
'post_type_archive_link',
'year_link',
'month_link',
'day_link',
'feed_link',
'author_link',
'term_link',
'category_feed_link',
'term_feed_link',
'taxonomy_feed_link',
'author_feed_link',
'search_feed_link',
'post_type_archive_feed_link',
);
add_filter('pre_post_link', array(__CLASS__, 'change_permalink_structure'), 10, 3);
foreach ($link_filters_needing_rewrite as $link_filter)
add_filter($link_filter, array(__CLASS__, 'rewrite_lang_in_permalink'), 11, 3);
}

public static function do_parse_request($cur) {
self::get_page_permastruct();
self::get_author_permastruct();
self::correct_extras();
return $cur;
}

public static function get_supported_langs() {
return apply_filters('lou-get-supported-languages', array(
'en',
));
}

public static function add_directory_rewrite() {
global $wp_rewrite;
$supported_languages = self::get_supported_langs();
add_rewrite_tag('%lang%', '('.implode('|', $supported_languages).')');
}

public static function unleadingslashit($str) {
return ltrim($str, '/');
}

public static function final_rules_correction($rules) {
global $wp_rewrite;

$new_rules = array();
$supported_languages = self::get_supported_langs();
$find = implode('|', $supported_languages);
$find_find = '#(?<!\()('.preg_quote($find, '#').')#';
$preg_node = str_replace('%%%', '(\d+)', preg_quote($wp_rewrite->preg_index('%%%'), '#'));

foreach ($rules as $k => $v) {
if (preg_match($find_find, $k)) {
$nk = preg_replace($find_find, '('.$find.')', $k);
$parts = explode('?', $v);
$index = array_shift($parts);
$pv = implode('?', $parts);
$pv = preg_replace_callback('#'.$preg_node.'#', function ($matches) use ($wp_rewrite) {
return $wp_rewrite->preg_index($matches[1]+1);
}, $pv);
$nv = $index.'?lang='.$wp_rewrite->preg_index(1).(!empty($pv) ? '&'.$pv : '');
$new_rules[$nk] = $nv;
} else {
$new_rules[$k] = $v;
}
}

return $new_rules;
}

public static function change_permalink_structure($struct) {
$struct = self::unleadingslashit($struct);
$struct = preg_replace('#^%lang%/?#', '', $struct);
return '/%lang%/'.$struct;
}

public static function extras_rewrite_rules($rules, $struct) {
global $wp_rewrite;

if ( is_array( $struct ) ) {
if ( count( $struct ) == 2 )
$new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct[0]), $struct[1] );
else
$new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct['struct']), $struct['ep_mask'], $struct['paged'], $struct['feed'], $struct['forcomments'], $struct['walk_dirs'], $struct['endpoints'] );
} else {
$new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct) );
}

return $new_rules + $rules;
}

public static function post_rewrite_rules($rules) {
global $wp_rewrite;

// hack to add code for extras type urls (usually created by other plugins)
$func = array(__CLASS__, 'extras_rewrite_rules');
foreach ($wp_rewrite->extra_permastructs as $type => $struct) {
$filter = ($type == 'post_tag' ? 'tag' : $type).'_rewrite_rules';
add_filter($filter, function ($rules) use ($struct, $func) { return call_user_func_array($func, array($rules, $struct)); });
}

return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->permalink_structure), EP_PERMALINK ) + $rules;
}

public static function date_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_date_permastruct()), EP_DATE) + $rules;
}

public static function root_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_date_permastruct()), EP_DATE) + $rules;
}

public static function comments_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->root . $wp_rewrite->comments_base), EP_COMMENTS, false, true, true, false) + $rules;
}

public static function search_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_search_permastruct()), EP_SEARCH) + $rules;
}

public static function author_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_author_permastruct()), EP_AUTHORS) + $rules;
}

public static function page_rewrite_rules($rules) {
global $wp_rewrite;
$page_structure = self::get_page_permastruct();
return $wp_rewrite->generate_rewrite_rules( $page_structure, EP_PAGES, true, true, false, false ) + $rules;
}

protected static function get_page_permastruct() {
global $wp_rewrite;

if (empty($wp_rewrite->permalink_structure)) {
$wp_rewrite->page_structure = '';
return false;
}

$wp_rewrite->page_structure = self::change_permalink_structure($wp_rewrite->root . '%pagename%');

return $wp_rewrite->page_structure;
}

protected static function get_author_permastruct() {
global $wp_rewrite;

if ( empty($wp_rewrite->permalink_structure) ) {
$wp_rewrite->author_structure = '';
return false;
}

$wp_rewrite->author_structure = self::change_permalink_structure($wp_rewrite->front . $wp_rewrite->author_base . '/%author%');

return $wp_rewrite->author_structure;
}

protected static function correct_extras() {
global $wp_rewrite;

foreach ($wp_rewrite->extra_permastructs as $k => $v)
$wp_rewrite->extra_permastructs[$k]['struct'] = self::change_permalink_structure($v['struct']);
}

public static function get_default_post_lang($post) {
return ( $lang = get_query_var('lang') ) ? $lang : 'en';
}

public static function rewrite_lang_in_permalink($permalink, $post=0, $leavename=false) {
// find the default post language via a function you have created to
// determine the default language url. this could be based on the current
// language the user has selected on the frontend, or based on the current
// url, or based on the post itself. it is up to you
$lang = self::get_default_post_lang($post);

// once you have the default language, it is a simple search and replace
return str_replace('%lang%', $lang, $permalink);
}

public static function add_lang_query_var($vars) {
// tell WP to expect the lang query_var, which you can then later use
$vars[] = 'lang';

// return the new list of query vars, which includes our lang param
return array_unique($vars);
}

public static function default_language($vars) {
if (array_diff( array_keys($vars), array('preview', 'page', 'paged', 'cpage') ))
$vars['lang'] = !empty($vars['lang']) ? $vars['lang'] : 'en';
return $vars;
}

public static function qsart_rewrite_debug() {
if (isset($_COOKIE['rwdebug']) && $_COOKIE['rwdebug'] == 1) {
global $wp_rewrite;
echo '<pre style="background-color:#ffffff; font-size:10px;">';
print_r($wp_rewrite->rules);
echo '</pre>';
}
}
}

if (defined('ABSPATH') && function_exists('add_action')) {
lou_rewrite_takeover::pre_init();
}

默认情况下,此插件支持的唯一语言代码是 'en' .显然,您需要的远不止这些。因此,一旦您安装了插件,您就可以在 <theme>/functions.php 中添加一些代码。看起来像这样的文件,以添加余数。
function more_languages($list) {
$my_languages = array(
'de', 'zh', 'bg', 'fr'
);
return array_unique($list + $my_languages);
}
add_filter('lou-get-supported-languages', 'more_languages', 10, 1);

一旦您拥有 两者 安装了插件并定义了您的自定义语言,然后您就完成了最后一步。您必须保存您的永久链接。要从管理员执行此操作,请转到:设置 -> 固定链接 -> 保存更改(按钮)。完成所有这些之后,您应该可以开始了!

希望这对某人有所帮助,并希望我能抽出一些时间在 wp.org 上解决这个问题。

关于php - Wordpress add_rewrite_tag()、add_rewrite_rule() 和 post_link(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20754505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com