워드프레스 숏코드: 완벽 가이드

이 글은 Smashing Magazine의 "WordPress Shortcodes: A Complete Guide"를 저작자의 허락을 얻어 번역하여 정리한 것입니다. 조금 오래된 글이라서 최신 버전의 워드프레스와 호환이 안 되는 부분도 있지만 학습 차원에서 읽어보시면 좋을 듯합니다. 그리고 뒷부분에 유용한 숏코드가 소개되어 있으니 참고하시기 바랍니다.


워드프레스 숏코드는 2.5 버전에서 도입되어 가장 유용한 기능 중 하나로 자리잡았습니다. 일반 사용자도 프로그래밍 지식 없이 일종의 매크로인 숏코드(단축 코드)를 사용하여 콘텐츠를 동적으로 발행할 수 있게 되었습니다.

워드프레스 글이나 페이지에 숏코드를 삽입하면 해당 숏코드는 특정 콘텐츠로 교체됩니다. 즉, 우리는 워드프레스에 대괄호([...])로 된 매크로를 찾아서 PHP 함수로 생성되는 해당 동적 콘텐츠로 바꾸도록 지시합니다.
WordPress shortcodes

사용법은 매우 간단합니다. 사용자가 원하는 글(Post)에 최신 글 목록을 표시하고자 하는 경우를 생각해 보겠습니다. 숏코드의 형태는 다음과 비슷할 수 있습니다.

[recent-posts]

이 숏코드를 조금 더 발전시켜 파라미터를 설정하여 표시할 글의 개수를 지정할 수 있습니다.

[recent-posts posts="5"]

한 단계 더 발전시켜, 최근 글 목록의 제목을 설정하는 것도 가능합니다.

[recent-posts posts="5"]글 제목[/recent-posts]

간단한 숏코드

이 가이드에서 먼저 다음과 같이 단순한 숏코드의 코드를 만들어보겠습니다.

[recent-posts]

만드는 과정은 간단하며 고급 PHP 지식이 없어도 가능합니다. 기본적인 단계는 다음과 같습니다.

  1. 숏코드를 찾으면 워드프레스에서 호출할 함수를 만듭니다.
  2. 숏코드를 등록합니다. 이때 고유한 이름을 사용해야 합니다.
  3. 등록 함수를 워드프레스 Action에 연결합니다.

이 글에 나오는 모든 코드는 테마의 함수 파일(functions.php)에 추가하면 됩니다. 또는 functions.php 파일에서 include를 사용하여 추가된 함수 파일에 넣으셔도 됩니다(사용자 정의 함수 파일을 추가하는 방법 참고).

Callback 함수 만들기

워드프레스에서 숏코드를 발견하면 숏코드를 코드로 교체하는 데 이것이 바로 Callback 함수입니다.

참고: Callback 함수란 다른 함수로 파라미터로 전달되는 함수로써, 다른 함수 내부에서 호출 또는 실행됩니다(참조).

그럼 데이터베이스에서 최근 글들을 가져오는 함수를 만들어 볼까요?

function recent_posts_function() {
query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => 1));
if (have_posts()) :
while (have_posts()) : the_post();
$return_string = '<a href="'.get_permalink().'">'.get_the_title().'</a>';
endwhile;
endif;
wp_reset_query();
return $return_string;
}

위의 함수에서는 최신 글을 가져와서 링크와 함께 문자열을 반환하도록 데이터베이스에 쿼리를 보냅니다. 이 Callback 함수는 아무 것도 출력하지 않고 문자열을 반환한다는 점에 유의하도록 합니다.

숏코드 등록하기

이제 워드프레스에 이 함수가 숏코드임을 알려주어야 합니다.

function register_shortcodes(){
add_shortcode('recent-posts', 'recent_posts_function');
}

글 내용 중에 숏코드 [recent-posts]가 있으면 recent_posts_function()이 자동으로 호출됩니다. 이때 고유한 숏코드 이름을 사용해야 합니다. 만약 중복되는 이름을 사용하면 충돌이 발생합니다.

워드프레스 후크

register_shortcodes() 함수를 실행하기 위해 이 함수를 워드프레스의 initialization action에 연결합니다.

add_action( 'init', 'register_shortcodes');

참고: 위의 숏코드 등록 함수와 아래의 initialization action을 하나로 통합하여 아래와 같이 함수 파일에 추가해도 동일한 결과가 나옵니다.

add_shortcode('recent-posts', 'recent_posts_function');

숏코드 테스트

간단한 숏코드가 준비되었으며 이제 제대로 작동하는지 테스트할 차례입니다. 새로운 글을 만들거나 기존 글을 열어서 다음 라인을 아무 곳에 추가하도록 합니다.

[recent-posts]

글을 발행하고 브라우저에서 열어보면 아래 그림과 그림과 같이 블로그의 가장 최신 글의 링크가 표시될 것입니다.
Simple Recent Post Shortcode

고급 숏코드

숏코드 파라미터

파라미터를 추가하여 숏코드의 기능성을 더욱 높일 수 있도록 숏코드는 유연성을 제공합니다. 가령 표시할 최신 글의 개수를 지정하고 싶은 경우가 있을 수 있습니다. 이 기능을 구현하려면 숏코드에 표시할 최신 글 개수를 지정하는 추가적인 옵션을 추가할 수 있습니다.

이를 위해 우리는 두 개의 함수를 사용해야 합니다. 첫 번째는 워드프레스의 내장 함수인 shortcode_atts()입니다. 이 함수는 사용자 숏코드 속성(attribute)를 네이티브 속성과 결합하여 필요한 곳에 기본값으로 채워 넣습니다. 두 번째 함수는 extract() PHP 함수입니다. 이 함수는 "추출"이라는 이름에서 알 수 있듯이 숏코드 속성을 추출합니다. (참고: shortcode_atts()에 대한 자세한 내용은 WordPress Codex를 참고하시기 바랍니다. extract()에 대해서는 여기에서 자세한 내용을 볼 수 있습니다.)

위에서 작성한 Callback 함수를 확장하여 글 개수 파라미터가 추출될 속성(Attribute) 배열인 인수를 추가하고자 합니다. 그런 다음 데이터베이스 쿼리를 통해 원하는 글 개수를 가져와서 HTML 리스트를 생성하여 표시합니다.

function recent_posts_function($atts){
extract(shortcode_atts(array(
'posts' => 1,
), $atts));

$return_string = '<ul>';
query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => $posts));
if (have_posts()) :
while (have_posts()) : the_post();
$return_string .= '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';
endwhile;
endif;
$return_string .= '</ul>';

wp_reset_query();
return $return_string;
}

숏코드에서 옵션을 지정하지 않으면 기본값인 1이 사용됩니다(즉, 1개의 최신 글이 표시됨). 동일한 방법으로 더 많은 속성을 추가하여 숏코드에서 여러 개의 파라미터를 사용할 수 있도록 할 수 있습니다.  이 덕분에 몇 개의 글을 표시할 것인지를 설정할 수 있습니다. 이 함수를 "간단한 숏코드" 부분에서 만들었던 함수를 대체하고 숏코드를 아래 형식으로 사용합니다.

[recent-posts posts="5"]

브라우저에서 확인해보면 최신 글 5개의 링크가 표시됩니다.
Advanced Recent Post Shortcode

숏코드 내의 콘텐츠

위의 숏코드를 한 단계 더 발전시켜 콘텐츠를 인수로 전달하는 기능을 추가할 수 있습니다. 여기에서는 최신 글 목록의 제목을 인수로 전달하는 예를 살펴보겠습니다. 이 기능을 구현하기 위해 Callback 함수에 두 번째 파라미터 $content를 사용하며 이 파라미터를 목록 앞에 h3 머리글로 추가하도록 합니다. 이제 함수를 다음과 같이 수정합니다.

function recent_posts_function($atts, $content = null) {
extract(shortcode_atts(array(
'posts' => 1,
), $atts));

$return_string = '<h3>'.$content.'</h3>';
$return_string .= '<ul>';
query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => $posts));
if (have_posts()) :
while (have_posts()) : the_post();
$return_string .= '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';
endwhile;
endif;
$return_string .= '</ul>';

wp_reset_query();
return $return_string;
}

이 유형의 숏코드는 HTML 태그와 비슷합니다. 즉, 콘텐츠를 시작 숏코드(Opening shortcode)와 종료 숏코드(Closing shortcode)로 둘러싸는 형식으로 사용합니다.

[recent-posts posts="5"]최신 글 목록 제목[/recent-posts]

결과는 "글 목록 제목"이 새롭게 추가된 점을 제외하고는 앞의 예제와 동일합니다.
Recent posts list with heading

숏코드 추가하기

위젯에 숏코드 사용하기

기본적으로 워드프레스 사이드바 위젯에서 숏코드는 무시됩니다. 예를 들어 다음과 같은 숏코드를 사이드바 위젯 영역에 텍스트 위젯을 사용하여 추가해보면:

[recent-posts posts="5"]

다음과 같이 정상적으로 글 목록이 출력되지 않고 숏코드 자체가 그대로 표시됩니다. (그렇지 않고 정상적으로 나오도록 테마 자체에서 설정되어 있는 경우도 많습니다.)
Shortcode in sidebar in WordPress

위와 같이 표시되는 경우 숏코드를 위젯에 사용할 수 있도록 활성화하기 위해 다음과 같은 코드 한 줄을 추가해 주면 됩니다. (어디에 추가하면 될까요? 당연히 함수 파일이죠.)

add_filter('widget_text', 'do_shortcode');

이제 숏코드가 위젯에서 정상적으로 작동합니다.
Shortcode in widgets in WordPress

비슷한 방법으로 댓글(Comments)에서도 숏코드를 사용할 수 있도록 설정이 가능합니다. 이 경우 다음 코드를 추가합니다.

add_filter( 'comment_text', 'do_shortcode' );

요약글(Excerpts)에서 숏코드를 활성화하려면 다음 코드를 추가하면 됩니다.

add_filter( 'the_excerpt', 'do_shortcode');

이것으로 단순한 숏코드부터 다소 복잡한 숏코드를 만드는 방법과 숏코드를 사이드바 등에 추가하는 방법을 살펴보았습니다.

숏코드 TinyMCE 편집기 버튼

숏코드는 동적 콘텐츠를 글 등에 추가하는 손쉬운 방법을 제공하지만 일반적인 사용자에게 다소 어려울 수 있습니다. 여러 개의 파라미터를 사용한 복잡한 숏코드의 경우 특히 사용이 쉽지 않을 수 있습니다. 대부분의 사용자는 HTML과 같은 코드에 익숙하지 않지만 숏코드를 제대로 사용하려면 숏코드의 정확한 구문과 지원되는 모든 속성에 대해 기억해야 합니다. 하지만 사소한 구문 오류도 원치 않는 결과로 이어질 수 있습니다.

이 문제를 해결하기 위해 워드프레스의 기본 글 편집기인 TinyMCE의 인터페이스에 버튼을 추가하여 사용자들이 간단한 클릭만으로 숏코드를 추가하도록 할 수 있습니다. 다음과 같은 2단계를 거쳐 이 버튼을 추가할 수 있습니다.

  1. 버튼용 JavaScript 파일 만들기
  2. 버튼과 JavaScript 파일 등록하기

참고: 아래 글은 작성된 지 조금 오래 되어서 최신 TinyMCE에서는 작동하지 않습니다. 제대로 작동하게 하려면 코드를 분석하여 최신 TinyMCE API에 맞게 수정해 주어야 할 것 같습니다. 제대로 작동하지 않기 때문에 생략하려고 생각했지만, 접근 방식이 중요할 것 같아서 번역하여 수록했습니다. 참고하세요.

버튼용 JavaScript 파일

JavaScript 파일을 사용하여 TinyMCE API를 통해 TinyMCE 플러그인을 등록합니다. 테마(자식 테마를 사용하는 경우 자식 테마) 아래에 js라는 폴더를 만들고 recent-posts.js라는 새로운 파일을 만든 다음, 다음 코드를 복사하여 붙여넣기 합니다.

(function() {
tinymce.create('tinymce.plugins.recentposts', {
init : function(ed, url) {
ed.addButton('recentposts', {
title : 'Recent posts',
image : url+'/recentpostsbutton.png',
onclick : function() {
var posts = prompt("글 개수", "1");
var text = prompt("목록 제목", "제목 텍스트입니다.");

if (text != null && text != ''){
if (posts != null && posts != '')
ed.execCommand('mceInsertContent', false, '[recent-posts posts="'+posts+'"]'+text+'[/recent-posts]');
else
ed.execCommand('mceInsertContent', false, '[recent-posts]'+text+'[/recent-posts]');
}
else{
if (posts != null && posts != '')
ed.execCommand('mceInsertContent', false, '[recent-posts posts="'+posts+'"]');
else
ed.execCommand('mceInsertContent', false, '[recent-posts]');
}
}
});
},
createControl : function(n, cm) {
return null;
},
getInfo : function() {
return {
longname : "최신 글",
author : 'Konstantinos Kouratoras',
authorurl : 'http://www.kouratoras.gr',
infourl : 'http://www.smashingmagazine.com',
version : "1.0"
};
}
});
tinymce.PluginManager.add('recentposts', tinymce.plugins.recentposts);
})();

아래와 나와 있듯이 tinymce.create() 메소드를 호출하여 플러그인의 이름과 속성을 전달하는 새로운 플러그인을 만듭니다. 이 코드에서 가장 중요한 부분은 init() 함수입니다. 이 함수에서 우리는 onclick() 함수를 사용하는 함수의 이름, 아이콘 파일, 이벤트 핸들러 등을 정의합니다.

onclick() 함수의 첫 두 라인에서 사용자에게 글 개수와 숏코드의 목록 제목을 입력하라는 프롬프트가 표시됩니다. 그런 다음 이 파라미터의 값에 따라 적절한 숏코드 폼이 편집기에 삽입됩니다.

마지막으로 add() 함수를 사용하여 TinyMCE 플러그인이 PluginManager에 추가합니다. 이상의 과정을 통해 [recent-posts] 숏코드가 워드프레스 테마에 성공적으로 통합됩니다.

버튼과 TINYMCE 플러그인 등록하기

JavaScript 파일을 만들었으면 이 파일과 숏코드 버튼을 등록해야 합니다. 그래서 두 개의 함수를 만들어 해당 워드프레스 필터에 연결시켜야 합니다.

첫 번째 함수는 register_button()이라는 함수로서 숏코드를 버튼 배열에 밀어 넣어 새 버튼과 기존 버튼 사이에 구분선을 추가합니다.

function register_button( $buttons ) {
array_push( $buttons, "|", "recentposts" );
return $buttons;
}

두 번째 함수인 add_plugin()은 Javascript 파일의 경로와 이름을 가리킵니다.

function add_plugin( $plugin_array ) {
$plugin_array['recentposts'] = get_stylesheet_directory_uri() . '/js/recentposts.js';
return $plugin_array;
}

다음 단계에서는 이전 함수를 사용하여 필터를 추가하도록 합니다. register_button() 함수는 mce_buttons 필터에 연결되어 편집기가 플러그인을 로드할 때 실행됩니다. 그리고 add_plugin()mce_external_plugins 필터에 연결되어 버튼이 로드되기 직전에 실행됩니다.

function my_recent_posts_button() {

if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) {
return;
}

if ( get_user_option('rich_editing') == 'true' ) {
add_filter( 'mce_external_plugins', 'add_plugin' );
add_filter( 'mce_buttons', 'register_button' );
}

}

사용자가 글 또는 페이지를 편집할 권한이 없거나 사용자가 비주얼 편집기 모드를 사용하는 경우 이전 함수는 아무런 동작을 하지 않습니다.

마지막으로 함수를 워드프레스의 initialization 액션에 후크하여 페이지가 로드될 때 실행이 되도록 합니다.

add_action('init', 'my_recent_posts_button');

참고: 위와 같은 단계를 거치면 TinyMCE 편집기에 숏코드 추가 버튼이 생성되어야 하지만 실제로는 잘 되지 않습니다. 앞에서 밝혔듯이 글이 오래되어 최신 버전에서는 호환이 되지 않습니다.

유용한 숏코드

이 단원에는 여러분의 블로그를 한 단계 업그레이드시켜줄 몇 가지 유용한 워드프레스 숏코드의 소스가 수록되어 있습니다.

링크 버튼

function linkbutton_function( $atts, $content = null ) {
return '<button type="button">'.do_shortcode($content).'</button>';
}
add_shortcode('linkbutton', 'linkbutton_function');

숏코드 사용 형식:

[linkbutton]클릭![/linkbutton]

위 숏코드를 사용하면 다음과 같은 버튼이 생깁니다.
Button shortcode
버튼 모양은 테마에 따라 달라지며 CSS를 통해 조정이 가능합니다.

WORDPRESS 메뉴

조금 복잡한 숏코드를 살펴볼까요? 아래 숏코드는 워드프레스 메뉴를 불러와 표시합니다.

function menu_function($atts, $content = null) {
extract(
shortcode_atts(
array( 'name' => null, ),
$atts
)
);
return wp_nav_menu(
array(
'menu' => $name,
'echo' => false
)
);
}
add_shortcode('menu', 'menu_function');

사용 형식은 다음과 같습니다.

[menu name="main-menu"]

위 숏코드를 글이나 페이지에 넣으면 다음과 같이 메뉴가 표시됩니다.
Menu shortcode

구글 지도

구글 맵 숏코드는 정말 유용합니다. 소스 코드를 편집할 필요 없이 콘텐츠에 지도를 삽입할 수 있습니다.

function googlemap_function($atts, $content = null) {
extract(shortcode_atts(array(
"width" => '640',
"height" => '480',
"src" => ''
), $atts));
return '<iframe width="'.$width.'" height="'.$height.'" src="'.$src.'&output=embed" ></iframe>';
}
add_shortcode("googlemap", "googlemap_function");

숏코드를 입력할 때, 폭과 높이와 함께 Google Maps의 링크를 파라미터로 전달하십시오.

[googlemap width="600" height="300" src="http://maps.google.com/maps?q=Heraklion,+Greece&hl=en&ll=35.327451,25.140495&spn=0.233326,0.445976& sll=37.0625,-95.677068&sspn=57.161276,114.169922& oq=Heraklion&hnear=Heraklion,+Greece&t=h&z=12"]

위와 같은 숏코드를 글에 추가해보면 아래와 같이 구글 지도가 삽입되어 나타납니다.
Google Maps shortcode in WordPress

Google Charts

다음으로 매우 유용한 숏코드를 소개해드립니다. Google Charts 서비스를 통해 원형 차트(파이 차트)를 쉽게 표시할 수 있습니다. 다음 숏코드 샘플을 통해 여러 가지 속성을 지정하여 원형 차트를 워드프레스 글이나 페이지에 추가할 수 있습니다.

function chart_function( $atts ) {
extract(shortcode_atts(array(
'data' => '',
'chart_type' => 'pie',
'title' => 'Chart',
'labels' => '',
'size' => '640x480',
'background_color' => 'FFFFFF',
'colors' => '',
), $atts));

switch ($chart_type) {
case 'line' :
$chart_type = 'lc';
break;
case 'pie' :
$chart_type = 'p3';
break;
default :
break;
}

$attributes = '';
$attributes .= '&chd=t:'.$data.'';
$attributes .= '&chtt='.$title.'';
$attributes .= '&chl='.$labels.'';
$attributes .= '&chs='.$size.'';
$attributes .= '&chf='.$background_color.'';
$attributes .= '&chco='.$colors.'';

return '<img title="'.$title.'" src="http://chart.apis.google.com/chart?cht='.$chart_type.''.$attributes.'" alt="'.$title.'" />';
}
add_shortcode('chart', 'chart_function');

네 가지 데이터로 원형 차트(파이 차트)를 만들려면 다음과 같은 숏코드를 글 등에 삽입하도록 합니다.

[chart type="pie" title="원형 차트 샘플" data="41.12,32.35,21.52,5.01" labels="첫번째+라벨|두번째+라벨|세번째+라벨|네번째+라벨" background_color="FFFFFF" colors="D73030,329E4A,415FB4,DFD32F" size="450x180"]

그러면 다음과 같은 결과를 얻을 수 있습니다.

Pie Charts in WordPress

PDF 문서 삽입하기

Google Docs PDF 뷰어를 사용하여 워드프레스 사이트에 PDF를 삽입할 수 있습니다. 다음과 같은 코드를 함수 파일에 추가하도록 하십시오.

function pdf_function($attr, $url) {
extract(shortcode_atts(array(
'width' => '640',
'height' => '480'
), $attr));
return '<iframe src="http://docs.google.com/viewer?url=' . $url . '&embedded=true" style="width:' .$width. '; height:' .$height. ';">Your browser does not support iframes</iframe>';
}
add_shortcode('pdf', 'pdf_function');

PDF를 삽입하려면 [pdf] 숏코드를 입력하고 URL을 콘텐츠 인수로 전달하면 됩니다.

[pdf width="520px" height="700px"]http://static.fsf.org/common/what-is-fs-new.pdf[/pdf]

페이지에 위의 숏코드를 삽입하면 방문자들은 PDF 문서를 뷰어로 볼 수 있습니다.

PDF viewer in WordPress

유용한 사이트

부록 - 숏코드를 사용하여 하위 페이지의 요약문 표시하기

function subpage_peek() {
global $post;

// 하위 페이지 쿼리 실행
$args = array(
'post_parent' => $post->ID,
'post_type' => 'page'
);
$subpages = new WP_query($args);

// 출력 만들기
if ($subpages->have_posts()) :
$output = '<ul>';
while ($subpages->have_posts()) : $subpages->the_post();
$output .= '<li><strong><a href="'.get_permalink().'">'.get_the_title().'</a></strong>
<p>'.get_the_excerpt().'<br />
<a href="'.get_permalink().'">Continue Reading →</a></p></li>';
endwhile;
$output .= '</ul>';
else :
$output = '<p>No subpages found.</p>';
endif;

// 쿼리 리셋
wp_reset_postdata();

// 반환
return $output;
}

다음 함수를 추가하여 숏코드를 만듭니다.

add_shortcode('subpage_peek', 'subpage_peek');

일부 글에 제휴 링크가 포함될 수 있으며 파트너스 활동으로 일정액의 수수료를 받을 수 있습니다.

13개 댓글

  1. 숏코드는 문단 블록에 넣어도 되고 사용자 정의 HTML 블록에 넣어도 되고 쇼트코드 블록에 넣어도 되고 작동만 하면 어느 블록에 넣든 상관없나요?

    1. 숏코드는 쇼트코드 블록에 넣으시면 됩니다. 문단 블록에서도 잘 작동할 것입니다. HTML 블록에서는 작동하는지 테스트해보시기 바랍니다.

  2. 여기에서 소개해준 googlemap, pdf 등의 숏코드를
    자식 테마함수 function.php에 추가만 해주면 되는 것이 맞을까요?
    'munu' 숏코드는 function.php에 추가하면 작동되는데,
    'googlemap'와 'pdf ' 내용은 function.php에 추가해도 작동이 되지 않습니다.

  3. 안녕하세요~ 숏코드를 functions.php에 애드센스로 넣었는데 어떤 날에 갑자기 설정해놓은 숏코드가 다 사라져 있는 경우가 있더라구요 ..... 이게 왜이럴까요 ㅜㅜㅜㅜ

  4. 안녕하세요 올려주신 자료 참고하여 진행 중인데 기존 php 게시판 소스를 숏코드로 이용할 수도 있나요?

    1. 안녕하세요, yoos님. 워드프레스 플러그인을 만드는 방법에 대한 워드프레스 개발자 문서를 참고해보시기 바랍니다:

      https://developer.wordpress.org/plugins/

      워드프레스에는 케이보드와 망보드 같은 게시판 플러그인이 있습니다. 그런 플러그인을 사용하는 것을 고려해볼 수 있습니다.

      https://www.thewordcracker.com/basic/how-to-start-wordpress/ 글에서 '게시판 만들기' 부분을 참고해보세요.

  5. 좋은 정보 감사합니다. 혹시 워드프레스에서 db와 데이터를 주고받는 기초방법에 대해서도 알 수 있을까요? 구글링해보니 전역변수 $wpdb를 선언한 뒤 워드프레스에서 제공하는 insert() 등 함수를 쓰면 된단 식으로 나와있는데, 아무리 코드를 사용해도 작동조차 하지 않네요. 혹시 코드 및 파일 위치가 정해져있다거나 선행 작업이 필요한 건가요? 간단하게 폼 양식을 만들어서 값을 넣고, 조회하는 기능을 구현해보려고 합니다.

댓글 남기기

* 이메일 정보는 공개되지 않습니다.