'Style guide', 'page callback' => 'styleguide_page', 'weight' => 40, 'access arguments' => array('view style guides'), 'theme callback' => '_styleguide_page_theme', 'theme arguments' => array($default), ); foreach (list_themes() as $theme) { $is_default = $theme->name == $default; $items['admin/appearance/styleguide/' . $theme->name] = array( 'title' => $theme->info['name'], 'page callback' => 'styleguide_page', 'page arguments' => array($theme->name), 'type' => $is_default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, 'access callback' => 'styleguide_access_check', 'access arguments' => array($theme), 'weight' => $is_default ? -10 : 0, 'theme callback' => '_styleguide_page_theme', 'theme arguments' => array($theme->name), ); } return $items; } /** * Theme callback for the styleguide pages. */ function _styleguide_page_theme($theme) { return $theme; } /** * Implements hook_theme(). */ function styleguide_theme($existing, $type, $theme, $path) { $themes = array( 'styleguide_header' => array( 'variables' => array('theme_info' => array()), ), 'styleguide_links' => array( 'variables' => array('items' => array()), ), 'styleguide_item' => array( 'variables' => array('key' => NULL, 'item' => array(), 'content' => NULL), ), 'styleguide_content' => array( 'variables' => array('content' => NULL), ), ); foreach ($themes as $theme => $data) { $themes[$theme]['file'] = 'styleguide.theme.inc'; } return $themes; } /** * Implements hook_permission(). */ function styleguide_permission() { $permissions = array( 'view style guides' => array( 'title' => t('View theme style guides'), ) ); return $permissions; } /** * Menu access callback. */ function styleguide_access_check($theme) { if (!user_access('view style guides')) { return FALSE; } if (drupal_theme_access($theme)) { return TRUE; } return FALSE; } /** * The styleguide page. */ function styleguide_page($theme = NULL) { drupal_add_css(drupal_get_path('module', 'styleguide') . '/styleguide.css'); // TODO: notice about the Overlay module? // Check the theme. if (is_null($theme)) { $theme = variable_get('theme_default', 'bartik'); } // Get theme data. $themes = list_themes(); $active = $themes[$theme]; // Get visual testing elements. $items = module_invoke_all('styleguide'); drupal_alter('styleguide', $items); // Get theme style information. $theme_info = $active->info; drupal_alter('styleguide_theme_info', $theme_info, $theme); $groups = array(); foreach ($items as $key => $item) { if (!isset($item['group'])) { $item['group'] = t('Common'); } else { $item['group'] = t('@group', array('@group' => $item['group'])); } $item['title'] = t('@title', array('@title' => $item['title'])); $groups[$item['group']][$key] = $item; } ksort($groups); // Create a navigation header. $header = array(); $head = ''; $content = ''; // Process the elements, by group. foreach ($groups as $group => $elements) { foreach ($elements as $key => $item) { $display = ''; // Output a standard theme item. if (isset($item['theme'])) { $display = theme($item['theme'], $item['variables']); } // Output a standard HTML tag. In Drupal 7, the preference // is to pass theme('html_tag') instead. This is kept for API // compatibility with Drupal 6. elseif (isset($item['tag']) && isset($item['content'])) { if (empty($item['attributes'])) { $display = '<' . $item['tag'] . '>' . $item['content'] . ''; } else { $display = '<' . $item['tag'] . ' ' . drupal_attributes($item['attributes']) . '>' . $item['content'] . ''; } } // Support a renderable array for content. elseif (isset($item['content']) && is_array($item['content'])) { $display = drupal_render($item['content']); } // Just print the provided content. elseif (isset($item['content'])) { $display = $item['content']; } // Add the content. $content .= theme('styleguide_item', array('key' => $key, 'item' => $item, 'content' => $display)); // Prepare the header link. $header[$group][] = l($item['title'], $_GET['q'], array('fragment' => $key)); } $head .= theme('item_list', array('items' => $header[$group], 'title' => $group)); } $output = theme('styleguide_header', array('theme_info' => $theme_info)); $output .= theme('styleguide_links', array('items' => $head)); $output .= theme('styleguide_content', array('content' => $content)); // Return the page. return $output; } /** * Implements hook_hook_info(). */ function styleguide_hook_info() { $hooks['styleguide'] = array( 'group' => 'styleguide', ); return $hooks; } /** * Return a simple array of words. * * @param $size * The size of the list to return. * @return * An array of words. */ function styleguide_list($size = 5) { $items = array(); for ($i = 0; $i < $size; $i++) { $items[] = styleguide_word(); } return $items; } /** * Return a random word. */ function styleguide_word($size = 1) { return styleguide_lorem(1, $size, 'lower', FALSE, FALSE); } /** * Return a random table header array. * * @param $size * The size of the list to return. * @return * An array of header elements. */ function styleguide_header($size = 5) { $header = styleguide_list($size); return $header; } /** * Return a random table row array. * * @param $size * The size of the list to return. * @return * An array of row elements. */ function styleguide_rows($size = 5) { $rows = array(); for ($i = 0; $i < $size; $i++) { $rows[] = styleguide_list($size); } return $rows; } /** * Lorum ipsum text, used to generate words and phrases. * * @param $size * The size of the list to return. * @param $words * The number of words to return. Pass 0 for a whole paragraph. * @param $case * The case of the text. Options are 'mixed', 'upper' and 'lower'. * @param $returns * Indicates whether line returns should not be stripped out of the result. * @param $punctuation * Indicates whether punctuation should not be stripped out of the result. * @param $array * Indicates that the return value should be an array instead of a string. * @return * A string or array of content. */ function styleguide_lorem($size = 5, $words = 0, $case = 'mixed', $returns = TRUE, $punctuation = TRUE, $array = FALSE) { $text = << 0) { $elements = explode(' ', implode(' ', $text)); $output = array(); for ($i = 0; $i < $words; $i++) { $val = array_rand($elements); $output[] = $elements[$val]; } return implode(' ', $output); } if (!$array) { return implode($spacer, $text); } return $text; } /** * Generate paragraph(s) of random text. * * @param $size * The number of paragraphs to return. * @return * HTML paragraphs. */ function styleguide_paragraph($size = 5) { $text = styleguide_lorem($size, 0, 'mixed', TRUE, TRUE, TRUE); $output = ''; foreach ($text as $item) { $output .= '

' . trim($item) . '

'; } return $output; } /** * Provide a default image for display. * * Images should be in the assets directory. The current images are * (c) Ken Rickard and used by permission. * * @param $image * The name of the image. Will be prefixed with 'image-'. * @param $type * The file type, (jpg, png, gif). Do not include a dot. * @return * The Drupal path to the file. */ function styleguide_image($image = 'vertical', $type = 'jpg') { $path = drupal_get_path('module', 'styleguide'); $filepath = $path . '/assets/image-' . $image . '.' . $type; if (file_exists($filepath)) { return $filepath; } } /** * Implements hook_system_theme_page_alter(). */ function styleguide_system_themes_page_alter(&$theme_groups) { if (!user_access('view style guides')) { return; } foreach ($theme_groups as $group => $members) { if (empty($group)) { continue; } foreach ($members as $key => $theme) { if (!styleguide_access_check($theme)) { continue; } $theme_groups[$group][$key]->operations[] = array( 'title' => t('Style guide'), 'href' => 'admin/appearance/styleguide/' . $theme->name, 'attributes' => array('title' => t('Style guide for @theme', array('@theme' => $theme->info['name']))), ); } } } /** * Generate a random sentence. */ function styleguide_sentence() { $graph = strip_tags(styleguide_paragraph()); $explode = explode('.', $graph); $rand = array_rand($explode); return trim($explode[$rand]) . '.'; } /** * Sample form, showing all elements. */ function styleguide_form($form, &$form_state, $form_keys = array()) { $form = array(); $options = array(); $list = styleguide_list(); foreach ($list as $item) { $options[$item] = $item; } $form['select'] = array( '#type' => 'select', '#title' => t('Select'), '#options' => $options, '#description' => styleguide_sentence(), ); $form['checkbox'] = array( '#type' => 'checkbox', '#title' => t('Checkbox'), '#value' => 1, '#default_value' => 1, '#description' => styleguide_sentence(), ); $form['checkboxes'] = array( '#type' => 'checkboxes', '#title' => t('Checkboxes'), '#options' => $options, '#description' => styleguide_sentence(), ); $form['radios'] = array( '#type' => 'radios', '#title' => t('Radios'), '#options' => $options, '#description' => styleguide_sentence(), ); $form['textfield'] = array( '#type' => 'textfield', '#title' => t('Textfield'), '#default_value' => styleguide_word(), '#description' => styleguide_sentence(), ); $form['autocomplete'] = array( '#type' => 'textfield', '#title' => t('Autocomplete textfield'), '#default_value' => styleguide_word(), '#description' => styleguide_sentence(), '#autocomplete_path' => 'user/autocomplete', ); $form['textfield-machine'] = array( '#type' => 'textfield', '#title' => t('Textfield, with machine name'), '#default_value' => styleguide_word() . ' ' . styleguide_word() . ' ' . styleguide_word(), '#description' => styleguide_sentence(), ); $form['machine_name'] = array( '#type' => 'machine_name', '#title' => t('Machine name'), '#machine_name' => array( 'source' => array('textfield-machine'), ), '#description' => styleguide_sentence(), ); $form['textarea'] = array( '#type' => 'textarea', '#title' => t('Textarea'), '#default_value' => styleguide_paragraph(), '#description' => styleguide_sentence(), ); $form['date'] = array( '#type' => 'date', '#title' => t('Date'), '#description' => styleguide_sentence(), ); $form['file'] = array( '#type' => 'file', '#title' => t('File'), '#description' => styleguide_sentence(), ); $form['managed_file'] = array( '#type' => 'managed_file', '#title' => t('Managed file'), '#description' => styleguide_sentence(), ); $form['password'] = array( '#type' => 'password', '#title' => t('Password'), '#default_value' => styleguide_word(), '#description' => styleguide_sentence(), ); $form['password_confirm'] = array( '#type' => 'password_confirm', '#title' => t('Password confirm'), ); $form['weight'] = array( '#type' => 'weight', '#title' => t('Weight'), '#delta' => 10, '#description' => styleguide_sentence(), ); $form['fieldset-collapsed'] = array( '#type' => 'fieldset', '#title' => t('Fieldset collapsed'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#description' => styleguide_sentence(), ); $form['fieldset-collapsible'] = array( '#type' => 'fieldset', '#title' => t('Fieldset collapsible'), '#collapsible' => TRUE, '#description' => styleguide_sentence(), ); $form['fieldset'] = array( '#type' => 'fieldset', '#title' => t('Fieldset'), '#collapsible' => FALSE, '#description' => styleguide_sentence(), ); $fieldsets = array('fieldset', 'fieldset-collapsed', 'fieldset-collapsible'); $count = 0; foreach ($form as $key => $value) { if ($value['#type'] != 'fieldset' && $value['#type'] != 'checkbox' && $count < 2) { $count++; foreach ($fieldsets as $item) { $form[$item][$key . '-' . $item] = $value; } } } $form['vertical_tabs'] = array( '#type' => 'vertical_tabs', ); foreach ($fieldsets as $fieldset) { $form['vertical_tabs'][$fieldset] = $form[$fieldset]; } $form['markup'] = array( '#markup' => t('

Markup: Note that markup does not allow titles or descriptions. Use "item" for those options.

') . styleguide_paragraph(1), ); $form['item'] = array( '#type' => 'item', '#title' => t('Item'), '#markup' => styleguide_paragraph(1), '#description' => styleguide_sentence(), ); $form['image_button'] = array( '#type' => 'image_button', '#src' => 'misc/druplicon.png', '#attributes' => array('height' => 20), '#name' => t('Image button'), ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); $form['button'] = array( '#type' => 'button', '#value' => t('Button'), ); if (!empty($form_keys)) { $items = array(); foreach ($form_keys as $key) { if (isset($form[$key])) { $items[$key] = $form[$key]; } } return $items; } return $form; }