web-dev-qa-db-ja.com

WYSIWYGエディタによって挿入されたときにリンクを変更する

WYSIWYGエディタを介して内部コンテンツへのリンクが挿入された場合、そのリンクされた投稿の投稿IDがリンクのデータ属性として追加されるように、WordPressのエディタにフックする可能性はありますか?

6
luke

挿入された内部リンクのHTMLはJavascriptによって生成されているので、それを変更する簡単な方法はわかりません。

HTMLの生成は、wpLink.htmlUpdateファイル内のwpLink.mceUpdateメソッド(HTMLモード)および/wp-includes/js/wplink.jsメソッド(TinyMCEモード)から制御されます。

ここにいくつかのアイデアがあります:

挿入したリンクにクエリパラメータを追加します。

投稿ID情報を含むクエリパラメータを、挿入されたリンクのURLに追加できます。次に例を示します。

http://example.dev/hello-world/?wpse_pid=475

次のように:

/**
 * Append the wpse_pid query argument to inserted links
 *
 * @see http://wordpress.stackexchange.com/a/170836/26350
 */

add_filter( 'wp_link_query_args', function( $query ) {
    add_filter( 'post_link', 'wpse_post_link', 10, 2 );
    return $query;
});

add_filter( 'wp_link_query', function( $query ) {
    remove_filter( 'post_link', 'wpse_post_link', 10 );
    return $query;   
});

function wpse_post_link( $permalink, $post )
{
    if( false === stripos( $permalink, '?p=' ) )
            $permalink = add_query_arg( array( 'wpse_pid' => $post->ID ), $permalink );
    return $permalink;
}

これが実行中のスクリーンショットです。

link with the wpse_pid parameter

wpLink.mceUpdateメソッドをオーバーライドします。

メソッドは将来変更される可能性があるので、次のハックはただの楽しみのためです。

これは上記のコードスニペットへの追加です。

/** 
 * Override the wpLink.mceUpdate method to modify the inserted link HTML.
 *
 * @see http://wordpress.stackexchange.com/a/170836/26350
 */

add_action( 'admin_footer-post.php', function(){
?>
<script>
jQuery( document ).ready( function( $ ){
    wpLink.mceUpdate = function(){
            var link,
            attrs = wpLink.getAttrs(),
            editor = tinyMCE.activeEditor;

            wpLink.close();
            editor.focus();

            if ( tinymce.isIE ) {
                editor.selection.moveToBookmark( editor.windowManager.bookmark );
            }
            link = editor.dom.getParent( editor.selection.getNode(), 'a[href]' );

            // If the values are empty, unlink and return
            if ( ! attrs.href || attrs.href == 'http://' ) {        
                editor.execCommand( 'unlink' );
                return;
            }

            // Set the class attribute.
            attrs.class = 'wpse_pid';

            // Grab the value of the wpse_pid parameter and use as id attribute.
            // Modified version of http://www.sitepoint.com/url-parameters-jquery/
            var results = new RegExp('[\?&]wpse_pid=([^&#]*)').exec( attrs.href );
            attrs.id = ( results != null ) ? 'wpse_pid_' + results[1] : ''

            // Remove the ?wpse_pid=* part
            // Modified version of http://stackoverflow.com/a/7126657/2078474
            attrs.href = attrs.href.replace(/[\?&]?wpse_pid=([^&]$|[^&]*)/i, "");

            if ( link ) {
                editor.dom.setAttribs( link, attrs );
            } else {
                editor.execCommand( 'mceInsertLink', false, attrs );
            }

            // Move the cursor to the end of the selection
            editor.selection.collapse();
    }
});
</script>
<?php
}, 99 );

挿入されたリンクのHTMLは次の形式になります。

<a id="wpse_pid_475" 
   class="wpse_pid"  
   title="Hello World" 
   href="http://example.dev/hello-world/">Hello World</a>

変更されていないリンクは次のとおりです。

<a title="Hello World" 
   href="http://example.dev/hello-world/">Hello World</a>

ここではclassとid属性を使用しました。これらは tinyMCE エディタによってサポートされている属性のようだからです。 attrs.dataを試しましたが、うまくいきませんでした。もっと深く見たいと思うかもしれません。

wpLink.htmlUpdateメソッドをオーバーライドするのと似ているはずです。しかし、これは単なる概念の証明です;-)

もう1つのアイデアは、更新中に投稿コンテンツのリンクをスキャンして、それらを巧妙な正規表現の置き換えやPHP DOMの変更で修正することです。

うまくいけば、あなたはこれをさらに進めてあなたのニーズに合わせて修正することができます。

6
birgire