Изменить текст на кнопке публикации
Есть ли способ изменить текст кнопки публикации для пользовательского типа записи на что-то другое? Например, заменить "Опубликовать" на "Сохранить". А также убрать кнопку черновика?

Если заглянуть в файл /wp-admin/edit-form-advanced.php
, вы найдете метабокс:
add_meta_box('submitdiv', __('Publish'), 'post_submit_meta_box', $post_type, 'side', 'core');
Обратите внимание на __('Publish')
– функция __()
ведет к translate()
, где вы получаете фильтр 'gettext'
.
Есть два способа решить вашу проблему: 1. Обработать строку в специализированной функции (убедитесь, что указан правильный текстовый домен!) или 2. использовать более универсальный подход.
@Rarst только что опубликовал первый вариант, поэтому я добавлю второй. :)
<?php
/*
Plugin Name: Retranslate
Description: Добавляет переводы.
Version: 0.1
Author: Thomas Scholz
Author URI: http://toscho.de
License: GPL v2
*/
class Toscho_Retrans {
// хранит параметры
protected $params;
/**
* Устанавливает базовую информацию
*
* @param array $options
* @return void
*/
public function __construct( array $options )
{
$defaults = array (
'domain' => 'default'
, 'context' => 'backend'
, 'replacements' => array ()
, 'post_type' => array ( 'post' )
);
$this->params = array_merge( $defaults, $options );
// Когда добавлять фильтр
$hook = 'backend' == $this->params['context']
? 'admin_head' : 'template_redirect';
add_action( $hook, array ( $this, 'register_filter' ) );
}
/**
* Контейнер для add_filter()
* @return void
*/
public function register_filter()
{
add_filter( 'gettext', array ( $this, 'translate' ), 10, 3 );
}
/**
* Основной рабочий код.
*
* @param string $translated
* @param string $original
* @param string $domain
* @return string
*/
public function translate( $translated, $original, $domain )
{
// ранний выход
if ( 'backend' == $this->params['context'] )
{
global $post_type;
if ( ! empty ( $post_type )
&& ! in_array( $post_type, $this->params['post_type'] ) )
{
return $translated;
}
}
if ( $this->params['domain'] !== $domain )
{
return $translated;
}
// Замена
return strtr( $original, $this->params['replacements'] );
}
}
// Пример использования
// Замена 'Publish' на 'Save' и 'Preview' на 'Lurk' для страниц и записей
$Toscho_Retrans = new Toscho_Retrans(
array (
'replacements' => array (
'Publish' => 'Save'
, 'Preview' => 'Lurk'
)
, 'post_type' => array ( 'page', 'post' )
)
);
Необязательно использовать этот код как плагин. Достаточно добавить его в functions.php вашей темы.
Обновление
Чтобы удалить оригинальную кнопку Save (не уверен насчет кнопки 'draft'), добавьте следующий код в functions.php/плагин:
add_action( 'admin_print_footer_scripts', 'remove_save_button' );
function remove_save_button()
{
?>
<script>
jQuery(document).ready(function($){$('#save-post').remove();});
</script><?php
}
Да, это некрасиво.

Удалить кнопку сохранения действительно сложно, потому что post_submit_meta_box()
просто выводит свой контент. Без каких-либо фильтров. Решить это можно с помощью Javascript или ob_start()
, но оба варианта не очень элегантны.

Хм, окей, я добавил код для удаления оригинальной кнопки Save. Было не так сложно. :)

Мне не хватает слов, чтобы описать это :) - и как уже говорил: использование запятой для форматирования массива заслуживает Награды PHP Форматтеров +1+

Спасибо за этот код! Искренний вопрос - какие преимущества у этого подхода ("версия 1") по сравнению с кодом @Rarst ("версия 2")? Использование gettext
кажется более чистым решением, поскольку мы не хотим менять функциональность, только текст - именно для этого и предназначен gettext
. Также Версия 2, скорее всего, более устойчива к изменениям в будущем.

Код предложения hakre для использования фильтра перевода будет выглядеть примерно так:
add_filter( 'gettext', 'change_publish_button', 10, 2 );
function change_publish_button( $translation, $text ) {
if ( $text == 'Publish' )
return 'Сохранить';
return $translation;
}

Есть ли причины, по которым "версия 1" (текущий принятый ответ, написанный @toscho) превосходит/уступает этому подходу? Мне кажется, что этот вариант лучше из двух — проще, не требует хаков для удаления кнопки "Сохранить" и более перспективен.

Ваш ответ вдохновил меня — я развил ваш подход, чтобы охватить гораздо больше строк. http://wordpress.stackexchange.com/a/230513/10388

Недостатком может быть то, что фильтр перевода срабатывает очень часто, и его подключение создает значительную нагрузку на производительность. Это можно уменьшить, применяя фильтр только в течение ограниченного времени, добавляя/удаляя его ближе к необходимому моменту выполнения.

Это не полный ответ, а лишь некоторые указания: Любой отображаемый текст проходит через фильтр перевода и поэтому может быть изменён в функции обратного вызова (хуке). Так что если хук регистрируется только на странице, где вы хотите изменить этот текст, задача решена.
Кнопку черновика можно "удалить", скрыв её с помощью CSS. Этот CSS можно добавить в тег <head>
админки с помощью ещё одного хука. Кажется, для этого используется фильтр admin_head
. Это немного грязное решение, так как кнопка остаётся на месте, например, если пользователь отключит CSS.

Для единообразия я предполагаю, что вы предпочитаете использовать "Сохранить" вместо "Опубликовать" во всем WordPress, а не только на тексте кнопки.
На основе решения, предложенного @Rarst, я расширил код, чтобы он переводил многие (все?) другие варианты слова "Опубликовать" в соответствующую вариацию "Сохранить".
add_filter("gettext", "translate_publish_post_status", 10, 2);
add_filter("ngettext", "translate_publish_post_status_number", 10, 5);
add_filter("ngettext_with_context", "translate_publish_post_status_number", 10, 6);
function translate_publish_post_status($translation, $text) {
switch($text) {
case "Publish": return "Сохранить";
case "Published on: <b>%1\$s</b>": return "Сохранено: <b>%1\$s</b>";
case "Publish <b>immediately</b>": return "Утвердить <b>немедленно</b>";
case "Publish on: <b>%1\$s</b>": return "Утвердить: <b>%1\$s</b>";
case "Privately Published": return "Приватно сохранено";
case "Published": return "Сохранено";
case "Save & Publish": return "Сохранить"; // "Двойное сохранение"? :)
default: return $translation;
}
}
function translate_publish_post_status_number($translation, $single, $plural, $number, $domain) {
if($translation == "Published <span class=\"count\">(%s)</span>") {
return "Сохранено <span class=\"count\">(%s)</span>";
}
return $translation;
}
Для удаления кнопки "Черновик" в ответе от @toscho содержится хорошее решение.

@Amjad - Попробуйте заменить все вхождения %1$s
на %1\$s
. Или отключение уведомлений/предупреждений скроет эти ошибки.

Другой подход заключается в отмене регистрации метабокса, а затем повторной регистрации того же блока с изменёнными значениями, в частности, текста публикации.
Смотрите обсуждение, которое я вёл здесь, касательно перемещения метабокса — вы сможете применить нечто подобное для переименования текста "Publish".

Более чистое и простое решение.
function change_publish_btn_txt() {
echo "<script type='text/javascript'>jQuery(document).ready(function(){
jQuery('#publish').attr('value', 'Ваш текст');
});</script>";
}
add_action('admin_footer-post-new.php', 'change_publish_btn_txt', 99);
