템플릿 파일을 사용하여 양식을 테마로 만드는 방법은 무엇입니까?


50

Drupal의 노드, 주석, 블록 및 기타 많은 것들이 테마 템플릿 파일 (node.tpl.php와 같은)을 사용하여 테마 화되지만 양식은 다른 이야기입니다. 양식에 대한 테마 템플릿 파일이 없습니다. 사용자 정의 테마 템플릿을 사용하기 위해 특정 양식을 얻으려면 어떻게해야합니까?

답변:


73

양식을 표시하기 위해 tpl 파일을 사용하는 것이 완전히 합리적입니다. 외부 CSS 및 #prefix/ #suffix속성을 많이 사용하여 유사한 결과를 얻을 수 있지만 tpl을 사용하면 논리 및 프리젠 테이션 레이어의 분리를 어지럽 힐 필요가 없으며과 같은 추악한 CSS 선택기를 타겟팅 할 필요가 없습니다 #user-login label. Drupal 7의 예는 다음과 같습니다.

mytheme / template.php :

function mytheme_theme($existing, $type, $theme, $path) {
    // Ex 1: the "story" node edit form.
    $items['story_node_form'] = array(
        'render element' => 'form',
        'template' => 'node-edit--story',
        'path' => drupal_get_path('theme', 'mytheme') . '/template/form',
    );

    // Ex 2: a custom form that comes from a custom module's "custom_donate_form()" function.
    $items['custom_donate_form'] = array(
        'render element' => 'form',
        'template' => 'donate',
        'path' => drupal_get_path('theme', 'mytheme') . '/template/form',
    );

    return $items;
}

custom_donate_form () :

function custom_donate_form($form, &$form_state) {
    $form['first_name'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('First name')),
    );
    $form['last_name'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Last name')),
    );
    $form['address'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Address')),
    );
    $form['city'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('City')),
    );
    $form['state'] = array(
        '#type' => 'select',
        '#options' => array(
            'default' => 'State',
            '...' => '...',
        ),
    );
    $form['zip'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Zip')),
    );
    $form['email'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Email')),
    );
    $form['phone'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Phone')),
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
    );

    return $form;
}

mytheme / template / form / donate.tpl.php :

<div class="row">
    <div class="small-12 medium-12 large-8 columns">

        <div class="row">
            <div class="small-12 columns">
                <h5>Contact Information</h5>
            </div>
        </div>

        <div class="row">
            <div class="small-12 large-6 medium-6 columns">
                <?php print render($form['first_name']); ?>
            </div>
            <div class="small-12 large-6 medium-6 columns">
                <?php print render($form['last_name']); ?>
            </div>
        </div>

        <div class="row">
            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['address']); ?>
            </div>

            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['city']); ?>
            </div>
        </div>

        <div class="row">
            <div class="small-12 medium-3 large-3 columns">
                <?php print render($form['state']); ?>
            </div>

            <div class="small-12 medium-3 large-3 columns">
                <?php print render($form['zip']); ?>
            </div>

            <div class="medium-6 large-6 columns"></div>
        </div>

        <div class="row">
            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['email']); ?>
            </div>

            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['phone']); ?>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="small-12 medium-12 large-8 large-offset-2 columns">
            <?php print render($form['submit']); ?>
        </div>
    </div>
</div>

<!-- Render any remaining elements, such as hidden inputs (token, form_id, etc). -->
<?php print drupal_render_children($form); ?>

이것은 Foundation을 사용하여 다음과 같은 양식을 제공합니다.

여기에 이미지 설명을 입력하십시오


mytheme_theme () 함수에서 리턴 상태를 잊어 버린 것 같습니다
sel_space

네 말이 맞아 추가 했어
Charlie Schliesser

5
매우 중요한 점은 코드 스 니펫의 맨 아래에 print drupal_render_children($form)양식이 실제로 작동하게한다는 것입니다. :).
Chris Rockwell

좋은 대답입니다. engine기본값이 아닌 것을 사용하는 경우 추가로 지정해야한다고 추가 할 수 있습니다 . 예 'engine' => 'twig'.
milkovsky

1
좋은 대답입니다. 당신 같은 테마 관리자 양식을 원하는 경우 명심 user_profile_formuser_register_form. 이 시나리오에서는 a) 관리자 테마에서 테마를 수행하거나 기본 관리자 테마를 변경할 수없는 경우 테마에서 하위 테마를 수행하거나 b) 테마를 사용자 정의 모듈에 배치해야합니다. 그렇지 않으면 테마가 보이지 않습니다.
therobyouknow

18

모듈 또는 template.php에서 hook_form_alter ()를 구현하고 양식의 #theme 속성을 설정 해야 합니다.

/**
 * Implements hook_form_alter().
 */
function hook_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login') {
    $form['#theme'] = array('overwrite_user_login');
  }
}

그런 다음 새로운 테마를 구현하십시오.

/**
 * Implements hook_theme().
 */
function hook_theme($existing, $type, $theme, $path){
  return array(
    'overwrite_user_login' => array(
      'render element' => 'form',
      'template' => 'form--user_login',
      'path' => $path . '/templates',
    ),
  );
}

그런 다음 form--user_login.tpl.php 템플릿에 다음 코드를 추가하여 양식을 렌더링하십시오.

<?php print drupal_render_children($form) ?> 

1
#theme부동산은 매우 간단하며 답변에서 처음으로 정말 낮습니다. 이것은 확실히 내가 가장 좋아하는 방법입니다.
Matt Fletcher 2018

1
이 코드를 테스트했으며 예상대로 작동합니다.
VladSavitsky

14

kiamlaluno의 솔루션을 사용할 수는 있지만 개인적으로는 그렇지 않습니다.

양식의 템플릿 파일이 필요한 이유는 무엇입니까? 기존 양식에 대해 약간 다른 마크 업을 원하기 때문입니까? 그렇다면 hook_form_alter()양식을 렌더링하기 전에 양식을 수정하는 데 사용할 수 있습니다 . Form API를 사용하면 html 요소 등을 주입하는 모든 양식 필드를 수정할 수 있습니다.

다음은 hook_form_alter()표준 드루팔 로그인 폼 블록을 수정하는 내가 만든 예제입니다 .

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {

  switch ($form_id) {
    case 'user_login_block':

      // Form modification code goes here.
            $form['divstart'] = array(
                '#value' => '<div style="background-color: red;">',
                '#weight' => -1,
            );

            $form['instruct'] = array(
                '#value' => '<p>Enter your username and password to login</p>',
                '#weight' => 0,
            );          

            $form['divend'] = array(
                '#value' => '</div>',
                '#weight' => 4,             
            );
      break;
  }
}

위의 예는 배경색을 빨간색으로 바꾸는 인라인 스타일의 DIV 내에서 전체 양식을 래핑합니다. 또한 양식의 시작 부분에 도움말 텍스트 단락을 추가합니다.

위의 코드가로드되면 내 사용자 로그인 양식이 나타납니다.

맞춤형 로그인 양식

자세한 정보는 Form API Reference를 참조하십시오. Form API Reference


1
이 예제에서 인라인 스타일의 사용을 명확히하는 것은 예제를 단순화하는 것입니다. 인라인 스타일을 사용하지 않는 것이 좋으며 클래스를 사용해야합니다.
Camsoft

양식을 렌더링하기 위해 템플릿 파일 사용을 지원하지 않습니다. 사실, 나는 또한 템플릿 파일을 사용하여 폼을 렌더링 한 적이 없으며 (폼 템플릿 파일을 사용하는 모듈의 코드를 실제로 변경했습니다) Drupal은 템플릿을 사용하지 않는다고 말했습니다. 양식을 렌더링 할 파일.
kiamlaluno

5
마크 업을 근본적으로 변경하려면 어떻게해야합니까? 때로는 템플릿 파일이 더 나은 옵션입니다.
cossovich

6
양식 논리 빌더의 마크 업에서 냄새가납니다.
Charlie Schliesser 2016 년

1
이 솔루션은 대부분의 경우에 작동하지만 ajax 콜백에서 폼 렌더링을 새로 고치면 실제로 중단 될 수 있습니다.
PatrickS

13

실제로 양식에 템플릿 파일을 사용할 필요가 없었습니다.
내가 볼 수있는 한 Drupal 코어 코드는 폼 또는 폼의 일부를 특정 방식으로 렌더링해야 할 때 테마 기능을 사용합니다. drupal_render () 를 호출하는 테마 함수 는 일반적으로 모든 목적에 충분합니다.

질문에 답하기 위해 양식의 템플리트 파일을 작성하는 것은 양식이 아닌 템플리트 파일을 작성하는 것과 다르지 않습니다.

테마 함수로 양식 빌더 콜백의 이름을 사용하여 테마 함수를 정의하십시오. 코드는 다음과 유사해야합니다.

/**
 * Implementation of hook_theme().
 */

 function mymodule_theme() {
   return array(
     'mymodule_form' => array(
       'template' => 'mymodule-form',
       'file' => 'mymodule.admin.inc',
       'arguments' => array('form' => NULL),
     ),
   );
 }

양식에 값이 포함 된 경우 $form['field_1']해당 값은 템플리트 파일에서로 사용할 수 있습니다 $field_1. 템플릿 파일은에서 전달 된 모든 값을 사용할 수도 있습니다 template_preprocess_mymodule_form().


테마 기능 / 템플릿을 사용하기 위해 다른 모듈, 아마도 핵심 모듈에 의해 정의 된 양식을 어떻게 제안합니까?
Shafiul

설정하십시오 $form['#theme'].
kiamlaluno

1
내가 양식을 제출하면 작동하지 않습니다, 그것은 form_submit 기능으로 이동하지 않습니다
gbstack

1

핵심 로그인 양식에 대해 다음과 같이 스타일을 지정할 요소를 식별하기 위해 선택기를 사용하여 CSS 파일에 추가하여 스타일을 지정합니다.

#user-login
{
   border:1px solid #888;
   padding-left:10px;
   padding-right:10px;
   background-image: url(http://www.zaretto.com/images/zlogo_s.png);
   background-repeat:no-repeat;
   background-position:right;
}

#user-login label
{
    display: inline-block;
}

위의 나는 단순히 추가 sites/all/themes/theme-name/css/theme-name.css

스타일을 지정해야하는 항목에 ID 나 충분히 정확한 선택기가 없으면 hookHTML을 수정하는 식별자를 추가하기 위해이 접근 방식을 사용해야합니다 .

IMO 요소에 대한 인라인 스타일을 사용하는 것은입니다 아주 나쁜 관행 사용되지 않으며 사용하여 교체해야 class하고id


0

양식 테마를 지정하려면 테마 Drupal 7 양식 (CSS 및 JS 포함)에 설명 된대로 사용자 정의 CSS를 사용할 수 있습니다 .

기본적으로 다음 단계를 수행해야합니다.

  1. hook_menu ()를 사용하여 폼의 경로를 등록하십시오
  2. 양식 정의
  3. hook_theme ()을 사용하여 테마 함수 등록
  4. 테마 기능 작성
  5. CSS 및 JavaScript 파일 작성

-2

양식에 템플릿을 사용할 수 있다고 확신하지만 hook_theme을 사용하여 템플릿을 먼저 등록해야합니다. 양식이 실제로 div 기반이 아닌 테이블 기반이어야 하는 상황이 있었고 간단한 # 접두사 및 # 접미사 변경으로 실제로 잘라 내지 못했습니다. 관심이 있다면 아마도 예제를 파고들 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.