Q&A

ckeditor(ck에디터) 특정 게시판에만 제한된 글자수 적용하는 방법 문의

2025.01.28 17:03
114
0
CMS/프레임워크 Rhymix 2.1
개발 언어 PHP 8.0

안녕하세요

 

https://xetown.com/questions/1856633

위 링크와 같이 ckeditor 작성시 글자수 제한하는 방법을 성공 했는데

이게 전체 게시판에 적용이되버려서요

 

특정 게시판에만 적용하는 방법을 알수있을까요? ㅜㅜ

 

https://xetown.com/questions/1018742

이 게시물에 따르면 또 config.js 파일에 코드를 넣으라고 되어있는데

config.js 파일이 안보이니 ㅜㅜ

 

 

if(currrent_mid == 'MIDNAME'){
// CODE

 

이 코드를 넣으면 된다고하시는데 

위에 제가 해봤던 plugin.js 파일에 넣어봤는데 작동이 안되네요 ㅜㅜ

 

고수님 계시면 답변 좀 부탁드려요 ㅜ

Maxter Lv. 6
반가워요~

댓글 11

  • 2025.01.29 09:07 #1856734
    음 혹시 게시판마다 다른 에디터를 설정하는 방법으로 안되려나요? 에디터 글자수 제한 버젼과 없는 버젼을 따로 만들어서 각각 적용...
  • 2025.01.29 15:28 #1856770

    이런 방법도 있었나요!?!?!?!?

    게시판별로 에디터를 다르게 설정도 되나요?

  • 2025.01.29 15:42 #1856778
    게시판 설정 → 추가 설정 들어가셔서 하단부에 위지윅 에디터 설정 보시면..
  • 2025.01.29 15:58 #1856782
    우왓 이런 기능이 있었네요!
    이것도 시도해볼께요 감사합니다!
  • 2025.01.29 11:06 #1856738

    여기를 보면 https://github.com/rhymix/rhymix/blob/ff499c56e66d220d392a8e04d233feda523c189f/common/js/plugins/ckeditor/ckeditor/plugins/rx_paste/plugin.js#L57
    plugin.js 파일에서 mid가 인식되는 데 문제는 없는 것으로 보이는데요...

  • 2025.01.29 15:28 #1856766
    안녕하세요 윤삼님!
    새해 복 많이 받으세요!

    플러그인
    wordcount 폴더내에 있는 plugin.js에

    if(currrent_mid == 'MIDNAME'){
    // CODE
    }

    위 코드를 중간에 넣으니 적용은 되는것 같습니다 ㅜㅜ
    감사합니다

    근데 다른 문제가 발생되어서요
    다른 게시판에서 ckeditor를 제대로 못불러오는 문제가 발생해버리네요
    일부 파일 첨부화면이랑은 출력이 되는데 본문 글쓰기 화면이 출력이 안되서 글 작성 자체가
    안되는 문제가 발생을 ㅜㅜ

    아래는 wordcount 폴더내에 있는 plugin.js 파일 코드인데요
    여기 어디에 위 게시판 지정 코드를 넣어야하는지 알려주실수 있으신가요? ㅜㅜ

    /**
    * @license Copyright (c) CKSource - Frederico Knabben. All rights reserved.
    * For licensing, see LICENSE.html or http://ckeditor.com/license
    */

    CKEDITOR.plugins.add("wordcount", {
    lang: "ar,ca,cs,da,de,el,en,es,eu,fa,fi,fr,he,hr,hu,it,ja,nl,no,pl,pt,pt-br,ru,sk,sv,tr,zh-cn,zh", // %REMOVE_LINE_CORE%
    version: 1.17,
    requires: 'htmlwriter,notification,undo',
    bbcodePluginLoaded: false,
    onLoad: function(editor) {
    CKEDITOR.document.appendStyleSheet(this.path + "css/wordcount.css");
    },
    init: function (editor) {
    var defaultFormat = "",
    intervalId,
    lastWordCount = -1,
    lastCharCount = -1,
    limitReachedNotified = false,
    limitRestoredNotified = false,
    snapShot = editor.getSnapshot(),
    notification = null;


    var dispatchEvent = function (type, currentLength, maxLength) {
    if (typeof document.dispatchEvent == 'undefined') {
    return;
    }

    type = 'ckeditor.wordcount.' + type;

    var cEvent;
    var eventInitDict = {
    bubbles: false,
    cancelable: true,
    detail: {
    currentLength: currentLength,
    maxLength: maxLength
    }
    };

    try {
    cEvent = new CustomEvent(type, eventInitDict);
    } catch (o_O) {
    cEvent = document.createEvent('CustomEvent');
    cEvent.initCustomEvent(
    type,
    eventInitDict.bubbles,
    eventInitDict.cancelable,
    eventInitDict.detail
    );
    }

    document.dispatchEvent(cEvent);
    };

    // Default Config
    var defaultConfig = {
    showRemaining: false,
    showParagraphs: false,
    showWordCount: false,
    showCharCount: true,
    countBytesAsChars: false,
    countSpacesAsChars: false,
    countHTML: false,
    countLineBreaks: false,
    hardLimit: true,

    //MAXLENGTH Properties
    maxWordCount: -1,
    maxCharCount: 300,

    // Filter
    filter: null,

    // How long to show the 'paste' warning
    pasteWarningDuration: 0,

    //DisAllowed functions
    wordCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
    dispatchEvent('wordCountGreaterThanMaxLengthEvent', currentLength, maxLength);
    },
    charCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
    dispatchEvent('charCountGreaterThanMaxLengthEvent', currentLength, maxLength);
    },

    //Allowed Functions
    wordCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
    dispatchEvent('wordCountLessThanMaxLengthEvent', currentLength, maxLength);
    },
    charCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
    dispatchEvent('charCountLessThanMaxLengthEvent', currentLength, maxLength);
    }
    };

    // Get Config & Lang
    var config = CKEDITOR.tools.extend(defaultConfig, editor.config.wordcount || {}, true);

    if (config.showParagraphs) {
    defaultFormat += editor.lang.wordcount.Paragraphs + " %paragraphs%";
    }

    if (config.showParagraphs && (config.showWordCount || config.showCharCount)) {
    defaultFormat += ", ";
    }

    if (config.showWordCount) {
    if (config.maxWordCount > -1) {
    if (config.showRemaining) {
    defaultFormat += "%wordCount% " + editor.lang.wordcount.WordCountRemaining;
    } else {
    defaultFormat += editor.lang.wordcount.WordCount + " %wordCount%";

    defaultFormat += "/" + config.maxWordCount;
    }
    } else {
    defaultFormat += editor.lang.wordcount.WordCount + " %wordCount%";
    }
    }

    if (config.showCharCount && config.showWordCount) {
    defaultFormat += ", ";
    }

    if (config.showCharCount) {
    if (config.maxCharCount > -1) {
    if (config.showRemaining) {
    defaultFormat += "%charCount% " + editor.lang.wordcount[config.countHTML
    ? "CharCountWithHTMLRemaining"
    : "CharCountRemaining"];
    } else {
    defaultFormat += editor.lang.wordcount[config.countHTML
    ? "CharCountWithHTML"
    : "CharCount"] + " %charCount%";

    defaultFormat += "/" + config.maxCharCount;
    }
    } else {
    defaultFormat += editor.lang.wordcount[config.countHTML ? "CharCountWithHTML" : "CharCount"] + " %charCount%";
    }
    }

    var format = defaultFormat;

    bbcodePluginLoaded = typeof editor.plugins.bbcode != 'undefined';

    function counterId(editorInstance) {
    return "cke_wordcount_" + editorInstance.name;
    }

    function counterElement(editorInstance) {
    return document.getElementById(counterId(editorInstance));
    }

    function strip(html) {
    if (bbcodePluginLoaded) {
    // stripping out BBCode tags [...][/...]
    return html.replace(/\[.*?\]/gi, '');
    }

    var tmp = document.createElement("div");

    // Add filter before strip
    html = filter(html);

    tmp.innerHTML = html;

    if (tmp.textContent == "" && typeof tmp.innerText == "undefined") {
    return "";
    }

    return tmp.textContent || tmp.innerText;
    }

    /**
    * Implement filter to add or remove before counting
    * @param html
    * @returns string
    */
    function filter(html) {
    if(config.filter instanceof CKEDITOR.htmlParser.filter) {
    var fragment = CKEDITOR.htmlParser.fragment.fromHtml(html),
    writer = new CKEDITOR.htmlParser.basicWriter();
    config.filter.applyTo( fragment );
    fragment.writeHtml( writer );
    return writer.getHtml();
    }
    return html;
    }

    function countCharacters(text, editorInstance) {
    if (config.countHTML) {
    return (filter(text).length);
    } else {
    var normalizedText;

    // strip body tags
    if (editor.config.fullPage) {
    var i = text.search(new RegExp("<body>", "i"));
    if (i != -1) {
    var j = text.search(new RegExp("</body>", "i"));
    text = text.substring(i + 6, j);
    }

    }

    normalizedText = text;

    if (!config.countSpacesAsChars) {
    normalizedText = text.replace(/\s/g, "").replace(/&nbsp;/g, "");
    }

    if (config.countLineBreaks) {
    normalizedText = normalizedText.replace(/(\r\n|\n|\r)/gm, "");
    } else {
    normalizedText = normalizedText.replace(/(\r\n|\n|\r)/gm, "").replace(/&nbsp;/gi, " ");
    }

    normalizedText = strip(normalizedText).replace(/^([\t\r\n]*)$/, "");

    return config.countBytesAsChars ? (countBytes(normalizedText)) : (normalizedText.length);
    }
    }

    function countBytes(text) {
    var count = 0, stringLength = text.length, i;
    text = String(text || "");
    for (i = 0; i < stringLength; i++) {
    var partCount = encodeURI(text[i]).split("%").length;
    count += partCount == 1 ? 1 : partCount - 1;
    }
    return count;
    }

    function countParagraphs(text) {
    return (text.replace(/&nbsp;/g, " ").replace(/(<([^>]+)>)/ig, "").replace(/^\s*$[\n\r]{1,}/gm, "++").split("++").length);
    }

    function countWords(text) {
    var normalizedText = text.
    replace(/(\r\n|\n|\r)/gm, " ").
    replace(/^\s+|\s+$/g, "").
    replace("&nbsp;", " ");

    normalizedText = strip(normalizedText);

    var words = normalizedText.split(/\s+/);

    for (var wordIndex = words.length - 1; wordIndex >= 0; wordIndex--) {
    if (words[wordIndex].match(/^([\s\t\r\n]*)$/)) {
    words.splice(wordIndex, 1);
    }
    }

    return (words.length);
    }

    function limitReached(editorInstance, notify) {
    limitReachedNotified = true;
    limitRestoredNotified = false;

    if (config.hardLimit) {
    editorInstance.loadSnapshot(snapShot);
    // lock editor
    editorInstance.config.Locked = 1;
    }

    if (!notify) {
    counterElement(editorInstance).className = "cke_path_item cke_wordcountLimitReached";
    editorInstance.fire("limitReached", {firedBy: "wordCount.limitReached"}, editor);
    }
    }

    function limitRestored(editorInstance) {
    limitRestoredNotified = true;
    limitReachedNotified = false;
    editorInstance.config.Locked = 0;
    snapShot = editor.getSnapshot();

    counterElement(editorInstance).className = "cke_path_item";
    }

    function updateCounter(editorInstance) {
    var paragraphs = 0,
    wordCount = 0,
    charCount = 0,
    text;

    // BeforeGetData and getData events are fired when calling
    // getData(). We can prevent this by passing true as an
    // argument to getData(). This allows us to fire the events
    // manually with additional event data: firedBy. This additional
    // data helps differentiate calls to getData() made by
    // wordCount plugin from calls made by other plugins/code.
    editorInstance.fire("beforeGetData", {firedBy: "wordCount.updateCounter"}, editor);
    text = editorInstance.getData(true);
    editorInstance.fire("getData", {dataValue: text, firedBy: "wordCount.updateCounter"}, editor);

    if (text) {
    if (config.showCharCount) {
    charCount = countCharacters(text, editorInstance);
    }

    if (config.showParagraphs) {
    paragraphs = countParagraphs(text);
    }

    if (config.showWordCount) {
    wordCount = countWords(text);
    }
    }


    var html = format.replace("%paragraphs%", paragraphs);

    if (config.showRemaining) {
    if (config.maxCharCount >= 0) {
    html = html.replace("%charCount%", config.maxCharCount - charCount);
    } else {
    html = html.replace("%charCount%", charCount);
    }

    if (config.maxWordCount >= 0) {
    html = html.replace("%wordCount%", config.maxWordCount - wordCount);
    } else {
    html = html.replace("%wordCount%", wordCount);
    }
    } else {
    html = html.replace("%wordCount%", wordCount).replace("%charCount%", charCount);
    }

    (editorInstance.config.wordcount || (editorInstance.config.wordcount = {})).wordCount = wordCount;
    (editorInstance.config.wordcount || (editorInstance.config.wordcount = {})).charCount = charCount;

    if (CKEDITOR.env.gecko) {
    counterElement(editorInstance).innerHTML = html;
    } else {
    counterElement(editorInstance).innerText = html;
    }

    if (charCount == lastCharCount && wordCount == lastWordCount) {
    if (charCount == config.maxCharCount || wordCount == config.maxWordCount) {
    snapShot = editor.getSnapshot();
    }
    return true;
    }

    //If the limit is already over, allow the deletion of characters/words. Otherwise,
    //the user would have to delete at one go the number of offending characters
    var deltaWord = wordCount - lastWordCount;
    var deltaChar = charCount - lastCharCount;

    lastWordCount = wordCount;
    lastCharCount = charCount;

    if (lastWordCount == -1) {
    lastWordCount = wordCount;
    }
    if (lastCharCount == -1) {
    lastCharCount = charCount;
    }

    // Check for word limit and/or char limit
    if ((config.maxWordCount > -1 && wordCount > config.maxWordCount && deltaWord > 0) ||
    (config.maxCharCount > -1 && charCount > config.maxCharCount && deltaChar > 0)) {

    limitReached(editorInstance, limitReachedNotified);
    } else if ((config.maxWordCount == -1 || wordCount <= config.maxWordCount) &&
    (config.maxCharCount == -1 || charCount <= config.maxCharCount)) {

    limitRestored(editorInstance);
    } else {
    snapShot = editorInstance.getSnapshot();
    }

    // Fire Custom Events
    if (config.charCountGreaterThanMaxLengthEvent && config.charCountLessThanMaxLengthEvent) {
    if (charCount > config.maxCharCount && config.maxCharCount > -1) {
    config.charCountGreaterThanMaxLengthEvent(charCount, config.maxCharCount);
    } else {
    config.charCountLessThanMaxLengthEvent(charCount, config.maxCharCount);
    }
    }

    if (config.wordCountGreaterThanMaxLengthEvent && config.wordCountLessThanMaxLengthEvent) {
    if (wordCount > config.maxWordCount && config.maxWordCount > -1) {
    config.wordCountGreaterThanMaxLengthEvent(wordCount, config.maxWordCount);

    } else {
    config.wordCountLessThanMaxLengthEvent(wordCount, config.maxWordCount);
    }
    }

    return true;
    }

    editor.on("key", function (event) {
    if (editor.mode === "source") {
    updateCounter(event.editor);
    }
    }, editor, null, 100);

    editor.on("change", function (event) {
    updateCounter(event.editor);
    }, editor, null, 100);

    editor.on("uiSpace", function (event) {
    if (editor.elementMode === CKEDITOR.ELEMENT_MODE_INLINE) {
    if (event.data.space == "top") {
    event.data.html += "<div class=\"cke_wordcount\" style=\"\"" +
    " title=\"" +
    editor.lang.wordcount.title +
    "\"" +
    "><span id=\"" +
    counterId(event.editor) +
    "\" class=\"cke_path_item\">&nbsp;</span></div>";
    }
    } else {
    if (event.data.space == "bottom") {
    event.data.html += "<div class=\"cke_wordcount\" style=\"\"" +
    " title=\"" +
    editor.lang.wordcount.title +
    "\"" +
    "><span id=\"" +
    counterId(event.editor) +
    "\" class=\"cke_path_item\">&nbsp;</span></div>";
    }
    }

    }, editor, null, 100);

    editor.on("dataReady", function (event) {
    updateCounter(event.editor);
    }, editor, null, 100);

    editor.on("paste", function(event) {
    if (config.maxWordCount > 0 || config.maxCharCount > 0) {

    // Check if pasted content is above the limits
    var wordCount = -1,
    charCount = -1;

    // BeforeGetData and getData events are fired when calling
    // getData(). We can prevent this by passing true as an
    // argument to getData(). This allows us to fire the events
    // manually with additional event data: firedBy. This additional
    // data helps differentiate calls to getData() made by
    // wordCount plugin from calls made by other plugins/code.
    event.editor.fire("beforeGetData", {firedBy: "wordCount.onPaste"}, event.editor);
    var text = event.editor.getData(true);
    event.editor.fire("getData", {dataValue: text, firedBy: "wordCount.onPaste"}, event.editor);

    text += event.data.dataValue;

    if (config.showCharCount) {
    charCount = countCharacters(text, event.editor);
    }

    if (config.showWordCount) {
    wordCount = countWords(text);
    }


    // Instantiate the notification when needed and only have one instance
    if(notification === null) {
    notification = new CKEDITOR.plugins.notification(event.editor, {
    message: event.editor.lang.wordcount.pasteWarning,
    type: 'warning',
    duration: config.pasteWarningDuration
    });
    }

    if (config.maxCharCount > 0 && charCount > config.maxCharCount && config.hardLimit) {
    if(!notification.isVisible()) {
    notification.show();
    }
    event.cancel();
    }

    if (config.maxWordCount > 0 && wordCount > config.maxWordCount && config.hardLimit) {
    if(!notification.isVisible()) {
    notification.show();
    }
    event.cancel();
    }
    }
    }, editor, null, 100);

    editor.on("afterPaste", function (event) {
    updateCounter(event.editor);
    }, editor, null, 100);

    editor.on("blur", function () {
    if (intervalId) {
    window.clearInterval(intervalId);
    }
    }, editor, null, 300);
    }
    });
  • 2025.01.29 23:40 #1856817
    저도 잘은 모릅니다ㅎㅎ
    근데 init 함수 안의 내용을 실행하지 못하도록 하면 되지 않을까요?
    예컨대 https://github.com/w8tcha/CKEditor-WordCount-Plugin/blob/master/wordcount/plugin.js 여기 파일의 16행에
    if(currrent_mid !== 'MIDNAME') return;
    같은 걸 넣어주면 어떨까 싶네요.
  • 2025.01.30 01:33 #1856825
    고맙습니다! 윤삼님! 좋은 하루 되세요!!
  • 2025.02.14 05:42 #1858873
    안녕하세요.
    특정 게시판에 글자수 제한 성공하셨나요?
    성공하셨으면 해당 내용 공유 가능할까요?
  • 2025.02.16 15:11 #1859160
    결론부터 말씀드리자면 특정 게시판에 글자수 제한하는건 실패 했구요 ㅜ

    위에 맘잉님이 말씀해주신 방법으로 우회 적용해보시는게 쉽고 간단한 방법 같아요
    -----------------------------------------------------------------------------------------------------------
    음 혹시 게시판마다 다른 에디터를 설정하는 방법으로 안되려나요? 에디터 글자수 제한 버젼과 없는 버젼을 따로 만들어서 각각 적용...
  • 2025.02.18 04:25 #1859352
    아... 그렇군요.
    시간날 때 한 번 도전해봐야겠군요.