通过向称为“语言”的帖子和页面添加自定义分类来使主题成为多语言主题?

时间:2011-01-24 作者:janoChen

最近,我一直在考虑在我的WordPress网站上实现一个简单易用的本地化功能。

我想在我的帖子和名为“语言”的页面中添加一个自定义分类法

因此,当你点击该语言的链接时,它只会过滤带有该语言术语的帖子。

我一直在使用WPML,它非常棒,但我只是想为我的主题提供一个嵌入式实现。

以前有人试过这个吗?

这样做的好处和坏处是什么?

2 个回复
SO网友:fuxia

Pro:您可以重用本机WP代码。

相反:你必须编写自己的分类选择器,以避免使用多种语言标记的帖子。插件Posts 2 Posts 从…起@scribu 应该引导您采取更灵活的方法。

SO网友:Tomas Buteler

本周,我也面临着类似的困境,最终制定了一个解决方案,我认为这可能会对您有所帮助。

我个人不喜欢为此目的使用分类法。我认为唯一的pro是它已经内置了,也许它提供了一个很好的开箱即用的permalink结构,但它感觉像是对分类法最初用途的破坏。

我的方法是相当自给自足的,并使用Posteta存储翻译。要过滤有翻译的帖子,你所要做的就是检查_translate_content_{$lang} 后元(例如。_translate_content_fr_FR). 我还没有对前端部分进行编码,但根据您在主题中想要做什么,这应该会有很大的不同。

代码已被注释,但如果有任何不清楚的地方,请告诉我。

注意:我只对页面执行此操作,但向其中添加帖子也应该很容易。另外,请记住,我还没有用修订版来测试这一点,我没有使用修订版。

# Create a list of available languages for translation;
# Note: the keys are WordPress locale codes, so we can easily integrate it
function my_available_languages() {
    return array(
        \'en_US\' => array(
            \'value\' => \'en_US\',
            \'label\' => \'English (U.S.)\',
        ),
        \'fr_FR\' => array(
            \'value\' => \'fr_FR\',
            \'label\' => \'Français\',
        ),
        \'de_DE\' => array(
            \'value\' => \'de_DE\',
            \'label\' => \'Deutsch\',
        ),
        \'es_ES\' => array(
            \'value\' => \'es_ES\',
            \'label\' => \'Español\',
        ),  
    );
}

# Allow translations
add_action(\'current_screen\', \'enable_translation\');
function enable_translation($screen) {
    # Only process translations for existing posts
    if(in_array($screen->post_type, array(\'page\')) && $screen->base == \'post\' && $screen->action != \'add\') {
        if(isset($_GET[\'translate\']) && array_key_exists($_GET[\'translate\'], my_available_languages())) {

            # Load translated fields instead of the original post content
            add_filter(\'title_edit_pre\', create_function(\'\', \'return get_translate_field("title", "\' . $_GET[\'translate\'] . \'");\'));
            add_filter(\'content_edit_pre\', create_function(\'\', \'return get_translate_field("content", "\' . $_GET[\'translate\'] . \'");\'));
            add_filter(\'excerpt_edit_pre\', create_function(\'\', \'return get_translate_field("excerpt", "\' . $_GET[\'translate\'] . \'");\'));

            # Add hidden field so that \'translate\' param persists
            add_action(\'submitpage_box\', \'doing_translate_hidden_field\');

            # Remove unnecessary metaboxes, which are not pertinent for translation
            add_action(\'add_meta_boxes\', \'redo_metaboxes_on_translate\', 99, 2);

            # Reduce the layout columns options
            add_filter(\'screen_layout_columns\', \'screen_layout_columns_translate_page\');
            function screen_layout_columns_translate_page($columns) {
                $columns[\'page\'] = 1;
                return $columns;
            }

            # Set one column default layout on dashboard
            add_filter(\'get_user_option_screen_layout_page\', create_function(\'\', \'return 1;\'));

            # Notify user that he is viewing a translated version
            add_action(\'admin_notices\', \'doing_translation_notification\');
        }
    }
}

add_action(\'add_meta_boxes\', \'add_translation_metabox\', 98, 2);
function add_translation_metabox($post_type, $post) {
    # Optional: add this box conditionally
    $types = array(\'page\');
    if(in_array($post_type, $types)) {
        foreach($types as $type) {
            add_meta_box(\'translate_mgmt\', __(\'Translations\', \'text_domain\'), \'output_translate_mgmt_metabox\', $type, \'side\', \'low\');   
        }
    }
}

# Output a list of links of available languages for translation
function output_translate_mgmt_metabox() {
    global $post;
    $default = \'en_US\';
    # get_edit_post_link will return a filtered admin_url link, so we must attempt to remove the translate param, in case it\'s already added
    $link = remove_query_arg(\'translate\', get_edit_post_link($post->ID));
    echo(\'<ul>\');
    foreach(my_available_languages() as $code => $lang) {
        $href = $code != $default ? add_query_arg(array(\'translate\' => $code), $link) : $link;
        echo(\'<li><a href="\' . $href . \'">\' . $lang[\'label\'] . \'</a></li>\');
    }
    echo(\'</ul>\');
}

function redo_metaboxes_on_translate($post_type, $post) {

    # Add alternative save metabox
    add_meta_box(\'translate_save\', __(\'Save\', \'text_domain\'), \'output_translate_save_metabox\', \'page\', \'normal\', \'low\');

    # Remove unnecessary metaboxes
    remove_meta_box(\'slugdiv\', \'page\', \'normal\');   
    remove_meta_box(\'authordiv\', \'page\', \'normal\');
    remove_meta_box(\'postcustom\', \'page\', \'normal\');
    remove_meta_box(\'commentsdiv\', \'page\', \'normal\');
    remove_meta_box(\'commentstatusdiv\', \'page\', \'normal\');  
    remove_meta_box(\'submitdiv\', \'page\', \'side\');
    remove_meta_box(\'pageparentdiv\', \'page\', \'side\');   
    remove_meta_box(\'revisionsdiv\', \'page\', \'side\');
    remove_meta_box(\'trackbacksdiv\', \'page\', \'side\');
    remove_meta_box(\'postimagediv\', \'page\', \'side\');
}

# Output a simpler, \'just save\' button, so translators are not confronted with too many options that affect main post
function output_translate_save_metabox() { ?>
    <input type="submit" class="ui_button big save" value="<?php _e(\'Save\', \'text_domain\'); ?>" />
<?php
}

# Add a notice to the user (like the update WordPress nag) so that it\'s clear that he is currently viewing a translated version
function doing_translation_notification() {
    global $post;
    $langs = my_available_languages();
    echo "<div class=\'update-nag\'>" . sprintf(__(\'You are currently translating the page "%s" into %s.\', \'text_domain\'), get_the_title($post->ID), $langs[$_REQUEST[\'translate\']][\'label\']) . "</div>";
}

# Add hidden input which will add \'translate\' to the $_POST object, thus allowing it to persist after redirection
# Note: I use jQuery to remove the slug below the title, but it\'s optional, I guess
function doing_translate_hidden_field() { ?>
    <input type="hidden" name="translate" value="<?php echo($_REQUEST[\'translate\']); ?>" />
    <script type="text/javascript">
        jQuery(function($){
            $(\'#edit-slug-box\').remove();
        });
    </script>
<?php
}

# Return translated content
function get_translate_field($field, $lang) {
    global $post;
    return get_post_meta($post->ID, \'_translate_\' . $field . \'_\' . $lang, true);    
}

add_action(\'admin_init\', \'add_translation_content_filters\');
function add_translation_content_filters() {
    $fields = array(\'title\', \'content\', \'excerpt\'); // As named in filters, not on their form inputs / db
    foreach($fields as $field) {
        add_action($field . \'_save_pre\', create_function(\'$cont\', \'return update_translation_on_save($cont, "\' . $field . \'");\'), 1, 1);
    }
}

# If doing translation, update pertinent post meta instead of post row on database
function update_translation_on_save($content, $field) {
    $db_fields = array(
        \'title\' => \'post_title\',
        \'content\' => \'post_content\',
        \'excerpt\' => \'post_excerpt\',
    );
    global $post;
    if(is_object($post) && isset($_REQUEST[\'translate\'])) {
        update_post_meta($post->ID, \'_translate_\' . $field . \'_\' . $_REQUEST[\'translate\'], $content);
        $content = $post->{$db_fields[$field]};
    }
    return $content;
}

# Function to add \'translate\' param to a given URL (to be used with filters) 
function add_translate_param($link) {
    # Optional: don\'t add \'translate\' on pages which are not for content management
    if(strpos($link, \'post.php\') === false && strpos($link, \'edit.php\') === false) {
        return $link;
    }
    return add_query_arg(array(\'translate\' => isset($_REQUEST[\'translate\']) ? $_REQUEST[\'translate\'] : \'\'), $link);
}

if(isset($_REQUEST[\'translate\'])) {
    # Make \'translate\' URL parameter persistent 
    add_filter(\'admin_url\', \'add_translate_param\');
    add_filter(\'wp_redirect\', \'add_translate_param\');
    # Add \'doing_translate\' body class
    add_filter(\'admin_body_class\', create_function(\'$c\', \'$c .= " doing_translate"; return $c;\'), 99);
}

结束

相关推荐