'admin/build/views/wizard', 'access' => user_access('administer views'), 'title' => t('Theme wizard'), 'callback' => 'views_theme_wizard_page', 'type' => MENU_LOCAL_TASK, ); } return $items; } function views_theme_wizard_page() { views_load_cache(); $result = db_query("SELECT name, description FROM {view_view}"); $views = array(); while ($view = db_fetch_object($result)) { $views[$view->name] = $view->name . ': ' . $view->description; } $default_views = _views_get_default_views(); $views_status = variable_get('views_defaults', array()); foreach ($default_views as $view) { if (!$views[$view->name] && ($views_status[$view->name] == 'enabled' || (!$views_status[$view->name] && !$view->disabled))) { $views[$view->name] = check_plain($view->name . ': ' . $view->description); } } return drupal_get_form('views_theme_wizard_form', $views); } function views_theme_wizard_form($views, $form_values = array()) { $form = array(); if (!isset($form_values['step'])) { $step = 1; } else { $step = $form_values['step']; } $form['markup'] = array( '#value' => t('

The views theming wizard generates code that you can use in your phptemplate theme to help you customize the output of a view. Simply select a theme and it will generate code for your template.php as well as template files for the individual views.

At this time this code assumes your view is a list type view! It may not generate effective code for other types of views. Future versions of this program will be smarter, and give more options, but this wizard is still a huge start.

'), '#weight' => 0, ); $op = isset($form_values['op']) ? $form_values['op'] : ''; while ($step != 0) { if (1 == $step) { $form['step'] = array( '#type' => 'hidden', '#value' => $step, ); $form['vid'] = array( '#type' => 'select', '#options' => $views, '#title' => t('Select a view'), '#weight' => 5, ); $form['theme_type'] = array( '#type' => 'select', '#title' => t('Select Theme Type'), '#options' => views_theme_wizard_get_theme_types(), '#weight' => 6, ); $form['submit'] = array( '#type' => 'button', '#value' => t('Select Theme Type'), '#weight' => 10, ); $form['submit2'] = array( '#type' => 'button', '#value' => t('List Theme Fields'), '#weight' => 11, ); $form['step'] = array( '#type' => 'hidden', '#value' => $step + 1, ); $step = 0; } elseif (2 == $step && $op == t('List Theme Fields')) { $view = views_get_view($form_values['vid']); $form['code1']['#type'] = 'textarea'; $form['code1']['#value'] = views_theme_wizard_list_fields($view); $form['code1']['#title'] = t('This is a list of all the theme functions you can use to override individual field displays'); $form['code1']['#rows'] = 20; $form['code2']['#type'] = 'textarea'; $form['code2']['#value'] = views_theme_wizard_example_field($view); $form['code2']['#title'] = t('This is a basic theme function', array('@s' => $view->name)); $form['code2']['#rows'] = 20; $step = 0; } elseif (2 == $step && $op = t('Select Theme Type')) { $view = views_get_view($form_values['vid']); $type = $form_values['theme_type']; $additions = module_invoke_all('views_theme_wizard_types', 'configure', $type, $view); if (! $additions) { $step = 3; continue; } $form['theme_type'] = array( '#type' => 'hidden', '#value' => $type, ); $form['vid'] = array( '#type' => 'hidden', '#value' => $form_values['vid'], ); foreach ($additions as $k => $v) { $form[$k] = $v; } $form['generate'] = array( '#type' => 'button', '#value' => t('Generate Theme'), '#weight' => 10, ); $form['step'] = array( '#type' => 'hidden', '#value' => $step + 1, ); $step = 0; } elseif (3 == $step) { $view = views_get_view($form_values['vid']); $form['code1']['#type'] = 'textarea'; $form['code1']['#value'] = views_theme_wizard_generate_list_code($form_values['theme_type'], $view, $form_values); $form['code1']['#title'] = t('This code goes in your template.php file'); $form['code1']['#rows'] = 20; $form['code2']['#type'] = 'textarea'; $form['code2']['#value'] = views_theme_wizard_generate_list_template_code($view); $form['code2']['#title'] = t('This code goes in a file named views-list-@s.tpl.php', array('@s' => $view->name)); $form['code2']['#rows'] = 20; $form['code3']['#type'] = 'textarea'; $form['code3']['#value'] = views_theme_wizard_generate_list_stylesheet_code($view); $form['code3']['#title'] = t('This code goes in a file named views-list-@s.css', array('@s' => $view->name)); $form['code3']['#rows'] = 20; $step = 0; } } $form['#multistep'] = TRUE; $form['#redirect'] = FALSE; return $form; } function views_theme_wizard_get_theme_types() { $types = module_invoke_all('views_theme_wizard_types', 'list'); ksort($types); return $types; } function views_theme_wizard_views_theme_wizard_types($op='list', $delta='', $view=NULL, $options = array()) { switch($op) { case 'list': if ('list' == $op) { return array( 'simple' => t('Simple List'), 'grouped' => t('Grouped List'), 'tree' => t('Nested Tree'), ); } case 'configure': switch ($delta) { case 'simple': break; case 'grouped': $options = array(); foreach ($view->field as $field) { $options[$field['queryname']] = $field['label'] ? $field['label'] : $field['queryname']; } $form['group_field'] = array( '#type' => 'select', '#title' => t('Select the field on which to group'), '#options' => $options, ); $form['test'] = array('#type'=>'markup'); return $form; break; case 'tree': $options = array(); foreach ($view->field as $field) { $options[$field['queryname']] = $field['label'] ? $field['label'] : $field['queryname']; } $form['tree_key_field'] = array( '#type' => 'select', '#title' => t('Select the field to use as the ID for each row (usually nid)'), '#options' => $options, ); $form['tree_reference_field'] = array( '#type' => 'select', '#title' => t('Select the field that refers to the parent node by the ID field'), '#options' => $options, ); return $form; break; } break; case 'code': switch ($delta) { case 'simple': return views_theme_wizard_type_generate_code_simple($view); break; case 'grouped': return views_theme_wizard_type_generate_code_grouped($view, $options); break; case 'tree': return views_theme_wizard_type_generate_code_tree($view, $options); break; } break; } } function views_theme_wizard_list_fields($view) { $fields = _views_get_fields(); $output = "These functions will override the given fields for just this view:\n\n"; foreach ($view->field as $field) { $fieldinfo = $fields[$field['id']]; $output .= "$fieldinfo[name]\n phptemplate_views_handle_field_{$view->name}_$field[queryname]\n\n"; } $output .= "\n\nThese functions will override the given fields for every view:\n\n"; foreach ($view->field as $field) { $fieldinfo = $fields[$field['id']]; $output .= "$fieldinfo[name]\n phptemplate_views_handle_field_$field[queryname]\n\n"; } return $output; } function views_theme_wizard_example_field($view) { $fieldname = 'phptemplate_views_handle_field_' . $view->name . '_' . $view->field[0]['queryname']; $output = <<\$field['queryname'], \$data); } if (\$info['handler'] && is_string(\$info['handler']) && function_exists(\$info['handler'])) { return \$info['handler'](\$info, \$field, \$data->\$field['queryname'], \$data); } return check_plain(\$data->\$field['queryname']); } EOT; return $output; } function views_theme_wizard_generate_list_code($theme_type, $view, $options) { $now = format_date(time()); $header = <<name * * This function goes in your template.php file */ EOT; $function = module_invoke_all('views_theme_wizard_types', 'code', $theme_type, $view, $options); return $header . implode($function); } function views_theme_wizard_type_generate_code_simple($view) { $code = <<name}(\$view, \$nodes, \$type) { \$fields = _views_get_fields(); \$taken = array(); // Set up the fields in nicely named chunks. foreach (\$view->field as \$id => \$field) { \$field_name = \$field['field']; if (isset(\$taken[\$field_name])) { \$field_name = \$field['queryname']; } \$taken[\$field_name] = true; \$field_names[\$id] = \$field_name; } // Set up some variables that won't change. \$base_vars = array( 'view' => \$view, 'view_type' => \$type, ); foreach (\$nodes as \$i => \$node) { \$vars = \$base_vars; \$vars['node'] = \$node; \$vars['count'] = \$i; \$vars['stripe'] = \$i % 2 ? 'even' : 'odd'; foreach (\$view->field as \$id => \$field) { \$name = \$field_names[\$id]; \$vars[\$name] = views_theme_field('views_handle_field', \$field['queryname'], \$fields, \$field, \$node, \$view); if (isset(\$field['label'])) { \$vars[\$name . '_label'] = \$field['label']; } } \$items[] = _phptemplate_callback('views-list-{$view->name}', \$vars); } if (\$items) { return theme('item_list', \$items); } } EOT; return $code; } function views_theme_wizard_type_generate_code_grouped($view, $options) { $group_field = $options['group_field']; $code = <<name}(\$view, \$nodes, \$type) { \$fields = _views_get_fields(); \$taken = array(); // Group our nodes \$set = array(); foreach (\$nodes as \$node) { \$set[\$node->{$group_field}][] = \$node; } // Set up the fields in nicely named chunks. foreach (\$view->field as \$id => \$field) { \$field_name = \$field['field']; if (isset(\$taken[\$field_name])) { \$field_name = \$field['queryname']; } \$taken[\$field_name] = true; \$field_names[\$id] = \$field_name; } // Set up some variables that won't change. \$base_vars = array( 'view' => \$view, 'view_type' => \$type, ); \$output = ''; foreach (\$set as \$label => \$nodes) { \$items = array(); foreach (\$nodes as \$i => \$node) { \$vars = \$base_vars; \$vars['node'] = \$node; \$vars['count'] = \$i; \$vars['stripe'] = \$i % 2 ? 'even' : 'odd'; foreach (\$view->field as \$id => \$field) { \$name = \$field_names[\$id]; \$vars[\$name] = views_theme_field('views_handle_field', \$field['queryname'], \$fields, \$field, \$node, \$view); if (isset(\$field['label'])) { \$vars[\$name . '_label'] = \$field['label']; } } \$items[] = _phptemplate_callback('views-list-{$view->name}', \$vars); } if (\$items) { \$output .= theme('item_list', \$items, \$label); } } return \$output; } EOT; return $code; } function views_theme_wizard_type_generate_code_tree($view, $options) { $tree_key_field = $options['tree_key_field']; $tree_reference_field = $options['tree_reference_field']; $code = <<name}(\$view, \$nodes, \$type, \$parent=NULL) { \$fields = _views_get_fields(); \$taken = array(); // Normalize the top level of nodes to all point to 0 as their parent // We only have to do this on the top-level pass, because otherwise it's // irrelevant. if (!isset(\$parent)) { \$parents = array(); foreach (\$nodes as \$node) { \$parents[] = \$node->{$tree_key_field}; } foreach (\$nodes as \$node) { if (! in_array(\$node->{$tree_reference_field}, \$parents)) { \$node->{$tree_reference_field} = 0; } } } // Set up the fields in nicely named chunks. foreach (\$view->field as \$id => \$field) { \$field_name = \$field['field']; if (isset(\$taken[\$field_name])) { \$field_name = \$field['queryname']; } \$taken[\$field_name] = true; \$field_names[\$id] = \$field_name; } // Set up some variables that won't change. \$base_vars = array( 'view' => \$view, 'view_type' => \$type, ); static \$count = 1; static \$stripe = 1; foreach (\$nodes as \$i => \$node) { if (\$node->{$tree_reference_field} != \$parent) { continue; } \$vars = \$base_vars; \$vars['node'] = \$node; \$vars['count'] = \$count++; \$vars['stripe'] = \$stripe++ % 2 ? 'even' : 'odd'; foreach (\$view->field as \$id => \$field) { \$name = \$field_names[\$id]; \$vars[\$name] = views_theme_field('views_handle_field', \$field['queryname'], \$fields, \$field, \$node, \$view); if (isset(\$field['label'])) { \$vars[\$name . '_label'] = \$field['label']; } } \$item = _phptemplate_callback('views-list-{$view->name}', \$vars); \$item .= call_user_func(__FUNCTION__, \$view, \$nodes, \$type, \$node->{$tree_key_field}); \$items[] = \$item; } if (\$items) { return theme('item_list', \$items); } else { return ''; } } EOT; return $code; } /** * generate a template file for a list theme */ function views_theme_wizard_generate_list_template_code($view) { $now = format_date(time()); $header = <<name * * Variables available: * \$view -- the entire view object. Important parts of this object are * $view->name, $view->real_url. * \$view_type -- The type of the view. Probably 'page' or 'block' but could * also be 'embed' or other string passed in from a custom view creator. * \$node -- the raw data. This is not a real node object, but will contain * the nid as well as other support fields that might be necessary. * \$count -- the current row in the view (not TOTAL but for this page) starting * from 0. * \$stripe -- 'odd' or 'even', alternating. EOT; $fields = _views_get_fields(); $taken = array(); // Set up the fields in nicely named chunks. foreach ($view->field as $id => $field) { $field_name = $field['field']; $css_field_name = views_css_safe($field['field']); if (isset($taken[$field_name])) { $field_name = $field['queryname']; $css_field_name = views_css_safe($field['queryname']); } $taken[$field_name] = true; $output .= <<
\n EOT; $fid = $view->field[$id]['id']; $header .= ' * $' . $field_name . ' -- ' . $fields[$fid]['help'] . "\n"; $header .= ' * $' . $field_name . '_label -- The assigned label for $' . $field_name . "\n"; } $header .= <<name}.tpl.php file */ //now we add the stylesheet... drupal_add_css(path_to_theme() .'/views-list-{$view->name}.css'); ?> EOT; return $header .$output; } /** * generate a stylesheet file for a list theme */ function views_theme_wizard_generate_list_stylesheet_code($view) { $now = format_date(time()); $header = <<name * * The class selectors are filled with a single comment line. * You should complete each selector according to your liking. */ \n EOT; $fields = _views_get_fields(); $taken = array(); $output .= <<field as $id => $field) { $field_name = views_css_safe($field['field']); if (isset($taken[$field_name])) { $field_name = views_css_safe($field['queryname']); } $taken[$field_name] = true; $output .= <<