diff --git includes/admin.inc includes/admin.inc index c049ff3..20653d5 100644 --- includes/admin.inc +++ includes/admin.inc @@ -4084,3 +4084,26 @@ function theme_views_ui_style_plugin_table($form) { return $output; } +/** + * Theme the form for the table style plugin + */ +function theme_views_ui_breadcrumb_plugin_custom($form) { + $output = drupal_render($form['description_markup']); + + $header = array( + t('Path'), + t('Title'), + ); + $rows = array(); + foreach (element_children($form['items']['path']) as $id) { + $row = array(); + $row[] = drupal_render($form['items']['path'][$id]); + $row[] = drupal_render($form['items']['title'][$id]); + $rows[] = $row; + } + + $output .= theme('table', $header, $rows); + $output .= drupal_render($form); + return $output; +} + diff --git includes/plugins.inc includes/plugins.inc index f0c4238..22b3333 100644 --- includes/plugins.inc +++ includes/plugins.inc @@ -275,6 +275,26 @@ function views_views_plugins() { 'help topic' => 'cache-time', ), ), + 'breadcrumb' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_breadcrumb', + 'parent' => '', + ), + 'default' => array( + 'title' => t('Default'), + 'help' => t('Default breadcrumb system.'), + 'handler' => 'views_plugin_breadcrumb_default', + 'help topic' => 'breadcrumb-default', + ), + 'custom' => array( + 'title' => t('Custom'), + 'help' => t('Customized breadcrumb system.'), + 'handler' => 'views_plugin_breadcrumb_custom', + 'uses options' => TRUE, + 'help topic' => 'breadcrumb-default', + ), + ), 'exposed_form' => array( 'parent' => array( 'no ui' => TRUE, diff --git includes/view.inc includes/view.inc index 0756282..b3e9de9 100644 --- includes/view.inc +++ includes/view.inc @@ -72,10 +72,7 @@ class view extends views_db_object { var $style_plugin; /** - * The current - - /** - * Constructor + * The current constructor */ function __construct() { parent::init(); @@ -1212,30 +1209,13 @@ class view extends views_db_object { * If true, use drupal_set_breadcrumb() to install the breadcrumb. */ function get_breadcrumb($set = FALSE) { - // Now that we've built the view, extract the breadcrumb. - $base = TRUE; - $breadcrumb = array(); + $breadcrumb_plugin = $this->display_handler->get_plugin('breadcrumb'); - if (!empty($this->build_info['breadcrumb'])) { - foreach ($this->build_info['breadcrumb'] as $path => $title) { - // Check to see if the frontpage is in the breadcrumb trail; if it - // is, we'll remove that from the actual breadcrumb later. - if ($path == variable_get('site_frontpage', 'node')) { - $base = FALSE; - $title = t('Home'); - } - if ($title) { - $breadcrumb[] = l($title, $path, array('html' => true)); - } - } - - if ($set) { - if ($base) { - $breadcrumb = array_merge(drupal_get_breadcrumb(), $breadcrumb); - } - drupal_set_breadcrumb($breadcrumb); - } + $breadcrumb = array(); + if ($breadcrumb_plugin) { + $breadcrumb = $breadcrumb_plugin->get_breadcrumb($set); } + return $breadcrumb; } diff --git plugins/views_plugin_breadcrumb.inc plugins/views_plugin_breadcrumb.inc new file mode 100644 index 0000000..4eb2e4a --- /dev/null +++ plugins/views_plugin_breadcrumb.inc @@ -0,0 +1,31 @@ +view = &$view; + $this->display = &$display; + + $this->unpack_options($this->options, $options); + } + + /** + * Return a string to display as the clickable title for the + * access control. + */ + function summary_title() { + return t('Unknown'); + } + + function get_breadcrumb($set = FALSE) { } + +} diff --git plugins/views_plugin_breadcrumb_custom.inc plugins/views_plugin_breadcrumb_custom.inc new file mode 100644 index 0000000..c36f21a --- /dev/null +++ plugins/views_plugin_breadcrumb_custom.inc @@ -0,0 +1,150 @@ + array( + 'title' => array(), + 'path' => array(), + ) + ); + + return $options; + } + + function options_form(&$form, &$form_state) { + $custom_breadcrumb = $this->options['items']; + + // Provide at least five items to configure the breadcrumb + $max_count = max(count(array_filter($custom_breadcrumb['title'])), 3) + 2; + + for ($breadcrumb_item = 0; $breadcrumb_item < $max_count; $breadcrumb_item++) { + $form['items']['path'][$breadcrumb_item] = array( + '#type' => 'textfield', + '#default_value' => !empty($custom_breadcrumb['path'][$breadcrumb_item]) ? $custom_breadcrumb['path'][$breadcrumb_item] : '', + '#size' => 40, + ); + + $form['items']['title'][$breadcrumb_item] = array( + '#type' => 'textfield', + '#default_value' => !empty($custom_breadcrumb['title'][$breadcrumb_item]) ? $custom_breadcrumb['title'][$breadcrumb_item] : '', + ); + } + + $count = 0; + foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) { + $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name())); + $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name())); + } + + // Default text. + // We have some options, so make a list. + $output = '

' . t('The following tokens are available for this breadcrumb.') . '

'; + if (!empty($options)) { + foreach (array_keys($options) as $type) { + if (!empty($options[$type])) { + $items = array(); + foreach ($options[$type] as $key => $value) { + $items[] = $key . ' == ' . $value; + } + $output .= theme('item_list', $items, $type); + } + } + } + $global_tokens = array( + 'front' => t('You can use <front> in the path section to link the tilte to the front page.'), + ); + $output .= theme('item_list', $global_tokens, t('Global tokens')); + + $form['description_markup'] = array( + '#prefix' => '
', + '#suffix' => '
', + '#value' => t('Here you can configure the breadcrumb to display when this view page is rendered. If the path is not defined, "title" will be rendered as normal text without link.') . $output, + ); + $form['#theme'] = 'views_ui_breadcrumb_plugin_custom'; + } + + function summary_title() { + return t('Custom'); + } + + /** + * Get the breadcrumb used for this view. + * + * @param $set + * If true, use drupal_set_breadcrumb() to install the breadcrumb. + */ + function get_breadcrumb($set = FALSE) { + // Now that we've built the view, extract the breadcrumb. + $base = TRUE; + $breadcrumb = array(); + + $custom_breadcrumb = $this->options['items']; + $tokens = $this->get_arguments_tokens(); + + foreach (array_filter($custom_breadcrumb['title']) as $id => $title) { + $path = $custom_breadcrumb['path'][$id]; + + if (!empty($path)) { + if (strpos($path, '!') !== FALSE || strpos($path, '%') !== FALSE) { + $path = strtr($path, $tokens); + } + } + if (strpos($title, '!') !== FALSE || strpos($title, '%') !== FALSE) { + $title = strtr($title, $tokens); + } + + if (!empty($title)) { + if (!empty($path)) { + $breadcrumb[] = l($title, $path, array('html' => true)); + } + else { + $breadcrumb[] = check_plain($title); + } + } + } + + if ($set) { + if ($base) { + $breadcrumb = array_merge(drupal_get_breadcrumb(), $breadcrumb); + } + drupal_set_breadcrumb($breadcrumb); + } + + return $breadcrumb; + } + + /** + * Returns to tokens for arguments. + * + * This function is similar to views_handler_field::get_render_tokens() + * but without fields tokens. + */ + function get_arguments_tokens() { + $tokens = array(); + if (!empty($this->view->build_info['substitutions'])) { + $tokens = $this->view->build_info['substitutions']; + } + $count = 0; + foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) { + $token = '%' . ++$count; + if (!isset($tokens[$token])) { + $tokens[$token] = ''; + } + + // Use strip tags as there should never be HTML in the path. + // However, we need to preserve special characters like " that + // were removed by check_plain(). + $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(html_entity_decode($this->view->args[$count - 1])) : ''; + } + + return $tokens; + } + +} diff --git plugins/views_plugin_breadcrumb_default.inc plugins/views_plugin_breadcrumb_default.inc new file mode 100644 index 0000000..1feec75 --- /dev/null +++ plugins/views_plugin_breadcrumb_default.inc @@ -0,0 +1,47 @@ +view->build_info['breadcrumb'])) { + foreach ($this->view->build_info['breadcrumb'] as $path => $title) { + // Check to see if the frontpage is in the breadcrumb trail; if it + // is, we'll remove that from the actual breadcrumb later. + if ($path == variable_get('site_frontpage', 'node')) { + $base = FALSE; + $title = t('Home'); + } + if ($title) { + $breadcrumb[] = l($title, $path, array('html' => true)); + } + } + + if ($set) { + if ($base) { + $breadcrumb = array_merge(drupal_get_breadcrumb(), $breadcrumb); + } + drupal_set_breadcrumb($breadcrumb); + } + } + return $breadcrumb; + } +} diff --git plugins/views_plugin_display_page.inc plugins/views_plugin_display_page.inc index dccd2fa..ca26dfa 100644 --- plugins/views_plugin_display_page.inc +++ plugins/views_plugin_display_page.inc @@ -41,7 +41,12 @@ class views_plugin_display_page extends views_plugin_display { 'name' => array('default' => 'navigation'), ), ); - + $options['breadcrumb'] = array( + 'contains' => array( + 'type' => array('default' => 'full', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + 'options' => array('default' => array(), 'export' => FALSE), + ), + ); return $options; } @@ -279,6 +284,24 @@ class views_plugin_display_page extends views_plugin_display { if ($menu['type'] == 'default tab') { $options['menu']['links']['tab_options'] = t('Change settings for the parent menu'); } + + $breadcrumb_plugin = $this->get_plugin('breadcrumb'); + if (!$breadcrumb_plugin) { + // use default breadcrumb plugin. + $breadcrumb_plugin = views_get_plugin('breadcrumb', 'default'); + } + + $breadcrumb_str = $breadcrumb_plugin->summary_title(); + + $options['breadcrumb'] = array( + 'category' => 'page', + 'title' => t('Breadcrumb'), + 'value' => $breadcrumb_str, + ); + + if (!empty($breadcrumb_plugin->definition['uses options'])) { + $options['breadcrumb']['links']['breadcrumb_options'] = t('Change settings for breadcrumb'); + } } /** @@ -459,6 +482,48 @@ class views_plugin_display_page extends views_plugin_display { '#dependency' => array('radio:tab_options[type]' => array('tab')), ); break; + case 'breadcrumb': + $form['#title'] .= t('Breadcrumb'); + $form['breadcrumb'] = array( + '#prefix' => '
', + '#suffix' => '
', + '#tree' => TRUE, + ); + + $breadcrumb = $this->get_option('breadcrumb'); + $form['breadcrumb']['type'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('breadcrumb'), + '#default_value' => $breadcrumb['type'], + ); + + $breadcrumb_plugin = views_fetch_plugin_data('breadcrumb', $breadcrumb['type']); + if (!empty($breadcrumb_plugin['uses options'])) { + $form['markup'] = array( + '#prefix' => '
', + '#suffix' => '
', + '#value' => t('You may also adjust the !settings for the currently selected breadcrumb mechanism by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'breadcrumb_options'))), + ); + } + break; + case 'breadcrumb_options': + $breadcrumb = $this->get_option('breadcrumb'); + $plugin = $this->get_plugin('breadcrumb'); + $form['#title'] .= t('Breadcrumb options'); + if ($plugin) { + $form['#help_topic'] = $plugin->definition['help topic']; + $form['#help_module'] = $plugin->definition['module']; + + $form['breadcrumb_options'] = array( + '#tree' => TRUE, + ); + $form['breadcrumb_options']['type'] = array( + '#type' => 'value', + '#value' => $breadcrumb['type'], + ); + $plugin->options_form($form['breadcrumb_options'], $form_state); + } + break; } } @@ -517,6 +582,29 @@ class views_plugin_display_page extends views_plugin_display { case 'tab_options': $this->set_option('tab_options', $form_state['values']['tab_options']); break; + case 'breadcrumb': + $breadcrumb = $this->get_option('breadcrumb'); + if ($breadcrumb['type'] != $form_state['values']['breadcrumb']['type']) { + $plugin = views_get_plugin('breadcrumb', $form_state['values']['breadcrumb']['type']); + if ($plugin) { + $breadcrumb = array('type' => $form_state['values']['breadcrumb']['type']); + $this->set_option('breadcrumb', $breadcrumb); + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('breadcrumb_options')); + } + } + } + + break; + case 'breadcrumb_options': + $plugin = $this->get_plugin('breadcrumb'); + if ($plugin) { + $breadcrumb = $this->get_option('breadcrumb'); + $plugin->options_submit($form['breadcrumb_options'], $form_state); + $breadcrumb['options'] = $form_state['values'][$form_state['section']]; + $this->set_option('breadcrumb', $breadcrumb); + } + break; } } diff --git views_ui.module views_ui.module index 5863a21..bbdc539 100644 --- views_ui.module +++ views_ui.module @@ -240,6 +240,10 @@ function views_ui_theme() { 'arguments' => array('form' => NULL), 'file' => 'includes/admin.inc', ), + 'views_ui_breadcrumb_plugin_custom' => array( + 'arguments' => array('form' => NULL), + 'file' => 'includes/admin.inc', + ), ); }