WordPress 플러그인 – Visual Editor Custom Buttons (TinyMCE에서 사용자 지정 버튼 지원)

 반드시 이 플러그인의 소스폴더를 Git 저장소로 만들어 관리해야 한다

특정 버튼을 수정하더라도 이미 생성된 다른 버튼 관련 .css, .js 파일까지 초기화하기 때문이다.  

코드를 완전히 뜯어고쳐서 해당 버튼에 대해서만 JS/CSS를 생성하고 저장하게 함. 아울러 JS 내용을 DB에 저장할 수 있게 변경했다.

 

 사용하는 테마에 적용한 Custom CSS를 동일하게 TinyMCE에 적용할 것

css/editor-style.css 파일을 테마에 적용한 Custom CSS와 동일하게 할 것.

에디터가 열릴 때 적용되는 CSS 순서에 주의해야 한다. PrismJS 관련 설정이 제대로 동작하려면 모든 WP 관련 CSS 다음, 그리고 Global Custom CSS 사이에 PrismJS Theme CSS가 와야 한다. (아래 코드의 35~44 라인 참조)

 

 Custom JS 적용시 타이밍에 주의

에디터 내의 document 객체에 접근하기는 쉽지만 페이지 로딩이 끝난 후 Action을 처리하도록 신경 써야 한다.

다른 플러그인의 컨텐츠 변경 로직과 충돌 할 수 있으므로 PrismJS 로딩 기능같은 걸 자동으로 놓지 말 것.

버튼 누르기 귀찮아서 ready 후 1초 뒤에 자동 로딩하게 수정함. 별다른 문제없다. 코드관련 글이 많아서 디폴트로 자동로딩하는게 좋긴한데, 이것도 옵션처리 해야 함.  Todo   

 

 예시: PrismJS 로더

// JavaScript Document
function getBaseURL () {
   return location.protocol + '//' + location.hostname +
      (location.port && ':' + location.port) + '/';
}
(function() {
    tinymce.create('tinymce.plugins.vecb_button10', {
        init : function(ed, url) {
            ed.addButton('vecb_button10', {
                title : '항목 표식',image : 'http://andrwj.com/wp-content/uploads/vecb/right-arrow.png',onclick : function() {
                     ed.selection.setContent('  |');
                }
            });
        },
        createControl : function(n, cm) {
            return null;
        },
    });
    tinymce.PluginManager.add('vecb_button10', tinymce.plugins.vecb_button10);
})();
➜  js git:(master) cat button-1-9.js
// JavaScript Document
function getBaseURL () {
   return location.protocol + '//' + location.hostname +
      (location.port && ':' + location.port) + '/';
}
let is_prismjs_loaded = false;
(function() {
  tinymce.create('tinymce.plugins.vecb_button9', {
    init : function(ed, url) {
      ed.addButton('vecb_button9', {
        title : 'Apply PrismJS',image : url+'/icons/magic.png',onclick : function() {
          if(is_prismjs_loaded) return;

          const doc = ed.dom.doc;
          const head = doc.getElementsByTagName('head')[0];
          const base ='/wp-content/plugins/prismatic/lib/prism/';
          const lastWPstyleNode = [...head.childNodes].filter(node => node.rel === 'stylesheet' && /wp\-custom\-style\.css/.test(node.href) ).pop();
          const link = document.createElement("link");
          link.setAttribute("rel", "stylesheet");
          link.setAttribute("type", "text/css");
          link.setAttribute("href", `${base}/css/theme-funky.css`);
          head.insertBefore(link, lastWPstyleNode);;

          ['prism-core.js', 'plugin-autoloader.js', 'plugin-toolbar.min.js',
           'plugin-normalize-whitespace.min.js', 'plugin-line-numbers.min.js', 'plugin-copy-to-clipboard.min.js'].forEach((lib) => {
             const script = doc.createElement('script');
             script.type = 'text/javascript';
             script.async = false;
             script.src = `${base}/js/${lib}`;
             head.appendChild(script);
           });
        }
      });
    },
    createControl : function(n, cm) {
      return null;
    },
  });
  tinymce.PluginManager.add('vecb_button9', tinymce.plugins.vecb_button9);
})();

 

 

 정렬 버그 수정 (2019-08-09)

원본 소스코드에서 버튼 루프를 돌며 처리하는 부분에서는 기존 파일을 수정하는 과정은 고려대상이 아니고 Over Write 만 하도록 되어 있다.  특정 파일만을 수정하기 위해서는 정렬된 상태로 루프를 돌아야 하는데 처리되어 있지 않았다. 

$args = array( 'post_type' => 'vecb_editor_buttons',
   'posts_per_page' => -1,
   'suppress_filters' => true,  //<-- 이 라인을 넣어줘야 'ASC'로 동작한다
   'orderby' => 'ID',
   'order' => 'ASC');