원댓글/대댓글 따로따로 애드온
자료 유형 | 애드온 |
---|---|
간단한 소개 | 원댓글만 리스트를 출력했다가, 대댓글은 ajax로 따로 로드하는 애드온 |
설치 경로 | ./addons/ap_comment_list |
코어 지원 범위 | Rhymix 2.0 |
PHP 지원 범위 | 기타 |
자료 구분 | 공개 자료 |
라이선스 | GPL v2 |
파일명 | 버전 | 날짜 | 용량 | 다운 |
---|---|---|---|---|
ap_comment_list.0.1.1.zip | 0.1.1 | 2022.03.29 | 6.5KB | 40 |
ap_comment_list.0.1.0.zip | 0.1.0 | 2022.03.28 | 6.5KB | 15 |
ap_comment_list.0.0.1.zip | 0.0.1 | 2022.03.26 | 15.1KB | 26 |
- 게시판 문서 로드시에는 원댓글만 로드했다가, 대댓글은 별도의 링크를 통해 ajax로 따로 로드하는 애드온입니다.
- 바로 실사용하기보다는, 충분한 테스트를 거쳐 버그 정보 및 개선 사항을 공유하고 함께 버전업을 한 뒤 실사용하시기를 권합니다.
- 이런 방식의 댓글 로딩은 몇 가지 장단점이 있을 것 같습니다.
- 장점 : 체계화된 댓글 출력, 포럼식 소통의 강화, 리소스 절약
- 단점 : 댓글 관련 서드 파티 자료들의 링크 방식을 대대적으로 손볼 필요가 있음(url에 comment_srl 파라미터가 있어야 좋습니다), 검색 엔진의 대댓글 접근 약화(이건 그냥 예상입니다)
- 애드온의 작동 방식, 적용 방법, 스킨 활용 등에 대한 보다 자세한 사항은 아래의 링크를 참고해주세요.
- 미리보기 : https://dev.aporia.blog/board_fKje47/40977
- 적용 방법 : https://dev.aporia.blog/board_fKje47/41206
업데이트 0.1.0 (2022.03.28)
- 코어의 dispBoardCommentPage 액션을 통해 사용 중인 스킨의 comment.html 부분을 직접 불러들임
1) 더 이상 애드온 스킨을 사용하지 않음
2) 0.1.0에서는 애드온 설정을 사용하지 않음
3) 외부 php 파일을 사용하지 않음
: 람보님 덕분에 애드온 구조가 훨씬 깔끔해졌습니다 :D
4) 다른 서드파티 자료들과의 호환성 강화
- 대댓글을 로드할 때 스크롤 이동을 하지 않음
- url에 comment_srl 파라미터만 있고 댓글번호에 해당하는 해시(#)가 없을 경우 자동으로 해시 첨가
- 기타 코드 및 파일 정리
* 기존 0.0.1 버전 사용자는 게시판 스킨의 _comment.html의 대댓글 링크에서 onclick 속성을 다음과 같이 바꿔주어야 합니다.
- onclick="getRecommentList(this, {$comment->comment_srl}); return false;"
업데이트 0.1.1 (2022.03.30)
- $target_head 변수의 스크립트 전달 구문 수정
- url로 대댓글 파라미터가 넘어왔을 때 head 번호를 가진 요소의 식별 방식 수정
- callback이 전달되지 않은 경우에 대비해서 코드 수정

댓글 90
{@
$target_mid = ModuleModel::getModuleInfo($val->get('module_srl'))->mid;
}
반복문 내에서 이렇게 선언을 해주면 타겟 mid를 잡을 수도 있을 것 같아요.
혹시 안 된다면 ModuleModel::getModuleInfo($val->get('module_srl'))을 print_r로 한번 찍어서 확인해보시구요.
근데 이게 궁극적으로는 mid값이 잘못돼서 코어가 url을 리다이렉트해주는 경우까지 애드온에서 고려를 하면 좋겠다는 생각은 드네요ㅎㅎ
한방에 찾아가네요.
이제 사용에 전혀 지장이 없습니다.
역시 윤삼님입니다👍
감사합니다.💕
적용한 코드 남깁니다.
<!--@ foreach($comment_list as $key => $val)-->
{@ $target_mid = ModuleModel::getModuleInfo($val->get('module_srl'))->mid;}
<div class="mhcomment">
<a href="{getUrl('', 'mid', $target_mid, 'document_srl',$val->get('document_srl'), 'comment_srl', $val->comment_srl)}#comment_{$val->get('comment_srl')}" title="">{$val->getSummary($wi->com_cut_size)}</a>
</div>
<!--@end-->
스케치북게시판이 예시라그런지 적용하기 쉽지가않네요..
꼭 적용하고 싶은데 slow 게시판 스킨의 구조가 많이다른듯합니다 ㅠㅠ 번거로우시겠지만 가능하시다면 구조를 확인한번 부탁드려도 괜찮을지요..
li 태그에있는 a href= 구조를 수정하는데 내용이 살짝다른듯합니다 ㅠㅠ
적어주신 순서대로 3부분을 모두수정했는데 제대로 작동이 안되구요.. 혹시 어떻게 수정해볼까요?
{@ // 페이지네이션 }
<div cond="$oDocument->comment_page_navigation" class="app-board-section-padding tw-border-b tw-border-gray-300">
<ul class="app-pagination">
<li>
<a href="{getUrl('cpage',1)}#comment" class="app-pagination-prev">
<ion-icon name="chevron-back-outline"></ion-icon>
</a>
</li>
<li loop="$page_no=$oDocument->comment_page_navigation->getNextPage()" class="app-active"|cond="$cpage == $page_no">
<a href="{getUrl('cpage',$page_no)}#comment">{$page_no}</a>
</li>
<li>
<a href="{getUrl('cpage',$oDocument->comment_page_navigation->last_page)}#comment" class="app-pagination-prev">
<ion-icon name="chevron-forward-outline"></ion-icon>
</a>
</li>
</ul>
</div>
테스트페이지 주소입니다! https://svrforum.com/test/217712
- 페이지네이션 링크는 다음과 같이 getUrl 안쪽에 'comment_srl', '', 을 넣어주시면 됩니다.
{@ // 페이지네이션 }
<div cond="$oDocument->comment_page_navigation" class="app-board-section-padding tw-border-b tw-border-gray-300">
<ul class="app-pagination">
<li>
<a href="{getUrl('comment_srl', '', 'cpage',1)}#comment" class="app-pagination-prev">
<ion-icon name="chevron-back-outline"></ion-icon>
</a>
</li>
<li loop="$page_no=$oDocument->comment_page_navigation->getNextPage()" class="app-active"|cond="$cpage == $page_no">
<a href="{getUrl('comment_srl', '', 'cpage',$page_no)}#comment">{$page_no}</a>
</li>
<li>
<a href="{getUrl('comment_srl', '', 'cpage',$oDocument->comment_page_navigation->last_page)}#comment" class="app-pagination-prev">
<ion-icon name="chevron-forward-outline"></ion-icon>
</a>
</li>
</ul>
</div>
바로적용해보겠습니다 늦은시간에 감사드립니다!
https://svrforum.com/test/217712
쪽지로 말씀드리긴 했는데 기록을 위해 댓글로도 남깁니다.
slow 게시판 스킨은 스킨 폴더에 바로 comment.html이 있는 구조가 아닙니다.
스킨으로서 체계적인 파일 관리를 위해 하위폴더들을 만든 것 같은데,
그래서 스킨의 최상위 지점(./modules/board/skins/slow)에서 comment.html을 누락한 것 같아요.
근데 그 위치에 그 파일이 있어야 이 애드온이 의존하는 dispBoardCommentPage라는 액션 실행이 가능해집니다.
다만, 꼼수를 쓴다면 스킨의 최상위 위치(./modules/board/skins/slow)에 comment.html을 더미로 하나 만들어놓고, 그 안에 <include target="components/comment/comment.html" /> 이라고 적어보세요.
제 예상이 맞다면 스킨에서 대댓글 링크를 누르면 바로 이 최상위 위치의 ./modules/board/skins/slow/comment.html을 불러들이게 될 겁니다.
그러면 실제의 댓글 코드가 담긴 ./modules/board/skins/slow/components/comment/comment.html 으로 자동 연결되겠죠.
그렇게 해서 성공을 한다면 다행인데,
만약 그렇게 해도 목록 로딩이 안 된다면 다른 방법은 없을 것 같습니다.
덧. 만약 목록 로딩에 성공한다면 댓글 및 대댓글 삭제 테스트도 부탁드립니다. 댓글 삭제가 별도의 js 함수와 연동되는 것으로 보이는데 호환성이 어떨지 궁금합니다 :)
말씀해주신대로 진행하였습니다.
일단 대댓글을 눌렀을때 댓글이 잘보입니다!
다만 문제점이 몇가지있는데
1. 댓글/대댓글 작성시 글 최하단으로 스크롤 이동 및 대댓글창 접힘
2. 대댓글의 수정/삭제/신고를 위한 ```클릭시 무반응(삭제 테스트를 못합니다 ㅠㅠ)
정도있는것같습니다.
https://svrforum.com/test/217712
바쁘신와중에도 하나하나확인해주시고 정말감사드립니다ㅠㅠ
혹시 댓글 작성시 새로고침 없이 새 댓글이 로드되는 방식인가요?
스크롤이 최하단으로 이동하는 건 이해가 잘 안 되긴 하네요. 새 댓글이 페이지에 존재할 때 스크롤 이동 명령이 있긴 한데 이게 작동을 한다면 새 댓글의 top으로 가야 하거든요. 없으면 스크롤 이동은 없구요.
1-2.
대댓글창 접힘은 혹시 모르니 대댓글 작성 직후 개발자 도구 콘솔창에서 current_url 라고 입력해보시겠어요? 댓글 작성후 url 세팅이 어떻게 되는지 확인이 필요할 것 같습니다. 제 경우에는 url에 comment_srl이 잘 찍히는데, 그렇지 않은 경우에는 대댓글창이 열리지 않을 수 있습니다.
2. 이거는 해당 클릭 이벤트가 담겨 있는 js에서 이벤트를 수정해주든지, 아니면 애드온 js에 클릭 이벤트를 다시 넣어주든지 하면 될 거예요. 스킨에서 클릭 이벤트가 들어 있는 js를 찾아보시고, 말씀해주시면 한번 살펴보겠습니다~
답변감사드립니다.!
1. 넵 기본 댓글작성시 새로고침없이 새 댓글이 로드됩니다.
일반적인 상황에서는 댓글을 달아도 ajax로 댓글작성만 되고 화면 이동은 없긴합니다 ㅠㅠ
+아마 2번상황에서 댓글작성후에 대댓글창이 자동으로 접힘으로써 이동이 되는건 아닐까.. 의심해볼수도있을거같습니다
2 말씀해주신 콘솔창에서 current_url 명령시 아래처럼 나옵니다!
'https://svrforum.com/?document_srl=217712&mid=test&act=dispBoardContent'
2. components/comment/comment-vote/comment-vote.js 이파일인거같긴합니다!
그렇다면 애드온의 default.js의 jQuery(document).ready(function($) { 로 시작하는 부분 전체를 지워보고 한번 테스트해주시겠어요?
1-2. 역시 url에 comment_srl이 들어가 있지 않네요. 이게 코어에서는 새로고침했을 때 comment_srl이 들어가게 되어 있거든요. 그래야 뎃글 페이지를 자동 탐색할 수 있어서요. 현재 새로고침 없는 댓글 기능은 slow 게시판 스킨에서 자체 제공되는 것인가요? 아니면 rx_ajax 클래스명 삽입처럼 코어의 기능을 이용해서 자체적으로 기능을 구현하신 건가요?
2. 그 파일은 댓글 추천이나 추천 취소에 해당하더라구요. app-dropdown-menu라는 클래스에 active 클래스를 토글(추가 및 삭제)시켜주는 js는 따로 있는 것 같은데, 저도 위치를 못 찾겠더라구요;;;
1-1. 댓글 작성시 대댓글창이 접히면서 스크롤이 최 하단으로 이동합니다.
말씀해주신 jQuery쪽을 지워봤는데도 동일하네요 ㅠㅠ
1-2. 이건 기본스킨에는없었는데 별도로 의뢰해서 구현한거라서 정확히어떤방식인지는 모르겠습니다 ㅠㅠ
2. 헛.. 그렇군요 한번더 확인해보겠습니다.
++ 확인해보니 comment-item-actions.html 이 맞는거같습니다!
$(obj).attr('onclick', '$(this).closest(\'[id^=comment_]\').siblings(".app-board-comment-list").toggle(); return false;');
이것으로 바꿔보시겠어요?
원래 있던 14행은 주석 처리하구요.
'https://svrforum.com/?document_srl=217712&mid=test&act=dispBoardContent'
헛.. 그렇군요...ㅠㅠㅠㅠ 너무 아쉽지만.. 제능력밖의일이군요...
이것만 해결되면 어찌어찌 실사용은 될거같은데.. 장고의 고민을해봐야겠습니다 하하...
대댓글 작성하면 대댓글창이 닫히고 그 댓글만 보입니다. 대댓글 숫자는 카운팅 됩니다.
현재는 비회원도 해당게시판에 작성이되서 한번 테스트해보셔도 될듯합니다!
https://svrforum.com/test/217712
여기서도 댓글 작성 함수가 어느 js에 있는지를 찾는 게 관건일 것 같습니다...
function setTextareaReplaceComment() {
var str = document.getElementById("temp-{$oDocument->document_srl}").value;
str = "<p>" + str.replace(/(?:\r\n|\r|\n)/g, "</p>\r\n<p>") + "</p>";
str = str.replaceAll("<p></p>", "<p> </p>");
document.getElementById("editor-{$oDocument->document_srl}").value = str;
};
function refreshComments(data){
var comment_srl = data.comment_srl;
var selector = '.app-card.app-board-comment.app-board-section';
var refresh_url = current_url;
jQuery.get(refresh_url, function(response) {
var old_comment_area = jQuery(selector);
var new_comment_area = jQuery(response).find(selector);
old_comment_area.empty().append(new_comment_area.contents());
jQuery('#app-board-comment-list').find('.app-dropdown-toggle').on('click', function() {
jQuery(this).closest('.app-dropdown').toggleClass('active')
})
const appDropdown = jQuery('#app-board-comment-list').find('.app-dropdown-toggle')
jQuery(document).mouseup(e => {
if (!appDropdown.is(e.target) && appDropdown.has(e.target).length === 0) {
appDropdown.removeClass('active')
}
})
});
}
네, 거기인 것 같습니다.
위의 소스들 중에서 다음 두 군데를 아래와 같이 바꿔보시겠어요?
var refresh_url = current_url;
jQuery('#app-board-comment-list').find('.app-dropdown-toggle').on('click', function() {
jQuery(this).closest('.app-dropdown').toggleClass('active')
})
jQuery(this).closest('.app-dropdown').toggleClass('active')
})
다만 기존처럼 대댓글 작성시 대댓글이 접히면서 부모댓글이 보이는 현상 + ```이 안눌리는건 동일하네요 ㅠㅠ
혹시 파일이 누락된게있는지 봐봐야겠네요 ㄷㄷ
jQuery('#app-board-comment-list').find('.app-dropdown-toggle').on('click', function() {
jQuery(this).closest('.app-dropdown').toggleClass('active')
})
이거를 function 바깥으로 빼보시거나,
아니면 삭제하시고 수정 제안 드렸던
jQuery(document).on('click', '#app-board-comment-list .app-dropdown-toggle', function() {
jQuery(this).closest('.app-dropdown').toggleClass('active')
})
이거를 function 바깥에 놓아보시겠어요?
좌충우돌, 시행착오 겪으면서 작업하는 타입인데, 이렇게밖에 도움을 못드리네요... 그마저도 과연 도움이 될지;;;
덧. 그리고
jQuery(document).on('click', '#app-board-comment-list .app-dropdown-toggle', function() {
jQuery(this).closest('.app-dropdown').toggleClass('active')
})
사실 이거는 이 파일이 아니라 다른 파일에 있어야 할 것 같은데, 파일 구조가 복잡하다보니 어지럽네요 @.@
혹시 그래도 팝업 메뉴가 뜨지 않는다면...
업데이트가 계속 있을 것 같고 전체 구조가 누더기가 될 것 같아 권하진 않지만,
애드온의 default.js의 jQuery(document).ready(function($) { ~~~~ });
안쪽에
$(document).on('click', '#app-board-comment-list .app-dropdown-toggle', function() {
$(this).closest('.app-dropdown').toggleClass('active');
});
를 넣어보시는 것도 방법일 것 같습니다.
그 이후로도 안 된다면, 그리고 이 기능이 꼭 필요하시다면 나머지는 제작 의뢰를 해보시는 게 어떨까 싶어요;;;
별말씀을요 ㅠㅠ 도와주시는것도 감사할 따름입니다..
일단 말씀해주신부분을 모두 수정해봤는데 동일증상입니다 ㅠ
(대댓글작성시 주소를 못찾는현상, 드롭다운버튼 안되는현상 )
첫번째
두번째, 애드온의 default.js 파일
혹시 이벤트가 중복되거나 해서 그런 걸지도 모르겠네요;;;
이제 댓글 작성시에는 작동을 안하는데 대댓글작성시에는 작동을 하네요..ㅎㅎ
제일중요한 대댓글 작성시 접힘현상부분은 새로고침없는 댓글쪽에서 문제를 수정해야하는걸까요??
대댓글 접힘 현상은 refreshComments 함수가 새로고침 이후의 콜백이거든요?
애드온의 default.js의 일부를 여기 함수에 적용해보면 어떨까 싶긴 해요.
개발자도구로 보니까 위에서처럼 애드온이 끼워넣는 스크립트 변수가 중복되어 있는 걸 볼 수 있었습니다.
그래서 이벤트가 중복돼서 열었다 닫혔다 이중 동작이 되는 것 같은데요.
어떤 이유인지 체크해보시는 게 중요할 것 같아요.
(혹시 페이지 로딩 때 getComments 함수가 두 번 실행되는 것은 아닌지...)
그리고 그와는 별도로... (사실 애드온 중복 문제를 해결한다면 아래는 불필요할 수도 있는데요...)
어제 이야기됐던 refreshComments 함수에 애드온의 스크립트 일부를 이식시켜봤습니다.
댓글 및 대댓글 작성후 해당 위치로 스크롤 이동하는 스크립트예요.
여기서 target_haed라는 스크립트 변수를 잘 받아와야 하는데, 새로고침 프로세스 때문에 잘 안 될 것 같기도 하고...
댓글/대댓글 작성 후 console.log(target_head);를 확인해보셔도 좋겠구요.
혹시 안된다면 animate 메소드가 두 군데 있는데, 거기에 있는 숫자 0을 100 단위로 올려가면서도 테스트해보시구요.
암튼 전반적으로 한번 테스트해봐주세요.
var comment_srl = data.comment_srl;
var selector = '.app-card.app-board-comment.app-board-section';
var refresh_url = current_url.setQuery('comment_srl', comment_srl);;
jQuery.get(refresh_url, function(response) {
var old_comment_area = jQuery(selector);
var new_comment_area = jQuery(response).find(selector);
old_comment_area.empty().append(new_comment_area.contents());
if ( !location.hash ) {
history.replaceState(null, '', current_url + '#comment_' + comment_srl);
}
console.log(target_haed);
if ( target_head ) {
var obj = $('#comment_' + target_head).find('[onclick^="getRecommentList"]')[0];
getRecommentList(obj, target_head, function() {
$('html, body').animate({
scrollTop: $('#comment_' + comment_srl).offset().top
}, 0);
});
} else {
$('html, body').animate({
scrollTop: $('#comment_' + comment_srl).offset().top
}, 0);
}
jQuery('#app-board-comment-list').find('.app-dropdown-toggle').on('click', function() {
jQuery(this).closest('.app-dropdown').toggleClass('active');
});
const appDropdown = jQuery('#app-board-comment-list').find('.app-dropdown-toggle');
jQuery(document).mouseup(e => {
if (!appDropdown.is(e.target) && appDropdown.has(e.target).length === 0) {
appDropdown.removeClass('active')
}
});
});
}
말씀해주신 부분을 업데이트해봤는데 중복되는 부분때문인지 제대로 작동이 안되는듯합니다 ㅎㅎ
시간 여유있을때 각잡고 봐봐야겠네요
첫 appCommentAjaxCall(targetSrl, action, callback) 이건 아닌거겠죠..??ㅠㅠ
너무어렵네요..
"회원 정보 보기"의 "작성 댓글 보기"도 수정을 해야 하네요
• 관리자설정 > 회원설정 > 디자인 > 스킨 확인 - 회원 기본 스킨(default)
- /modules/member/skins/default/comment_list.html
[수정전]
<tr loop="$comment_list => $no,$comment">
<td>{$no}</td>
<td>
<a href="{getUrl('','document_srl',$comment->document_srl)}#comment_{$comment->comment_srl}" target="_blank">{$comment->getSummary() ?: $lang->msg_no_text_comment}</a>
</td>
<td>{$comment->getRegdate("Y-m-d")}</td>
</tr>
[수정후]
<tr loop="$comment_list => $no,$comment">
<td>{$no}</td>
<td>
{@ $target_mid = ModuleModel::getModuleInfo($comment->get('module_srl'))->mid; }
<a href="{getUrl('', 'mid', $target_mid, 'document_srl',$comment->get('document_srl'), 'comment_srl', $comment->comment_srl)}#comment_{$comment->get('comment_srl')}" target="_blank">{$comment->getSummary() ?: $lang->msg_no_text_comment}</a>
</td>
<td>{$comment->getRegdate("Y-m-d")}</td>
</tr>
제보 감사합니다!!!
{@ $target_mid = ModuleModel::getMidByModuleSrl($comment->get('module_srl')); }