WordPress hook/filter для обработки ссылки внутри сообщения
Есть ли hook/filter для обработки ссылки, добавляемой в сообщение WordPress?
Моя цель - предварительно обработать ссылку, вставленную в сообщение, используя следующую кнопку и сократить ее с помощью стороннего API, такого как bit.ly
Я хочу сделать это как для внутренних, так и для внешних ссылок.
![Кнопка добавления ссылки TinyMCE]()
Одно из решений, о котором я думаю, заключается в добавлении дополнительной кнопки в мой редактор, который делает это, но я бы предпочел хук/фильтр, который выполняет эту работу, таким образом, это будет более чистым и Я преобразую это в пользовательский плагин для моего сайта (там, позволяя моему WordPress быть повышающимся).
Я прошел через документы WordPress и просмотрел следующие перехватчики/фильтры, которые мне не нужны
Ответы
Ответ 1
Обновление 1. Насколько я знаю, внешние URL-адреса вставляются в почтовый контент плагином редактора TinyMCE, PHP ничего не делает.
В WordPress есть два плагина, которые расположены в wp-includes/js/wplink.js
и wp-includes/js/tinymce/plugins/wplink/plugin.js
. Обратите внимание: если вы не находитесь в режиме SCRIPT_DEBUG
, у них есть суффикс .min
.
-
wp-includes/js/wplink.js обрабатывает это диалоговое окно:
![wplink dialog box 1]()
Чтобы фильтровать URL-адреса, вставленные в это диалоговое окно, мы должны переопределить метод wpLink.getAttrs
. Например, чтобы добавить строку so39115564
к каждому URL-адресу:
jQuery(document).ready(function($) {
wpLink.getAttrs = function() {
wpLink.correctURL();
return {
href: $.trim( $("#wp-link-url").val() + "so39115564" ),
target: $("#wp-link-target").prop("checked") ? "_blank" : ""
};
}
});
Вы можете посмотреть wp-includes/js/wplink.js
для получения дополнительной информации. Это слишком долго, чтобы подробно объяснить здесь.
И пусть говорят, что выше script есть mylink.js
, вот как мы должны заключить его в очередь:
add_filter('admin_enqueue_scripts', function()
{
// { Maybe some conditions for a valid screen here. }
wp_enqueue_script('mylink', 'link/to/the/mylink.js', ['link'], '1.0', true);
}, 0, 0);
-
wp-includes/js/tinymce/plugins/wplink/plugin.js обрабатывает это диалоговое окно:
![диалог wplink 2]()
На этот раз мы также должны переопределить метод setURL
tinymce.ui.WPLinkPreview
. Но это почти невозможно, если вы не отмените регистрацию этого script и не зарегистрируете измененную версию. Затем управляйте этим script самостоятельно с непредсказуемыми изменениями из WordPress.
Теперь, выберите это мудро! Сократите любые внешние URL-адреса, прежде чем вставлять их в свои сообщения или испортить плагины WordPress TinyMCE или использовать диалоговое окно плагина wp-includes/js/wplink.js
.
Да! WordPress вставляет встроенные ссылки через wp_link_ajax
действие, которое выполняется функция wp_ajax_wp_link_ajax().
Как вы можете видеть в исходном коде этой функции, $results
извлекается _WP_Editors::wp_link_query
. Проверьте этот метод, вы встретите wp_link_query фильтр. Этот фильтр принимает два аргумента: $results
и $query
. $results
будет тем, что нам нужно отфильтровать.
Например, нам нужно добавить so39115564
в запрошенную ссылку:
add_filter('wp_link_query', function(array $results, array $query)
{
$results[0]['permalink'] = $results[0]['permalink'] . 'so39115564';
return $results;
}, PHP_INT_MAX, 2);
Теперь вы должны знать, как это сделать. Обязательно посмотрите _ WP_Editors:: wp_link_query, чтобы фильтр $results
стал более эффективным.
Ответ 2
Вы считали, что не обрабатываете ссылку до тех пор, пока не сохраните сообщение? В плагине wordpress api есть действие, называемое "save_post", которое запускается при сохранении.
Используя "save_post", вы можете анализировать содержимое сообщения и заменять ссылки, используя укороченный URL-адрес.
https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
Ответ 3
Для этого могут быть доступны плагины, но здесь используется логика по умолчанию.
1st Way: сохранение сокращенного URL-адреса в DB также
add_action( 'save_post', 'save_book_meta', 10, 3 );
function save_book_meta( $post_id, $post, $update ) {
global $wpdb;
$slug = 'event';
// If this isn't a 'book' post, don't update it.
if ( $slug != $post->post_type ) {
return;
}
preg_match_all('|<a.*(?=href=\"([^\"]*)\")[^>]*>([^<]*)</a>|i', $post->post_content, $match);
$new_content = $post->post_content;
foreach($match[1] as $link){
$url = 'https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyAnw98CCy5owhpgB2HvW3SkoXfm0MrLjks';
$json_data = json_encode( array( 'longUrl' => $link ) );
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$result = json_decode($result);
$new_content = str_replace($link, $result->id, $new_content);
}
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'save_book_meta' );
$post_new = array(
'ID' => $post_id,
'post_content' => $new_content
);
$post_id = wp_update_post( $post_new, true );
if (is_wp_error($post_id)) {
$errors = $post_id->get_error_messages();
foreach ($errors as $error) {
echo $error;
}
}
add_action( 'save_post', 'save_book_meta' );
}
Чтобы достичь вышеуказанного, вам нужно будет сделать следующее:
- Используйте
save_post
для получения сообщения после сохранения.
- В этом крюке выберите все внешние ссылки в массиве (измените
условия согласно требованиям).
- Сократите URL-адрес с помощью API Google (требуется ключ).
- Получите ответ от API Google и обновите post_data
соответственно в базе данных.
- В
wp_update_post
мы удаляем крючок, чтобы избежать бесконечного цикла.
2nd Way: Чтобы показать URL-адрес укороченного пользователя в интерфейсе (у DB будет longUrl, хотя)
- Вместо этого используйте крючок фильтра и с той же логикой.
3rd Way: использование плагинов (не используется лично).
Ответ 4
Я не совершенен в TinyMCE, потому что я не использовал TinyMCE в нескольких проектах, но у меня есть опыт работы с javascript, поэтому я нашел какое-то событие TinyMCE api для использования, вы можете сделать короткий URL-адрес. Я проверил последнюю версию WP и версию TinyMCE 4.x. Вы также можете найти подходящий api для запуска пользовательского обратного вызова.
Перед инициализацией tinymce в функции настройки регистра регистратора wordpress с помощью клавиши wordpress tiny_mce_before_init.
add_filter( 'tiny_mce_before_init', 'my_plugin_tiny_mce_before_init' );
function my_plugin_tiny_mce_before_init( $in ){
$in['setup'] = 'myplugin_tinymce_setup'; // javascript callback
return $in;
}
add_action( 'admin_footer', 'add_admin_footer' );
После добавления обратного вызова javascript в нижний колонтитул администратора. У меня есть два метода для этого решения.
# 1
function add_admin_footer(){
?>
<script type="text/javascript">
var counter = 1, insert_url, shorten_url;
function myplugin_tinymce_setup( editor ){
editor.onNodeChange.add(function(ed, cm, e) {
// Activates the link button when the caret is placed in a anchor element
if (e.nodeName.toLowerCase() == 'a'){
var element = jQuery(e).not('a[href="_wp_link_placeholder"],a[data-wplink-edit="true"]');
if( element.length ){
if( is_shorten = getShortenUrl( element.attr( 'href') ) ){
element.attr( 'href', is_shorten );
element.attr( 'data-mce-href', is_shorten );
}
}
}
});
var hostname = new RegExp(location.host);
var shorten_host = new RegExp('http://www.example.com'); // enter your short url generate host name
function getShortenUrl( url ){
// add more condition here...
// Add here ajax or shorten javascript api etc.
// filter and return short url
if( hostname.test( url ) ){
// internal link
// Return internal url with shorten
return 'http://www.example.com/Internal/'+counter++;
}else if( shorten_host.test( url ) ){
// not update already update with shorten url
return false;
}else{
// Return external url with shorten
return 'http://www.example.com/External/'+counter++;
}
}
</script>
<?php
![Сокращение ссылки WP в редакторе]()
# 2
function add_admin_footer(){
?>
<script type="text/javascript">
var counter = 1, insert_url, shorten_url;
function myplugin_tinymce_setup( editor ){
editor.on('ExecCommand', function(e) {
// Eexcute command when click on button apply on insert/edit link
if( e.command == 'wp_link_apply' ){
if( editor.selection.getContent() ){
element = tinymce.$(editor.selection.getContent()); // Create new link
}else{
element = tinymce.$(editor.selection.getNode()); // Edit link option
}
if( element.prop('tagName').toLowerCase() == 'a' ){
current_link_url = element.attr('href'); // Real url added in editor.
// and also check current_link_url is not shorten url
// add more logic here. Get short url using ajax or bitly javascript api.
if( is_shorten_url = getShortenUrl( element.attr('href')) ){
editor.execCommand('mceInsertLink',false,{ href: is_shorten_url });
}
}
}
});
}
var hostname = new RegExp(location.host);
var shorten_host = new RegExp('http://www.example.com'); // enter your short url generate host name
function getShortenUrl( url ){
// add more condition here...
// Add here ajax or shorten javascript api etc.
// filter and return short url
if( hostname.test( url ) ){
// internal link
// Return internal url with shorten
return 'http://www.example.com/Internal/'+counter++;
}else if( shorten_host.test( url ) ){
// not update already update with shorten url
return false;
}else{
// Return external url with shorten
return 'http://www.example.com/External/'+counter++;
}
}
</script>
<?php
}
Желаем удачи:)