여러분이 사용하고 계신 브라우저는 HTML5를 지원하지 않기 때문에 몇몇 요소가 제대로 보이도록 JScript를 사용하고 있습니다. 하지만 여러분의 브라우저 설정에서 스크립트 기능이 꺼져있으므로, 현재 페이지를 제대로 확인하시려면 스크립트 기능을 켜주셔야 합니다. 워드프레스 테마 제작 – 11편 - comments.php 만들기
워드프레스 테마 제작 – 11편 – comments.php 만들기
2년전 작성
2년전 수정

인터넷 서핑을 하다보면 대부분의 블로그에 댓글 남기는 칸이 있다.

워드프레스 comments.php

댓글 템플릿 만들고 single.php에 적용까지 시켜보자.

워드프레스 comments.php
comment_form()매개변수 설명
‘fields’
:
기본 댓글 필드.
‘author’
:
댓글 작성자 필드.
’email’
:
댓글 작성자 이메일 필드.
‘url’
:
주석 작성자 URL 필드.
‘cookies’
:
쿠키 사용 필드.
‘comment_field’
:
댓글 텍스트 필드.
‘must_log_in’
:
로그인을 해야 댓글을 남길 수 있도록 할 때 표시되는 문구. 예: 댓글을 남기려면 로그인해야 합니다. 기본 값 = must be logged in to comment.
‘logged_in_as’
:
로그인시 표시되는 문구. 예: [밍구]로 로그인. 기본 값 = logged in as [user].
‘comment_notes_before’
:
로그인하지 않은 경우 댓글 전에 표시되는 문구. 기본 값 = Your email address will not be published.
‘comment_notes_after’
:
로그인하지 않은 경우 댓글 다음에 표시되는 문구.
‘action’
:
댓글 양식에 대한 action. 기본 값 = /wp-comments-post.php.
‘id_form’
:
댓글 양식에 대한 ID. 기본 값 = commentform.
‘id_submit’
:
제출 버튼에 대한 ID. 기본 값 = submit.
‘class_container’
:
댓글 양식에 대한 컨테이너 클래스. 기본 값 = comment-respond.
‘class_form’
:
댓글 양식에 대한 form 클래스. 기본 값 = comment-form.
‘class_submit’
:
댓글 submit 버튼 클래스. 기본 값 = submit.
‘name_submit’
:
댓글 submit 버튼 이름. 기본 값 = submit.
‘title_reply’
:
답글 버튼 레이블. 기본 값 = Leave a Reply.
‘title_reply_to’
:
~에게 답글 남기기 레이블. 기본 값 = Leave a Reply to %s. %s = 기존 댓글 작성자 이름.
‘title_reply_before’
:
답글 제목 앞에 표시되는 코드. 기본 값 = <h3 id=”reply-title” class=”comment-reply-title”>.</h3>
‘title_reply_after’
:
답글 제목 뒤에 표시되는 코드. 기본 값 = </h3>.
‘cancel_reply_before’
:
답글 취소 버튼 전에 표시되는 코드.
‘cancel_reply_after’
:
답글 취소 버튼 뒤에 표시되는 코드.
‘cancel_reply_link’
:
답글 취소 버튼 레이블. 기본 값 = Cancel reply.
‘label_submit’
:
제출 버튼 레이블. 기본 값 = Post a comment.
‘submit_button’
:
제출 버튼에 대한 코드. 기본 값 = <input id=”%2$s” class=”%3$s” name=”%1$s” type=”submit” value=”%4$s” />.
‘submit_field’
:
제출 버튼을 둘러싼 코드. 기본 값 = <p class=”form-submit”>%1$s %2$s</p>. %1$s = 제출 버튼 태그. %2$s = 숨겨진 댓글 필드.
‘format’
:
댓글 양식 형식.
wp_list_comments() 매개변수 설명
‘walker’
:
코멘트를 보여주는 Walker 클래스의 인스턴스. 기본 값 = null.
‘max_depth’
:
최대 코멘트 깊이.
‘style’
:
목록의 스타일. ul, ol, div 사용 가능. 기본 값 = ul.
‘callback’
:
콜백 기능 사용. 기본 값 = null.
‘end-callback’
:
콜백 기능 종료. 기본 값 = null.
‘type’
:
유형 설정. all, comment, ‘pingback’, ‘trackback’, ‘pings’ 사용 가능. 기본 값 = all.
‘page’
:
코멘트 표시할 페이지 ID.
‘per_page’
:
댓글 수.
‘avatar_size’
:
아바타 크기. 기본 값 = 32.
‘reverse_top_level’
:
코멘트의 순서. true면 가장 최신 코멘트라 가장 위로. 기본 값 = null.
‘reverse_children’
:
하위 코멘트를 취소할지 여부. 기본 값 = null.
‘format’
:
목록 형식. html5, xhtml 사용 가능. 기본 값 = html5.
‘short_ping’
:
짧은 핑을 출력할지 여부. 기본 값 = false.
‘echo’
:
출력을 표시할지 여부. 기본 값 = true.

comments.php 파일 만들기

comments.php 예시
<?php
	$comment_send = '등록';
	$comment_reply = '댓글';
	$comment_reply_to = '답글';

	$comment_author = '이름';
	$comment_email = 'E-Mail';
	$comment_body = '댓글을 남겨주세요.';
	$comment_cookies_1 = '개인 정보 보호 정책';
	$comment_cookies_2 = '에 동의합니다.';

	$comment_before = '';
	$comment_after = '';

	$comment_cancel = '답글 취소';

	if ( post_password_required() )
	{
		return;
	}

?>
<?php
	$comments_args = array
	(
		'fields' => array
		(
			'author' => '<p class="comment-form-author"><br /><input id="author" name="author" aria-required="true" placeholder="' . $comment_author .'"></input></p>',
			'email' => '<p class="comment-form-email"><br /><input id="email" name="email" placeholder="' . $comment_email .'"></input></p>',
			'cookies' => '<input type="checkbox" required> <a href="' . get_privacy_policy_url() . '">' . $comment_cookies_1 . '</a>'  . $comment_cookies_2,
		),

		'label_submit' => __( $comment_send ),
		'title_reply' => __( $comment_reply ),
		'title_reply_to' => __( $comment_reply_to ),
		'cancel_reply_link' => __( $comment_cancel ),
		'comment_field' => '<p class="comment-form-comment"><br /><textarea id="comment" name="comment" aria-required="true" placeholder="' . $comment_body .'"></textarea></p>',
		'logged_in_as' => '',
		'comment_notes_before' => __( $comment_before),
		'comment_notes_after' => __( $comment_after),
		'id_submit' => __( 'comment-submit' ),
	);

	comment_form( $comments_args );
?>
		<div class="comment-list">
<?php
			wp_list_comments(
				array(
					'style'			=> 'div',
					'short_ping'	=> true,
				)
			);
?>
		</div>
사용된 코드 설명
post_password_required()
:
포스트에 암호가 필요한경우 입력하는 조건문
return;
:
돌아가기.
comment_form()
:
코멘트 폼을 불러오는 함수.
wp_list_comments()
:
코멘트 리스트를 불러오는 함수.

single.php에 적용

기존 single.php
<?php
	get_header(); 
	$postcat = get_the_category();
	$catid = $postcat[0]->cat_ID;
?>
<?php
	if ( have_posts() ) :
		while ( have_posts() ) :
			the_post();
			echo get_category_parents($catid,true,'»');
			the_time(); the_author_posts_link();
			previous_post_link( '%link', '« ', TRUE);
			next_post_link( '%link', ' »', TRUE );
			the_title( '

', '

' ); the_content(); endwhile; else: _e( '죄송합니다. 포스트를 찾을 수 없습니다.', 'mingg' ); endif; ?> <?php get_sidebar(); ?> <?php get_footer(); ?>
수정된 single.php
<?php
	get_header(); 
	$postcat = get_the_category();
	$catid = $postcat[0]->cat_ID;
?>
<?php
	if ( have_posts() ) :
		while ( have_posts() ) :
			the_post();
			echo get_category_parents($catid,true,'&raquo;');
			the_time(); the_author_posts_link();
			previous_post_link( '%link', '&laquo;&nbsp;', TRUE);
			next_post_link( '%link', '&nbsp;&raquo;', TRUE );
			the_title( '<h1>', '</h1>' );
			the_content(); 
		endwhile; 

		else: _e( '죄송합니다. 포스트를 찾을 수 없습니다.', 'mingg' ); 
	endif;

	comments_template();
?>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
사용된 코드 설명
comments_template();
:
코멘트 템플릿 불러오는 코드.

function.php

코멘트 수정, 삭제 인스턴스 생성 예시
<?php
	include 'mycommteditable.php';
	$GLOBALS['mycommteditable'] = new MY_Commt_Editable();
?>
사용된 코드 설명
include ‘mycommteditable.php’;
:
mycommteditable.php 파일 추가.
$GLOBALS[‘mycommteditable’] = new MY_Commt_Editable();
:
MY_Commt_Editable 인스턴스 생성.

mycommteditable.php 파일 만들기

mycommteditable.php 예시
<?php
	class MY_Commt_Editable
	{
		function __construct()
		{
			add_action( 'comment_post', array($this, 'set_cookie') );
			add_filter( 'comment_text', array($this, 'add_links'), 10, 2 );
			add_filter( 'comment_text', array($this, 'add_editor'), 99, 2 );
			add_action( 'admin_post_mycommtedit', array($this, 'edit_request') );
			add_action( 'admin_post_nopriv_mycommtedit', array($this, 'edit_request') );
			add_action( 'admin_post_mycommtdelete', array($this, 'delete_request') );
			add_action( 'admin_post_nopriv_mycommtdelete', array($this, 'delete_request') );
		}

		function add_links($comment_text, $comment)
		{
			if( $this->can_edit( $comment->comment_ID ) ){
				$edit_url = add_query_arg( array(
					'mycommtedit' => $comment->comment_ID,
				), get_comment_link($comment->comment_ID) );

				$delete_url = add_query_arg( array(
					'action' => 'mycommtdelete',
					'comment_id' => $comment->comment_ID,
					'nonce' => wp_create_nonce('mycommtdelete'),
				), admin_url('admin-post.php') );

				$links = '<a class="edit" href="' . $edit_url . '">수정</a>';
				$links .= '<span class="sep"> | </span>';
				$links .= '<a class="delete" href="' . $delete_url . '">삭제</a>';
				$links = ' <span class="mycommteditable-links">' . $links .'</span> ';
				$comment_text .= $links;
			}
			return $comment_text;
		}

		function add_editor($comment_text, $comment)
		{
			if( isset( $_REQUEST['mycommtedit'] )
				&& $_REQUEST['mycommtedit'] == $comment->comment_ID
				&& $this->can_edit( $comment->comment_ID ) ){
				ob_start();
				?>
				<form id="mycommtedit-form" action="<?php echo admin_url('admin-post.php')?>" method="post">
					<input type="hidden" name="action" value="mycommtedit">
					<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('mycommtedit');?>">
					<input type="hidden" name="comment_id" value="<?php echo $comment->comment_ID; ?>">
					<textarea name="comment_content" rows="6"><?php echo esc_textarea($comment->comment_content);?></textarea>
					<input type="submit" value="업데이트">
				</form>
				<?php
				$comment_text .= ob_get_clean();
			}
			return $comment_text;
		}

		function set_cookie($comment_id)
		{
			$comment = get_comment($comment_id);
			$cookie_lifetime = apply_filters('mycommteditable_cookie_lifetime', 60*1440);
			setcookie( 'mycommteditable_' . $comment_id . '_' . COOKIEHASH, md5($comment->comment_author_IP), time() + $cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
		}

		function delete_cookie($comment_id)
		{
			setcookie( 'mycommteditable_' . $comment_id . '_' . COOKIEHASH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
		}

		function can_edit($comment_id)
		{
			$comment = get_comment($comment_id);
			if( isset($_COOKIE['mycommteditable_' . $comment_id . '_' . COOKIEHASH]) 
				&& $_COOKIE['mycommteditable_' . $comment_id . '_' . COOKIEHASH] == md5($comment->comment_author_IP) )
				return true;
			return false;
		}

		function edit_request()
		{
			if( ! isset($_REQUEST['nonce'])
				|| ! wp_verify_nonce($_REQUEST['nonce'], 'mycommtedit') 
				|| ! isset($_REQUEST['comment_id']) )
				return;

			$comment_id = $_REQUEST['comment_id'];
			if( $this->can_edit( $comment_id ) ){
				$data = array(
					'comment_ID' => $comment_id,
					'comment_content' => $_REQUEST['comment_content'],
				);
				wp_update_comment( $data );
				$goback = get_comment_link($comment_id);
				wp_redirect( $goback );
				exit;

			}else{
				wp_die( '댓글 수정 권한이 없거나 쿠키가 만료되었습니다.' );
			}
		}

		function delete_request()
		{
			if( ! isset($_REQUEST['nonce'])
				|| ! wp_verify_nonce($_REQUEST['nonce'], 'mycommtdelete') 
				|| ! isset($_REQUEST['comment_id']) )
				return;

			$comment_id = $_REQUEST['comment_id'];
			if( $this->can_edit( $comment_id ) ){
				wp_delete_comment( $comment_id, false );
				$this->delete_cookie($comment_id);
				$goback = wp_get_referer();
				wp_redirect( $goback );
				exit;

			}else{
				wp_die( '댓글 삭제 권한이 없거나 쿠키가 만료되었습니다.' );
			}
		}
	}
?>
사용된 코드 설명
function set_cookie()
:
작성자 인증을 위해 쿠키 생성하는 함수.
add_action( ‘comment_post’, array($this, ‘set_cookie’) );
:
댓글이 저장되자마자 실행되는 ‘comment_post’ 훅 이용하여 액션 걸어주기.
$cookie_lifetime = apply_filters(‘mycommteditable_cookie_lifetime’, 60*1440);
:
기본 유지시간을 1440분(24시간)으로 설정. 1440 대신 15 기재시 15분으로 설정된다.
setcookie( ‘mycommteditable_’ . $comment_id . ‘_’ . COOKIEHASH, md5($comment->comment_author_IP), time() + $cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
:
댓글별로 IP를 저장하고 md5로 암호화 한다.
add_filter( ‘comment_text’, array($this, ‘add_links’), 10, 2 );
:
댓글 내용 뒷부분에 링크를 표시하는 ‘comment_text’ 훅 이용하여 액션 걸어주기.
function add_links($comment_text, $comment){ … }
:
작성자 인증 후 댓글 고유주소에 댓글 아이디가 할당된 ‘mycommtedit’ 변수를 붙여 수정 URL 만들기.
function can_edit($comment_id){ … }
:
인증 코드를 재사용하기위해 함수화하기.
add_filter( ‘comment_text’, array($this, ‘add_editor’), 99, 2 );
:
댓글 내용 뒷부분에 코멘트폼을 표시하는 ‘comment_text’ 훅 이용하여 액션 걸어주기.
if( isset( $_REQUEST[‘mycommtedit’] )
:
‘mycommtedit’ 변수요청이 있는지 확인.
&& $_REQUEST[‘mycommtedit’] == $comment->comment_ID
:
‘mycommtedit’ 변수가 현재 댓글 아이디와 같은지 확인.
&& $this->can_edit( $comment->comment_ID )
:
작성자 인증.
ob_start();
:
출력 버퍼 시작.
$comment_text = ob_get_clean();
:
출력 버퍼 리턴.
add_action( ‘admin_post_mycommtedit’, array($this, ‘edit_request’) );
:
수정 요청을 캐치하기 위해 ‘admin_post_mycommtedit’ 훅 이용하여 액션 걸어주기.
add_action( ‘admin_post_nopriv_mycommtedit’, array($this, ‘edit_request’) );
:
수정 요청을 캐치하기 위해 ‘admin_post_nopriv_mycommtedit’ 훅 이용하여 액션 걸어주기.
if( ! isset($_REQUEST[‘nonce’]) … return;
:
요청 변수 검증.
if( $this->can_edit( $comment_id ) ) { … }
:
작성자 인증. 댓글 내용 업데이트.
wp_update_comment( $data ); … exit;
:
댓글 고유주소로 리다이렉트.
delete_url = add_query_arg( … );
:
삭제 URL 구성.
add_action( ‘admin_post_mycommtdelete’, array($this, ‘delete_request’) );
:
삭제 요청을 캐치하기 위해 ‘admin_post_mycommtdelete’ 훅 이용하여 액션 걸어주기.
add_action( ‘admin_post_nopriv_mycommtdelete’, array($this, ‘delete_request’) );
:
삭제 요청을 캐치하기 위해 ‘admin_post_nopriv_mycommtdelete’ 훅 이용하여 액션 걸어주기.
if( ! isset($_REQUEST[‘nonce’]) … return;
:
요청 변수 검증.
if( $this->can_edit( $comment_id ) )
:
작성자 인증.
wp_delete_comment( $comment_id, false );
:
댓글 삭제.
$this->delete_cookie($comment_id);
:
쿠키 삭제.
$goback = wp_get_referer(); … exit;
:
이전 페이지로 리다이렉트.

테마 적용

워드프레스 테마 제작 – 11편 - 로그아웃 상태
워드프레스 테마 제작 – 11편 - 로그아웃 상태 - 답글
워드프레스 테마 제작 – 11편 - 로그인 상태
워드프레스 테마 제작 – 11편 - 로그인 상태 - 답글
워드프레스 테마 제작 – 11편 - 로그인 상태 - 수정

문제 없이 출력 잘 되는것 확인된다.

참고
관련 포스트

Mingg`s Diary
밍구
공부 목적 블로그