wordpress post, page에 form 집어 넣기

Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn
Share on print
Print

별거 아닐 줄 알았다. PHP & MySQL 닌자 비법서를 읽고 form을 만드는 PHP 코드를 봤다. wordpress를 사용하면서 page나 post를 작성할 줄 알게 되었다. Elementor 같은 비주얼 에디터를 사용하면 더더욱 현란한 page도 작성할 수 있다. 그런데 닌자 비법서에서 배운 form을 집어 넣으려고 하니 어디에 코드를 넣어야 할 지를 알수가 없었다.

wordpress를 다루면서 느끼는 점은 수많은 테마와 플러그인들을 보면 뭐든지 할 수 있을 거 같은 기분이 들다가, 막상 무언가를 하려고 하면 무언가를 어떻게 하는지 알 수가 없다는 거다. 어쨋건, 모든 일은 구글링에서 시작한다. 그리고 몇 가지 방법을 찾은 걸 정리해본다. 삽질도 같이 할 예정이라 제대로 동작하는 경우와 동작하지 않는 경우를 색깔과 취소선으로 구분해서 글을 써본다.

제대로 동작하는 경우

동작하지 않는 경우


1. Editor의 HTML 편집 기능 사용하기

가장 처음에 시도하는 방법은 포스트나 페이지를 편집하다 바로 code를 삽입하는 방법이다. 될 거 같다는 생각은 들지만, 정말 복잡한 코드도 집어 넣을 수 있는 건지 의심되기도 한다. 한번 해보자.

1) Editor에 간단한 Form 삽입하기 (가능 여부 확인)

Gutenberg Editor에는 Custom HTML을 삽입하는 block이 있다. 아마 예전 Editor에선 Visual / HTML 탭에서 HTML을 선택해서 코드를 삽입했던 거 같다. (확인 안해봄) 1

다음의 HTML 코드를 삽입해 보자.

	<form action="" method="post">
		<label for="firstname">이름:</label> 
		<input type="text" name="firstname" id="firstname"> 
		<label for="lastname">성:</label> 
		<input type="text" name="lastname" id="lastname"> 
		<input type="submit" value="제출">
	</form>

HTML 코드를 삽입한 결과는 아래와 같다. action이 정의가 안되어 있기에 이름과 성을 입력하고 제출해도 실행되는 내용은 없다.

이렇게 넣어도 Form이 동작하는 걸 확인했다. 다음은 PHP 코드를 넣어서 action을 받아보자.


2) HTML Block에 PHP 코드를 함께 삽입하기

HTML 코드와 PHP 코드를 함께 넣어도 잘 동작할까? 한번 해보도록 하자.

<?php 
if (! isset($_POST['firstname2'])) {
?>
<form action="" method="post">
	<label for="firstname2">이름:</label> <input type="text"
		name="firstname2" id="firstname2"> <label for="lastname2">성:</label> <input
		type="text" name="lastname2" id="lastname2"> <input type="submit"
		value="제출">
</form>
<?php
} else {
    $firstName2 = $_POST['firstname2'];
    $lastName2 = $_POST['lastname2'];

    $output = htmlspecialchars($firstName, ENT_QUOTES, 'UTF-8') . ' ' . htmlspecialchars($lastName, ENT_QUOTES, 'UTF-8') . '님, 홈페이지 방문을 환영합니다!';
?>
<p>
<?php echo $output; ?>
</p>
<?php
}
?>

위 코드를 삽입한 결과는 아래와 같다.

잘 동작하지 않는다. HTML 코드를 확인해 보면 PHP 코드 부분이 모두 주석 처리되어 들어가 있는 것을 확인할 수 있다. 이렇게 해선 안되고 다른 방법을 시도해보자.


3) Block Editor엔 HTML 코드만, PHP 코드는 별도 파일로 분리

이번엔 Block Editor로는 HTML 코드만 집어넣고, PHP 코드는 별도 파일로 분리해보자.

먼저 HTML 코드에 aciton php 파일을 집어넣고 삽입해 보자.

	<form action="/myaction.php" method="post">
		<label for="firstname3">이름:</label> 
		<input type="text" name="firstname3" id="firstname3"> 
		<label for="lastname3">성:</label> 
		<input type="text" name="lastname3" id="lastname3"> 
		<input type="submit" value="제출">
	</form>

그리고 다음과 같이 myaction.php 파일과 welcome.html.php 파일을 만들어 다음 위치에 넣어둔다.

myaction.php

<?php
if (! isset($_POST['firstname3'])) {
    // do nothing
} else {
    $firstName3 = $_POST['firstname3'];
    $lastName3 = $_POST['lastname3'];

    $output = htmlspecialchars($lastName3, ENT_QUOTES, 'UTF-8') . ' ' . htmlspecialchars($firstName3, ENT_QUOTES, 'UTF-8') . '님, 홈페이지 방문을 환영합니다!';

    include __DIR__ . '/../templates/welcome.html.php';
}

welcome.html.php

// welcome.html.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>폼 예제</title>
  </head>
  <body>
    <p>
      <?php echo $output; ?>
    </p>
  </body>
</html>

두 파일의 위치는 각각 다음과 같다.

  • / (root directory)
    • www (public directory)
      • myaction.php
    • templates
      • welcome.html.php

위 내용을 실제 입력하면 다음과 같다.

이렇게 하면 폼에 입력한 값들을 잘 받아온다.

문제는 현재 주소에서 https://bekseju9n.pe.kr/myaction.php 주소로 이동한다는 거다. 단순히 DB에 insert하거나 update하는 경우 문제 없겠지만, 현재 포스트/페이지에서 입력값을 처리해서 무언가 값을 보여주고자 한다면 주소가 이동해선 안된다.

코드를 약간 수정해서 원래 호출 주소로 redirect할 수도 있겠지만, 그런 지저분한 방법보다는 ajax를 쓰던지 다른 방법을 찾아보도록 해야겠다.


4) 논외지만 javascript로 validation하는 form 넣어보기

이 주제와는 조금 떨어져 있지만, form에 javascript로 validation하는 코드를 넣어보자. 간단한 validation으로 name4 입력이 비어있는지 확인하는 코드를 넣어보겠다. 2

<form name="myForm" action="" onsubmit="return validateForm()" method="post">
Name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>

이제 validateForm() 함수를 head나 footer에 넣어야 하는데, 다음 코드를 child theme의 functions.php 파일에 추가해본다. 3

    add_action('wp_head', 'wpb_hook_javascript');
    function wpb_hook_javascript() {
    	if (is_single ('2678')) { 
    		?>
    		<script type="text/javascript">
    			function validateForm() {
    				var x = document.forms["myForm"]["fname"].value;
    				if (x == "") {
    					alert("Name must be filled out");
    					return false;
    				}
    			}        
    		</script>
    		<?php
		}
	}

위 코드들을 적용하면 아래와 같다. action은 blank로 되어 있으므로 submit 시 action은 없다.

Name:


2. Plugin 으로 Form 만들고 shortcode로 전달하기

sitepoint에 있는 Build Your Own WordPress Contact Form Plugin in 5 Minutes 를 보고 따라해보았다. 5분만에 할 수 있단다. 한번 해보자.

① Plugin을 만들고 form을 생성하는 함수를 작성한다.

sp-form-example 플러그인을 만든다.

/wp-content/plugins/sp-form-example/sp-form-example.php

<?php
/*
Plugin Name: Example Contact Form Plugin
Plugin URI: http://example.com
Description: Simple non-bloated WordPress Contact Form
Version: 1.0
Author: Agbonghama Collins
Author URI: http://w3guy.com
*/

// form code 반환
function html_form_code() {
	echo '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
	echo '<p>';
	echo 'Your Name (required) <br />';
	echo '<input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="' . ( isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : '' ) . '" size="40" />';
	echo '</p>';
	echo '<p>';
	echo 'Your Email (required) <br />';
	echo '<input type="email" name="cf-email" value="' . ( isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : '' ) . '" size="40" />';
	echo '</p>';
	echo '<p>';
	echo 'Subject (required) <br />';
	echo '<input type="text" name="cf-subject" pattern="[a-zA-Z ]+" value="' . ( isset( $_POST["cf-subject"] ) ? esc_attr( $_POST["cf-subject"] ) : '' ) . '" size="40" />';
	echo '</p>';
	echo '<p>';
	echo 'Your Message (required) <br />';
	echo '<textarea rows="10" cols="35" name="cf-message">' . ( isset( $_POST["cf-message"] ) ? esc_attr( $_POST["cf-message"] ) : '' ) . '</textarea>';
	echo '</p>';
	echo '<p><input type="submit" name="cf-submitted" value="Send"/></p>';
	echo '</form>';
}

// mail 전송
function deliver_mail() {

    // if the submit button is clicked, send the email
    if ( isset( $_POST['cf-submitted'] ) ) {

        // sanitize form values
        $name    = sanitize_text_field( $_POST["cf-name"] );
        $email   = sanitize_email( $_POST["cf-email"] );
        $subject = sanitize_text_field( $_POST["cf-subject"] );
        $message = esc_textarea( $_POST["cf-message"] );

        // get the blog administrator's email address
        $to = get_option( 'admin_email' );

        $headers = "From: $name <$email>" . "\r\n";

        // If email has been process for sending, display a success message
        if ( wp_mail( $to, $subject, $message, $headers ) ) {
            echo '<div>';
            echo '<p>Thanks for contacting me, expect a response soon.</p>';
            echo '</div>';
        } else {
            echo 'An unexpected error occurred';
        }
    }
}

// short code 추가
function cf_shortcode() {
    ob_start();
    deliver_mail();
    html_form_code();

    return ob_get_clean();
}
add_shortcode( 'sitepoint_contact_form', 'cf_shortcode' );
?>

② Example Contact Form Plugin을 활성화한다.

③ post, page에 shortcode를 추가한다.

post, page에 shortcode를 추가한다. 결과는 다음과 같다.

Your Name (required)

Your Email (required)

Subject (required)

Your Message (required)


3. Plugin 으로 Form 만들고 shortcode로 전달하기 (action 코드를 shortcode에서 분리)

위 2번 예를 변형해서 shortcode 안에서 deliver_mail 하던 코드를 shortcode는 화면 표시만, deliver_mail은 action만 담당하도록 분리해본다.

① shortcode 생성 함수를 수정한다.

cf_shortcode 함수에서 deliver_mail, html_form_code을 차례로 부르던 구조에서 html_form_code2 함수를 바로 부르는 구조로 변경한다. 이 때 21 line에서 hidden input으로 action=deliver_mail 값을 전달한다.

/wp-content/plugins/sp-form-example/sp-form-example.php

add_shortcode( 'sitepoint_contact_form2', 'html_form_code2' );
function html_form_code2() {
    $output= '';
    $output.=  '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
    $output.=  '<p>';
    $output.=  'Your Name (required) <br />';
    $output.=  '<input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="' . ( isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : '' ) . '" size="40" />';
    $output.=  '</p>';
    $output.=  '<p>';
    $output.=  'Your Email (required) <br />';
    $output.=  '<input type="email" name="cf-email" value="' . ( isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : '' ) . '" size="40" />';
    $output.=  '</p>';
    $output.=  '<p>';
    $output.=  'Subject (required) <br />';
    $output.=  '<input type="text" name="cf-subject" pattern="[a-zA-Z ]+" value="' . ( isset( $_POST["cf-subject"] ) ? esc_attr( $_POST["cf-subject"] ) : '' ) . '" size="40" />';
    $output.=  '</p>';
    $output.=  '<p>';
    $output.=  'Your Message (required) <br />';
    $output.=  '<textarea rows="10" cols="35" name="cf-message">' . ( isset( $_POST["cf-message"] ) ? esc_attr( $_POST["cf-message"] ) : '' ) . '</textarea>';
    $output.=  '</p>';
    $output.=  '<p><input type="hidden" name="action" value="deliver_mail"/></p>';
    $output.=  '<p><input type="submit" name="cf-submitted" value="Send"/></p>';
    $output.=  '</form>';

    return $output;
}

② deliver_mail 함수를 ajax 액션으로 등록한다.

/wp-content/plugins/sp-form-example/sp-form-example.php

// mail 전송
add_action( 'wp_ajax_deliver_mail', 'deliver_mail2');
function deliver_mail2() {

    // if the submit button is clicked, send the email
    if ( isset( $_POST['cf-submitted'] ) ) {

        // sanitize form values
        $name    = sanitize_text_field( $_POST["cf-name"] );
        $email   = sanitize_email( $_POST["cf-email"] );
        $subject = sanitize_text_field( $_POST["cf-subject"] );
        $message = esc_textarea( $_POST["cf-message"] );

        // get the blog administrator's email address
        $to = get_option( 'admin_email' );

        $headers = "From: $name <$email>" . "\r\n";

        // If email has been process for sending, display a success message
        if ( wp_mail( $to, $subject, $message, $headers ) ) {
            echo '<div>';
            echo '<p>Thanks for contacting me, expect a response soon.</p>';
            echo '</div>';
        } else {
            echo 'An unexpected error occurred';
        }
    }
}

이제 화면을 만드는 shortcode 코드 부분과 action을 처리하는 코드가 분리되었다. 아래 화면은 동일하게 동작한다.

Your Name (required)

Your Email (required)

Subject (required)

Your Message (required)


4. child theme의 template을 사용하기 – 방법1

다음 강좌를 참고하였다. How to code custom submit form in php in wordpress

참고로 위 강좌의 동영상 파일도 있다.

멋지다 @.@

① 새로운 Page 만들고 저장하기

Page의 이름을 test form 190909 라고 해보자. 내용은 아무 내용도 입력할 필요 없다.
이 Page의 slug는 test-form-190909 이다. 기억하자.

② theme 디렉토리 안에 page.php를 복사해서 page-[slug명].php로 이름을 변경

child theme의 page.php 파일을 복사하고 이름을 page-[slug명].php로 변경한다.

만약 child theme에 page.php 파일이 없다면, parent theme에 가서 page.php를 복사해서 child theme에 page-[slug명].php 파일을 만들면 된다. 난 twenty twelve를 parent theme으로 하는 child theme을 사용 중인데 내 child theme엔 page.php 파일이 없어 parent theme의 파일을 copy해 왔다.

/wp-content/[테마명]/page-test-form-190909.php

<?php
/**
 * The template for displaying all pages
 *
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages
 * and that other 'pages' on your WordPress site will use a
 * different template.
 *
 * @package WordPress
 * @subpackage Twenty_Twelve
 * @since Twenty Twelve 1.0
 */

get_header(); ?>

	<div id="primary" class="site-content">
		<div id="content" role="main">

			<?php
			while ( have_posts() ) :
				the_post();
				?>
				<?php get_template_part( 'content', 'page' ); ?>
<form id="formid" action="" method="POST">
  <input type="text" name="inputname" value="" />
  <input type="submit" name="submit" value="submit" />
</form>				
				<?php comments_template( '', true ); ?>
			<?php endwhile; // end of the loop. ?>

		</div><!-- #content -->
	</div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

위와 같이 코드를 넣으면 잘 보인다.

③ submit 버튼 누르면 처리할 action을 코드에 추가한다.

<?php
/**
 * The template for displaying all pages
 *
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages
 * and that other 'pages' on your WordPress site will use a
 * different template.
 *
 * @package WordPress
 * @subpackage Twenty_Twelve
 * @since Twenty Twelve 1.0
 */

get_header(); ?>

	<div id="primary" class="site-content">
		<div id="content" role="main">

			<?php
			while ( have_posts() ) :
				the_post();
				?>
				<?php get_template_part( 'content', 'page' ); ?>
<?php
  if($_POST['submit']) {
    // we will add the code to process submitted form here
    // we can also echo some text here if form is submitted
  } else { ?>
    <form id="formid" action="" method="POST">
      <input type="text" name="inputname" value="" />
      <input type="submit" name="submit" value="submit" />
    </form>
<?php } ?>
  				<?php comments_template( '', true ); ?>
			<?php endwhile; // end of the loop. ?>

		</div><!-- #content -->
	</div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

④ 끝

작성된 샘플은 다음 URL에서 접근할 수 있다. https://bekseju9n.pe.kr/test-form-190909/

이 방법이 다음에 설명할 template 파일 사용하는 방법에 비해 나아보이는 점은 ‘특정 page를 위한 php 파일을 만들고, 명확히 그 파일 내에서 필요한 코딩을 한다‘는 점이다.

위에선 form 하나만 입력했지만, 필요하다면 어떤 내용이건 추가할 수 있다는 거다. 이제 다음 방법을 알아보자.


5. child theme의 template을 사용하기 – 방법2

다음의 강좌를 참고했다. How to Create Contact Page Template in Your WordPress Theme

방법1과 유사하지만 약간의 차이가 있다.

① theme 디렉토리 아래에 contact.php 파일을 만든다.

<?php 
/* 
  Template Name: Contact Us 
 */ 
get_header(); ?> 
<div id="primary"> 
  <div id="content" role="main"> 
  </div><!-- #content --> 
</div><!-- #primary --> 
<?php get_footer(); ?>

line 3에 적어놓은 template name은 뒤에 설명될 내용에서 page template 선택 목록에 나타낼 이름을 정의한다.

② 위 파일에 Form과 action 코드를 추가한다.

<?php 
/* Template Name: Contact Us */ 
get_header(); ?>
<div id="primary">
	<div id="content" role="main">
		<font color="#FF0000"> 
		<?php if(isset($_POST['submit'])) { 
		    $flag=1; 
		    if($_POST['yourname']=='') { 
		        $flag=0; 
		        echo "Please Enter Your Name<br>"; 
		    } else if(!preg_match('/[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*/',$_POST['yourname'])) { 
		        $flag=0; 
		        echo "Please Enter Valid Name<br>"; 
		    } 
		    if($_POST['email']=='') { 
		        $flag=0; 
		        echo "Please Enter E-mail<br>"; 
		    } else if(!eregi("^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$", $_POST['email'])) {
		        $flag=0; 
		        echo "Please Enter Valid E-Mail<br>"; 
		    } 
		    if($_POST['subject']=='') { 
		        $flag=0; 
		        echo "Please Enter Subject<br>"; 
		    } 
		    if($_POST['message']=='') { 
		        $flag=0; echo "Please Enter Message"; 
		    } 
		    if ( empty($_POST) ) { 
		        print 'Sorry, your nonce did not verify.'; 
		        exit; 
		    } else if($flag==1) { 
		        wp_mail(get_option("admin_email"),trim($_POST[yourname])." sent you a message from ".get_option("blogname"),stripslashes(trim($_POST[message])),"From: ".trim($_POST[yourname])." <".trim($_POST[email]).">rnReply-To:".trim($_POST[email])); 
		        echo "Mail Successfully Sent"; 
		    } 
		} ?> 
		</font>
		<form method="post" id="contactus_form">
			Your Name:<input type="text" name="yourname" id="yourname" rows="1" value="" /> 
			<br />
			<br /> 
			Your Email:<input type="text" name="email" id="email" rows="1" value="" /> 
			<br />
			<br /> 
			Subject:<input type="text" name="subject" id="subject" rows="1" value="">
			<br />
			<br /> Leave a Message:
			<textarea name="message" id="message"></textarea>
			<br />
			<br /> 
			<input type="submit" name="submit" id="submit" value="Send" />
		</form>
	</div>
	<!-- #content -->
</div>
<!-- #primary -->
<?php get_footer(); ?>

7-32 라인은 validation, 33-36 라인은 mail send, 39-53 라인은 form에 대한 코드이다. 실제 실행시켜보진 않았으나, 잘 될거라 생각된다.

③ 새로운 page를 만들고, template으로 위에서 만든 contact us를 선택한다.

끝. 유사한 강좌도 참고해보자. 4


Footnotes

  1. https://www.inmotionhosting.com/support/edu/business/wordpress-introduction/adding-html-wordpress
  2. JavaScript Form Validation https://www.w3schools.com/js/js_validation.asp
  3. How to Easily Add JavaScript in WordPress Pages or Posts (3 Methods) https://www.wpbeginner.com/wp-tutorials/how-to-easily-add-javascript-in-wordpress-pages-or-posts/
    다른 validation 예로는 https://shibulijack.wordpress.com/2012/03/18/create-custom-forms-in-wordpress/
  4. https://www.wpbeginner.com/wp-themes/how-to-create-a-custom-page-in-wordpress/

9 Responses

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다

  • 카테고리

  • Count per Day

    • 1094This post:
    • 118238Total reads:
    • 67405Total visitors:
    • 4Reads today:
    • 3Visitors today:
    • 2019년 3월 10일Counter starts on: