WordPress 与 ACE Editor 集成

ace editor within wordpress post

Ace Editor 是一款完全用 JavaScript 写的可用于浏览器的文本及代码编辑器,支持非常多的格式,语法高亮超过 120种语言。由于其丰富的功能,高性能,可以编辑多达 400万行代码的文档,同时又易于集成,获得了广泛的应用。Ace Editor 目前是完全开源的。

本篇文章介绍如何实现在文章中加载 Ace Editor,通过 Ajax 提取后台服务器端的文档内容,然后显示在编辑器中,编辑完成后可以保存到后台。有关 WordPress Ajax 方面的使用方法请参看这篇文章的相关内容。

一、创建一篇文档

在需要显示 Ace Editor 的位置创建两个按钮区块,像下面这样:

按钮的 “链接rel” 中写入 “test.php”,
高级设置中的 HTML 锚点输入 “load_file”。

按钮高级设置中的 HTML 锚点输入 “save_file” 。

在按钮下面的位置创建自定义 HTML 区块,并填写下面的代码:

<div id="wp-ace-container" style="height:500px; width:100%;">
    <div>
        <h3 id="wp-ace-filename" style="display: inline;"></h3>
        <span>文件内容将显示在下面</span>
    </div>
    <div id="wp-ace-content" style="display:block; position: relative; border: 1px solid;height: -webkit-fill-available; width:100%"></div>
</div>

<script>
    var editor = ace.edit("wp-ace-content");
    editor.setPrintMarginColumn(false);
    editor.setTheme("ace/theme/chrome");  //设置主题
    editor.renderer.setVScrollBarAlwaysVisible(true);  //滚动设置
    editor.renderer.setHScrollBarAlwaysVisible(true);
    var phpMode = ace.require("ace/mode/php").Mode;  //代码模式,Php代码
    editor.getSession().setMode(new phpMode());

    jQuery(document).ready(function($) {
        filename = $("#load_file a").click(function(e) {
            //点击“载入文件”按钮的响应代码
            $("#wp-ace-filename").html(filename);
            //ajax调用的url、ace_nonce参数值由后台生成
            $.ajax({
        	    url : ace_ajax.ajax_url,
        	    type : 'post',
        	    data : {
            		action : 'ace_get_file',
            		file_name : filename,
        	    	ace_nonce : ace_ajax.ace_nonce
        	    },
        	    success : function( response ) {
        		    editor.getSession().setValue( response );
        		    $("#save_file a").attr("rel", filename);
        	    },
        	    error : function( response ) {
        		    console.log(response);
        	    }
            });
    
            $("#wp-ace-content textarea").focus();
        }).attr("rel");
        //点击“保存”按钮的响应代码,ajax调用的url、ace_nonce参数值由后台生成
        $("#save_file a").click(function(e) {
            filesavename = $("#save_file a").attr("rel");
            if(filesavename) {
                $.ajax({
            	    url : ace_ajax.ajax_url,
            	    type : 'post',
            	    data : {
                		action : 'ace_save_file',
                		file_name : filesavename,
                		ace_text: editor.getSession().getValue(),
            	    	ace_nonce : ace_ajax.ace_nonce
            	    },
            	    success : function( response ) {
            		    alert("Ok");
            	    },
            	    error : function( response ) {
            		    console.log(response);
            	    }
                });
            } else alert("No file name");
        });
    })
</script>

二、后端 Ajax 服务

后端服务就是调用 WordPress 基于操作系统的文件管理功能,比如打开文件、写入文件等,代码如下(使用插件方式实现,里面用到的一些函数、常量请参考这里):

<?php
// 在插件主目录中创建子目录“ace-1.5”,把 Ace Editor 代码拷贝到该目录中
// 在插件主目录中创建“js”子目录,插件有关的javascript代码放到该目录中,文件名比如叫ace-ajax-code.js
add_action( 'wp_footer', 'plugin_enqueue_scripts' );
function plugin_enqueue_scripts() {
	if(is_single())	{
		// wp_enqueue_script()的第一个参数要同wp_localize_script()一致
		wp_enqueue_script( 'ace-file', plugin_dir_url(__FILE__) . 'js/ace-ajax-code.js', array('jquery') );
		wp_enqueue_script('ace-1.5', plugin_dir_url(__FILE__) . 'ace-1.5/ace.js');
		wp_enqueue_script('ace-theme', plugin_dir_url(__FILE__) . 'ace-1.5/theme-chrome.js', array('ace-1.5') );  //选择主题代码供前端调用
		wp_enqueue_script('ace-mode', plugin_dir_url(__FILE__) . 'ace-1.5/mode-php.js', array('ace-1.5') );  //选择语言模式代码供前端调用
		//前端ajax调用的url、ace_nonce参数值在这生成
		wp_localize_script( 'ace-file', 'ace_ajax', array(
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'ace_nonce' => wp_create_nonce('ace-nonce')
		));
	}
}
//建立前端ajax调用后端服务的钩链
add_action( 'wp_ajax_nopriv_ace_get_file', 'ace_get_file' );
add_action( 'wp_ajax_ace_get_file', 'ace_get_file' );

add_action( 'wp_ajax_nopriv_ace_save_file', 'ace_save_file' );
add_action( 'wp_ajax_ace_save_file', 'ace_save_file' );
//获取文件内容
function ace_get_file() {
    check_ajax_referer( 'ace-nonce', 'ace_nonce' );

    global $wp_filesystem;
    $url = wp_nonce_url('admin.php?file_name=', 'ace_nonce');
    if (false === ($creds = request_filesystem_credentials($url, 'direct', false, false, null))) {
        return true;
    }
    if (!WP_Filesystem($creds))
    return false;
    //提前在 wordpress uploads目录中放一个 test.php 文件
    $root = apply_filters('ace_filesystem_root', WP_CONTENT_DIR);
    $file_name = $root . "/uploads/" . $_POST['file_name'];
    echo $wp_filesystem->get_contents($file_name);
    wp_die();
}
//保存文件内容
function ace_save_file() {
    check_ajax_referer( 'ace-nonce', 'ace_nonce' );

    global $wp_filesystem;
    $url = wp_nonce_url('admin.php?file_name=', 'ace_nonce');
    if (false === ($creds = request_filesystem_credentials($url, 'direct', false, false, null))) {
        return true;
    }
    if (!WP_Filesystem($creds))
    return false;

    $root = apply_filters('ace_filesystem_root', WP_CONTENT_DIR);
    $file_name = $root . "/uploads/" . $_POST['file_name'];
    $wp_filesystem->put_contents($file_name, stripslashes($_POST['ace_text']));
    wp_die();
}

三、保存文章并发布

像正常文章那样保存并发布后,点击该文章就可以看到加载 Ace Editor 后的界面,点击“载入文件”按钮就把后端的 test.php 文件的内容载入编辑器,然后就可以编辑其中的内容,点击“保存”按钮就把编辑好的内容保存到后端的服务器中。

ace editor within wordpress post
文章中使用 Ace Editor

另外,根据本篇文章介绍的方法,可以进一步拓展功能,如增加后台文件管理树,对后台的文件做编辑;再就是实现写代码的同时实时观看运行情况等。

发表评论

邮箱地址不会被公开。 必填项已用*标注