'Theming Example', 'description' => 'Some theming examples.', 'page callback' => 'theming_example_page', 'access callback' => TRUE, 'access arguments' => array('access content'), ); $items['examples/theming_example/theming_example_list_page'] = array( 'title' => 'Theming a list', 'page callback' => 'theming_example_list_page', 'access arguments' => array('access content'), 'weight' => 1, ); $items['examples/theming_example/theming_example_select_form'] = array( 'title' => 'Theming a form (select form)', 'page callback' => 'drupal_get_form', 'page arguments' => array('theming_example_select_form'), 'access arguments' => array('access content'), 'weight' => 2, ); $items['examples/theming_example/theming_example_text_form'] = array( 'title' => 'Theming a form (text form)', 'page callback' => 'drupal_get_form', 'page arguments' => array('theming_example_text_form'), 'access arguments' => array('access content'), 'weight' => 3, ); return $items; } /** * Implements hook_theme(). * * Defines the theming capabilities provided by this module. */ function theming_example_theme($existing, $type, $theme, $path) { return array( 'theming_example_content_array' => array( // We use 'render element' when the item to be passed is a self-describing // render array (it will have #theme_wrappers) 'render element' => 'element', ), 'theming_example_list' => array( // We use 'variables' when the item to be passed is an array whose // structure must be described here. 'variables' => array( 'title' => NULL, 'items' => NULL, ), ), 'theming_example_select_form' => array( 'render element' => 'form', ), 'theming_example_text_form' => array( 'render element' => 'form', // In this one the rendering will be done by a template file // (theming-example-text-form.tpl.php) instead of being rendered by a // function. Note the use of dashes to separate words in place of // underscores. The template file's extension is also left out so that // it may be determined automatically depending on the template engine // the site is using. 'template' => 'theming-example-text-form', ), ); } /** * Initial landing page explaining the use of the module. * * We create a render array and specify the theme to be used through the use * of #theme_wrappers. With all output, we aim to leave the content as a * render array just as long as possible, so that other modules (or the theme) * can alter it. * * @see render_example.module * @see form_example_elements.inc */ function theming_example_page() { $content[]['#markup'] = t('Some examples of pages and forms that are run through theme functions.'); $content[]['#markup'] = l(t('Simple page with a list'), 'examples/theming_example/theming_example_list_page'); $content[]['#markup'] = l(t('Simple form 1'), 'examples/theming_example/theming_example_select_form'); $content[]['#markup'] = l(t('Simple form 2'), 'examples/theming_example/theming_example_text_form'); $content['#theme_wrappers'] = array('theming_example_content_array'); return $content; } /** * The list page callback. * * An example page where the output is supplied as an array which is themed * into a list and styled with css. * * In this case we'll use the core-provided theme_item_list as a #theme_wrapper. * Any theme need only override theme_item_list to change the behavior. */ function theming_example_list_page() { $items = array( t('First item'), t('Second item'), t('Third item'), t('Fourth item'), ); // First we'll create a render array that simply uses theme_item_list. $title = t("A list returned to be rendered using theme('item_list')"); $build['render_version'] = array( // We use #theme here instead of #theme_wrappers because theme_item_list() // is the classic type of theme function that does not just assume a // render array, but instead has its own properties (#type, #title, #items). '#theme' => 'item_list', // '#type' => 'ul', // The default type is 'ul' // We can easily make sure that a css or js file is present using #attached. '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), '#title' => $title, '#items' => $items, '#attributes' => array('class' => array('render-version-list')), ); // Now we'll create a render array which uses our own list formatter, // theme('theming_example_list'). $title = t("The same list rendered by theme('theming_example_list')"); $build['our_theme_function'] = array( '#theme' => 'theming_example_list', '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), '#title' => $title, '#items' => $items, ); return $build; } /** * A simple form that displays a select box and submit button. * * This form will be be themed by the 'theming_example_select_form' theme * handler. */ function theming_example_select_form($form, &$form_state) { $options = array( 'newest_first' => t('Newest first'), 'newest_last' => t('Newest last'), 'edited_first' => t('Edited first'), 'edited_last' => t('Edited last'), 'by_name' => t('By name'), ); $form['choice'] = array( '#type' => 'select', '#options' => $options, '#title' => t('Choose which ordering you want'), ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Go'), ); return $form; } /** * Submit handler for the select form. * * @param array $form * Form API form array. * @param array $form_state * Form API form state array. */ function theming_example_select_form_submit($form, &$form_state) { drupal_set_message(t('You chose %input', array('%input' => $form_state['values']['choice']))); } /** * A simple form that displays a textfield and submit button. * * This form will be rendered by theme('form') (theme_form() by default) * because we do not provide a theme function for it here. */ function theming_example_text_form($form, &$form_state) { $form['text'] = array( '#type' => 'textfield', '#title' => t('Please input something!'), '#required' => TRUE, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Go'), ); return $form; } /** * Submit handler for the text form. * * @param array $form * Form API form array. * @param array $form_state * Form API form state array. */ function theming_example_text_form_submit($form, &$form_state) { drupal_set_message(t('You entered %input', array('%input' => $form_state['values']['text']))); } /** * Theme a simple content array. * * This theme function uses the newer recommended format where a single * render array is provided to the theme function. */ function theme_theming_example_content_array($variables) { $element = $variables['element']; $output = ''; foreach (element_children($element) as $count) { if (!$count) { // The first paragraph is bolded. $output .= '

' . $element[$count]['#children'] . '

'; } else { // Following paragraphs are just output as routine paragraphs. $output .= '

' . $element[$count]['#children'] . '

'; } } return $output; } /** * Theming a simple list. * * This is just a simple wrapper around theme('item_list') but it's worth * showing how a custom theme function can be implemented. * * @see theme_item_list() */ function theme_theming_example_list($variables) { $title = $variables['title']; $items = $variables['items']; // Add the title to the list theme and // state the list type. This defaults to 'ul'. // Add a css class so that you can modify the list styling. // We'll just call theme('item_list') to render. $variables = array( 'items' => $items, 'title' => $title, 'type' => 'ol', 'attributes' => array('class' => 'theming-example-list'), ); $output = theme('item_list', $variables); return $output; } /** * Theming a simple form. * * Since our form is named theming_example_select_form(), the default * #theme function applied to is will be 'theming_example_select_form' * if it exists. The form could also have specified a different * #theme. * * Here we collect the title, theme it manually and * empty the form title. We also wrap the form in a div. */ function theme_theming_example_select_form($variables) { $form = $variables['form']; $title = $form['choice']['#title']; $form['choice']['#title'] = ''; $output = '' . $title . ''; $form['choice']['#prefix'] = '
'; $form['submit']['#suffix'] = '
'; $output .= drupal_render_children($form); return $output; } /** * Implements template_preprocess(). * * We prepare variables for use inside the theming-example-text-form.tpl.php * template file. * * In this example, we create a couple new variables, 'text_form' and * 'text_form_content', that clean up the form output. Drupal will turn the * array keys in the $variables array into variables for use in the template. * * So $variables['text_form'] becomes available as $text_form in the template. * * @see theming-example-text-form.tpl.php */ function template_preprocess_theming_example_text_form(&$variables) { $variables['text_form_content'] = array(); $text_form_hidden = array(); // Each form element is rendered and saved as a key in $text_form_content, to // give the themer the power to print each element independently in the // template file. Hidden form elements have no value in the theme, so they // are grouped into a single element. foreach (element_children($variables['form']) as $key) { $type = $variables['form'][$key]['#type']; if ($type == 'hidden' || $type == 'token') { $text_form_hidden[] = drupal_render($variables['form'][$key]); } else { $variables['text_form_content'][$key] = drupal_render($variables['form'][$key]); } } $variables['text_form_content']['hidden'] = implode($text_form_hidden); // The entire form is then saved in the $text_form variable, to make it easy // for the themer to print the whole form. $variables['text_form'] = implode($variables['text_form_content']); } /** * @} End of "defgroup theming_example". */