-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Lauri Kallioniemi
committed
Jun 22, 2021
0 parents
commit 397e0ad
Showing
5 changed files
with
650 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
Polylang - Translate URL Rewrite Slugs | ||
=============================================================================== | ||
WordPress plugin that add rewrite url slugs translation feature to Polylang. | ||
|
||
Work in progress ;) | ||
|
||
Upgrade notice < 0.3.0 | ||
------------------------------------------------------------------------------- | ||
If you used a version prior to 0.3.0, the plugin will probably crash as the structure of the param for the "pll_translated_post_type_rewrite_slugs" filter has changed. | ||
|
||
Translate Post Type URLs | ||
------------------------------------------------------------------------------- | ||
Translate rewrite slugs for post types by doing 5 things: | ||
- Remove original extra rewrite rules and permastruct for these post types; | ||
- Translate the extra rewrite rules and permastruct for these post types; | ||
- Stop Polylang from translating rewrite rules for these post types; | ||
- Fix "get_permalink" for these post types. | ||
- Fix "get_post_type_archive_link" for these post types. | ||
|
||
To translate a post type rewrite slug, add the filter "pll_translated_post_type_rewrite_slugs" to your functions.php file or your plugin and add the "has_archive" and "rewrite" key has you normally do for the params of the "register_post_type" Wordpress function but add it for each post type and language you want. | ||
|
||
Example | ||
~~~php | ||
<?php | ||
add_filter('pll_translated_post_type_rewrite_slugs', function($post_type_translated_slugs) { | ||
// Add translation for "product" post type. | ||
$post_type_translated_slugs = array( | ||
'product' => array( | ||
'fr' => array( | ||
'has_archive' => true, | ||
'rewrite' => array( | ||
'slug' => 'produit', | ||
), | ||
), | ||
'en' => array( | ||
'has_archive' => true, | ||
'rewrite' => array( | ||
'slug' => 'product', | ||
), | ||
), | ||
), | ||
); | ||
return $post_type_translated_slugs; | ||
}); | ||
?> | ||
~~~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"name": "jussikinnula/wp-polylang-translate-rewrite-slugs", | ||
"description": "Polylang - Translate URL Rewrite Slugs", | ||
"homepage": "https://github.com/jussikinnula/wp-polylang-translate-rewrite-slugs", | ||
"type": "wordpress-plugin" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<?php | ||
/** | ||
* Post type related object. | ||
* | ||
* @todo Filter "extra_rules_top" after Polylang has create his translated version | ||
* of them. See $this->replace_extra_rules_top. | ||
*/ | ||
class PLL_TRS_Post_Type { | ||
// The post type object. | ||
public $post_type_object; | ||
// The translated rewrite slugs. | ||
public $translated_slugs; | ||
|
||
/** | ||
* Contructor. | ||
*/ | ||
public function __construct($post_type_object, $translated_slugs) { | ||
$this->post_type_object = $post_type_object; | ||
$this->translated_slugs = $this->sanitize_translated_slugs($translated_slugs); | ||
|
||
// Replace "extra_rules_top", for archive. | ||
$this->replace_extra_rules_top(); | ||
// Replace "permastruct", for single. | ||
$this->replace_permastruct(); | ||
} | ||
|
||
private function sanitize_translated_slugs($translated_slugs) { | ||
$post_type = $this->post_type_object->name; | ||
|
||
// Add defaults to translated_slugs. | ||
$defaults = array( | ||
'has_archive' => false, | ||
'rewrite' => true, | ||
); | ||
|
||
foreach ($translated_slugs as $lang => $translated_slug) { | ||
$args = wp_parse_args( $translated_slug, $defaults ); | ||
$args = (object) $args; | ||
|
||
if ( false !== $args->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { | ||
if ( ! is_array( $args->rewrite ) ) | ||
$args->rewrite = array(); | ||
if ( empty( $args->rewrite['slug'] ) ) | ||
$args->rewrite['slug'] = $post_type; | ||
if ( ! isset( $args->rewrite['with_front'] ) ) | ||
$args->rewrite['with_front'] = true; | ||
if ( ! isset( $args->rewrite['pages'] ) ) | ||
$args->rewrite['pages'] = true; | ||
if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive ) | ||
$args->rewrite['feeds'] = (bool) $args->has_archive; | ||
if ( ! isset( $args->rewrite['ep_mask'] ) ) { | ||
if ( isset( $args->permalink_epmask ) ) | ||
$args->rewrite['ep_mask'] = $args->permalink_epmask; | ||
else | ||
$args->rewrite['ep_mask'] = EP_PERMALINK; | ||
} | ||
} | ||
|
||
$translated_slugs[$lang] = $args; | ||
} | ||
|
||
return $translated_slugs; | ||
} | ||
|
||
/** | ||
* Replace "extra_rules_top", for archive. | ||
* | ||
* This code simulate the code used in WordPress function "register_post_type" | ||
* and execute it for each language. After that, Polylang will consider these | ||
* rules like "individual" post types (one by lang) and will create the appropriated | ||
* rules. | ||
* | ||
* @see Extra rules from WordPress (wp-include/post.php, register_post_type()). | ||
*/ | ||
private function replace_extra_rules_top() { | ||
global $polylang, $wp_rewrite; | ||
|
||
$post_type = $this->post_type_object->name; | ||
|
||
// Remove the original extra rules. | ||
if ( $this->post_type_object->has_archive ) { | ||
$archive_slug = $this->post_type_object->has_archive === true ? $this->post_type_object->rewrite['slug'] : $this->post_type_object->has_archive; | ||
if ( $this->post_type_object->rewrite['with_front'] ) | ||
$archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; | ||
else | ||
$archive_slug = $wp_rewrite->root . $archive_slug; | ||
|
||
unset($wp_rewrite->extra_rules_top["{$archive_slug}/?$"]); | ||
if ( $this->post_type_object->rewrite['feeds'] && $wp_rewrite->feeds ) { | ||
$feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; | ||
unset($wp_rewrite->extra_rules_top["{$archive_slug}/feed/$feeds/?$"]); | ||
unset($wp_rewrite->extra_rules_top["{$archive_slug}/$feeds/?$"]); | ||
} | ||
if ( $this->post_type_object->rewrite['pages'] ) | ||
unset($wp_rewrite->extra_rules_top["{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$"]); | ||
} | ||
|
||
// Add the translated extra rules for each languages. | ||
foreach ($this->translated_slugs as $lang => $translated_slug) { | ||
if ($translated_slug->has_archive) { | ||
$archive_slug = $translated_slug->has_archive === true ? $translated_slug->rewrite['slug'] : $translated_slug->has_archive; | ||
if ( $translated_slug->rewrite['with_front'] ) | ||
$archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; | ||
else | ||
$archive_slug = $wp_rewrite->root . $archive_slug; | ||
|
||
add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' ); | ||
if ( $translated_slug->rewrite['feeds'] && $wp_rewrite->feeds ) { | ||
$feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; | ||
add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); | ||
add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); | ||
} | ||
if ( $translated_slug->rewrite['pages'] ) | ||
add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' ); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Replace "permastruct", for single. | ||
* | ||
* This code simulate the code used in WordPress function "register_post_type" | ||
* and execute it for each language. | ||
* | ||
* @see Permstruct from WordPress (wp-include/post.php, register_post_type()). | ||
*/ | ||
private function replace_permastruct() { | ||
global $polylang, $wp_rewrite; | ||
|
||
$post_type = $this->post_type_object->name; | ||
|
||
// Remove the original permastructs. | ||
unset($wp_rewrite->extra_permastructs[$post_type]); | ||
|
||
// Add the translated permastructs for each languages. | ||
foreach ($this->translated_slugs as $lang => $translated_slug) { | ||
$args = $translated_slug; | ||
|
||
if ( false !== $args->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { | ||
$permastruct_args = $args->rewrite; | ||
$permastruct_args['feed'] = $permastruct_args['feeds']; | ||
// Set the walk_dirs to false to avoid conflict with has_archive = false and the %language% | ||
// in the rewrite directive. Without it the archive page redirect to the frontpage if has_archive is false. | ||
$permastruct_args['walk_dirs'] = false; | ||
|
||
// If "Hide URL language information for default language" option is | ||
// set to true the rules has to be different for the default language. | ||
if ($polylang->options['hide_default'] && $lang == pll_default_language()) { | ||
add_permastruct( $post_type.'_'.$lang, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args ); | ||
} else { | ||
add_permastruct( $post_type.'_'.$lang, "%language%/{$args->rewrite['slug']}/%$post_type%", $permastruct_args ); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
/** | ||
* Taxonomy related object. | ||
*/ | ||
class PLL_TRS_Taxonomy { | ||
// The post type object. | ||
public $taxonomy_object; | ||
// The translated rewrite slugs. | ||
public $translated_slugs; | ||
// The translated object struct. | ||
public $translated_struct; | ||
|
||
/** | ||
* Contructor. | ||
*/ | ||
public function __construct($taxonomy_object, $translated_slugs, $translated_struct) { | ||
$this->taxonomy_object = $taxonomy_object; | ||
$this->translated_slugs = $translated_slugs; | ||
$this->translated_struct = $translated_struct; | ||
|
||
// Translate the rewrite rules of the post type. | ||
add_filter($this->taxonomy_object->name.'_rewrite_rules', array($this, 'taxonomy_rewrite_rules_filter')); | ||
} | ||
|
||
/** | ||
* Translate the rewrite rules. | ||
*/ | ||
public function taxonomy_rewrite_rules_filter($rewrite_rules) { | ||
global $polylang, $wp_rewrite; | ||
|
||
$translated_rules = array(); | ||
|
||
// For each lang. | ||
foreach ($this->translated_slugs as $lang => $translated_slug) { | ||
// If "Hide URL language information for default language" option is | ||
// set to true the rules has to be different for the default language. | ||
if ($polylang->options['hide_default'] && $lang == pll_default_language()) { | ||
// For each rule. | ||
foreach ($rewrite_rules as $rule_key => $rule_value) { | ||
// Only translate the rewrite slug. | ||
$translated_rules[str_replace(trim($this->taxonomy_object->rewrite['slug'], '/'), $translated_slug, $rule_key)] = $rule_value; | ||
} | ||
} else { | ||
// For each rule. | ||
foreach ($rewrite_rules as $rule_key => $rule_value) { | ||
$taxonomy_rewrite_slug = $this->taxonomy_object->rewrite['slug']; | ||
|
||
// Replace the rewrite tags in slugs. | ||
foreach ($wp_rewrite->rewritecode as $position => $code) { | ||
$taxonomy_rewrite_slug = str_replace($code, $wp_rewrite->rewritereplace[$position], $taxonomy_rewrite_slug); | ||
$translated_slug = str_replace($code, $wp_rewrite->rewritereplace[$position], $translated_slug); | ||
} | ||
|
||
// Shift the matches up cause "lang" will be the first. | ||
$translated_rules['('.$lang.')/'.str_replace(trim($taxonomy_rewrite_slug, '/'), $translated_slug, $rule_key)] = str_replace( | ||
array('[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]'), | ||
array('[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]'), | ||
$rule_value | ||
); | ||
} | ||
} | ||
} | ||
|
||
return $translated_rules; | ||
} | ||
} |
Oops, something went wrong.