欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

How to a use a template file to theme a form?

While nodes, comments, blocks and many other things in Drupal are themed using theme template files (like node.tpl.php), forms are a different story. There are no theme template files for forms. How can I get a particular form to use a custom theme template?

shareimprove this question
 

It's completely reasonable to want to use a tpl file to display a form. You can use lots of extraneous CSS and #prefix/#suffix properties to achieve similar results, but by using tpl's you don't have to clutter up the separation of your logic and presentation layers and don't have to target ugly CSS selectors like #user-login label. Here's an example in 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); ?>

This is using Foundation, which gives us a form like this:

enter image description here

shareimprove this answer
 
   
it looks like you forgot a return state on the mytheme_theme() function – sel_space Nov 25 '14 at 9:55
   
You're right, I've added it. – Charlie S Nov 25 '14 at 15:53
2 
Very important note is that, at the bottom of the code snippet, is print drupal_render_children($form) which makes the form actually do stuff :). – Chris Rockwell Nov 13 '15 at 16:52
   
Good answer. I can add that you need to specify additionally engine, if you are using something not default. E.g. 'engine' => 'twig'. – milkovsky Jul 21 at 16:47
   
@milkovsky sounds like you're in Drupal 8 – you may want to post an example if there are any other differences and tag it as such, I'm sure a lot of folks will appreciate that. – Charlie S Jul 21 at 16:51

Even though you may be able to use kiamlaluno's solution I personally wouldn't.

What is your reason for needing a template file for a form? If it's because you want slightly different markup for an existing form? If so then you can use hook_form_alter() to modify the form before it is rendered. Using the Form API you you can modify all the form fields inject html elements etc.

Here is an example of hook_form_alter() that I've created that modifies the standard drupal login form block:

/**
 * 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;
  }
}

The above example wraps the entire form within a DIV which has an inline style to turn the background colour to red. It also adds a paragraph of help text to the beginning of the form.

This is what my user login form looks like now once the above code is loaded:

Customised login form

See the Form API reference for more information: Form API Reference

shareimprove this answer
 
1 
Just to clarify the use of inline styles in this example is just to simplify the example. I don't recommend using inline styles and you should use classes. – Camsoft Mar 4 '11 at 13:07
   
I am not supporting using a template file for rendering a form; as a matter of fact, I also said that I have never used a template file to render a form (I have actually changed the code of a module that was using a template file for a form), and that Drupal doesn't use template files to render forms. – kiamlaluno Mar 5 '11 at 15:17
5 
What if you want to radically alter the markup? Sometimes a template file is a better option. – cossovich Oct 16 '13 at 15:25
6 
Markup in a form logic builder smells. – Charlie S Jun 24 '14 at 16:02
1 
Although this solution works in most cases, it may actually break when the form rendering is refreshed in an ajax callback – PatrickS Jan 23 '15 at 6:04

I have actually never needed to use a template file for a form.
As far as I can see, Drupal core code uses theme functions, when a form, or part of a form needs to be rendered in a particular way; a theme function that calls drupal_render() is normally enough for any purposes.

To reply to the question, creating a template file for a form is not different from creating a template file that is not for a form.

Define a theme function, using as theme function the name of the form builder callback. The code should be similar to the following:

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

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

If the form contains the value $form['field_1'], its value will be available in the template file as $field_1. The template file will be also able to use any values passed from template_preprocess_mymodule_form().

shareimprove this answer
 
   
How do I suggest a form defined by some other modules, possibly core modules to use my theme function/template? – giga Mar 21 '12 at 20:48
   
Set $form['#theme']. – kiamlaluno Jan 2 '13 at 17:47
   
Not working, when I submit the form, it will not go to the form_submit function – gbstack May 29 '14 at 6:10

You have to implement hook_form_alter() in a module or template.php and set the form's #theme property:

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

Then implement new theme:

/**
 * 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',
    ),
  );
}

And then add form--user_login.tpl.php template with follow code to render form:

<?php print drupal_render_children($form) ?> 
shareimprove this answer
 
   
The #theme property is so very simple and is mentioned for the first time really low down in the answers, super weird. This is definitely my favourite method. – Matt Fletcher Jun 6 at 11:01

I would always style by adding to my CSS file using selectors to identify the element to be styled as follows for the core login form

#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;
}

The above I simply add to sites/all/themes/theme-name/css/theme-name.css

If what you need to style doesn't have an ID or a sufficiently accurate selector then it is necessary to use the hook approach to modify the HTML too add identifiers.

IMO using inline style on elements is a very bad practice that should be deprecated and replaced by use of class and id

shareimprove this answer
 

We at DesignsSquare are starting to use Template API that comes with basic templates for contact, login, password-reset, register, comment, search forms. All, you have to do is drop you template in themes/YOUR-THEME/templates/template-api dir and user the Template API to insert content. See more info at http://designssquare.com/tapi-docs/

shareimprove this answer
 

To theme a form, you can use a custom css, as explained in Themeing Drupal 7 Forms (Including CSS and JS).

Basically you need to perform these steps:

  1. Register a path to the form using hook_menu()
  2. Define the form
  3. Register a theme function with hook_theme()
  4. Write the theme function
  5. Create the CSS and JavaScript files
shareimprove this answer
 

I'm pretty sure you're able to use a template for forms, but you have to use hook_theme to register the template in the first place. I had a situation where the form really needed to be table based rather than div based and the simple #prefix and #suffix changes didn't really cut it. If interested I could probably try and dig up an example.


来自  http://drupal.stackexchange.com/questions/312/how-to-a-use-a-template-file-to-theme-a-form


Drupal Custom Elements API Errors

Posted on July 29, 2013, 4 p.m.

The Drupal Form API is powerful, but very extensive and complicated. In another post we discussed how to add a custom element from scratch. Watch out for the errors and mistakes highlighted in this advanced-level post.

Element and Field Defaults

To fully understand the API, you need to understand how elements are built. When you define a form field, custom or not, you have to give it a #type.

When the form is being built, Drupal will look at the #type and decide what to do with it. If it's a custom element you've defined, Drupal will look at the hook_element_info() that defined that custom element, and grab all the information from that array. That is, keys and values in that array will be merged into your field. This allows you to set defaults for that element #type. Let's look at an example. For simplification, let's define a basic custom element type:

1
2
3
4
5
6
7
8
<?php

function example_element_info() {
  $elements['custom_element'] = array(
    // Element declaration here ...
  );
  return $elements;
}

Note that this element won't do much. But now, let's use it in a form:

1
2
3
4
5
6
7
8
<?php

function example_some_form() {
  $form['my_field'] = array(
    '#type' => 'custom_element',
  );
  return $form;
}

If we want each usage of the element to, by default, have certain properties, we can just add it to the hook_element_info() function. So doing this:

1
2
3
4
5
6
7
8
9
<?php

function example_element_info() {
  $elements['custom_element'] = array(
    // Rest of element declaration here ...
    '#some_property' => 'some_property',
  );
  return $elements;
}

Will mean that all uses of your element in forms would be as if you had declared the form like so:

1
2
3
4
5
6
7
8
9
<?php

function example_some_form() {
  $form['my_field'] = array(
    '#type' => 'custom_element',
    '#some_property' => 'some_property',
  );
  return $form;
}

In other words, #some_property will "bubble" up from the element declaration to the actual element useful.

Learning Drupal? Subscribe to my Drupal articles, tips and tutorials.

 

This means you can do powerful things, like declaring default #theme functions, default #prefix and #suffix content, etc.

To summarize: the form declaration for that element will get merged to the properties defined in hook_element_info(). So keep this in mind when defining your custom elements.

Hook Theme and Render Element

So you've defined your custom element, but now want to control its appearance. Easy right? Just give it a #theme function in hook_element_info(). Well, it's not that simple.

You might notice it's not rendering now or ignoring your theme function. So you go and add that function to the theme registry, using hook_theme().

But now we have another problem: our theme function isn't being called with the right arguments. That's because when defining this function in hook_theme(), you need to use the render element property, rather than your typical variables property. As follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php

// DO THIS
function example_theme() {
  return array(
    'gitbucket_field' => array(
      'render element' => 'element',
    ),
  );
}

// NOT THIS
function example_theme() {
  return array(
    'gitbucket_field' => array(
      'variables' => array('element' => NULL),
    ),
  );
}

And there you go: two big secrets about custom Drupal elements. With this knowledge on hand, you should be able to create all the custom elements you'll need. Without surprises.

Tags: Drupal Drupal Planet


自  https://www.silviogutierrez.com/blog/drupal-custom-elements-api-errors/


Custom Drupal Elements for Forms

Posted on July 8, 2013, 8:41 p.m.

One of the most cryptic tasks in Drupal is defining a custom form element. That is, defining your own element types to be used and resused in your forms. This post will walk you through the basics. And there's no better way than to learn by example.

For our example element, let's define one that links to a github or bitbucket repository. These two sites host a lot of open source projects, so it makes sense to have an element that handles both. Note: this guide applies to Drupal 7. You should be able to make it work on Drupal 6 with some minor modifications. Let's call our element gitbucket.

Learning Drupal? Subscribe to my Drupal articles, tips and tutorials.

 

A custom Drupal element in use.A custom Drupal element in use.

Part of what makes the Form API in Drupal so powerful is that we can define compound custom elements. In other words, elements that contain one or more existing elements. This is quite useful for our use case, where we want our gitbucket field to have both, a source field (github or bitbucket) and ausername/repository field. So let's get started.

The key to creating a custom element is hook_element_info(), where we provide information about our element. So let's define it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php

function example_element_info() {
  $elements['gitbucket'] = array(
    '#default_value' => '',
    '#input' => TRUE,
    '#process' => array('example_gitbucket_element_process'),
    '#theme' => array('gitbucket_field'),
    '#theme_wrappers' => array('form_element'),
    '#tree' => TRUE,
    '#value_callback' => 'example_gitbucket_element_value_callback',
  );
  return $elements;
}

As you can see above, we're providing the Form API with quite a bit of info. Let's walk through this hook step by step.

Our #process callback is what gets called when we're going to use the element in a form. This is where we turn our element from a simple definition into the compound element that we want. So we provide a callback function for it. We'll get to that in a bit.

We also define a #theme callback. This is what renders the inside of our element, including the subelements that we'll define. We have a lot of flexibility here when rendering. Using this callback, we'll make sure our element looks nice and readable.

Next we provide #theme_wrappers. As you'd imagine, this wraps all the elements after they come back from the #theme callback. Generally, you can just use the built-in form_element and let it do the work for you. That's exactly what we're doing here.

Last but not least, we define #tree and #value_callback. The first makes sure our nested element structure is preserved for our values, rather than flattened. The second provides a way to process values before they are returned to the form submit function. You need to provide a #value_callback if you want to do fancy processing on the input.

With all of that declared, we can now implement our #process function to construct our very own custom element:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php

function example_gitbucket_element_process($element, $form_state, $complete_form) {

  $element['gitbucket']['source'] = array(
    '#type' => 'select',
    '#empty_option' => '- ' . t('Source') . ' -',
    '#options' => array(
      'github' => 'github://',
      'bitbucket' => 'bitbucket://',
    ),
    '#required' => $element['#required'],
    '#title' => t('Repository Source'),
    '#title_display' => 'invisible',
    '#theme_wrappers' => array(),
  );

  if (isset($element['#default_value']['gitbucket']['source'])) {
    $element['gitbucket']['source']['#default_value'] = $element['#default_value']['gitbucket']['source'];
  }

  $element['gitbucket']['address'] = array(
    '#type' => 'textfield',
    '#size' => 50,
    '#required' => $element['#required'],
    '#title' => t('Repository Name'),
    '#title_display' => 'invisible',
    '#theme_wrappers' => array(),
    '#attributes' => array('placeholder' => 'username/repository'),
  );

  if (isset($element['#default_value']['gitbucket']['address'])) {
    $element['gitbucket']['address']['#default_value'] = $element['#default_value']['gitbucket']['address'];
  }

  return $element;
}

As you can see, we're nesting elements in the snippet above. Our custom element consists of a select field for the repository source, and a textfield for the actual repository. The actual declaration of these fields is straightforward, and you can use almost anything in the Form API.

When nesting elements, there are a couple of quirks to watch out for. First, you probably don't want a bunch of nested titles shown. That's why we set #title_display to invisible. But we still declare a title for error handling purposes. We want the Form API to be able to pinpoint fields required nested fields and the like.

You also don't want the wrapping HTML structure around each individual nested element. You want it outside the entire compound element. So for each nested element, we set #theme_wrappers to an empty array.

And that's it. We load up default values as necessary, and we're done processing our custom elemenet. Let's move on to theming.

We want a nice inline look for our field, so let's keep the theming simple. First we need to register our function, and then implement it. Like so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php

function example_theme() {
  return array(
    'gitbucket_field' => array(
      'render element' => 'element',
    ),
  );
}

function theme_gitbucket_field($variables) {
  $element = $variables['element'];
  $output = '';
  $output .= drupal_render($element['gitbucket']['source']);
  $output .= " "; // This space forces our fields to have a little room in between.
  $output .= drupal_render($element['gitbucket']['address']);
  return $output;
}

Now we're ready for the last part: the value callback. As you can see, our custom element has two parts. You should select either or none. But what happens if they just select a source with no repository name? If we marked the field as required, Drupal handles that for us by requesting both fields be populated. The problem appears when our field is not marked as required. In this case, if we fill just one and not the other, we want to treat this as the user having left the field empty. We can use the value callback for this 1.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php

function example_gitbucket_element_value_callback($element, $input = FALSE, &$form_state) {
  if ($input !== FALSE) {
    if ($input['gitbucket']['source'] && !$input['gitbucket']['address']) {
      $input['gitbucket']['source'] = '';
    }
    if ($input['gitbucket']['address'] && !$input['gitbucket']['source']) {
      $input['gitbucket']['address'] = '';
    }
    return $input;
  }
  elseif (!empty($element['#default_value'])) {
    return $element['#default_value'];
  }

  return;
}

Value callbacks should be divided into three conditions:

  1. Input is being provided directly. This happens when a form is submitted.
  2. No input is provided, but the field definition has a default value.
  3. No input is provided and there is no default value.

In the first part, we handle the edge case of partial input. If only half the field is filled out, we simply treat it as empty. Then we return the modified input.

And that's it. You're done. You've now defined a custom compound field that can be used in any Drupal forms. For example, let's declare a simple system settings form that uses our newly minted element.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php

function example_form() {
  $form = array();
  $form['required_field'] = array(
    '#type' => 'gitbucket',
    '#title' => t('Your favorite repository'),
    '#required' => TRUE,
    '#default_value' => variable_get('required_field', array()),
  );
  $form['optional_field'] = array(
    '#type' => 'gitbucket',
    '#title' => t('Your least favorite repository'),
    '#default_value' => variable_get('optional_field', array()),
  );
  return system_settings_form($form);
}

Try it out. Fill in partial input and hit submit. You'll see how our fields behave properly even with missing input.


  1. Technically, you can also use validation hooks for this. 


来自 https://www.silviogutierrez.com/blog/custom-drupal-elements-forms/


 
 

I'm having trouble understanding the 'render element' key purpose when implementing hook_theme().

function personal_news_theme($existing, $type, $theme, $path) {
  return array(
    'teaser_list_by_user' => array(
      'render element' => 'element',
    ),
  );
}

I did my research and the way I understand it, the render element key is use when creating a theme function to modify another theme function's output ONLY! And there's no way to use it as to implement a new theme function. If I'm wrong, how can I use it instead of variables?

shareimprove this question
 


正确答案
In the example below, I created a new theme function using a render element.

/**
 * Implements hook_theme().
 */
function rojo_theme() {
  $items = array(
    'rojo_content' => array(
      'render element' => 'element',
    ),
  );
  return $items;
}

/**
 * Theme function.
 */
function theme_rojo_content($vars) {
  return '<pre>' . print_r($vars, TRUE) . '</pre>';
}

/**
 * Render function.
 */
function rojo_render() {
  $build = array(
    '#theme' => 'rojo_content',
    '#module' => 'rojo',
    'content' => 'Page content for the render function',
    'list' => array('one', 'two'),
    'tag' => 'div',
  );
  return render($build);
}

This will print the output of the $vars passed into the theme function. From here, you should be able to see what is going on. The #theme property will be called with theme() and passed the $buildarray during the render() process. Notice I added #module property and Drupal added the #printed / #children properties.

This is purely an example to demonstrate the creation of a new theme function using render elementand argument passing. I hope this helps somebody out.

Array
(
  [element] => Array
    (
      [#theme] => rojo_content
      [#module] => rojo
      [content] => Page content for the render function
      [list] => Array
        (
          [0] => one
          [1] => two
        )
      [tag] => div
      [#printed] => 
      [#children] => 
    )
)
shareimprove this answer
 

If your theme function returns an array - you can specify which key of the array to use for rendering.

render element: The name of the renderable element or element tree to pass to the theme function. This name is used as the name of the variable that holds the renderable element or tree in preprocess and process functions.

(Source: hook_theme)

来自  http://stackoverflow.com/questions/23644323/drupal-7-how-to-use-render-element-instead-of-variables-...

 

Join the Stack Overflow Community
 
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other. 
Join them; it only takes a minute: 
Sign up

Drupal doesn't call my theme function for my form in my module.

I added the hook_theme in the .module file as this :

function agil_theme() {
    return array(
        'agil_list_form' => array(
            'render element' => 'form',
        ),
    );
}

where :

  • agil is the name of my module (not my theme)
  • agil_list_form is the name of my form declaration (chich render with default theme)

I want to call a function to create my own markup, as this one :

function theme_agil_list_form($form) {
  $output  = "<table><th><td></td><td>".t('Title')."</td><td>".t('Link')."</td></th>";
    $output .= "<tr><td>";
  $output .= drupal_render($form['name']);
  ...

But Drupal is never calling this function... I cleared the cache but nothing..

Where do I miss something ?

I read also this about new theme declaration in Drupal 7 :http://drupal.org/update/modules/6/7#hook_theme_render_changes

shareimprove this question
 

正确答案
All theme functions in Drupal 7 take a single array argument (usually named as $vars or $variables by convention), and that array contains the variables/render elements you've declared. The theme function itself would look like this:

function theme_agil_list_form($vars) {
  $form = $vars['form'];
  // Now manipulate $form
}

Also you need to tell Drupal that your form will be using this theme, by doing this in your form function:

$form['#theme'] = 'agil_list_form';
shareimprove this answer
 
1 
Great. It works. I missed the $form['#theme'] in my form declaration and it was not mentionned in the documentation I read... Thx ! – Stéphane V Apr 23 '12 at 16:19



  来自  http://stackoverflow.com/questions/10259840/calling-custom-theme-function-for-form-in-drupal-7




 
 
 

When making my ticket-system I want managers to be able to reply to tickets when viewing the ticket. On the page to view any ticket I load my form. Because I want it to be a bit more fancier than just the default 'element under element' style I render each item by item manually.

<?php print drupal_render($form['open']); ?>

Now the problem is, my form doens't work. Clicking on my rendered submit doesn't perform any action.

My guess is that rendering each item manually doesn't include the 'form container'. How should I include is? Or is my style of working completely wrong?

shareimprove this question
 

The best way to implement custom rendering of a form would be to use a custom theme hook for the form:

/**
 * Builder function for the ticket form.
 */ 
function MODULE_ticket_form($form, $form_state) {
  // Build the $form array here...

  // Let the theme API knows that this form use it own theme hook.
  $form['#theme'] = 'ticket_form';
  return $form;
}

/**
 * Implements hook_theme().
 */
function MODULE_theme() {
  return array(
    // Custom theme hook for the ticket form.
    'ticket_form' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Default implementation for the ticket_form theme hook. 
 */
function theme_ticket_form($variables) {
  $form =& $variables['form'];

  //Custom rendering of forms elements goes here...
  $output = ...;    

  // Render every other elements (incl. hidden system ones).
  $output .= drupal_render_children($form);
  return $output;
}

Instead of using only a theme function, you can also use a template file. The theme function can also return a render array instead of a string.

shareimprove this answer
 

Try following will work:

<?php $form = drupal_get_form('yourform_id'); ?>

<?php print '<form id="'.$form['#id'].'" accept-charset="UTF-8" method="'.$form['#method'].'" action="'.$form['#action'].'">'; ?>
<?php print drupal_render($form['form_id']);?>
<?php print drupal_render($form['form_build_id']);?>
<?php print drupal_render($form['form_token']);?>
<?php print '</form>'; ?>
shareimprove this answer



来自  http://drupal.stackexchange.com/questions/33759/rendering-form-manually

普通分类: