Breadcrumb NavXT - Version 4.0.0-Beta1

Version Description

Download this release

Release Info

Developer mtekk
Plugin Icon 128x128 Breadcrumb NavXT
Version 4.0.0-Beta1
Comparing to
See all releases

Code changes from version 3.9.0 to 4.0.0-Beta1

breadcrumb_navxt_admin.php CHANGED
@@ -3,9 +3,13 @@
3
  Plugin Name: Breadcrumb NavXT
4
  Plugin URI: http://mtekk.us/code/breadcrumb-navxt/
5
  Description: Adds a breadcrumb navigation showing the visitor&#39;s path to their current location. For details on how to use this plugin visit <a href="http://mtekk.us/code/breadcrumb-navxt/">Breadcrumb NavXT</a>.
6
- Version: 3.9.0
7
  Author: John Havlik
8
  Author URI: http://mtekk.us/
 
 
 
 
9
  */
10
  /* Copyright 2007-2011 John Havlik (email : mtekkmonkey@gmail.com)
11
 
@@ -43,34 +47,24 @@ require_once(dirname(__FILE__) . '/breadcrumb_navxt_class.php');
43
  //Include the WP 2.8+ widget class
44
  require_once(dirname(__FILE__) . '/breadcrumb_navxt_widget.php');
45
  //Include admin base class
46
- if(!class_exists('mtekk_admin'))
47
  {
48
- require_once(dirname(__FILE__) . '/mtekk_admin_class.php');
49
  }
50
  /**
51
  * The administrative interface class
52
  *
53
  */
54
- class bcn_admin extends mtekk_admin
55
  {
56
- /**
57
- * local store for breadcrumb version
58
- *
59
- * @var string
60
- */
61
- protected $version = '3.9.0';
62
  protected $full_name = 'Breadcrumb NavXT Settings';
63
  protected $short_name = 'Breadcrumb NavXT';
64
  protected $access_level = 'manage_options';
65
  protected $identifier = 'breadcrumb_navxt';
66
  protected $unique_prefix = 'bcn';
67
  protected $plugin_basename = 'breadcrumb-navxt/breadcrumb_navxt_admin.php';
68
- /**
69
- * local store for the breadcrumb object
70
- *
71
- * @see bcn_admin()
72
- * @var bcn_breadcrumb
73
- */
74
  public $breadcrumb_trail;
75
  /**
76
  * Administrative interface class default constructor
@@ -79,6 +73,9 @@ class bcn_admin extends mtekk_admin
79
  {
80
  //We'll let it fail fataly if the class isn't there as we depend on it
81
  $this->breadcrumb_trail = new bcn_breadcrumb_trail;
 
 
 
82
  //Grab defaults from the breadcrumb_trail object
83
  $this->opt = $this->breadcrumb_trail->opt;
84
  //We set the plugin basename here, could manually set it, but this is for demonstration purposes
@@ -99,11 +96,7 @@ class bcn_admin extends mtekk_admin
99
  function init()
100
  {
101
  //We're going to make sure we run the parent's version of this function as well
102
- parent::init();
103
- //Grab the current settings from the DB
104
- $this->opt = $this->get_option('bcn_options');
105
- //Add javascript enqeueing callback
106
- add_action('wp_print_scripts', array($this, 'javascript'));
107
  }
108
  /**
109
  * Makes sure the current user can manage options to proceed
@@ -116,49 +109,6 @@ class bcn_admin extends mtekk_admin
116
  wp_die(__('Insufficient privileges to proceed.', 'breadcrumb_navxt'));
117
  }
118
  }
119
- /**
120
- * This sets up and upgrades the database settings, runs on every activation
121
- */
122
- function install()
123
- {
124
- //Call our little security function
125
- $this->security();
126
- //Try retrieving the options from the database
127
- $opts = $this->get_option('bcn_options');
128
- //If there are no settings, copy over the default settings
129
- if(!is_array($opts))
130
- {
131
- //Grab defaults from the breadcrumb_trail object
132
- $opts = $this->breadcrumb_trail->opt;
133
- //Add custom post types
134
- $this->find_posttypes($opts);
135
- //Add custom taxonomy types
136
- $this->find_taxonomies($opts);
137
- //Add the options
138
- $this->add_option('bcn_options', $opts);
139
- $this->add_option('bcn_options_bk', $opts, false);
140
- //Add the version, no need to autoload the db version
141
- $this->add_option('bcn_version', $this->version, false);
142
- }
143
- else
144
- {
145
- //Retrieve the database version
146
- $db_version = $this->get_option('bcn_version');
147
- if($this->version !== $db_version)
148
- {
149
- //Add custom post types
150
- $this->find_posttypes($opts);
151
- //Add custom taxonomy types
152
- $this->find_taxonomies($opts);
153
- //Run the settings update script
154
- $this->opts_upgrade($opts, $db_version);
155
- //Always have to update the version
156
- $this->update_option('bcn_version', $this->version);
157
- //Store the options
158
- $this->update_option('bcn_options', $this->opt);
159
- }
160
- }
161
- }
162
  /**
163
  * Upgrades input options array, sets to $this->opt
164
  *
@@ -171,297 +121,168 @@ class bcn_admin extends mtekk_admin
171
  //If our version is not the same as in the db, time to update
172
  if($version !== $this->version)
173
  {
174
- //Upgrading to 3.4
175
- if(version_compare($version, '3.4.0', '<'))
176
- {
177
- //Inline upgrade of the tag setting
178
- if($opts['post_taxonomy_type'] === 'tag')
179
- {
180
- $opts['post_taxonomy_type'] = 'post_tag';
181
- }
182
- //Fix our tag settings
183
- $opts['archive_post_tag_prefix'] = $this->breadcrumb_trail->opt['archive_tag_prefix'];
184
- $opts['archive_post_tag_suffix'] = $this->breadcrumb_trail->opt['archive_tag_suffix'];
185
- $opts['post_tag_prefix'] = $this->breadcrumb_trail->opt['tag_prefix'];
186
- $opts['post_tag_suffix'] = $this->breadcrumb_trail->opt['tag_suffix'];
187
- $opts['post_tag_anchor'] = $this->breadcrumb_trail->opt['tag_anchor'];
188
- }
189
- //Upgrading to 3.6
190
- if(version_compare($version, '3.6.0', '<'))
191
  {
192
- //Added post_ prefix to avoid conflicts with custom taxonomies
193
- $opts['post_page_prefix'] = $opts['page_prefix'];
194
- unset($opts['page_prefix']);
195
- $opts['post_page_suffix'] = $opts['page_suffix'];
196
- unset($opts['page_suffix']);
197
- $opts['post_page_anchor'] = $opts['page_anchor'];
198
- unset($opts['page_anchor']);
199
- $opts['post_post_prefix'] = $opts['post_prefix'];
200
- unset($opts['post_prefix']);
201
- $opts['post_post_suffix'] = $opts['post_suffix'];
202
- unset($opts['post_suffix']);
203
- $opts['post_post_anchor'] = $opts['post_anchor'];
204
- unset($opts['post_anchor']);
205
- $opts['post_post_taxonomy_display'] = $opts['post_taxonomy_display'];
206
- unset($opts['post_taxonomy_display']);
207
- $opts['post_post_taxonomy_type'] = $opts['post_taxonomy_type'];
208
- unset($opts['post_taxonomy_type']);
209
- //Update to non-autoload db version
210
- $this->delete_option('bcn_version');
211
- $this->add_option('bcn_version', $this->version, false);
212
- $this->add_option('bcn_options_bk', $opts, false);
213
  }
214
- //Upgrading to 3.7
215
- if(version_compare($version, '3.7.0', '<'))
216
  {
217
- //Add the new options for multisite
218
- //Should the mainsite be shown
219
- $opts['mainsite_display'] = true;
220
- //Title displayed when for the main site
221
- $opts['mainsite_title'] = __('Home', 'breadcrumb_navxt');
222
- //The anchor template for the main site, this is global, two keywords are available %link% and %title%
223
- $opts['mainsite_anchor'] = __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt');
224
- //The prefix for mainsite breadcrumbs, placed inside of current_item prefix
225
- $opts['mainsite_prefix'] = '';
226
- //The prefix for mainsite breadcrumbs, placed inside of current_item prefix
227
- $opts['mainsite_suffix'] = '';
228
- //Now add post_root for all of the custom types
229
- foreach($wp_post_types as $post_type)
230
  {
231
- //We only want custom post types
232
- if($post_type->name != 'post' && $post_type->name != 'page' && $post_type->name != 'attachment' && $post_type->name != 'revision' && $post_type->name != 'nav_menu_item')
233
  {
234
- //If the post type does not have blog_display setting, add it
235
- if(!array_key_exists('post_' . $post_type->name . '_root', $opts))
236
  {
237
- //Default for blog_display type dependent
238
- if($post_type->hierarchical)
239
- {
240
- //Set post_root for hierarchical types
241
- $opts['post_' . $post_type->name . '_root'] = get_option('page_on_front');
242
- }
243
- else
244
- {
245
- //Set post_root for flat types
246
- $opts['post_' . $post_type->name . '_root'] = get_option('page_for_posts');
247
- }
 
 
 
 
 
 
 
248
  }
249
  }
250
  }
251
- }
252
- //Upgrading to 3.8.1
253
- if(version_compare($version, '3.8.1', '<'))
254
- {
255
- $opts['post_page_root'] = get_option('page_on_front');
256
- $opts['post_post_root'] = get_option('page_for_posts');
 
 
 
 
 
257
  }
258
  //Save the passed in opts to the object's option array
259
  $this->opt = $opts;
260
  }
261
  }
262
  /**
263
- * Updates the database settings from the webform
 
 
 
264
  */
265
- function opts_update()
266
  {
267
- //Do some security related thigns as we are not using the normal WP settings API
268
- $this->security();
269
- //Do a nonce check, prevent malicious link/form problems
270
- check_admin_referer('bcn_options-options');
271
- //Update local options from database, going to always do a safe get
272
- $this->opt = wp_parse_args($this->get_option('bcn_options'), $this->breadcrumb_trail->opt);
273
- //If we did not get an array, might as well just quit here
274
- if(!is_array($this->opt))
275
- {
276
- return;
277
- }
278
- //Add custom post types
279
- $this->find_posttypes($this->opt);
280
- //Add custom taxonomy types
281
- $this->find_taxonomies($this->opt);
282
- //Update our backup options
283
- $this->update_option('bcn_options_bk', $this->opt);
284
- //Grab our incomming array (the data is dirty)
285
- $input = $_POST['bcn_options'];
286
- //We have two "permi" variables
287
- $input['post_page_root'] = get_option('page_on_front');
288
- $input['post_post_root'] = get_option('page_for_posts');
289
- //Loop through all of the existing options (avoids random setting injection)
290
- foreach($this->opt as $option => $value)
291
- {
292
- //Handle all of our boolean options first
293
- if(strpos($option, 'display') > 0 || $option == 'current_item_linked')
294
- {
295
- $this->opt[$option] = isset($input[$option]);
296
- }
297
- //Now handle anything that can't be blank
298
- else if(strpos($option, 'anchor') > 0)
299
- {
300
- //Only save a new anchor if not blank
301
- if(isset($input[$option]))
302
- {
303
- //Do excess slash removal sanitation
304
- $this->opt[$option] = stripslashes($input[$option]);
305
- }
306
- }
307
- //Now everything else
308
- else
309
- {
310
- $this->opt[$option] = stripslashes($input[$option]);
311
- }
312
- }
313
- //Commit the option changes
314
- $this->update_option('bcn_options', $this->opt);
315
- //Check if known settings match attempted save
316
- if(count(array_diff_key($input, $this->opt)) == 0)
317
- {
318
- //Let the user know everything went ok
319
- $this->message['updated fade'][] = __('Settings successfully saved.', $this->identifier) . $this->undo_anchor(__('Undo the options save.', $this->identifier));
320
- }
321
- else
322
  {
323
- //Let the user know the following were not saved
324
- $this->message['updated fade'][] = __('Some settings were not saved.', $this->identifier) . $this->undo_anchor(__('Undo the options save.', $this->identifier));
325
- $temp = __('The following settings were not saved:', $this->identifier);
326
- foreach(array_diff_key($input, $this->opt) as $setting => $value)
327
- {
328
- $temp .= '<br />' . $setting;
329
- }
330
- $this->message['updated fade'][] = $temp . '<br />' . sprintf(__('Please include this message in your %sbug report%s.', $this->identifier),'<a title="' . __('Go to the Breadcrumb NavXT support post for your version.', $this->identifier) . '" href="http://mtekk.us/archives/wordpress/plugins-wordpress/breadcrumb-navxt-' . $this->version . '/#respond">', '</a>');
331
- }
332
- add_action('admin_notices', array($this, 'message'));
333
- }
334
- /**
335
- * Enqueues JS dependencies (jquery) for the tabs
336
- *
337
- * @see admin_init()
338
- * @return void
339
- */
340
- function javascript()
341
  {
342
- //Enqueue ui-tabs
343
- wp_enqueue_script('jquery-ui-tabs');
344
- }
345
- /**
346
- * get help text
347
- *
348
- * @return string
349
- */
350
- protected function _get_help_text()
351
  {
352
- return '<p>' . sprintf(__('Tips for the settings are located below select options. Please refer to the %sdocumentation%s for more information.', 'breadcrumb_navxt'),
353
- '<a title="' . __('Go to the Breadcrumb NavXT online documentation', 'breadcrumb_navxt') . '" href="http://mtekk.us/code/breadcrumb-navxt/breadcrumb-navxt-doc/">', '</a>') . ' ' .
354
- sprintf(__('If you think you have found a bug, please include your WordPress version and details on how to reproduce the bug when you %sreport the issue%s.', $this->identifier),'<a title="' . __('Go to the Breadcrumb NavXT support post for your version.', 'breadcrumb_navxt') . '" href="http://mtekk.us/archives/wordpress/plugins-wordpress/breadcrumb-navxt-' . $this->version . '/#respond">', '</a>') . '</p><h5>' .
355
- __('Quick Start Information', 'breadcrumb_navxt') . '</h5><p>' . __('For the settings on this page to take effect, you must either use the included Breadcrumb NavXT widget, or place either of the code sections below into your theme.', 'breadcrumb_navxt') .
356
- '</p><h5>' . __('Breadcrumb trail with separators', 'breadcrumb_navxt').'</h5><code>&lt;div class="breadcrumbs"&gt;'."&lt;?php if(function_exists('bcn_display')){ bcn_display();}?&gt;&lt;/div&gt;</code>" .
357
- '<h5>' . __('Breadcrumb trail in list form', 'breadcrumb_navxt').'</h5><code>&lt;ol class="breadcrumbs"&gt;'."&lt;?php if(function_exists('bcn_display_list')){ bcn_display_list();}?&gt;&lt;/ol&gt;</code>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  }
359
  /**
360
- * Adds in the JavaScript and CSS for the tabs in the adminsitrative
361
- * interface
362
- *
363
  */
364
- function admin_head()
365
- {
366
- // print style and script element (should go into head element)
367
- ?>
368
- <style type="text/css">
369
- /**
370
- * Tabbed Admin Page (CSS)
371
- *
372
- * @see Breadcrumb NavXT (Wordpress Plugin)
373
- * @author Tom Klingenberg
374
- * @colordef #c6d9e9 light-blue (older tabs border color, obsolete)
375
- * @colordef #dfdfdf light-grey (tabs border color)
376
- * @colordef #f9f9f9 very-light-grey (admin standard background color)
377
- * @colordef #fff white (active tab background color)
378
- */
379
- #hasadmintabs ul.ui-tabs-nav {border-bottom:1px solid #dfdfdf; font-size:12px; height:29px; list-style-image:none; list-style-position:outside; list-style-type:none; margin:13px 0 0; overflow:visible; padding:0 0 0 8px;}
380
- #hasadmintabs ul.ui-tabs-nav li {display:block; float:left; line-height:200%; list-style-image:none; list-style-position:outside; list-style-type:none; margin:0; padding:0; position:relative; text-align:center; white-space:nowrap; width:auto;}
381
- #hasadmintabs ul.ui-tabs-nav li a {background:transparent none no-repeat scroll 0 50%; border-bottom:1px solid #dfdfdf; display:block; float:left; line-height:28px; padding:1px 13px 0; position:relative; text-decoration:none;}
382
- #hasadmintabs ul.ui-tabs-nav li.ui-tabs-selected a{-moz-border-radius-topleft:4px; -moz-border-radius-topright:4px;border:1px solid #dfdfdf; border-bottom-color:#f9f9f9; color:#333333; font-weight:normal; padding:0 12px;}
383
- #hasadmintabs ul.ui-tabs-nav a:focus, a:active {outline-color:-moz-use-text-color; outline-style:none; outline-width:medium;}
384
- #screen-options-wrap p.submit {margin:0; padding:0;}
385
- </style>
386
- <script type="text/javascript">
387
- /* <![CDATA[ */
388
- /**
389
- * Breadcrumb NavXT Admin Page (javascript/jQuery)
390
- *
391
- * unobtrusive approach to add tabbed forms into
392
- * the wordpress admin panel and various other
393
- * stuff that needs javascript with the Admin Panel.
394
- *
395
- * @see Breadcrumb NavXT (Wordpress Plugin)
396
- * @author Tom Klingenberg
397
- * @author John Havlik
398
- * @uses jQuery
399
- * @uses jQuery.ui.tabs
400
- */
401
- jQuery(function()
402
  {
403
- bcn_context_init();
404
- bcn_tabulator_init();
405
- });
406
- /**
407
- * Tabulator Bootup
408
- */
409
- function bcn_tabulator_init(){
410
- if (!jQuery("#hasadmintabs").length) return;
411
- /* init markup for tabs */
412
- jQuery('#hasadmintabs').prepend("<ul><\/ul>");
413
- jQuery('#hasadmintabs > fieldset').each(function(i){
414
- id = jQuery(this).attr('id');
415
- caption = jQuery(this).find('h3').text();
416
- jQuery('#hasadmintabs > ul').append('<li><a href="#'+id+'"><span>'+caption+"<\/span><\/a><\/li>");
417
- jQuery(this).find('h3').hide();
418
- });
419
- /* init the tabs plugin */
420
- jQuery("#hasadmintabs").tabs();
421
- /* handler for opening the last tab after submit (compability version) */
422
- jQuery('#hasadmintabs ul a').click(function(i){
423
- var form = jQuery('#bcn_admin-options');
424
- var action = form.attr("action").split('#', 1) + jQuery(this).attr('href');
425
- form.get(0).setAttribute("action", action);
426
- });
427
  }
428
  /**
429
- * context screen options for import/export
430
  */
431
- function bcn_context_init(){
432
- if (!jQuery("#bcn_import_export_relocate").length) return;
433
- jQuery('#screen-meta').prepend(
434
- '<div id="screen-options-wrap" class="hidden"></div>'
435
- );
436
- jQuery('#screen-meta-links').append(
437
- '<div id="screen-options-link-wrap" class="hide-if-no-js screen-meta-toggle">' +
438
- '<a class="show-settings" id="show-settings-link" href="#screen-options"><?php printf('%s/%s/%s', __('Import', 'breadcrumb_navxt'), __('Export', 'breadcrumb_navxt'), __('Reset', 'breadcrumb_navxt')); ?></a>' +
439
- '</div>'
440
- );
441
- var code = jQuery('#bcn_import_export_relocate').html();
442
- jQuery('#bcn_import_export_relocate').html('');
443
- code = code.replace(/h3>/gi, 'h5>');
444
- jQuery('#screen-options-wrap').prepend(code);
445
- }
446
- /* ]]> */
447
- </script>
448
- <?php
449
  }
450
  /**
451
  * The administrative page for Breadcrumb NavXT
452
- *
453
  */
454
  function admin_page()
455
  {
456
  global $wp_taxonomies, $wp_post_types;
457
- $this->security();?>
458
- <div class="wrap"><h2><?php _e('Breadcrumb NavXT Settings', 'breadcrumb_navxt'); ?></h2>
459
- <div<?php if($this->_has_contextual_help): ?> class="hide-if-js"<?php endif; ?>><?php
460
- print $this->_get_help_text();
461
- ?></div>
462
  <?php
463
  //We exit after the version check if there is an action the user needs to take before saving settings
464
- if(!$this->version_check($this->get_option($this->unique_prefix . '_version')))
465
  {
466
  return;
467
  }
@@ -473,8 +294,8 @@ class bcn_admin extends mtekk_admin
473
  <h3><?php _e('General', 'breadcrumb_navxt'); ?></h3>
474
  <table class="form-table">
475
  <?php
476
- $this->input_text(__('Breadcrumb Separator', 'breadcrumb_navxt'), 'separator', '32', false, __('Placed in between each breadcrumb.', 'breadcrumb_navxt'));
477
- $this->input_text(__('Breadcrumb Max Title Length', 'breadcrumb_navxt'), 'max_title_length', '10');
478
  ?>
479
  <tr valign="top">
480
  <th scope="row">
@@ -482,25 +303,25 @@ class bcn_admin extends mtekk_admin
482
  </th>
483
  <td>
484
  <label>
485
- <input name="bcn_options[home_display]" type="checkbox" id="home_display" value="true" <?php checked(true, $this->opt['home_display']); ?> />
486
  <?php _e('Place the home breadcrumb in the trail.', 'breadcrumb_navxt'); ?>
487
  </label><br />
488
  <ul>
489
  <li>
490
- <label for="home_title">
491
  <?php _e('Home Title: ','breadcrumb_navxt');?>
492
- <input type="text" name="bcn_options[home_title]" id="home_title" value="<?php echo htmlentities($this->opt['home_title'], ENT_COMPAT, 'UTF-8'); ?>" size="20" />
493
  </label>
494
  </li>
495
  </ul>
496
  </td>
497
  </tr>
498
  <?php
499
- $this->input_text(__('Home Prefix', 'breadcrumb_navxt'), 'home_prefix', '32');
500
- $this->input_text(__('Home Suffix', 'breadcrumb_navxt'), 'home_suffix', '32');
501
- $this->input_text(__('Home Anchor', 'breadcrumb_navxt'), 'home_anchor', '64', false, __('The anchor template for the home breadcrumb.', 'breadcrumb_navxt'));
502
- $this->input_check(__('Blog Breadcrumb', 'breadcrumb_navxt'), 'blog_display', __('Place the blog breadcrumb in the trail.', 'breadcrumb_navxt'), ($this->get_option('show_on_front') !== "page"));
503
- $this->input_text(__('Blog Anchor', 'breadcrumb_navxt'), 'blog_anchor', '64', ($this->get_option('show_on_front') !== "page"), __('The anchor template for the blog breadcrumb, used only in static front page environments.', 'breadcrumb_navxt'));
504
  ?>
505
  <tr valign="top">
506
  <th scope="row">
@@ -508,38 +329,35 @@ class bcn_admin extends mtekk_admin
508
  </th>
509
  <td>
510
  <label>
511
- <input name="bcn_options[mainsite_display]" type="checkbox" id="mainsite_display" <?php if(!is_multisite()){echo 'disabled="disabled" class="disabled"';}?> value="true" <?php checked(true, $this->opt['mainsite_display']); ?> />
512
  <?php _e('Place the main site home breadcrumb in the trail in an multisite setup.', 'breadcrumb_navxt'); ?>
513
  </label><br />
514
  <ul>
515
  <li>
516
- <label for="mainsite_title">
517
- <?php _e('Main Site Home Title: ','breadcrumb_navxt');?>
518
- <input type="text" name="bcn_options[mainsite_title]" id="mainsite_title" <?php if(!is_multisite()){echo 'disabled="disabled" class="disabled"';}?> value="<?php echo htmlentities($this->opt['mainsite_title'], ENT_COMPAT, 'UTF-8'); ?>" size="20" />
519
- <?php if(!is_multisite()){?><input type="hidden" name="bcn_options[mainsite_title]" value="<?php echo htmlentities($this->opt['mainsite_title'], ENT_COMPAT, 'UTF-8');?>" /><?php } ?>
520
  </label>
521
  </li>
522
  </ul>
523
  </td>
524
  </tr>
525
  <?php
526
- $this->input_text(__('Main Site Home Prefix', 'breadcrumb_navxt'), 'mainsite_prefix', '32', !is_multisite(), __('Used for the main site home breadcrumb in an multisite setup', 'breadcrumb_navxt'));
527
- $this->input_text(__('Main Site Home Suffix', 'breadcrumb_navxt'), 'mainsite_suffix', '32', !is_multisite(), __('Used for the main site home breadcrumb in an multisite setup', 'breadcrumb_navxt'));
528
- $this->input_text(__('Main Site Home Anchor', 'breadcrumb_navxt'), 'mainsite_anchor', '64', !is_multisite(), __('The anchor template for the main site home breadcrumb, used only in multisite environments.', 'breadcrumb_navxt'));
529
- ?>
530
  </table>
531
  </fieldset>
532
  <fieldset id="current" class="bcn_options">
533
  <h3><?php _e('Current Item', 'breadcrumb_navxt'); ?></h3>
534
  <table class="form-table">
535
  <?php
536
- $this->input_check(__('Link Current Item', 'breadcrumb_navxt'), 'current_item_linked', __('Yes'));
537
- $this->input_text(__('Current Item Prefix', 'breadcrumb_navxt'), 'current_item_prefix', '32', false, __('This is always placed in front of the last breadcrumb in the trail, before any other prefixes for that breadcrumb.', 'breadcrumb_navxt'));
538
- $this->input_text(__('Current Item Suffix', 'breadcrumb_navxt'), 'current_item_suffix', '32', false, __('This is always placed after the last breadcrumb in the trail, and after any other prefixes for that breadcrumb.', 'breadcrumb_navxt'));
539
- $this->input_text(__('Current Item Anchor', 'breadcrumb_navxt'), 'current_item_anchor', '64', false, __('The anchor template for current item breadcrumbs.', 'breadcrumb_navxt'));
540
- $this->input_check(__('Paged Breadcrumb', 'breadcrumb_navxt'), 'paged_display', __('Include the paged breadcrumb in the breadcrumb trail.', 'breadcrumb_navxt'), false, __('Indicates that the user is on a page other than the first on paginated posts/pages.', 'breadcrumb_navxt'));
541
- $this->input_text(__('Paged Prefix', 'breadcrumb_navxt'), 'paged_prefix', '32');
542
- $this->input_text(__('Paged Suffix', 'breadcrumb_navxt'), 'paged_suffix', '32');
543
  ?>
544
  </table>
545
  </fieldset>
@@ -547,10 +365,9 @@ class bcn_admin extends mtekk_admin
547
  <h3><?php _e('Posts &amp; Pages', 'breadcrumb_navxt'); ?></h3>
548
  <table class="form-table">
549
  <?php
550
- $this->input_text(__('Post Prefix', 'breadcrumb_navxt'), 'post_post_prefix', '32');
551
- $this->input_text(__('Post Suffix', 'breadcrumb_navxt'), 'post_post_suffix', '32');
552
- $this->input_text(__('Post Anchor', 'breadcrumb_navxt'), 'post_post_anchor', '64', false, __('The anchor template for post breadcrumbs.', 'breadcrumb_navxt'));
553
- $this->input_check(__('Post Taxonomy Display', 'breadcrumb_navxt'), 'post_post_taxonomy_display', __('Show the taxonomy leading to a post in the breadcrumb trail.', 'breadcrumb_navxt'));
554
  ?>
555
  <tr valign="top">
556
  <th scope="row">
@@ -558,17 +375,17 @@ class bcn_admin extends mtekk_admin
558
  </th>
559
  <td>
560
  <?php
561
- $this->input_radio('post_post_taxonomy_type', 'category', __('Categories'));
562
- $this->input_radio('post_post_taxonomy_type', 'date', __('Dates'));
563
- $this->input_radio('post_post_taxonomy_type', 'post_tag', __('Tags'));
564
- $this->input_radio('post_post_taxonomy_type', 'page', __('Pages'));
565
  //Loop through all of the taxonomies in the array
566
  foreach($wp_taxonomies as $taxonomy)
567
  {
568
  //We only want custom taxonomies
569
  if(($taxonomy->object_type == 'post' || is_array($taxonomy->object_type) && in_array('post', $taxonomy->object_type)) && !$taxonomy->_builtin)
570
  {
571
- $this->input_radio('post_post_taxonomy_type', $taxonomy->name, mb_convert_case(__($taxonomy->label), MB_CASE_TITLE, 'UTF-8'));
572
  }
573
  }
574
  ?>
@@ -576,11 +393,10 @@ class bcn_admin extends mtekk_admin
576
  </td>
577
  </tr>
578
  <?php
579
- $this->input_text(__('Page Prefix', 'breadcrumb_navxt'), 'post_page_prefix', '32');
580
- $this->input_text(__('Page Suffix', 'breadcrumb_navxt'), 'post_page_suffix', '32');
581
- $this->input_text(__('Page Anchor', 'breadcrumb_navxt'), 'post_page_anchor', '64', false, __('The anchor template for page breadcrumbs.', 'breadcrumb_navxt'));
582
- $this->input_text(__('Attachment Prefix', 'breadcrumb_navxt'), 'attachment_prefix', '32');
583
- $this->input_text(__('Attachment Suffix', 'breadcrumb_navxt'), 'attachment_suffix', '32');
584
  ?>
585
  </table>
586
  </fieldset>
@@ -592,40 +408,40 @@ class bcn_admin extends mtekk_admin
592
  if(!$post_type->_builtin)
593
  {
594
  //If the post type does not have settings in the options array yet, we need to load some defaults
595
- if(!array_key_exists('post_' . $post_type->name . '_anchor', $this->opt) || !$post_type->hierarchical && !array_key_exists('post_' . $post_type->name . '_taxonomy_type', $this->opt))
596
  {
597
  //Add the necessary option array members
598
- $this->opt['post_' . $post_type->name . '_prefix'] = '';
599
- $this->opt['post_' . $post_type->name . '_suffix'] = '';
600
- $this->opt['post_' . $post_type->name . '_anchor'] = __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt');
601
  //Do type dependent tasks
602
  if($post_type->hierarchical)
603
  {
604
  //Set post_root for hierarchical types
605
- $this->opt['post_' . $post_type->name . '_root'] = get_option('page_on_front');
606
  }
607
  //If it is flat, we need a taxonomy selection
608
  else
609
  {
610
  //Set post_root for flat types
611
- $this->opt['post_' . $post_type->name . '_root'] = get_option('page_for_posts');
612
  //Default to not displaying a taxonomy
613
- $this->opt['post_' . $post_type->name . '_taxonomy_display'] = false;
614
  //Loop through all of the possible taxonomies
615
  foreach($wp_taxonomies as $taxonomy)
616
  {
617
  //Activate the first taxonomy valid for this post type and exit the loop
618
  if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type))
619
  {
620
- $this->opt['post_' . $post_type->name . '_taxonomy_display'] = true;
621
- $this->opt['post_' . $post_type->name . '_taxonomy_type'] = $taxonomy->name;
622
  break;
623
  }
624
  }
625
  //If there are no valid taxonomies for this type, we default to not displaying taxonomies for this post type
626
- if(!isset($this->opt['post_' . $post_type->name . '_taxonomy_type']))
627
  {
628
- $this->opt['post_' . $post_type->name . '_taxonomy_type'] = 'date';
629
  }
630
  }
631
  }?>
@@ -633,24 +449,24 @@ class bcn_admin extends mtekk_admin
633
  <h3><?php echo $post_type->labels->singular_name; ?></h3>
634
  <table class="form-table">
635
  <?php
636
- $this->input_text(sprintf(__('%s Prefix', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'post_' . $post_type->name . '_prefix', '32');
637
- $this->input_text(sprintf(__('%s Suffix', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'post_' . $post_type->name . '_suffix', '32');
638
- $this->input_text(sprintf(__('%s Anchor', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'post_' . $post_type->name . '_anchor', '64', false, sprintf(__('The anchor template for %s breadcrumbs.', 'breadcrumb_navxt'), strtolower(__($post_type->labels->singular_name))));
639
- $optid = $this->get_valid_id('post_' . $post_type->name . '_root');
640
  ?>
641
  <tr valign="top">
642
  <th scope="row">
643
  <label for="<?php echo $optid;?>"><?php printf(__('%s Root Page', 'breadcrumb_navxt'), $post_type->labels->singular_name);?></label>
644
  </th>
645
  <td>
646
- <?php wp_dropdown_pages(array('name' => $this->unique_prefix . '_options[post_' . $post_type->name . '_root]', 'id' => $optid, 'echo' => 1, 'show_option_none' => __( '&mdash; Select &mdash;' ), 'option_none_value' => '0', 'selected' => $this->opt['post_' . $post_type->name . '_root']));?>
647
  </td>
648
  </tr>
649
  <?php
 
650
  //If it is flat, we need a taxonomy selection
651
  if(!$post_type->hierarchical)
652
  {
653
- $this->input_check(sprintf(__('%s Taxonomy Display', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'post_' . $post_type->name . '_taxonomy_display', sprintf(__('Show the taxonomy leading to a %s in the breadcrumb trail.', 'breadcrumb_navxt'), strtolower(__($post_type->labels->singular_name))));
654
  ?>
655
  <tr valign="top">
656
  <th scope="row">
@@ -658,15 +474,15 @@ class bcn_admin extends mtekk_admin
658
  </th>
659
  <td>
660
  <?php
661
- $this->input_radio('post_' . $post_type->name . '_taxonomy_type', 'date', __('Dates'));
662
- $this->input_radio('post_' . $post_type->name . '_taxonomy_type', 'page', __('Pages'));
663
  //Loop through all of the taxonomies in the array
664
  foreach($wp_taxonomies as $taxonomy)
665
  {
666
  //We only want custom taxonomies
667
  if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type))
668
  {
669
- $this->input_radio('post_' . $post_type->name . '_taxonomy_type', $taxonomy->name, $taxonomy->labels->singular_name);
670
  }
671
  }
672
  ?>
@@ -679,27 +495,14 @@ class bcn_admin extends mtekk_admin
679
  <?php
680
  }
681
  }?>
682
- <fieldset id="category" class="bcn_options">
683
- <h3><?php _e('Categories', 'breadcrumb_navxt'); ?></h3>
684
- <table class="form-table">
685
- <?php
686
- $this->input_text(__('Category Prefix', 'breadcrumb_navxt'), 'category_prefix', '32', false, __('Applied before the anchor on all category breadcrumbs.', 'breadcrumb_navxt'));
687
- $this->input_text(__('Category Suffix', 'breadcrumb_navxt'), 'category_suffix', '32', false, __('Applied after the anchor on all category breadcrumbs.', 'breadcrumb_navxt'));
688
- $this->input_text(__('Category Anchor', 'breadcrumb_navxt'), 'category_anchor', '64', false, __('The anchor template for category breadcrumbs.', 'breadcrumb_navxt'));
689
- $this->input_text(__('Archive by Category Prefix', 'breadcrumb_navxt'), 'archive_category_prefix', '32', false, __('Applied before the title of the current item breadcrumb on an archive by cateogry page.', 'breadcrumb_navxt'));
690
- $this->input_text(__('Archive by Category Suffix', 'breadcrumb_navxt'), 'archive_category_suffix', '32', false, __('Applied after the title of the current item breadcrumb on an archive by cateogry page.', 'breadcrumb_navxt'));
691
- ?>
692
- </table>
693
- </fieldset>
694
- <fieldset id="post_tag" class="bcn_options">
695
- <h3><?php _e('Tags', 'breadcrumb_navxt'); ?></h3>
696
  <table class="form-table">
697
  <?php
698
- $this->input_text(__('Tag Prefix', 'breadcrumb_navxt'), 'post_tag_prefix', '32', false, __('Applied before the anchor on all tag breadcrumbs.', 'breadcrumb_navxt'));
699
- $this->input_text(__('Tag Suffix', 'breadcrumb_navxt'), 'post_tag_suffix', '32', false, __('Applied after the anchor on all tag breadcrumbs.', 'breadcrumb_navxt'));
700
- $this->input_text(__('Tag Anchor', 'breadcrumb_navxt'), 'post_tag_anchor', '64', false, __('The anchor template for tag breadcrumbs.', 'breadcrumb_navxt'));
701
- $this->input_text(__('Archive by Tag Prefix', 'breadcrumb_navxt'), 'archive_post_tag_prefix', '32', false, __('Applied before the title of the current item breadcrumb on an archive by tag page.', 'breadcrumb_navxt'));
702
- $this->input_text(__('Archive by Tag Suffix', 'breadcrumb_navxt'), 'archive_post_tag_suffix', '32', false, __('Applied after the title of the current item breadcrumb on an archive by tag page.', 'breadcrumb_navxt'));
703
  ?>
704
  </table>
705
  </fieldset>
@@ -711,25 +514,19 @@ class bcn_admin extends mtekk_admin
711
  if(!$taxonomy->_builtin)
712
  {
713
  //If the taxonomy does not have settings in the options array yet, we need to load some defaults
714
- if(!array_key_exists($taxonomy->name . '_anchor', $this->opt))
715
  {
716
  //Add the necessary option array members
717
- $this->opt[$taxonomy->name . '_prefix'] = '';
718
- $this->opt[$taxonomy->name . '_suffix'] = '';
719
- $this->opt[$taxonomy->name . '_anchor'] = __(sprintf('<a title="Go to the %%title%% %s archives." href="%%link%%">', $taxonomy->labels->singular_name), 'breadcrumb_navxt');
720
- $this->opt['archive_' . $taxonomy->name . '_prefix'] = '';
721
- $this->opt['archive_' . $taxonomy->name . '_suffix'] = '';
722
  }
723
  ?>
724
- <fieldset id="<?php echo $taxonomy->name; ?>" class="bcn_options">
725
  <h3><?php echo mb_convert_case(__($taxonomy->label), MB_CASE_TITLE, 'UTF-8'); ?></h3>
726
  <table class="form-table">
727
  <?php
728
- $this->input_text(sprintf(__('%s Prefix', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), $taxonomy->name . '_prefix', '32', false, sprintf(__('Applied before the anchor on all %s breadcrumbs.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
729
- $this->input_text(sprintf(__('%s Suffix', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), $taxonomy->name . '_suffix', '32', false, sprintf(__('Applied after the anchor on all %s breadcrumbs.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
730
- $this->input_text(sprintf(__('%s Anchor', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), $taxonomy->name . '_anchor', '64', false, sprintf(__('The anchor template for %s breadcrumbs.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
731
- $this->input_text(sprintf(__('Archive by %s Prefix', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), 'archive_' . $taxonomy->name . '_prefix', '32', false, sprintf(__('Applied before the title of the current item breadcrumb on an archive by %s page.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
732
- $this->input_text(sprintf(__('Archive by %s Suffix', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), 'archive_' . $taxonomy->name . '_suffix', '32', false, sprintf(__('Applied after the title of the current item breadcrumb on an archive by %s page.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
733
  ?>
734
  </table>
735
  </fieldset>
@@ -737,43 +534,42 @@ class bcn_admin extends mtekk_admin
737
  }
738
  }
739
  ?>
740
- <fieldset id="date" class="bcn_options">
741
- <h3><?php _e('Date Archives', 'breadcrumb_navxt'); ?></h3>
742
- <table class="form-table">
743
- <?php
744
- $this->input_text(__('Date Anchor', 'breadcrumb_navxt'), 'date_anchor', '64', false, __('The anchor template for date breadcrumbs.', 'breadcrumb_navxt'));
745
- $this->input_text(__('Archive by Date Prefix', 'breadcrumb_navxt'), 'archive_date_prefix', '32', false, __('Applied before the anchor on all date breadcrumbs.', 'breadcrumb_navxt'));
746
- $this->input_text(__('Archive by Date Suffix', 'breadcrumb_navxt'), 'archive_date_suffix', '32', false, __('Applied after the anchor on all date breadcrumbs.', 'breadcrumb_navxt'));
747
- ?>
748
- </table>
749
- </fieldset>
750
  <fieldset id="miscellaneous" class="bcn_options">
751
  <h3><?php _e('Miscellaneous', 'breadcrumb_navxt'); ?></h3>
752
  <table class="form-table">
753
  <?php
754
- $this->input_text(__('Author Prefix', 'breadcrumb_navxt'), 'author_prefix', '32');
755
- $this->input_text(__('Author Suffix', 'breadcrumb_navxt'), 'author_suffix', '32');
756
- $this->input_select(__('Author Display Format', 'breadcrumb_navxt'), 'author_name', array("display_name", "nickname", "first_name", "last_name"), false, __('display_name uses the name specified in "Display name publicly as" under the user profile the others correspond to options in the user profile.', 'breadcrumb_navxt'));
757
- $this->input_text(__('Search Prefix', 'breadcrumb_navxt'), 'search_prefix', '32');
758
- $this->input_text(__('Search Suffix', 'breadcrumb_navxt'), 'search_suffix', '32');
759
- $this->input_text(__('Search Anchor', 'breadcrumb_navxt'), 'search_anchor', '64', false, __('The anchor template for search breadcrumbs, used only when the search results span several pages.', 'breadcrumb_navxt'));
760
- $this->input_text(__('404 Title', 'breadcrumb_navxt'), '404_title', '32');
761
- $this->input_text(__('404 Prefix', 'breadcrumb_navxt'), '404_prefix', '32');
762
- $this->input_text(__('404 Suffix', 'breadcrumb_navxt'), '404_suffix', '32');
763
  ?>
764
  </table>
765
  </fieldset>
766
  </div>
767
  <p class="submit"><input type="submit" class="button-primary" name="bcn_admin_options" value="<?php esc_attr_e('Save Changes') ?>" /></p>
768
  </form>
769
- <?php $this->import_form(); ?>
 
 
770
  </div>
771
  <?php
772
  }
 
 
 
 
 
 
 
773
  /**
774
  * Places settings into $opts array, if missing, for the registered post types
775
  *
776
- * @param $opts
777
  */
778
  function find_posttypes(&$opts)
779
  {
@@ -785,40 +581,40 @@ class bcn_admin extends mtekk_admin
785
  if(!$post_type->_builtin)
786
  {
787
  //If the post type does not have settings in the options array yet, we need to load some defaults
788
- if(!array_key_exists('post_' . $post_type->name . '_anchor', $opts) || !$post_type->hierarchical && !array_key_exists('post_' . $post_type->name . '_taxonomy_type', $opts))
789
  {
790
  //Add the necessary option array members
791
- $opts['post_' . $post_type->name . '_prefix'] = '';
792
- $opts['post_' . $post_type->name . '_suffix'] = '';
793
- $opts['post_' . $post_type->name . '_anchor'] = __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt');
794
  //Do type dependent tasks
795
  if($post_type->hierarchical)
796
  {
797
  //Set post_root for hierarchical types
798
- $opts['post_' . $post_type->name . '_root'] = get_option('page_on_front');
799
  }
800
  //If it is flat, we need a taxonomy selection
801
  else
802
  {
803
  //Set post_root for flat types
804
- $opts['post_' . $post_type->name . '_root'] = get_option('page_for_posts');
805
- //Be safe and disable taxonomy display by default
806
- $opts['post_' . $post_type->name . '_taxonomy_display'] = false;
807
  //Loop through all of the possible taxonomies
808
  foreach($wp_taxonomies as $taxonomy)
809
  {
810
  //Activate the first taxonomy valid for this post type and exit the loop
811
  if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type))
812
  {
813
- $opts['post_' . $post_type->name . '_taxonomy_display'] = true;
814
- $opts['post_' . $post_type->name . '_taxonomy_type'] = $taxonomy->name;
815
  break;
816
  }
817
  }
818
  //If there are no valid taxonomies for this type, we default to not displaying taxonomies for this post type
819
- if(!isset($opts['post_' . $post_type->name . '_taxonomy_type']))
820
  {
821
- $opts['post_' . $post_type->name . '_taxonomy_type'] = 'date';
822
  }
823
  }
824
  }
@@ -840,68 +636,15 @@ class bcn_admin extends mtekk_admin
840
  if(!$taxonomy->_builtin)
841
  {
842
  //If the taxonomy does not have settings in the options array yet, we need to load some defaults
843
- if(!array_key_exists($taxonomy->name . '_anchor', $opts))
844
  {
845
- $opts[$taxonomy->name . '_prefix'] = '';
846
- $opts[$taxonomy->name . '_suffix'] = '';
847
- $opts[$taxonomy->name . '_anchor'] = __(sprintf('<a title="Go to the %%title%% %s archives." href="%%link%%">', mb_convert_case(__($taxonomy->label), MB_CASE_TITLE, 'UTF-8')), 'breadcrumb_navxt');
848
- $opts['archive_' . $taxonomy->name . '_prefix'] = '';
849
- $opts['archive_' . $taxonomy->name . '_suffix'] = '';
850
  }
851
  }
852
  }
853
  }
854
- /**
855
- * This inserts the value into the option name, works around WP's stupid string bool
856
- *
857
- * @param (string) key name where to save the value in $value
858
- * @param (mixed) value to insert into the options db
859
- * @param (bool) should WordPress autoload this option
860
- * @return (bool)
861
- */
862
- function add_option($key, $value, $autoload = true)
863
- {
864
- if($autoload)
865
- {
866
- return add_option($key, $value);
867
- }
868
- else
869
- {
870
- return add_option($key, $value, '', 'no');
871
- }
872
- }
873
- /**
874
- * This removes the option name, WPMU safe
875
- *
876
- * @param (string) key name of the option to remove
877
- * @return (bool)
878
- */
879
- function delete_option($key)
880
- {
881
- return delete_option($key);
882
- }
883
- /**
884
- * This updates the value into the option name, WPMU safe
885
- *
886
- * @param (string) key name where to save the value in $value
887
- * @param (mixed) value to insert into the options db
888
- * @return (bool)
889
- */
890
- function update_option($key, $value)
891
- {
892
- return update_option($key, $value);
893
- }
894
- /**
895
- * This grabs the the data from the db it is WPMU safe and can place the data
896
- * in a HTML form safe manner.
897
- *
898
- * @param (string) key name of the wordpress option to get
899
- * @return (mixed) value of option
900
- */
901
- function get_option($key)
902
- {
903
- return get_option($key);
904
- }
905
  /**
906
  * Outputs the breadcrumb trail
907
  *
@@ -911,11 +654,8 @@ class bcn_admin extends mtekk_admin
911
  */
912
  function display($return = false, $linked = true, $reverse = false)
913
  {
914
- //First make sure our defaults are safe
915
- $this->find_posttypes($this->breadcrumb_trail->opt);
916
- $this->find_taxonomies($this->breadcrumb_trail->opt);
917
  //Grab the current settings from the db
918
- $this->breadcrumb_trail->opt = wp_parse_args($this->get_option('bcn_options'), $this->breadcrumb_trail->opt);
919
  //Generate the breadcrumb trail
920
  $this->breadcrumb_trail->fill();
921
  return $this->breadcrumb_trail->display($return, $linked, $reverse);
@@ -930,35 +670,12 @@ class bcn_admin extends mtekk_admin
930
  */
931
  function display_list($return = false, $linked = true, $reverse = false)
932
  {
933
- //First make sure our defaults are safe
934
- $this->find_posttypes($this->breadcrumb_trail->opt);
935
- $this->find_taxonomies($this->breadcrumb_trail->opt);
936
  //Grab the current settings from the db
937
- $this->breadcrumb_trail->opt = wp_parse_args($this->get_option('bcn_options'), $this->breadcrumb_trail->opt);
938
  //Generate the breadcrumb trail
939
  $this->breadcrumb_trail->fill();
940
  return $this->breadcrumb_trail->display_list($return, $linked, $reverse);
941
  }
942
- /**
943
- * Outputs the breadcrumb trail
944
- *
945
- * @since 3.8.0
946
- * @param bool $return Whether to return data or to echo it.
947
- * @param bool $linked[optional] Whether to allow hyperlinks in the trail or not.
948
- * @param string $tag[optional] The tag to use for the nesting
949
- * @param string $mode[optional] Whether to follow the rdfa or Microdata format
950
- */
951
- function display_nested($return = false, $linked = true, $tag = 'span', $mode = 'rdfa')
952
- {
953
- //First make sure our defaults are safe
954
- $this->find_posttypes($this->breadcrumb_trail->opt);
955
- $this->find_taxonomies($this->breadcrumb_trail->opt);
956
- //Grab the current settings from the db
957
- $this->breadcrumb_trail->opt = wp_parse_args($this->get_option('bcn_options'), $this->breadcrumb_trail->opt);
958
- //Generate the breadcrumb trail
959
- $this->breadcrumb_trail->fill();
960
- return $this->breadcrumb_trail->display_nested($return, $linked, $tag, $mode);
961
- }
962
  }
963
  //Let's make an instance of our object takes care of everything
964
  $bcn_admin = new bcn_admin;
@@ -991,20 +708,4 @@ function bcn_display_list($return = false, $linked = true, $reverse = false)
991
  {
992
  return $bcn_admin->display_list($return, $linked, $reverse);
993
  }
994
- }
995
- /**
996
- * A wrapper for the internal function in the class
997
- *
998
- * @param bool $return Whether to return data or to echo it.
999
- * @param bool $linked[optional] Whether to allow hyperlinks in the trail or not.
1000
- * @param string $tag[optional] The tag to use for the nesting
1001
- * @param string $mode[optional] Whether to follow the rdfa or Microdata format
1002
- */
1003
- function bcn_display_nested($return = false, $linked = true, $tag = 'span', $mode = 'rdfa')
1004
- {
1005
- global $bcn_admin;
1006
- if($bcn_admin !== null)
1007
- {
1008
- return $bcn_admin->display_nested($return, $linked, $tag, $mode);
1009
- }
1010
  }
3
  Plugin Name: Breadcrumb NavXT
4
  Plugin URI: http://mtekk.us/code/breadcrumb-navxt/
5
  Description: Adds a breadcrumb navigation showing the visitor&#39;s path to their current location. For details on how to use this plugin visit <a href="http://mtekk.us/code/breadcrumb-navxt/">Breadcrumb NavXT</a>.
6
+ Version: 3.9.80 Beta 1
7
  Author: John Havlik
8
  Author URI: http://mtekk.us/
9
+ License: GPL2
10
+ TextDomain: breadcrumb_navxt
11
+ DomainPath: /languages/
12
+
13
  */
14
  /* Copyright 2007-2011 John Havlik (email : mtekkmonkey@gmail.com)
15
 
47
  //Include the WP 2.8+ widget class
48
  require_once(dirname(__FILE__) . '/breadcrumb_navxt_widget.php');
49
  //Include admin base class
50
+ if(!class_exists('mtekk_adminKit'))
51
  {
52
+ require_once(dirname(__FILE__) . '/includes/mtekk_adminkit.php');
53
  }
54
  /**
55
  * The administrative interface class
56
  *
57
  */
58
+ class bcn_admin extends mtekk_adminKit
59
  {
60
+ protected $version = '3.99.80';
 
 
 
 
 
61
  protected $full_name = 'Breadcrumb NavXT Settings';
62
  protected $short_name = 'Breadcrumb NavXT';
63
  protected $access_level = 'manage_options';
64
  protected $identifier = 'breadcrumb_navxt';
65
  protected $unique_prefix = 'bcn';
66
  protected $plugin_basename = 'breadcrumb-navxt/breadcrumb_navxt_admin.php';
67
+ protected $support_url = 'http://mtekk.us/archives/wordpress/plugins-wordpress/breadcrumb-navxt-';
 
 
 
 
 
68
  public $breadcrumb_trail;
69
  /**
70
  * Administrative interface class default constructor
73
  {
74
  //We'll let it fail fataly if the class isn't there as we depend on it
75
  $this->breadcrumb_trail = new bcn_breadcrumb_trail;
76
+ //First make sure our defaults are safe
77
+ $this->find_posttypes($this->breadcrumb_trail->opt);
78
+ $this->find_taxonomies($this->breadcrumb_trail->opt);
79
  //Grab defaults from the breadcrumb_trail object
80
  $this->opt = $this->breadcrumb_trail->opt;
81
  //We set the plugin basename here, could manually set it, but this is for demonstration purposes
96
  function init()
97
  {
98
  //We're going to make sure we run the parent's version of this function as well
99
+ parent::init();
 
 
 
 
100
  }
101
  /**
102
  * Makes sure the current user can manage options to proceed
109
  wp_die(__('Insufficient privileges to proceed.', 'breadcrumb_navxt'));
110
  }
111
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  /**
113
  * Upgrades input options array, sets to $this->opt
114
  *
121
  //If our version is not the same as in the db, time to update
122
  if($version !== $this->version)
123
  {
124
+ //Upgrading to 3.8.1
125
+ if(version_compare($version, '3.8.1', '<'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  {
127
+ $opts['post_page_root'] = get_option('page_on_front');
128
+ $opts['post_post_root'] = get_option('page_for_posts');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
+ //Upgrading to 4.0
131
+ if(version_compare($version, '4.0.0', '<'))
132
  {
133
+ //Only migrate if we haven't migrated yet
134
+ if(isset($opts['current_item_linked']))
 
 
 
 
 
 
 
 
 
 
 
135
  {
136
+ //Loop through the old options, migrate some of them
137
+ foreach($opts as $option => $value)
138
  {
139
+ //Handle all of our boolean options first, they're real easy, just add a 'b'
140
+ if(strpos($option, 'display') > 0 || $option == 'current_item_linked')
141
  {
142
+ $this->breadcrumb_trail->opt['b'.$option] = $this->opt[$option];
143
+ }
144
+ //Handle migration of anchor templates to the templates
145
+ else if(strpos($option, 'anchor') > 0)
146
+ {
147
+ $parts = explode('_', $option);
148
+ //Do excess slash removal sanitation
149
+ $this->breadcrumb_trail->opt['H' . $parts[0] . '_template'] = $this->opt[$option] . '%htitle%</a>';
150
+ }
151
+ //Handle our abs integers
152
+ else if($option == 'max_title_length' || $option == 'post_post_root' || $option == 'post_page_root')
153
+ {
154
+ $this->breadcrumb_trail->opt['a' . $option] = $this->opt[$option];
155
+ }
156
+ //Now everything else, minus prefix and suffix
157
+ else if(strpos($option, 'prefix') === false && strpos($option, 'suffix') === false)
158
+ {
159
+ $this->breadcrumb_trail->opt['S' . $option] = $this->opt[$option];
160
  }
161
  }
162
  }
163
+ //Add in the new settings for CPTs introduced in 4.0
164
+ foreach($wp_post_types as $post_type)
165
+ {
166
+ //We only want custom post types
167
+ if(!$post_type->_builtin)
168
+ {
169
+ //Add in the archive_display option
170
+ $this->breadcrumb_trail->opt['bpost_' . $post_type->name . '_archive_display'] = $post_type->has_archive;
171
+ }
172
+ }
173
+ $opts = $this->breadcrumb_trail->opt;
174
  }
175
  //Save the passed in opts to the object's option array
176
  $this->opt = $opts;
177
  }
178
  }
179
  /**
180
+ * help action hook function
181
+ *
182
+ * @return string
183
+ *
184
  */
185
+ function help()
186
  {
187
+ $screen = get_current_screen();
188
+ //Add contextual help on current screen
189
+ if($screen->id == 'settings_page_' . $this->identifier)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  {
191
+ $general_tab = '<p>' . __('Tips for the settings are located below select options.', $this->identifier) .
192
+ '</p><h5>' . __('Resources', $this->identifier) . '</h5><ul><li>' .
193
+ sprintf(__("%sTutorials and How Tos%s: There are several guides, tutorials, and how tos available on the author's website.", $this->identifier),'<a title="' . __('Go to the Breadcrumb NavXT tag archive.', 'breadcrumb_navxt') . '" href="http://mtekk.us/archives/tag/breadcrumb-navxt">', '</a>') . '</li><li>' .
194
+ sprintf(__('%sOnline Documentation%s: Check out the documentation for more indepth technical information.', 'breadcrumb_navxt'), '<a title="' . __('Go to the Breadcrumb NavXT online documentation', 'breadcrumb_navxt') . '" href="http://mtekk.us/code/breadcrumb-navxt/breadcrumb-navxt-doc/">', '</a>') . '</li><li>' .
195
+ sprintf(__('%sReport a Bug%s: If you think you have found a bug, please include your WordPress version and details on how to reproduce the bug.', $this->identifier),'<a title="' . __('Go to the Breadcrumb NavXT support post for your version.', 'breadcrumb_navxt') . '" href="http://mtekk.us/archives/wordpress/plugins-wordpress/breadcrumb-navxt-' . $this->version . '/#respond">', '</a>') . '</li></ul>' .
196
+ '<h5>' . __('Giving Back', $this->identifier) . '</h5><ul><li>' .
197
+ sprintf(__('%sDonate%s: Love Breadcrumb NavXT and want to help development? Consider buying the author a beer.', $this->identifier),'<a title="' . __('Go to PayPal to give a donation to Breadcrumb NavXT.', 'breadcrumb_navxt') . '" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=FD5XEU783BR8U&lc=US&item_name=Breadcrumb%20NavXT%20Donation&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted">', '</a>') . '</li><li>' .
198
+ sprintf(__('%sTranslate%s: Is your language not available? Contact John Havlik to get translating.', $this->identifier),'<a title="' . __('Go to the Breadcrumb NavXT support post for your version.', 'breadcrumb_navxt') . '" href="">', '</a>') . '</li></ul>';
199
+
200
+ $screen->add_help_tab(
201
+ array(
202
+ 'id' => $this->identifier . '-base',
203
+ 'title' => __('General', $this->identifier),
204
+ 'content' => $general_tab
205
+ ));
206
+ $quickstart_tab = '<p>' . __('For the settings on this page to take effect, you must either use the included Breadcrumb NavXT widget, or place either of the code sections below into your theme.', 'breadcrumb_navxt') .
207
+ '</p><h5>' . __('Breadcrumb trail with separators', 'breadcrumb_navxt') . '</h5><pre><code>&lt;div class="breadcrumbs"&gt;' . "
208
+ &lt;?php if(function_exists('bcn_display'))
209
  {
210
+ bcn_display();
211
+ }?&gt;
212
+ &lt;/div&gt;</code></pre>" .
213
+ '<h5>' . __('Breadcrumb trail in list form', 'breadcrumb_navxt').'</h5><pre><code>&lt;ol class="breadcrumbs"&gt;'."
214
+ &lt;?php if(function_exists('bcn_display_list'))
 
 
 
 
215
  {
216
+ bcn_display_list();
217
+ }?&gt;
218
+ &lt;/ol&gt;</code></pre>";
219
+ $screen->add_help_tab(
220
+ array(
221
+ 'id' => $this->identifier . '-quick-start',
222
+ 'title' => __('Quick Start', $this->identifier),
223
+ 'content' => $quickstart_tab
224
+ ));
225
+ $styling_tab = '<p>' . __('Using the code from the Quick Start section above, the following CSS can be used as base for styling your breadcrumb trail.', $this->identifier) . '</p>' .
226
+ '<pre><code>.breadcrumbs
227
+ {
228
+ font-size: 1.1em;
229
+ color: #fff;
230
+ margin: 30px 0 0 10px;
231
+ position: relative;
232
+ float: left;
233
+ }</code></pre>';
234
+ $screen->add_help_tab(
235
+ array(
236
+ 'id' => $this->identifier . '-styling',
237
+ 'title' => __('Styling', $this->identifier),
238
+ 'content' => $styling_tab
239
+ ));
240
+ $screen->add_help_tab(
241
+ array(
242
+ 'id' => $this->identifier . '-import-export-reset',
243
+ 'title' => __('Import/Export/Reset', $this->identifier),
244
+ 'content' => $this->import_form()
245
+ ));
246
+ }
247
  }
248
  /**
249
+ * enqueue's the tab style sheet on the settings page
 
 
250
  */
251
+ function admin_styles()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  {
253
+ wp_enqueue_style('mtekk_adminkit_tabs');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  }
255
  /**
256
+ * enqueue's the tab js and translation js on the settings page
257
  */
258
+ function admin_scripts()
259
+ {
260
+ //Enqueue ui-tabs
261
+ wp_enqueue_script('jquery-ui-tabs');
262
+ //Enqueue the admin tabs javascript
263
+ wp_enqueue_script('mtekk_adminkit_tabs');
264
+ //Load the translations for the tabs
265
+ wp_localize_script('mtekk_adminkit_tabs', 'objectL10n', array(
266
+ 'mtad_uid' => 'bcn_admin',
267
+ 'mtad_import' => __('Import', $this->identifier),
268
+ 'mtad_export' => __('Export', $this->identifier),
269
+ 'mtad_reset' => __('Reset', $this->identifier),
270
+ ));
 
 
 
 
 
271
  }
272
  /**
273
  * The administrative page for Breadcrumb NavXT
 
274
  */
275
  function admin_page()
276
  {
277
  global $wp_taxonomies, $wp_post_types;
278
+ $this->security();
279
+ //Let's call the parent version of the page, will handle our setting stuff
280
+ parent::admin_page();
281
+ ?>
282
+ <div class="wrap"><h2><?php _e('Breadcrumb NavXT Settings', 'breadcrumb_navxt'); ?></h2>
283
  <?php
284
  //We exit after the version check if there is an action the user needs to take before saving settings
285
+ if(!$this->version_check(get_option($this->unique_prefix . '_version')))
286
  {
287
  return;
288
  }
294
  <h3><?php _e('General', 'breadcrumb_navxt'); ?></h3>
295
  <table class="form-table">
296
  <?php
297
+ $this->input_text(__('Breadcrumb Separator', 'breadcrumb_navxt'), 'hseparator', '32', false, __('Placed in between each breadcrumb.', 'breadcrumb_navxt'));
298
+ $this->input_text(__('Breadcrumb Max Title Length', 'breadcrumb_navxt'), 'amax_title_length', '10');
299
  ?>
300
  <tr valign="top">
301
  <th scope="row">
303
  </th>
304
  <td>
305
  <label>
306
+ <input name="bcn_options[bhome_display]" type="checkbox" id="bhome_display" value="true" <?php checked(true, $this->opt['bhome_display']); ?> />
307
  <?php _e('Place the home breadcrumb in the trail.', 'breadcrumb_navxt'); ?>
308
  </label><br />
309
  <ul>
310
  <li>
311
+ <label for="Shome_title">
312
  <?php _e('Home Title: ','breadcrumb_navxt');?>
313
+ <input type="text" name="bcn_options[Shome_title]" id="Shome_title" value="<?php echo esc_html($this->opt['Shome_title'], ENT_COMPAT, 'UTF-8'); ?>" size="20" />
314
  </label>
315
  </li>
316
  </ul>
317
  </td>
318
  </tr>
319
  <?php
320
+ $this->input_text(__('Home Template', 'breadcrumb_navxt'), 'Hhome_template', '64', false, __('The template for the home breadcrumb.', 'breadcrumb_navxt'));
321
+ $this->input_text(__('Home Template (Unlinked)', 'breadcrumb_navxt'), 'Hhome_template_no_anchor', '64', false, __('The template for the home breadcrumb, used when the breadcrumb is not linked.', 'breadcrumb_navxt'));
322
+ $this->input_check(__('Blog Breadcrumb', 'breadcrumb_navxt'), 'bblog_display', __('Place the blog breadcrumb in the trail.', 'breadcrumb_navxt'), (get_option('show_on_front') !== "page"));
323
+ $this->input_text(__('Blog Template', 'breadcrumb_navxt'), 'Hblog_template', '64', (get_option('show_on_front') !== "page"), __('The template for the blog breadcrumb, used only in static front page environments.', 'breadcrumb_navxt'));
324
+ $this->input_text(__('Blog Template (Unlinked)', 'breadcrumb_navxt'), 'Hblog_template_no_anchor', '64', (get_option('show_on_front') !== "page"), __('The template for the blog breadcrumb, used only in static front page environments and when the breadcrumb is not linked.', 'breadcrumb_navxt'));
325
  ?>
326
  <tr valign="top">
327
  <th scope="row">
329
  </th>
330
  <td>
331
  <label>
332
+ <input name="bcn_options[bmainsite_display]" type="checkbox" id="bmainsite_display" <?php if(!is_multisite()){echo 'disabled="disabled" class="disabled"';}?> value="true" <?php checked(true, $this->opt['bmainsite_display']); ?> />
333
  <?php _e('Place the main site home breadcrumb in the trail in an multisite setup.', 'breadcrumb_navxt'); ?>
334
  </label><br />
335
  <ul>
336
  <li>
337
+ <label for="Smainsite_title">
338
+ <?php _e('Main Site Home Title: ', 'breadcrumb_navxt');?>
339
+ <input type="text" name="bcn_options[Smainsite_title]" id="Smainsite_title" <?php if(!is_multisite()){echo 'disabled="disabled" class="disabled"';}?> value="<?php echo htmlentities($this->opt['Smainsite_title'], ENT_COMPAT, 'UTF-8'); ?>" size="20" />
340
+ <?php if(!is_multisite()){?><input type="hidden" name="bcn_options[Smainsite_title]" value="<?php echo htmlentities($this->opt['Smainsite_title'], ENT_COMPAT, 'UTF-8');?>" /><?php } ?>
341
  </label>
342
  </li>
343
  </ul>
344
  </td>
345
  </tr>
346
  <?php
347
+ $this->input_text(__('Main Site Home Template', 'breadcrumb_navxt'), 'Hmainsite_template', '64', !is_multisite(), __('The template for the main site home breadcrumb, used only in multisite environments.', 'breadcrumb_navxt'));
348
+ $this->input_text(__('Main Site Home Template (Unlinked)', 'breadcrumb_navxt'), 'Hmainsite_template_no_anchor', '64', !is_multisite(), __('The template for the main site home breadcrumb, used only in multisite environments and when the breadcrumb is not linked.', 'breadcrumb_navxt'));
349
+ ?>
 
350
  </table>
351
  </fieldset>
352
  <fieldset id="current" class="bcn_options">
353
  <h3><?php _e('Current Item', 'breadcrumb_navxt'); ?></h3>
354
  <table class="form-table">
355
  <?php
356
+ $this->input_check(__('Link Current Item', 'breadcrumb_navxt'), 'bcurrent_item_linked', __('Yes'));
357
+ $this->input_text(__('Current Item Template', 'breadcrumb_navxt'), 'Hcurrent_item_template', '64', false, __('The template for current item breadcrumbs.', 'breadcrumb_navxt'));
358
+ $this->input_text(__('Current Item Template (Unlinked)', 'breadcrumb_navxt'), 'Hcurrent_item_template_no_anchor', '64', false, __('The template for current item breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
359
+ $this->input_check(__('Paged Breadcrumb', 'breadcrumb_navxt'), 'bpaged_display', __('Include the paged breadcrumb in the breadcrumb trail.', 'breadcrumb_navxt'), false, __('Indicates that the user is on a page other than the first on paginated posts/pages.', 'breadcrumb_navxt'));
360
+ $this->input_text(__('Paged Template', 'breadcrumb_navxt'), 'Hpaged_template', '64', false, __('The template for paged breadcrumbs.', 'breadcrumb_navxt'));
 
 
361
  ?>
362
  </table>
363
  </fieldset>
365
  <h3><?php _e('Posts &amp; Pages', 'breadcrumb_navxt'); ?></h3>
366
  <table class="form-table">
367
  <?php
368
+ $this->input_text(__('Post Template', 'breadcrumb_navxt'), 'Hpost_post_template', '64', false, __('The template for post breadcrumbs.', 'breadcrumb_navxt'));
369
+ $this->input_text(__('Post Template (Unlinked)', 'breadcrumb_navxt'), 'Hpost_post_template_no_anchor', '64', false, __('The template for post breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
370
+ $this->input_check(__('Post Taxonomy Display', 'breadcrumb_navxt'), 'bpost_post_taxonomy_display', __('Show the taxonomy leading to a post in the breadcrumb trail.', 'breadcrumb_navxt'));
 
371
  ?>
372
  <tr valign="top">
373
  <th scope="row">
375
  </th>
376
  <td>
377
  <?php
378
+ $this->input_radio('Spost_post_taxonomy_type', 'category', __('Categories'));
379
+ $this->input_radio('Spost_post_taxonomy_type', 'date', __('Dates'));
380
+ $this->input_radio('Spost_post_taxonomy_type', 'post_tag', __('Tags'));
381
+ $this->input_radio('Spost_post_taxonomy_type', 'page', __('Pages'));
382
  //Loop through all of the taxonomies in the array
383
  foreach($wp_taxonomies as $taxonomy)
384
  {
385
  //We only want custom taxonomies
386
  if(($taxonomy->object_type == 'post' || is_array($taxonomy->object_type) && in_array('post', $taxonomy->object_type)) && !$taxonomy->_builtin)
387
  {
388
+ $this->input_radio('Spost_post_taxonomy_type', $taxonomy->name, mb_convert_case(__($taxonomy->label), MB_CASE_TITLE, 'UTF-8'));
389
  }
390
  }
391
  ?>
393
  </td>
394
  </tr>
395
  <?php
396
+ $this->input_text(__('Page Template', 'breadcrumb_navxt'), 'Hpost_page_template', '64', false, __('The template for page breadcrumbs.', 'breadcrumb_navxt'));
397
+ $this->input_text(__('Page Template (Unlinked)', 'breadcrumb_navxt'), 'Hpost_page_template_no_anchor', '64', false, __('The template for page breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
398
+ $this->input_text(__('Attachment Template', 'breadcrumb_navxt'), 'Hpost_attachment_template', '64', false, __('The template for attachment breadcrumbs.', 'breadcrumb_navxt'));
399
+ $this->input_text(__('Attachment Template (Unlinked)', 'breadcrumb_navxt'), 'Hpost_attachment_template_no_anchor', '64', false, __('The template for attachment breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
 
400
  ?>
401
  </table>
402
  </fieldset>
408
  if(!$post_type->_builtin)
409
  {
410
  //If the post type does not have settings in the options array yet, we need to load some defaults
411
+ if(!array_key_exists('Hpost_' . $post_type->name . '_template', $this->opt) || !$post_type->hierarchical && !array_key_exists('Spost_' . $post_type->name . '_taxonomy_type', $this->opt))
412
  {
413
  //Add the necessary option array members
414
+ $this->opt['Hpost_' . $post_type->name . '_template'] = __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt');
415
+ $this->opt['Hpost_' . $post_type->name . '_template_no_anchor'] = __('%htitle%', 'breadcrumb_navxt');
416
+ $this->opt['bpost_' . $post_type->name . '_archive_display'] = $post_type->has_archive;
417
  //Do type dependent tasks
418
  if($post_type->hierarchical)
419
  {
420
  //Set post_root for hierarchical types
421
+ $this->opt['apost_' . $post_type->name . '_root'] = get_option('page_on_front');
422
  }
423
  //If it is flat, we need a taxonomy selection
424
  else
425
  {
426
  //Set post_root for flat types
427
+ $this->opt['apost_' . $post_type->name . '_root'] = get_option('page_for_posts');
428
  //Default to not displaying a taxonomy
429
+ $this->opt['bpost_' . $post_type->name . '_taxonomy_display'] = false;
430
  //Loop through all of the possible taxonomies
431
  foreach($wp_taxonomies as $taxonomy)
432
  {
433
  //Activate the first taxonomy valid for this post type and exit the loop
434
  if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type))
435
  {
436
+ $this->opt['bpost_' . $post_type->name . '_taxonomy_display'] = true;
437
+ $this->opt['Spost_' . $post_type->name . '_taxonomy_type'] = $taxonomy->name;
438
  break;
439
  }
440
  }
441
  //If there are no valid taxonomies for this type, we default to not displaying taxonomies for this post type
442
+ if(!isset($this->opt['Spost_' . $post_type->name . '_taxonomy_type']))
443
  {
444
+ $this->opt['Spost_' . $post_type->name . '_taxonomy_type'] = 'date';
445
  }
446
  }
447
  }?>
449
  <h3><?php echo $post_type->labels->singular_name; ?></h3>
450
  <table class="form-table">
451
  <?php
452
+ $this->input_text(sprintf(__('%s Template', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'Hpost_' . $post_type->name . '_template', '64', false, sprintf(__('The template for %s breadcrumbs.', 'breadcrumb_navxt'), strtolower(__($post_type->labels->singular_name))));
453
+ $this->input_text(sprintf(__('%s Template (Unlinked)', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'Hpost_' . $post_type->name . '_template_no_anchor', '64', false, sprintf(__('The template for %s breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'), strtolower(__($post_type->labels->singular_name))));
454
+ $optid = $this->get_valid_id('apost_' . $post_type->name . '_root');
 
455
  ?>
456
  <tr valign="top">
457
  <th scope="row">
458
  <label for="<?php echo $optid;?>"><?php printf(__('%s Root Page', 'breadcrumb_navxt'), $post_type->labels->singular_name);?></label>
459
  </th>
460
  <td>
461
+ <?php wp_dropdown_pages(array('name' => $this->unique_prefix . '_options[apost_' . $post_type->name . '_root]', 'id' => $optid, 'echo' => 1, 'show_option_none' => __( '&mdash; Select &mdash;' ), 'option_none_value' => '0', 'selected' => $this->opt['apost_' . $post_type->name . '_root']));?>
462
  </td>
463
  </tr>
464
  <?php
465
+ $this->input_check(sprintf(__('%s Archive Display', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'bpost_' . $post_type->name . '_archive_display', sprintf(__('Show the breadcrumb for the %s post type archives in the breadcrumb trail.', 'breadcrumb_navxt'), strtolower(__($post_type->labels->singular_name))), !$post_type->has_archive);
466
  //If it is flat, we need a taxonomy selection
467
  if(!$post_type->hierarchical)
468
  {
469
+ $this->input_check(sprintf(__('%s Taxonomy Display', 'breadcrumb_navxt'), $post_type->labels->singular_name), 'bpost_' . $post_type->name . '_taxonomy_display', sprintf(__('Show the taxonomy leading to a %s in the breadcrumb trail.', 'breadcrumb_navxt'), strtolower(__($post_type->labels->singular_name))));
470
  ?>
471
  <tr valign="top">
472
  <th scope="row">
474
  </th>
475
  <td>
476
  <?php
477
+ $this->input_radio('Spost_' . $post_type->name . '_taxonomy_type', 'date', __('Dates'));
478
+ $this->input_radio('Spost_' . $post_type->name . '_taxonomy_type', 'page', __('Pages'));
479
  //Loop through all of the taxonomies in the array
480
  foreach($wp_taxonomies as $taxonomy)
481
  {
482
  //We only want custom taxonomies
483
  if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type))
484
  {
485
+ $this->input_radio('Spost_' . $post_type->name . '_taxonomy_type', $taxonomy->name, $taxonomy->labels->singular_name);
486
  }
487
  }
488
  ?>
495
  <?php
496
  }
497
  }?>
498
+ <fieldset id="tax" class="bcn_options alttab">
499
+ <h3><?php _e('Categories &amp; Tags', 'breadcrumb_navxt'); ?></h3>
 
 
 
 
 
 
 
 
 
 
 
 
500
  <table class="form-table">
501
  <?php
502
+ $this->input_text(__('Category Template', 'breadcrumb_navxt'), 'Hcategory_template', '64', false, __('The template for category breadcrumbs.', 'breadcrumb_navxt'));
503
+ $this->input_text(__('Category Template (Unlinked)', 'breadcrumb_navxt'), 'Hcategory_template_no_anchor', '64', false, __('The template for category breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
504
+ $this->input_text(__('Tag Template', 'breadcrumb_navxt'), 'Hpost_tag_template', '64', false, __('The template for tag breadcrumbs.', 'breadcrumb_navxt'));
505
+ $this->input_text(__('Tag Template (Unlinked)', 'breadcrumb_navxt'), 'Hpost_tag_template_no_anchor', '64', false, __('The template for tag breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
 
506
  ?>
507
  </table>
508
  </fieldset>
514
  if(!$taxonomy->_builtin)
515
  {
516
  //If the taxonomy does not have settings in the options array yet, we need to load some defaults
517
+ if(!array_key_exists('H' . $taxonomy->name . '_template', $this->opt))
518
  {
519
  //Add the necessary option array members
520
+ $this->opt['H' . $taxonomy->name . '_template'] = __(sprintf('<a title="Go to the %%title%% %s archives." href="%%link%%">%%htitle%%</a>', $taxonomy->labels->singular_name), 'breadcrumb_navxt');
521
+ $this->opt['H' . $taxonomy->name . '_template_no_anchor'] = __(sprintf('%%htitle%%', $taxonomy->labels->singular_name), 'breadcrumb_navxt');
 
 
 
522
  }
523
  ?>
524
+ <fieldset id="<?php echo $taxonomy->name; ?>" class="bcn_options alttab">
525
  <h3><?php echo mb_convert_case(__($taxonomy->label), MB_CASE_TITLE, 'UTF-8'); ?></h3>
526
  <table class="form-table">
527
  <?php
528
+ $this->input_text(sprintf(__('%s Template', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), 'H' . $taxonomy->name . '_template', '64', false, sprintf(__('The template for %s breadcrumbs.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
529
+ $this->input_text(sprintf(__('%s Template (Unlinked)', 'breadcrumb_navxt'), $taxonomy->labels->singular_name), 'H' . $taxonomy->name . '_template_no_anchor', '64', false, sprintf(__('The template for %s breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'), strtolower(__($taxonomy->label))));
 
 
 
530
  ?>
531
  </table>
532
  </fieldset>
534
  }
535
  }
536
  ?>
 
 
 
 
 
 
 
 
 
 
537
  <fieldset id="miscellaneous" class="bcn_options">
538
  <h3><?php _e('Miscellaneous', 'breadcrumb_navxt'); ?></h3>
539
  <table class="form-table">
540
  <?php
541
+ $this->input_text(__('Author Template', 'breadcrumb_navxt'), 'Hauthor_template', '64', false, __('The template for author breadcrumbs.', 'breadcrumb_navxt'));
542
+ $this->input_text(__('Author Template (Unlinked)', 'breadcrumb_navxt'), 'Hauthor_template_no_anchor', '64', false, __('The template for author breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
543
+ $this->input_select(__('Author Display Format', 'breadcrumb_navxt'), 'Sauthor_name', array("display_name", "nickname", "first_name", "last_name"), false, __('display_name uses the name specified in "Display name publicly as" under the user profile the others correspond to options in the user profile.', 'breadcrumb_navxt'));
544
+ $this->input_text(__('Date Template', 'breadcrumb_navxt'), 'Hdate_template', '64', false, __('The template for date breadcrumbs.', 'breadcrumb_navxt'));
545
+ $this->input_text(__('Date Template (Unlinked)', 'breadcrumb_navxt'), 'Hdate_template_no_anchor', '64', false, __('The template for date breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb_navxt'));
546
+ $this->input_text(__('Search Template', 'breadcrumb_navxt'), 'Hsearch_template', '64', false, __('The anchor template for search breadcrumbs, used only when the search results span several pages.', 'breadcrumb_navxt'));
547
+ $this->input_text(__('Search Template (Unlinked)', 'breadcrumb_navxt'), 'Hsearch_template_no_anchor', '64', false, __('The anchor template for search breadcrumbs, used only when the search results span several pages and the breadcrumb is not linked.', 'breadcrumb_navxt'));
548
+ $this->input_text(__('404 Title', 'breadcrumb_navxt'), 'S404_title', '32');
549
+ $this->input_text(__('404 Template', 'breadcrumb_navxt'), 'H404_template', '64', false, __('The template for 404 breadcrumbs.', 'breadcrumb_navxt'));
550
  ?>
551
  </table>
552
  </fieldset>
553
  </div>
554
  <p class="submit"><input type="submit" class="button-primary" name="bcn_admin_options" value="<?php esc_attr_e('Save Changes') ?>" /></p>
555
  </form>
556
+ <?php
557
+ //Need to add a separate menu thing for this
558
+ $this->import_form(); ?>
559
  </div>
560
  <?php
561
  }
562
+ function opts_update_prebk(&$opts)
563
+ {
564
+ //Add custom post types
565
+ $this->find_posttypes($this->opt);
566
+ //Add custom taxonomy types
567
+ $this->find_taxonomies($this->opt);
568
+ }
569
  /**
570
  * Places settings into $opts array, if missing, for the registered post types
571
  *
572
+ * @param array $opts
573
  */
574
  function find_posttypes(&$opts)
575
  {
581
  if(!$post_type->_builtin)
582
  {
583
  //If the post type does not have settings in the options array yet, we need to load some defaults
584
+ if(!array_key_exists('Hpost_' . $post_type->name . '_template', $opts) || !$post_type->hierarchical && !array_key_exists('Spost_' . $post_type->name . '_taxonomy_type', $opts))
585
  {
586
  //Add the necessary option array members
587
+ $opts['Hpost_' . $post_type->name . '_template'] = __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt');
588
+ $opts['Hpost_' . $post_type->name . '_template_no_anchor'] = __('%htitle%', 'breadcrumb_navxt');
589
+ $opts['bpost_' . $post_type->name . '_archive_display'] = $post_type->has_archive;
590
  //Do type dependent tasks
591
  if($post_type->hierarchical)
592
  {
593
  //Set post_root for hierarchical types
594
+ $opts['apost_' . $post_type->name . '_root'] = get_option('page_on_front');
595
  }
596
  //If it is flat, we need a taxonomy selection
597
  else
598
  {
599
  //Set post_root for flat types
600
+ $opts['apost_' . $post_type->name . '_root'] = get_option('page_for_posts');
601
+ //Default to not displaying a taxonomy
602
+ $opts['bpost_' . $post_type->name . '_taxonomy_display'] = false;
603
  //Loop through all of the possible taxonomies
604
  foreach($wp_taxonomies as $taxonomy)
605
  {
606
  //Activate the first taxonomy valid for this post type and exit the loop
607
  if($taxonomy->object_type == $post_type->name || in_array($post_type->name, $taxonomy->object_type))
608
  {
609
+ $opts['bpost_' . $post_type->name . '_taxonomy_display'] = true;
610
+ $opts['Spost_' . $post_type->name . '_taxonomy_type'] = $taxonomy->name;
611
  break;
612
  }
613
  }
614
  //If there are no valid taxonomies for this type, we default to not displaying taxonomies for this post type
615
+ if(!isset($opts['Spost_' . $post_type->name . '_taxonomy_type']))
616
  {
617
+ $opts['Spost_' . $post_type->name . '_taxonomy_type'] = 'date';
618
  }
619
  }
620
  }
636
  if(!$taxonomy->_builtin)
637
  {
638
  //If the taxonomy does not have settings in the options array yet, we need to load some defaults
639
+ if(!array_key_exists('H' . $taxonomy->name . '_template', $opts))
640
  {
641
+ //Add the necessary option array members
642
+ $opts['H' . $taxonomy->name . '_template'] = __(sprintf('<a title="Go to the %%title%% %s archives." href="%%link%%">%%htitle%%</a>', $taxonomy->labels->singular_name), 'breadcrumb_navxt');
643
+ $opts['H' . $taxonomy->name . '_template_no_anchor'] = __(sprintf('%%htitle%%', $taxonomy->labels->singular_name), 'breadcrumb_navxt');
 
 
644
  }
645
  }
646
  }
647
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  /**
649
  * Outputs the breadcrumb trail
650
  *
654
  */
655
  function display($return = false, $linked = true, $reverse = false)
656
  {
 
 
 
657
  //Grab the current settings from the db
658
+ $this->breadcrumb_trail->opt = wp_parse_args(get_option('bcn_options'), $this->breadcrumb_trail->opt);
659
  //Generate the breadcrumb trail
660
  $this->breadcrumb_trail->fill();
661
  return $this->breadcrumb_trail->display($return, $linked, $reverse);
670
  */
671
  function display_list($return = false, $linked = true, $reverse = false)
672
  {
 
 
 
673
  //Grab the current settings from the db
674
+ $this->breadcrumb_trail->opt = wp_parse_args(get_option('bcn_options'), $this->breadcrumb_trail->opt);
675
  //Generate the breadcrumb trail
676
  $this->breadcrumb_trail->fill();
677
  return $this->breadcrumb_trail->display_list($return, $linked, $reverse);
678
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
679
  }
680
  //Let's make an instance of our object takes care of everything
681
  $bcn_admin = new bcn_admin;
708
  {
709
  return $bcn_admin->display_list($return, $linked, $reverse);
710
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
711
  }
breadcrumb_navxt_class.php CHANGED
@@ -23,73 +23,64 @@ class bcn_breadcrumb
23
  //Our member variables
24
  //The main text that will be shown
25
  protected $title;
 
 
 
 
26
  //Boolean, is this element linked
27
  protected $linked;
28
- //Linked anchor contents, null if $linked == false
29
- protected $anchor;
30
- //Global prefix, outside of link tags
31
- protected $prefix;
32
- //Global suffix, outside of link tags
33
- protected $suffix;
 
34
  //The type of this breadcrumb
35
  public $type;
36
  /**
37
- * The enhanced default constructor
38
- *
39
- * @return
40
- * @param string $title[optional]
41
- * @param string $prefix[optional]
42
- * @param string $suffix[optional]
43
- * @param string $anchor[optional]
44
- * @param bool $linked[optional]
45
  */
46
- public function bcn_breadcrumb($title = '', $prefix = '', $suffix = '', $anchor = NULL, $linked = false)
47
  {
48
  //Set the title
49
- $this->title = __($title, 'breadcrumb_navxt');
50
- //Set the prefix
51
- $this->prefix = __($prefix, 'breadcrumb_navxt');
52
- //Set the suffix
53
- $this->suffix = __($suffix, 'breadcrumb_navxt');
54
- //Default state of unlinked
55
- $this->linked = $linked;
 
 
 
 
 
 
 
 
 
56
  //Always NULL if unlinked
57
- $this->anchor = $anchor;
58
- //null out the type, it's not fully used yet
59
- $this->type = NULL;
60
  }
61
  /**
62
  * Function to set the protected title member
63
  *
64
- * @param string $title
65
  */
66
  public function set_title($title)
67
  {
68
  //Set the title
69
  $this->title = apply_filters('bcn_breadcrumb_title', __($title, 'breadcrumb_navxt'));
70
  }
71
- /**
72
- * Function to set the protected prefix member
73
- *
74
- * @param string $prefix
75
- */
76
- public function set_prefix($prefix)
77
- {
78
- //Set the prefix
79
- $this->prefix = __($prefix, 'breadcrumb_navxt');
80
- }
81
- /**
82
- * Function to set the protected suffix member
83
- *
84
- * @param string $suffix
85
- */
86
- public function set_suffix($suffix)
87
- {
88
- //Set the suffix
89
- $this->suffix = __($suffix, 'breadcrumb_navxt');
90
- }
91
  /**
92
  * Function to get the protected title member
 
93
  * @return $this->title
94
  */
95
  public function get_title()
@@ -98,41 +89,37 @@ class bcn_breadcrumb
98
  return $this->title;
99
  }
100
  /**
101
- * Function to get the protected prefix member
102
- * @return $this->prefix
 
103
  */
104
- public function get_prefix()
105
  {
106
- //Return the prefix
107
- return $this->prefix;
 
 
 
 
108
  }
109
  /**
110
- * Function to get the protected suffix member
111
- * @return $this->suffix
 
112
  */
113
- public function get_suffix()
114
  {
115
- //Return the suffix
116
- return $this->suffix;
117
  }
118
  /**
119
- * Sets the anchor attribute for the breadcrumb, will set $linked to true
120
- *
121
- * @param string $template the anchor template to use
122
- * @param string $url the url to replace the %link% tag in the anchor
123
  *
 
124
  */
125
- public function set_anchor($template, $url)
126
  {
127
- //Set a safe tempalte if none was specified
128
- if($template == '')
129
- {
130
- $template = __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt');
131
- }
132
- //Set the anchor, we strip tangs from the title to prevent html validation problems
133
- $this->anchor = str_replace('%title%', strip_tags($this->title), str_replace('%link%', $url, __($template, 'breadcrumb_navxt')));
134
- //Set linked to true since we called this function
135
- $this->linked = true;
136
  }
137
  /**
138
  * This function will intelligently trim the title to the value passed in through $max_length.
@@ -146,7 +133,7 @@ class bcn_breadcrumb
146
  {
147
  //Trim the title
148
  $this->title = mb_substr($this->title, 0, $max_length - 1);
149
- //Make sure we can split at a space, but we want to limmit to cutting at max an additional 25%
150
  if(mb_strpos($this->title, ' ', .75 * $max_length) > 0)
151
  {
152
  //Don't split mid word
@@ -162,25 +149,35 @@ class bcn_breadcrumb
162
  /**
163
  * Assembles the parts of the breadcrumb into a html string
164
  *
 
165
  * @return string The compiled breadcrumb string
166
- * @param bool $linked[optional] Allow the output to contain anchors?
167
  */
168
  public function assemble($linked = true)
169
  {
170
- //Place in the breadcrumb's elements
171
- $breadcrumb_str = $this->prefix;
172
- //If we are linked we'll need to do up the link
173
- if($this->linked && $linked && $this->anchor)
 
 
 
 
 
 
 
 
 
 
174
  {
175
- $breadcrumb_str .= $this->anchor . $this->title . '</a>';
 
176
  }
177
- //Otherwise we just slip in the title
178
  else
179
  {
180
- $breadcrumb_str .= $this->title;
 
181
  }
182
- //Return the assembled string
183
- return $breadcrumb_str . $this->suffix;
184
  }
185
  }
186
 
@@ -188,7 +185,7 @@ class bcn_breadcrumb
188
  class bcn_breadcrumb_trail
189
  {
190
  //Our member variables
191
- public $version = '3.9.0';
192
  //An array of breadcrumbs
193
  public $trail = array();
194
  //The options
@@ -199,132 +196,111 @@ class bcn_breadcrumb_trail
199
  //Load the translation domain as the next part needs it
200
  load_plugin_textdomain($domain = 'breadcrumb_navxt', false, 'breadcrumb-navxt/languages');
201
  //Initilize with default option values
202
- $this->opt = array
203
- (
204
  //Should the mainsite be shown
205
- 'mainsite_display' => true,
206
  //Title displayed when for the main site
207
- 'mainsite_title' => __('Home', 'breadcrumb_navxt'),
208
- //The anchor template for the main site, this is global, two keywords are available %link% and %title%
209
- 'mainsite_anchor' => __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt'),
210
- //The prefix for mainsite breadcrumbs, placed inside of current_item prefix
211
- 'mainsite_prefix' => '',
212
- //The prefix for mainsite breadcrumbs, placed inside of current_item prefix
213
- 'mainsite_suffix' => '',
214
  //Should the home page be shown
215
- 'home_display' => true,
216
  //Title displayed when is_home() returns true
217
- 'home_title' => __('Blog', 'breadcrumb_navxt'),
218
- //The anchor template for the home page, this is global, two keywords are available %link% and %title%
219
- 'home_anchor' => __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt'),
 
 
220
  //Should the blog page be shown globally
221
- 'blog_display' => true,
222
- //The anchor template for the blog page only in static front page mode, this is global, two keywords are available %link% and %title%
223
- 'blog_anchor' => __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt'),
224
- //The prefix for home breadcrumbs, placed inside of current_item prefix
225
- 'home_prefix' => '',
226
- //The suffix for home breadcrumbs, placed inside of current_item suffix
227
- 'home_suffix' => '',
228
  //Separator that is placed between each item in the breadcrumb trial, but not placed before
229
  //the first and not after the last breadcrumb
230
- 'separator' => ' &gt; ',
231
  //The maximum title lenght
232
- 'max_title_length' => 0,
233
  //Current item options, really only applies to static pages and posts unless other current items are linked
234
- 'current_item_linked' => false,
235
- //The anchor template for current items, this is global, two keywords are available %link% and %title%
236
- 'current_item_anchor' => __('<a title="Reload the current page." href="%link%">', 'breadcrumb_navxt'),
237
- //The prefix for current items allows separate styling of the current location breadcrumb
238
- 'current_item_prefix' => '',
239
- //The suffix for current items allows separate styling of the current location breadcrumb
240
- 'current_item_suffix' => '',
241
  //Static page options
242
- //The prefix for page breadcrumbs, place on all page elements and inside of current_item prefix
243
- 'post_page_prefix' => '',
244
- //The suffix for page breadcrumbs, place on all page elements and inside of current_item suffix
245
- 'post_page_suffix' => '',
246
- //The anchor template for page breadcrumbs, two keywords are available %link% and %title%
247
- 'post_page_anchor' => __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt'),
248
  //Just a link to the page on front property
249
- 'post_page_root' => get_option('page_on_front'),
250
  //Paged options
251
- //The prefix for paged breadcrumbs, place on all page elements and inside of current_item prefix
252
- 'paged_prefix' => '',
253
- //The suffix for paged breadcrumbs, place on all page elements and inside of current_item suffix
254
- 'paged_suffix' => '',
255
  //Should we try filling out paged information
256
- 'paged_display' => false,
257
  //The post options previously singleblogpost
258
- //The prefix for post breadcrumbs, place on all page elements and inside of current_item prefix
259
- 'post_post_prefix' => '',
260
- //The suffix for post breadcrumbs, place on all page elements and inside of current_item suffix
261
- 'post_post_suffix' => '',
262
- //The anchor template for post breadcrumbs, two keywords are available %link% and %title%
263
- 'post_post_anchor' => __('<a title="Go to %title%." href="%link%">', 'breadcrumb_navxt'),
264
  //Just a link for the page for posts
265
- 'post_post_root' => get_option('page_for_posts'),
266
  //Should the trail include the taxonomy of the post
267
- 'post_post_taxonomy_display' => true,
268
  //What taxonomy should be shown leading to the post, tag or category
269
- 'post_post_taxonomy_type' => 'category',
270
  //Attachment settings
271
- //The prefix for attachment breadcrumbs, place on all page elements and inside of current_item prefix
272
- 'attachment_prefix' => '',
273
- //The suffix for attachment breadcrumbs, place on all page elements and inside of current_item suffix
274
- 'attachment_suffix' => '',
 
275
  //404 page settings
276
- //The prefix for 404 breadcrumbs, place on all page elements and inside of current_item prefix
277
- '404_prefix' => '',
278
- //The suffix for 404 breadcrumbs, place on all page elements and inside of current_item suffix
279
- '404_suffix' => '',
280
  //The text to be shown in the breadcrumb for a 404 page
281
- '404_title' => __('404', 'breadcrumb_navxt'),
282
  //Search page options
283
- //The prefix for search breadcrumbs, place on all page elements and inside of current_item prefix
284
- 'search_prefix' => __('Search results for &#39;', 'breadcrumb_navxt'),
285
- //The suffix for search breadcrumbs, place on all page elements and inside of current_item suffix
286
- 'search_suffix' => '&#39;',
287
- //The anchor template for search breadcrumbs, two keywords are available %link% and %title%
288
- 'search_anchor' => __('<a title="Go to the first page of search results for %title%." href="%link%">', 'breadcrumb_navxt'),
289
  //Tag related stuff
290
- //The prefix for tag breadcrumbs, place on all page elements and inside of current_item prefix
291
- 'post_tag_prefix' => '',
292
- //The suffix for tag breadcrumbs, place on all page elements and inside of current_item suffix
293
- 'post_tag_suffix' => '',
294
- //The anchor template for tag breadcrumbs, two keywords are available %link% and %title%
295
- 'post_tag_anchor' => __('<a title="Go to the %title% tag archives." href="%link%">', 'breadcrumb_navxt'),
296
  //Author page stuff
297
- //The prefix for author breadcrumbs, place on all page elements and inside of current_item prefix
298
- 'author_prefix' => __('Articles by: ', 'breadcrumb_navxt'),
299
- //The suffix for author breadcrumbs, place on all page elements and inside of current_item suffix
300
- 'author_suffix' => '',
301
- //The anchor template for author breadcrumbs, two keywords are available %link% and %title%
302
- 'author_anchor' => __('<a title="Go to the first page of posts by %title%." href="%link%">', 'breadcrumb_navxt'),
303
  //Which of the various WordPress display types should the author breadcrumb display
304
- 'author_name' => 'display_name',
305
  //Category stuff
306
- //The prefix for category breadcrumbs, place on all page elements and inside of current_item prefix
307
- 'category_prefix' => '',
308
- //The suffix for category breadcrumbs, place on all page elements and inside of current_item suffix
309
- 'category_suffix' => '',
310
- //The anchor template for category breadcrumbs, two keywords are available %link% and %title%
311
- 'category_anchor' => __('<a title="Go to the %title% category archives." href="%link%">', 'breadcrumb_navxt'),
312
- //Archives related settings
313
- //Prefix for category archives, place inside of both the current_item prefix and the category_prefix
314
- 'archive_category_prefix' => __('Archive by category &#39;', 'breadcrumb_navxt'),
315
- //Suffix for category archives, place inside of both the current_item suffix and the category_suffix
316
- 'archive_category_suffix' => '&#39;',
317
- //Prefix for tag archives, place inside of the current_item prefix
318
- 'archive_post_tag_prefix' => __('Archive by tag &#39;', 'breadcrumb_navxt'),
319
- //Suffix for tag archives, place inside of the current_item suffix
320
- 'archive_post_tag_suffix' => '&#39;',
321
- 'date_anchor' => __('<a title="Go to the %title% archives." href="%link%">', 'breadcrumb_navxt'),
322
- //Prefix for date archives, place inside of the current_item prefix
323
- 'archive_date_prefix' => '',
324
- //Suffix for date archives, place inside of the current_item suffix
325
- 'archive_date_suffix' => ''
326
  );
327
  }
 
 
 
 
 
 
 
 
 
328
  /**
329
  * Adds a breadcrumb to the breadcrumb trail
330
  *
@@ -344,16 +320,17 @@ class bcn_breadcrumb_trail
344
  */
345
  function do_search()
346
  {
347
- global $s;
348
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
349
- $breadcrumb = $this->add(new bcn_breadcrumb(esc_html($s), $this->opt['search_prefix'], $this->opt['search_suffix']));
350
- //If we're paged, let's link to the first page
351
- if(is_paged() && $this->opt['paged_display'])
352
  {
 
 
353
  //Figure out the hyperlink for the anchor
354
- $url = get_settings('home') . '?s=' . str_replace(' ', '+', esc_html($s));
355
  //Figure out the anchor for the search
356
- $breadcrumb->set_anchor($this->opt['search_anchor'], $url);
357
  }
358
  }
359
  /**
@@ -369,16 +346,18 @@ class bcn_breadcrumb_trail
369
  //Setup array of valid author_name values
370
  $valid_author_name = array('display_name', 'nickname', 'first_name', 'last_name');
371
  //This translation allows us to easily select the display type later on
372
- $author_name = $this->opt['author_name'];
373
  //Make sure user picks only safe values
374
  if(in_array($author_name, $valid_author_name))
375
  {
376
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
377
- $breadcrumb = $this->add(new bcn_breadcrumb(apply_filters('the_author', $curauth->$author_name),
378
- $this->opt['author_prefix'], $this->opt['author_suffix']));
379
- if(is_paged() && $this->opt['paged_display'])
380
  {
381
- $breadcrumb->set_anchor($this->opt['author_anchor'], get_author_posts_url($curauth->ID));
 
 
382
  }
383
  }
384
  }
@@ -387,23 +366,26 @@ class bcn_breadcrumb_trail
387
  *
388
  * This function fills breadcrumbs for any post taxonomy.
389
  * @param int $id The id of the post to figure out the taxonomy for.
390
- * @param sting $type The post type of the post to figure out the taxonomy for.
 
 
 
391
  */
392
- function post_taxonomy($id, $type)
393
  {
394
  //Check to see if breadcrumbs for the taxonomy of the post needs to be generated
395
- if($this->opt['post_' . $type . '_taxonomy_display'])
396
  {
397
  //Check if we have a date 'taxonomy' request
398
- if($this->opt['post_' . $type . '_taxonomy_type'] == 'date')
399
  {
400
  $this->do_archive_by_date();
401
  }
402
  //Handle all hierarchical taxonomies, including categories
403
- else if(is_taxonomy_hierarchical($this->opt['post_' . $type . '_taxonomy_type']))
404
  {
405
  //Fill a temporary object with the terms
406
- $bcn_object = get_the_terms($id, $this->opt['post_' . $type . '_taxonomy_type']);
407
  if(is_array($bcn_object))
408
  {
409
  //Now find which one has a parent, pick the first one that does
@@ -419,24 +401,30 @@ class bcn_breadcrumb_trail
419
  }
420
  }
421
  //Fill out the term hiearchy
422
- $this->term_parents($bcn_object[$bcn_use_term]->term_id, $this->opt['post_' . $type . '_taxonomy_type']);
423
  }
424
  }
425
  //Handle the use of hierarchical posts as the 'taxonomy'
426
- else if(is_post_type_hierarchical($this->opt['post_' . $type . '_taxonomy_type']))
427
  {
 
 
 
 
 
 
428
  //Done with the current item, now on to the parents
429
  $bcn_frontpage = get_option('page_on_front');
430
  //If there is a parent page let's find it
431
- if($post->post_parent && $id != $post->post_parent && $bcn_frontpage != $post->post_parent)
432
  {
433
- $this->post_parents($post->post_parent, $bcn_frontpage);
434
  }
435
  }
436
  //Handle the rest of the taxonomies, including tags
437
  else
438
  {
439
- $this->post_terms($id, $this->opt['post_' . $type . '_taxonomy_type']);
440
  }
441
  }
442
  }
@@ -447,7 +435,8 @@ class bcn_breadcrumb_trail
447
  * @param int $id The id of the post to find the terms for.
448
  * @param string $taxonomy The name of the taxonomy that the term belongs to
449
  *
450
- * @TODO Need to implement this cleaner, fix up the entire tag_ thing, as this is now generic
 
451
  */
452
  function post_terms($id, $taxonomy)
453
  {
@@ -472,15 +461,17 @@ class bcn_breadcrumb_trail
472
  $bcn_breadcrumb->set_title($bcn_breadcrumb->get_title() . ', ');
473
  }
474
  //This is a bit hackish, but it compiles the term anchor and appends it to the current breadcrumb title
475
- $bcn_breadcrumb->set_title($bcn_breadcrumb->get_title() . $this->opt[$taxonomy . '_prefix'] . str_replace('%title%', $term->name, str_replace('%link%', get_term_link($term, $taxonomy), $this->opt[$taxonomy . '_anchor'])) .
476
- $term->name . '</a>' . $this->opt[$taxonomy . '_suffix']);
 
 
477
  $is_first = false;
478
  }
479
  }
480
  else
481
  {
482
  //If there are no tags, then we set the title to "Untagged"
483
- $bcn_breadcrumb->set_title(__('Un' . $taxonomy->name, 'breadcrumb_navxt'));
484
  }
485
  }
486
  /**
@@ -489,16 +480,15 @@ class bcn_breadcrumb_trail
489
  * This recursive functions fills the trail with breadcrumbs for parent terms.
490
  * @param int $id The id of the term.
491
  * @param string $taxonomy The name of the taxonomy that the term belongs to
 
492
  */
493
  function term_parents($id, $taxonomy)
494
  {
495
  global $post;
496
  //Get the current category object, filter applied within this call
497
  $term = &get_term($id, $taxonomy);
498
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
499
- $breadcrumb = $this->add(new bcn_breadcrumb($term->name, $this->opt[$taxonomy . '_prefix'], $this->opt[$taxonomy . '_suffix']));
500
- //Figure out the anchor for the term
501
- $breadcrumb->set_anchor($this->opt[$taxonomy . '_anchor'], get_term_link($term, $taxonomy));
502
  //Make sure the id is valid, and that we won't end up spinning in a loop
503
  if($term->parent && $term->parent != $id)
504
  {
@@ -517,11 +507,8 @@ class bcn_breadcrumb_trail
517
  {
518
  //Use WordPress API, though a bit heavier than the old method, this will ensure compatibility with other plug-ins
519
  $parent = get_post($id);
520
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
521
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title($id), $this->opt['post_' . $parent->post_type . '_prefix'],
522
- $this->opt['post_' . $parent->post_type . '_suffix']));
523
- //Assign the anchor properties
524
- $breadcrumb->set_anchor($this->opt['post_' . $parent->post_type . '_anchor'], get_permalink($id));
525
  //Make sure the id is valid, and that we won't end up spinning in a loop
526
  if($parent->post_parent >= 0 && $parent->post_parent != false && $id != $parent->post_parent && $frontpage != $parent->post_parent)
527
  {
@@ -532,52 +519,59 @@ class bcn_breadcrumb_trail
532
  /**
533
  * A Breadcrumb Trail Filling Function
534
  *
535
- * This functions fills a breadcrumb for a hierarchical post/page.
 
536
  */
537
- function do_post_hierarchical()
538
  {
539
  global $post, $page;
540
- //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, prefix, and suffix
541
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title(), $this->opt['post_' . $post->post_type . '_prefix'], $this->opt['post_' . $post->post_type . '_suffix']));
542
- if($page > 0 && $this->opt['paged_display'])
 
543
  {
544
- $breadcrumb->set_anchor($this->opt['post_page_anchor'], get_permalink());
 
 
 
545
  }
546
- //Done with the current item, now on to the parents
547
- $bcn_frontpage = get_option('page_on_front');
548
- //If there is a parent page let's find it
549
- if($post->post_parent && $post->ID != $post->post_parent && $bcn_frontpage != $post->post_parent)
550
  {
551
- $this->post_parents($post->post_parent, $bcn_frontpage);
 
 
 
 
 
 
552
  }
553
- }
554
- /**
555
- * A Breadcrumb Trail Filling Function
556
- *
557
- * This functions fills a breadcrumb for a post.
558
- */
559
- function do_post_flat()
560
- {
561
- global $post, $page;
562
- //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, prefix, and suffix
563
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title(), $this->opt['post_' . $post->post_type . '_prefix'], $this->opt['post_' . $post->post_type . '_suffix']));
564
- if($page > 0 && $this->opt['paged_display'])
565
  {
566
- $breadcrumb->set_anchor($this->opt['post_post_anchor'], get_permalink());
 
567
  }
568
- //Handle the post's taxonomy
569
- $this->post_taxonomy($post->ID, $post->post_type);
570
  }
571
  /**
572
  * A Breadcrumb Trail Filling Function
573
  *
574
  * This functions fills a breadcrumb for an attachment page.
 
 
575
  */
576
  function do_attachment()
577
  {
578
  global $post;
579
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
580
- $this->trail[] = new bcn_breadcrumb(get_the_title(), $this->opt['attachment_prefix'], $this->opt['attachment_suffix']);
 
 
 
 
 
 
 
581
  //Get the parent's information
582
  $parent = get_post($post->post_parent);
583
  //We need to treat flat and hiearchical post attachment hierachies differently
@@ -590,11 +584,8 @@ class bcn_breadcrumb_trail
590
  }
591
  else
592
  {
593
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
594
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title($post->post_parent),
595
- $this->opt['post_post_prefix'], $this->opt['post_post_suffix']));
596
- //Assign the anchor properties
597
- $breadcrumb->set_anchor($this->opt['post_post_anchor'], get_permalink($post->post_parent));
598
  //Handle the post's taxonomy
599
  $this->post_taxonomy($post->post_parent, $parent->post_type);
600
  }
@@ -602,23 +593,24 @@ class bcn_breadcrumb_trail
602
  /**
603
  * A Breadcrumb Trail Filling Function
604
  *
605
- * This functions fills a breadcrumb for a hierarchical taxonomy (e.g. category) archive.
 
606
  */
607
- function do_archive_by_term_hierarchical()
608
  {
609
  global $wp_query;
610
  //Simmilar to using $post, but for things $post doesn't cover
611
  $term = $wp_query->get_queried_object();
612
  //Run through a filter for good measure
613
  $term->name = apply_filters('get_' . $term->taxonomy, $term->name);
614
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
615
- $breadcrumb = $this->add(new bcn_breadcrumb($term->name, $this->opt[$term->taxonomy . '_prefix'] . $this->opt['archive_' . $term->taxonomy . '_prefix'],
616
- $this->opt['archive_' . $term->taxonomy . '_suffix'] . $this->opt[$term->taxonomy . '_suffix']));
617
  //If we're paged, let's link to the first page
618
- if(is_paged() && $this->opt['paged_display'])
619
  {
 
620
  //Figure out the anchor for current category
621
- $breadcrumb->set_anchor($this->opt[$term->taxonomy . '_anchor'], get_term_link($term, $term->taxonomy));
622
  }
623
  //Get parents of current category
624
  if($term->parent)
@@ -626,32 +618,11 @@ class bcn_breadcrumb_trail
626
  $this->term_parents($term->parent, $term->taxonomy);
627
  }
628
  }
629
- /**
630
- * A Breadcrumb Trail Filling Function
631
- *
632
- * This functions fills a breadcrumb for a flat taxonomy (e.g. tag) archive.
633
- */
634
- function do_archive_by_term_flat()
635
- {
636
- global $wp_query;
637
- //Simmilar to using $post, but for things $post doesn't cover
638
- $term = $wp_query->get_queried_object();
639
- //Run through a filter for good measure
640
- $term->name = apply_filters('get_' . $term->taxonomy, $term->name);
641
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
642
- $breadcrumb = $this->add(new bcn_breadcrumb($term->name, $this->opt['archive_' . $term->taxonomy . '_prefix'] . $this->opt[$term->taxonomy . '_prefix'],
643
- $this->opt[$term->taxonomy . '_suffix'] . $this->opt['archive_' . $term->taxonomy . '_suffix']));
644
- //If we're paged, let's link to the first page
645
- if(is_paged() && $this->opt['paged_display'])
646
- {
647
- //Figure out the anchor for current category
648
- $breadcrumb->set_anchor($this->opt[$term->taxonomy . '_anchor'], get_term_link($term, $term->taxonomy));
649
- }
650
- }
651
  /**
652
  * A Breadcrumb Trail Filling Function
653
  *
654
  * This functions fills a breadcrumb for a date archive.
 
655
  */
656
  function do_archive_by_date()
657
  {
@@ -660,33 +631,70 @@ class bcn_breadcrumb_trail
660
  if(is_day() || is_single())
661
  {
662
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
663
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_time('d'), $this->opt['archive_date_prefix'], $this->opt['archive_date_suffix']));
 
 
 
 
 
664
  //If we're paged, let's link to the first page
665
- if(is_paged() && $this->opt['paged_display'] || is_single())
666
  {
 
 
667
  //Deal with the anchor
668
- $breadcrumb->set_anchor($this->opt['date_anchor'], get_day_link(get_the_time('Y'), get_the_time('m'), get_the_time('d')));
669
  }
670
  }
671
  //Now deal with the month breadcrumb
672
  if(is_month() || is_day() || is_single())
673
  {
674
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
675
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_time('F'), $this->opt['archive_date_prefix'], $this->opt['archive_date_suffix']));
 
 
 
 
 
676
  //If we're paged, or not in the archive by month let's link to the first archive by month page
677
- if(is_day() || is_single() || (is_month() && is_paged() && $this->opt['paged_display']))
678
  {
 
 
679
  //Deal with the anchor
680
- $breadcrumb->set_anchor($this->opt['date_anchor'], get_month_link(get_the_time('Y'), get_the_time('m')));
681
  }
682
  }
683
  //Place the year breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
684
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_time('Y'), $this->opt['archive_date_prefix'], $this->opt['archive_date_suffix']));
 
 
 
 
 
685
  //If we're paged, or not in the archive by year let's link to the first archive by year page
686
- if(is_day() || is_month() || is_single() || (is_paged() && $this->opt['paged_display']))
687
  {
 
 
688
  //Deal with the anchor
689
- $breadcrumb->set_anchor($this->opt['date_anchor'], get_year_link(get_the_time('Y')));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
  }
691
  }
692
  /**
@@ -698,24 +706,45 @@ class bcn_breadcrumb_trail
698
  {
699
  global $post, $current_site;
700
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
701
- $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['home_title'], $this->opt['home_prefix'], $this->opt['home_suffix']));
 
 
 
 
 
 
 
702
  //If we have a multi site and are not on the main site we may need to add a breadcrumb for the main site
703
- if($this->opt['mainsite_display'] && !is_main_site())
704
  {
705
  //Place the main site breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
706
- $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['mainsite_title'], $this->opt['mainsite_prefix'], $this->opt['mainsite_suffix']));
707
- //Deal with the anchor
708
- $breadcrumb->set_anchor($this->opt['mainsite_anchor'], get_home_url($current_site->blog_id));
709
  }
710
- //If we're paged, let's link to the first page
711
- if(is_paged() && $this->opt['paged_display'])
 
 
 
 
 
 
 
 
 
712
  {
713
- //Figure out the anchor for home page
714
- $breadcrumb->set_anchor($this->opt['home_anchor'], get_home_url());
 
 
 
 
 
 
715
  }
716
  }
717
  /**
718
  * A modified version of WordPress' function of the same name
 
719
  * @param object $object the post or taxonomy object used to attempt to find the title
720
  * @return string the title
721
  */
@@ -738,11 +767,24 @@ class bcn_breadcrumb_trail
738
  return $type->_builtin;
739
  }
740
  /**
741
- * A Breadcrumb Trail Filling Function
742
  *
743
- * This functions fills a breadcrumb for the home page.
 
744
  */
745
- function do_home()
 
 
 
 
 
 
 
 
 
 
 
 
746
  {
747
  global $post, $wp_query, $wp_taxonomies, $current_site;
748
  //Simmilar to using $post, but for things $post doesn't cover
@@ -750,51 +792,56 @@ class bcn_breadcrumb_trail
750
  //We need to do special things for custom post types
751
  if(is_singular() && !$this->is_builtin($type->post_type))
752
  {
 
 
753
  //This will assign a ID for root page of a custom post
754
- if(is_numeric($this->opt['post_' . $type->post_type . '_root']))
755
  {
756
- $posts_id = $this->opt['post_' . $type->post_type . '_root'];
757
  }
758
  }
759
- //We need to do special things for custom post type archives, but not author or date archives
760
- else if(is_archive() && !is_author() && !is_date() && !is_post_type_archive() && !$this->is_builtin($wp_taxonomies[$type->taxonomy]->object_type[0]))
761
- //else if((is_tax() || is_category() || is_tag()) && !$this->is_builtin($wp_taxonomies[$type->taxonomy]->object_type[0]))
762
  {
 
 
763
  //This will assign a ID for root page of a custom post's taxonomy archive
764
- if(is_numeric($this->opt['post_' . $wp_taxonomies[$type->taxonomy]->object_type[0] . '_root']))
765
  {
766
- $posts_id = $this->opt['post_' . $wp_taxonomies[$type->taxonomy]->object_type[0] . '_root'];
767
  }
768
  }
769
- if(is_post_type_archive())
 
770
  {
771
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
772
- $breadcrumb = $this->add(new bcn_breadcrumb(post_type_archive_title('', false), $this->opt['post_page_prefix'],
773
- $this->opt['post_page_suffix']));
774
- if(is_paged() && $this->opt['paged_display'])
775
  {
776
- //Deal with the anchor
777
- $breadcrumb->set_anchor($this->opt['blog_anchor'], get_post_type_archive_link(get_post_type()));
778
  }
779
  }
780
- else if(isset($type->post_type) && !$this->is_builtin($type->post_type))
 
 
 
 
 
781
  {
782
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
783
- $breadcrumb = $this->add(new bcn_breadcrumb($this->post_type_archive_title(get_post_type_object($type->post_type)), $this->opt['post_page_prefix'],
784
- $this->opt['post_page_suffix']));
785
- //Deal with the anchor
786
- $breadcrumb->set_anchor($this->opt['blog_anchor'], get_post_type_archive_link($type->post_type));
787
  }
788
- else if(isset($type->taxonomy) && !$this->is_builtin($wp_taxonomies[$type->taxonomy]->object_type[0]))
789
  {
 
 
790
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
791
- $breadcrumb = $this->add(new bcn_breadcrumb($this->post_type_archive_title(get_post_type_object($wp_taxonomies[$type->taxonomy]->object_type[0])), $this->opt['post_page_prefix'],
792
- $this->opt['post_page_suffix']));
793
- //Deal with the anchor
794
- $breadcrumb->set_anchor($this->opt['blog_anchor'], get_post_type_archive_link($wp_taxonomies[$type->taxonomy]->object_type[0]));
795
  }
796
  //We only need the "blog" portion on members of the blog, and only if we're in a static frontpage environment
797
- if(isset($posts_id) || $this->opt['blog_display'] && get_option('show_on_front') == 'page' && (is_home() || is_post_type_archive() || is_single() || is_tax() || is_category() || is_tag()))
 
798
  {
799
  //If we entered here with a posts page, we need to set the id
800
  if(!isset($posts_id))
@@ -807,17 +854,19 @@ class bcn_breadcrumb_trail
807
  {
808
  //Get the blog page
809
  $bcn_post = get_post($posts_id);
810
- if(!is_post_type_archive())
 
 
 
811
  {
812
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
813
- $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title($posts_id), $this->opt['post_page_prefix'],
814
- $this->opt['post_page_suffix']));
815
- //If we're not on the current item we need to setup the anchor
816
- if(!is_home()|| (is_paged() && $this->opt['paged_display']))
817
- {
818
- //Deal with the anchor
819
- $breadcrumb->set_anchor($this->opt['blog_anchor'], get_permalink($posts_id));
820
- }
821
  }
822
  //Done with the "root", now on to the parents
823
  //If there is a parent post let's find it
@@ -827,22 +876,6 @@ class bcn_breadcrumb_trail
827
  }
828
  }
829
  }
830
- //On everything else we need to link, but no current item (pre/suf)fixes
831
- if($this->opt['home_display'])
832
- {
833
- //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
834
- $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['home_title'], $this->opt['home_prefix'], $this->opt['home_suffix']));
835
- //Deal with the anchor
836
- $breadcrumb->set_anchor($this->opt['home_anchor'], get_home_url());
837
- //If we have a multi site and are not on the main site we need to add a breadcrumb for the main site
838
- if($this->opt['mainsite_display'] && !is_main_site())
839
- {
840
- //Place the main site breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
841
- $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['mainsite_title'], $this->opt['mainsite_prefix'], $this->opt['mainsite_suffix']));
842
- //Deal with the anchor
843
- $breadcrumb->set_anchor($this->opt['mainsite_anchor'], get_home_url($current_site->blog_id));
844
- }
845
- }
846
  }
847
  /**
848
  * A Breadcrumb Trail Filling Function
@@ -852,7 +885,7 @@ class bcn_breadcrumb_trail
852
  function do_404()
853
  {
854
  //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, prefix, and suffix
855
- $this->trail[] = new bcn_breadcrumb($this->opt['404_title'], $this->opt['404_prefix'], $this->opt['404_suffix']);
856
  }
857
  /**
858
  * A Breadcrumb Trail Filling Function
@@ -872,7 +905,7 @@ class bcn_breadcrumb_trail
872
  $page_number = $page;
873
  }
874
  //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, prefix, and suffix
875
- $this->trail[] = new bcn_breadcrumb($page_number, $this->opt['paged_prefix'], $this->opt['paged_suffix']);
876
  }
877
  /**
878
  * Breadcrumb Trail Filling Function
@@ -890,11 +923,9 @@ class bcn_breadcrumb_trail
890
  }
891
  //Do any actions if necessary, we past through the current object instance to keep life simple
892
  do_action('bcn_before_fill', $this);
893
- //Need to grab the queried object here as multiple branches need it
894
- $queried_object = $wp_query->get_queried_object();
895
  //Do specific opperations for the various page types
896
  //Check if this isn't the first of a multi paged item
897
- if($this->opt['paged_display'] && (is_paged() || is_singular() && $page > 0))
898
  {
899
  $this->do_paged();
900
  }
@@ -902,7 +933,7 @@ class bcn_breadcrumb_trail
902
  if(is_front_page())
903
  {
904
  //Must have two seperate branches so that we don't evaluate it as a page
905
- if($this->opt['home_display'])
906
  {
907
  $this->do_front_page();
908
  }
@@ -910,20 +941,15 @@ class bcn_breadcrumb_trail
910
  //For posts
911
  else if(is_singular())
912
  {
913
- //For hierarchical posts
914
- if(is_page() || (is_post_type_hierarchical($queried_object->post_type) && !is_home()))
915
- {
916
- $this->do_post_hierarchical();
917
- }
918
  //For attachments
919
- else if(is_attachment())
920
  {
921
  $this->do_attachment();
922
  }
923
- //For flat posts
924
  else
925
  {
926
- $this->do_post_flat();
927
  }
928
  }
929
  //For searches
@@ -944,23 +970,14 @@ class bcn_breadcrumb_trail
944
  {
945
  $this->do_archive_by_date();
946
  }
947
- /*else if(is_post_type_archive($queried_object->name))
948
  {
949
- echo "moo";
950
- }*/
951
  //For taxonomy based archives
952
  else if(is_category() || is_tag() || is_tax())
953
  {
954
- //For hierarchical taxonomy based archives
955
- if(is_taxonomy_hierarchical($queried_object->taxonomy))
956
- {
957
- $this->do_archive_by_term_hierarchical();
958
- }
959
- //For flat taxonomy based archives
960
- else
961
- {
962
- $this->do_archive_by_term_flat();
963
- }
964
  }
965
  }
966
  //For 404 pages
@@ -971,6 +988,7 @@ class bcn_breadcrumb_trail
971
  //We always do the home link last, unless on the frontpage
972
  if(!is_front_page())
973
  {
 
974
  $this->do_home();
975
  }
976
  //Do any actions if necessary, we past through the current object instance to keep life simple
@@ -995,31 +1013,6 @@ class bcn_breadcrumb_trail
995
  krsort($this->trail);
996
  }
997
  }
998
- /**
999
- * Performs actions specific to current item breadcrumbs. It will wrap the prefix/suffix
1000
- * with the current_item_prefix and current_item_suffix. Additionally, it will link the
1001
- * current item if current_item_linked is set to true.
1002
- *
1003
- * @param bcn_breadrumb $breadcrumb pointer to a bcn_breadcrumb object to opperate on
1004
- */
1005
- function current_item($breadcrumb)
1006
- {
1007
- //We are misusing the breadcrumb type property here, but in 4.0 this will be unnecessary
1008
- if($breadcrumb->type == null)
1009
- {
1010
- //Prepend the current item prefix
1011
- $breadcrumb->set_prefix($this->opt['current_item_prefix'] . $breadcrumb->get_prefix());
1012
- //Append the current item suffix
1013
- $breadcrumb->set_suffix($breadcrumb->get_suffix() . $this->opt['current_item_suffix']);
1014
- //Set the breadcrumb's type to current_item
1015
- $breadcrumb->type = 'current_item';
1016
- //Link the current item, if required
1017
- if($this->opt['current_item_linked'])
1018
- {
1019
- $breadcrumb->set_anchor($this->opt['current_item_anchor'], '');
1020
- }
1021
- }
1022
- }
1023
  /**
1024
  * This functions outputs or returns the breadcrumb trail in string form.
1025
  *
@@ -1036,7 +1029,7 @@ class bcn_breadcrumb_trail
1036
  //Initilize the string which will hold the assembled trail
1037
  $trail_str = '';
1038
  //The main compiling loop
1039
- foreach($this->trail as $key=>$breadcrumb)
1040
  {
1041
  //Must branch if we are reversing the output or not
1042
  if($reverse)
@@ -1044,7 +1037,7 @@ class bcn_breadcrumb_trail
1044
  //Add in the separator only if we are the 2nd or greater element
1045
  if($key > 0)
1046
  {
1047
- $trail_str .= $this->opt['separator'];
1048
  }
1049
  }
1050
  else
@@ -1052,19 +1045,14 @@ class bcn_breadcrumb_trail
1052
  //Only show the separator when necessary
1053
  if($key < count($this->trail) - 1)
1054
  {
1055
- $trail_str .= $this->opt['separator'];
1056
  }
1057
  }
1058
- //If we are on the current item there are some things that must be done
1059
- if($key === 0)
1060
- {
1061
- $this->current_item($breadcrumb);
1062
- }
1063
  //Trim titles, if needed
1064
- if($this->opt['max_title_length'] > 0)
1065
  {
1066
  //Trim the breadcrumb's title
1067
- $breadcrumb->title_trim($this->opt['max_title_length']);
1068
  }
1069
  //Place in the breadcrumb's assembled elements
1070
  $trail_str .= $breadcrumb->assemble($linked);
@@ -1076,7 +1064,7 @@ class bcn_breadcrumb_trail
1076
  }
1077
  else
1078
  {
1079
- //Giving credit where credit is due, please don't remove it
1080
  $credits = "<!-- Breadcrumb NavXT " . $this->version . " -->\n";
1081
  echo $credits . $trail_str;
1082
  }
@@ -1089,6 +1077,8 @@ class bcn_breadcrumb_trail
1089
  * @param bool $return Whether to return data or to echo it.
1090
  * @param bool $linked[optional] Whether to allow hyperlinks in the trail or not.
1091
  * @param bool $reverse[optional] Whether to reverse the output or not.
 
 
1092
  */
1093
  function display_list($return = false, $linked = true, $reverse = false)
1094
  {
@@ -1097,7 +1087,7 @@ class bcn_breadcrumb_trail
1097
  //Initilize the string which will hold the assembled trail
1098
  $trail_str = '';
1099
  //The main compiling loop
1100
- foreach($this->trail as $key=>$breadcrumb)
1101
  {
1102
  $trail_str .= '<li';
1103
  //On the first run we need to add in a class for the home breadcrumb
@@ -1113,15 +1103,14 @@ class bcn_breadcrumb_trail
1113
  //If we are on the current item there are some things that must be done
1114
  else if($key === 0)
1115
  {
1116
- $this->current_item($breadcrumb);
1117
  //Add in a class for current_item
1118
  $trail_str .= ' class="current_item"';
1119
  }
1120
  //Trim titles, if needed
1121
- if($this->opt['max_title_length'] > 0)
1122
  {
1123
  //Trim the breadcrumb's title
1124
- $breadcrumb->title_trim($this->opt['max_title_length']);
1125
  }
1126
  //Place in the breadcrumb's assembled elements
1127
  $trail_str .= '>' . $breadcrumb->assemble($linked);
@@ -1134,83 +1123,7 @@ class bcn_breadcrumb_trail
1134
  }
1135
  else
1136
  {
1137
- //Giving credit where credit is due, please don't remove it
1138
- $credits = "<!-- Breadcrumb NavXT " . $this->version . " -->\n";
1139
- echo $credits . $trail_str;
1140
- }
1141
- }
1142
- function nested_loop($linked, $tag, $mode)
1143
- {
1144
- //Grab the current breadcrumb from the trail, move the iterator forward one
1145
- if(list($key, $breadcrumb) = each($this->trail))
1146
- {
1147
- //If we are on the current item there are some things that must be done
1148
- if($key === 0)
1149
- {
1150
- $this->current_item($breadcrumb);
1151
- }
1152
- //Trim titles, if needed
1153
- if($this->opt['max_title_length'] > 0)
1154
- {
1155
- //Trim the breadcrumb's title
1156
- $breadcrumb->title_trim($this->opt['max_title_length']);
1157
- }
1158
- if($mode === 'rdfa')
1159
- {
1160
- return sprintf('%1$s<%2$s rel="v:child"><%2$s typeof="v:Breadcrumb">%3$s%4$s</%2$s></%2$s>', $this->opt['separator'], $tag, $breadcrumb->assemble($linked), $this->nested_loop($linked, $tag, $mode));
1161
- }
1162
- else
1163
- {
1164
- return sprintf('%1$s<%2$s itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">%3$s%4$s</%2$s>', $this->opt['separator'], $tag, $breadcrumb->assemble($linked), $this->nested_loop($linked, $tag, $mode));
1165
- }
1166
- }
1167
- else
1168
- {
1169
- return '';
1170
- }
1171
- }
1172
- /**
1173
- * Breadcrumb Creation Function
1174
- *
1175
- * This functions outputs or returns the breadcrumb trail in string form.
1176
- *
1177
- * @return void Void if Option to print out breadcrumb trail was chosen.
1178
- * @return string String-Data of breadcrumb trail.
1179
- * @param bool $return Whether to return data or to echo it.
1180
- * @param bool $linked[optional] Whether to allow hyperlinks in the trail or not.
1181
- * @param string $tag[optional] The tag to use for the nesting
1182
- * @param string $mode[optional] Whether to follow the rdfa or Microdata format
1183
- */
1184
- function display_nested($return = false, $linked = true, $tag = 'span', $mode = 'rdfa')
1185
- {
1186
- //Set trail order based on reverse flag
1187
- $this->order(false);
1188
- //Makesure the iterator is pointing to the first element
1189
- $breadcrumb = reset($this->trail);
1190
- //Trim titles, if needed
1191
- if($this->opt['max_title_length'] > 0)
1192
- {
1193
- //Trim the breadcrumb's title
1194
- $breadcrumb->title_trim($this->opt['max_title_length']);
1195
- }
1196
- if($mode === 'rdfa')
1197
- {
1198
- //Start up the recursive engine
1199
- $trail_str = sprintf('<%1$s typeof="v:Breadcrumb">%2$s %3$s</%1$s>', $tag, $breadcrumb->assemble($linked), $this->nested_loop($linked, $tag, $mode));
1200
- }
1201
- else
1202
- {
1203
- //Start up the recursive engine
1204
- $trail_str = sprintf('%2$s %3$s', $tag, $breadcrumb->assemble($linked), $this->nested_loop($linked, $tag, $mode));
1205
- }
1206
- //Should we return or echo the assembled trail?
1207
- if($return)
1208
- {
1209
- return $trail_str;
1210
- }
1211
- else
1212
- {
1213
- //Giving credit where credit is due, please don't remove it
1214
  $credits = "<!-- Breadcrumb NavXT " . $this->version . " -->\n";
1215
  echo $credits . $trail_str;
1216
  }
23
  //Our member variables
24
  //The main text that will be shown
25
  protected $title;
26
+ //The breadcrumb's template, used durring assembly
27
+ protected $template;
28
+ //The breadcrumb's no anchor template, used durring assembly when there won't be an anchor
29
+ protected $template_no_anchor = '%title%';
30
  //Boolean, is this element linked
31
  protected $linked;
32
+ //The link the breadcrumb leads to, null if $linked == false
33
+ protected $url;
34
+ protected $_tags = array(
35
+ '%title%',
36
+ '%link%',
37
+ '%htitle%',
38
+ '%type%');
39
  //The type of this breadcrumb
40
  public $type;
41
  /**
42
+ * The enhanced default constructor, ends up setting all parameters via the set_ functions
43
+ *
44
+ * @param string $title (optional) The title of the breadcrumb
45
+ * @param string $template (optional) The html template for the breadcrumb
46
+ * @param string $type (optional) The breadcrumb type
47
+ * @param string $url (optional) The url the breadcrumb links to
 
 
48
  */
49
+ public function bcn_breadcrumb($title = '', $template = '', $type = '', $url = NULL)
50
  {
51
  //Set the title
52
+ $this->set_title($title);
53
+ //Assign the breadcrumb template
54
+ if($template == NULL)
55
+ {
56
+ $template = __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt');
57
+ }
58
+ if($url == NULL)
59
+ {
60
+ $this->template_no_anchor = $template;
61
+ }
62
+ else
63
+ {
64
+ $this->template = $template;
65
+ }
66
+ //The breadcrumb type
67
+ $this->type = $type;
68
  //Always NULL if unlinked
69
+ $this->set_url($url);
 
 
70
  }
71
  /**
72
  * Function to set the protected title member
73
  *
74
+ * @param string $title The title of the breadcrumb
75
  */
76
  public function set_title($title)
77
  {
78
  //Set the title
79
  $this->title = apply_filters('bcn_breadcrumb_title', __($title, 'breadcrumb_navxt'));
80
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /**
82
  * Function to get the protected title member
83
+ *
84
  * @return $this->title
85
  */
86
  public function get_title()
89
  return $this->title;
90
  }
91
  /**
92
+ * Function to set the internal URL variable
93
+ *
94
+ * @param string $url the url to link to
95
  */
96
+ public function set_url($url)
97
  {
98
+ $this->url = $url;
99
+ //Set linked to true if we set a non-null $url
100
+ if($url)
101
+ {
102
+ $this->linked = true;
103
+ }
104
  }
105
  /**
106
+ * Sets the internal breadcrumb template
107
+ *
108
+ * @param string $template the template to use durring assebly
109
  */
110
+ public function set_template($template)
111
  {
112
+ //Assign the breadcrumb template
113
+ $this->template = $template;
114
  }
115
  /**
116
+ * Append a type entry to the type array
 
 
 
117
  *
118
+ * @param string $type the type to append
119
  */
120
+ public function add_type($type)
121
  {
122
+ $this->type[] = $type;
 
 
 
 
 
 
 
 
123
  }
124
  /**
125
  * This function will intelligently trim the title to the value passed in through $max_length.
133
  {
134
  //Trim the title
135
  $this->title = mb_substr($this->title, 0, $max_length - 1);
136
+ //Make sure we can split a, four keywords are available %link%, %title%, %htitle%, and %type%pace, but we want to limmit to cutting at max an additional 25%
137
  if(mb_strpos($this->title, ' ', .75 * $max_length) > 0)
138
  {
139
  //Don't split mid word
149
  /**
150
  * Assembles the parts of the breadcrumb into a html string
151
  *
152
+ * @param bool $linked (optional) Allow the output to contain anchors?
153
  * @return string The compiled breadcrumb string
 
154
  */
155
  public function assemble($linked = true)
156
  {
157
+ //var_dump($this);
158
+ //Build our replacements array
159
+ $replacements = array(
160
+ esc_attr(strip_tags($this->title)),
161
+ $this->url,
162
+ $this->title,
163
+ $this->type);
164
+ //The type may be an array, implode it if that is the case
165
+ if(is_array($replacements[3]))
166
+ {
167
+ $replacements[3] = implode(' ', $replacements[3]);
168
+ }
169
+ //If we are linked we'll need to use the normal template
170
+ if($this->linked && $linked)
171
  {
172
+ //Return the assembled breadcrumb string
173
+ return str_replace($this->_tags, $replacements, $this->template);
174
  }
175
+ //Otherwise we use the no anchor template
176
  else
177
  {
178
+ //Return the assembled breadcrumb string
179
+ return str_replace($this->_tags, $replacements, $this->template_no_anchor);
180
  }
 
 
181
  }
182
  }
183
 
185
  class bcn_breadcrumb_trail
186
  {
187
  //Our member variables
188
+ private $version = '3.99.80';
189
  //An array of breadcrumbs
190
  public $trail = array();
191
  //The options
196
  //Load the translation domain as the next part needs it
197
  load_plugin_textdomain($domain = 'breadcrumb_navxt', false, 'breadcrumb-navxt/languages');
198
  //Initilize with default option values
199
+ $this->opt = array(
 
200
  //Should the mainsite be shown
201
+ 'bmainsite_display' => true,
202
  //Title displayed when for the main site
203
+ 'Smainsite_title' => __('Home', 'breadcrumb_navxt'),
204
+ //The breadcrumb template for the main site, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
205
+ 'Hmainsite_template' => __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
206
+ //The breadcrumb template for the main site, used when an anchor is not needed, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
207
+ 'Hmainsite_template_no_anchor' => '%htitle%',
 
 
208
  //Should the home page be shown
209
+ 'bhome_display' => true,
210
  //Title displayed when is_home() returns true
211
+ 'Shome_title' => __('Home', 'breadcrumb_navxt'),
212
+ //The breadcrumb template for the home page, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
213
+ 'Hhome_template' => __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
214
+ //The breadcrumb template for the home page, used when an anchor is not needed, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
215
+ 'Hhome_template_no_anchor' => '%htitle%',
216
  //Should the blog page be shown globally
217
+ 'bblog_display' => true,
218
+ //The breadcrumb template for the blog page only in static front page mode, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
219
+ 'Hblog_template' => __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
220
+ //The breadcrumb template for the blog page only in static front page mode, used when an anchor is not needed, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
221
+ 'Hblog_template_no_anchor' => '%htitle%',
 
 
222
  //Separator that is placed between each item in the breadcrumb trial, but not placed before
223
  //the first and not after the last breadcrumb
224
+ 'hseparator' => ' &gt; ',
225
  //The maximum title lenght
226
+ 'amax_title_length' => 0,
227
  //Current item options, really only applies to static pages and posts unless other current items are linked
228
+ 'bcurrent_item_linked' => false,
229
+ //The breadcrumb template for current items, this is global, four keywords are available %link%, %title%, %htitle%, and %type%
230
+ 'Hcurrent_item_template' => __('<a title="Reload the current page." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
231
+ //The breadcrumb template for current items, used when an anchor is not needed, four keywords are available %link%, %title%, %htitle%, and %type%
232
+ 'Hcurrent_item_template_no_anchor' => '%htitle%',
 
 
233
  //Static page options
234
+ //The anchor template for page breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
235
+ 'Hpost_page_template' => __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
236
+ //The anchor template for page breadcrumbs, used when an anchor is not needed, four keywords are available %link%, %title%, %htitle%, and %type%
237
+ 'Hpost_page_template_no_anchor' => '%htitle%',
 
 
238
  //Just a link to the page on front property
239
+ 'apost_page_root' => get_option('page_on_front'),
240
  //Paged options
241
+ //The template for paged breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
242
+ 'Hpaged_template' => __('Page %htitle%', 'breadcrumb_navxt'),
 
 
243
  //Should we try filling out paged information
244
+ 'bpaged_display' => false,
245
  //The post options previously singleblogpost
246
+ //The breadcrumb template for post breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
247
+ 'Hpost_post_template' => __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
248
+ //The breadcrumb template for post breadcrumbs, used when an anchor is not needed, four keywords are available %link%, %title%, %htitle%, and %type%
249
+ 'Hpost_post_template_no_anchor' => '%htitle%',
 
 
250
  //Just a link for the page for posts
251
+ 'apost_post_root' => get_option('page_for_posts'),
252
  //Should the trail include the taxonomy of the post
253
+ 'bpost_post_taxonomy_display' => true,
254
  //What taxonomy should be shown leading to the post, tag or category
255
+ 'Spost_post_taxonomy_type' => 'category',
256
  //Attachment settings
257
+ //TODO: Need to move attachments to support via normal post handlers
258
+ //The breadcrumb template for attachment breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
259
+ 'Hpost_attachment_template' => __('<a title="Go to %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
260
+ //The breadcrumb template for attachment breadcrumbs, used when an anchor is not needed, four keywords are available %link%, %title%, %htitle%, and %type%
261
+ 'Hpost_attachment_template_no_anchor' => '%htitle%',
262
  //404 page settings
263
+ //The template for 404 breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
264
+ 'H404_template' => '%htitle%',
 
 
265
  //The text to be shown in the breadcrumb for a 404 page
266
+ 'S404_title' => __('404', 'breadcrumb_navxt'),
267
  //Search page options
268
+ //The breadcrumb template for search breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
269
+ 'Hsearch_template' => __('Search results for &#39;<a title="Go to the first page of search results for %title%." href="%link%">%htitle%</a>&#39;', 'breadcrumb_navxt'),
270
+ //The breadcrumb template for search breadcrumbs, used when an anchor is not necessary, four keywords are available %link%, %title%, %htitle%, and %type%
271
+ 'Hsearch_template_no_anchor' => __('Search results for &#39;%htitle%&#39;', 'breadcrumb_navxt'),
 
 
272
  //Tag related stuff
273
+ //The breadcrumb template for tag breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
274
+ 'Hpost_tag_template' => __('<a title="Go to the %title% tag archives." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
275
+ //The breadcrumb template for tag breadcrumbs, used when an anchor is not needed, four keywords are available %link%, %title%, %htitle%, and %type%
276
+ 'Hpost_tag_template_no_anchor' => '%htitle%',
 
 
277
  //Author page stuff
278
+ //The anchor template for author breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
279
+ 'Hauthor_template' => __('Articles by: <a title="Go to the first page of posts by %title%." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
280
+ //The anchor template for author breadcrumbs, used when anchors are not needed, four keywords are available %link%, %title%, %htitle%, and %type%
281
+ 'Hauthor_template_no_anchor' => __('Articles by: %htitle%', 'breadcrumb_navxt'),
 
 
282
  //Which of the various WordPress display types should the author breadcrumb display
283
+ 'Sauthor_name' => 'display_name',
284
  //Category stuff
285
+ //The breadcrumb template for category breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
286
+ 'Hcategory_template' => __('<a title="Go to the %title% category archives." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
287
+ //The breadcrumb template for category breadcrumbs, used when anchors are not needed, four keywords are available %link%, %title%, %htitle%, and %type%
288
+ 'Hcategory_template_no_anchor' => '%htitle%',
289
+ //The breadcrumb template for date breadcrumbs, four keywords are available %link%, %title%, %htitle%, and %type%
290
+ 'Hdate_template' => __('<a title="Go to the %title% archives." href="%link%">%htitle%</a>', 'breadcrumb_navxt'),
291
+ //The breadcrumb template for date breadcrumbs, used when anchors are not needed, four keywords are available %link%, %title%, %htitle%, and %type%
292
+ 'Hdate_template_no_anchor' => '%htitle%'
 
 
 
 
 
 
 
 
 
 
 
 
293
  );
294
  }
295
+ /**
296
+ * This returns the internal version
297
+ *
298
+ * @return string internal version of the Breadcrumb trail
299
+ */
300
+ public function get_version()
301
+ {
302
+ return $this->version;
303
+ }
304
  /**
305
  * Adds a breadcrumb to the breadcrumb trail
306
  *
320
  */
321
  function do_search()
322
  {
 
323
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
324
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_search_query(), $this->opt['Hsearch_template_no_anchor'], array('search', 'current-item')));
325
+ //If we're paged, or allowing the current item to be linked, let's link to the first page
326
+ if($this->opt['bcurrent_item_linked'] || (is_paged() && $this->opt['bpaged_display']))
327
  {
328
+ //Since we are paged and are linking the root breadcrumb, time to change to the regular template
329
+ $breadcrumb->set_template($this->opt['Hsearch_template']);
330
  //Figure out the hyperlink for the anchor
331
+ $url = get_option('home') . '?s=' . str_replace(' ', '+', get_search_query());
332
  //Figure out the anchor for the search
333
+ $breadcrumb->set_url($url);
334
  }
335
  }
336
  /**
346
  //Setup array of valid author_name values
347
  $valid_author_name = array('display_name', 'nickname', 'first_name', 'last_name');
348
  //This translation allows us to easily select the display type later on
349
+ $author_name = $this->opt['Sauthor_name'];
350
  //Make sure user picks only safe values
351
  if(in_array($author_name, $valid_author_name))
352
  {
353
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
354
+ $breadcrumb = $this->add(new bcn_breadcrumb(apply_filters('the_author', $curauth->$author_name), $this->opt['Hauthor_template_no_anchor'], array('author', 'current-item')));
355
+ //If we're paged, or allowing the current item to be linked, let's link to the first page
356
+ if($this->opt['bcurrent_item_linked'] || is_paged() && $this->opt['paged_display'])
357
  {
358
+ //Set the template to our one containing an anchor
359
+ $breadcrumb->set_template($this->opt['Hauthor_template']);
360
+ $breadcrumb->set_url(get_author_posts_url($curauth->ID));
361
  }
362
  }
363
  }
366
  *
367
  * This function fills breadcrumbs for any post taxonomy.
368
  * @param int $id The id of the post to figure out the taxonomy for.
369
+ * @param string $type The post type of the post to figure out the taxonomy for.
370
+ * @param int $parent (optional) The id of the parent of the current post, used if hiearchal posts will be the "taxonomy" for the current post
371
+ *
372
+ * TODO: Add logic for contextual taxonomy selection
373
  */
374
+ function post_taxonomy($id, $type, $parent = null)
375
  {
376
  //Check to see if breadcrumbs for the taxonomy of the post needs to be generated
377
+ if($this->opt['bpost_' . $type . '_taxonomy_display'])
378
  {
379
  //Check if we have a date 'taxonomy' request
380
+ if($this->opt['Spost_' . $type . '_taxonomy_type'] == 'date')
381
  {
382
  $this->do_archive_by_date();
383
  }
384
  //Handle all hierarchical taxonomies, including categories
385
+ else if(is_taxonomy_hierarchical($this->opt['Spost_' . $type . '_taxonomy_type']))
386
  {
387
  //Fill a temporary object with the terms
388
+ $bcn_object = get_the_terms($id, $this->opt['Spost_' . $type . '_taxonomy_type']);
389
  if(is_array($bcn_object))
390
  {
391
  //Now find which one has a parent, pick the first one that does
401
  }
402
  }
403
  //Fill out the term hiearchy
404
+ $this->term_parents($bcn_object[$bcn_use_term]->term_id, $this->opt['Spost_' . $type . '_taxonomy_type']);
405
  }
406
  }
407
  //Handle the use of hierarchical posts as the 'taxonomy'
408
+ else if(is_post_type_hierarchical($this->opt['Spost_' . $type . '_taxonomy_type']))
409
  {
410
+ if($parent == null)
411
+ {
412
+ //We have to grab the post to find its parent, can't use $post for this one
413
+ $parent = get_post($id);
414
+ $parent = $parent->post_parent;
415
+ }
416
  //Done with the current item, now on to the parents
417
  $bcn_frontpage = get_option('page_on_front');
418
  //If there is a parent page let's find it
419
+ if($parent && $id != $parent && $bcn_frontpage != $parent)
420
  {
421
+ $this->post_parents($parent, $bcn_frontpage);
422
  }
423
  }
424
  //Handle the rest of the taxonomies, including tags
425
  else
426
  {
427
+ $this->post_terms($id, $this->opt['Spost_' . $type . '_taxonomy_type']);
428
  }
429
  }
430
  }
435
  * @param int $id The id of the post to find the terms for.
436
  * @param string $taxonomy The name of the taxonomy that the term belongs to
437
  *
438
+ * @TODO Need to implement this cleaner, fix up the entire tag_ thing, as this is now generic
439
+ * TODO: This still needs to be updated to the new method
440
  */
441
  function post_terms($id, $taxonomy)
442
  {
461
  $bcn_breadcrumb->set_title($bcn_breadcrumb->get_title() . ', ');
462
  }
463
  //This is a bit hackish, but it compiles the term anchor and appends it to the current breadcrumb title
464
+ $bcn_breadcrumb->set_title($bcn_breadcrumb->get_title() . str_replace(
465
+ array('%title%', '%link%', '%htitle%', '%type%'),
466
+ array($term->name, get_term_link($term, $taxonomy), $term->name, $term->taxonomy),
467
+ $this->opt['H' . $term->taxonomy . '_template']));
468
  $is_first = false;
469
  }
470
  }
471
  else
472
  {
473
  //If there are no tags, then we set the title to "Untagged"
474
+ $bcn_breadcrumb->set_title(__('Un' . $taxonomy, 'breadcrumb_navxt'));
475
  }
476
  }
477
  /**
480
  * This recursive functions fills the trail with breadcrumbs for parent terms.
481
  * @param int $id The id of the term.
482
  * @param string $taxonomy The name of the taxonomy that the term belongs to
483
+ * @TODO Evaluate if we need to do tax_ for a prefix
484
  */
485
  function term_parents($id, $taxonomy)
486
  {
487
  global $post;
488
  //Get the current category object, filter applied within this call
489
  $term = &get_term($id, $taxonomy);
490
+ //Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, get a pointer to it in return
491
+ $breadcrumb = $this->add(new bcn_breadcrumb($term->name, $this->opt['H' . $taxonomy . '_template'], array($taxonomy), get_term_link($term, $taxonomy)));
 
 
492
  //Make sure the id is valid, and that we won't end up spinning in a loop
493
  if($term->parent && $term->parent != $id)
494
  {
507
  {
508
  //Use WordPress API, though a bit heavier than the old method, this will ensure compatibility with other plug-ins
509
  $parent = get_post($id);
510
+ //Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, get a pointer to it in return
511
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title($id), $this->opt['Hpost_' . $parent->post_type . '_template'], array($parent->post_type), get_permalink($id)));
 
 
 
512
  //Make sure the id is valid, and that we won't end up spinning in a loop
513
  if($parent->post_parent >= 0 && $parent->post_parent != false && $id != $parent->post_parent && $frontpage != $parent->post_parent)
514
  {
519
  /**
520
  * A Breadcrumb Trail Filling Function
521
  *
522
+ * This functions fills a breadcrumb for posts
523
+ *
524
  */
525
+ function do_post()
526
  {
527
  global $post, $page;
528
+ //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, template, and type
529
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title(), $this->opt['Hpost_' . $post->post_type . '_template_no_anchor'], array('post-' . $post->post_type, 'current-item')));
530
+ //If the current item is to be linked, or this is a paged post, add in links
531
+ if($this->opt['bcurrent_item_linked'] || ($page > 0 && $this->opt['bpaged_display']))
532
  {
533
+ //Change the template over to the normal, linked one
534
+ $breadcrumb->set_template($this->opt['Hpost_' . $post->post_type . '_template']);
535
+ //Add the link
536
+ $breadcrumb->set_url(get_permalink());
537
  }
538
+ //If we have a hiearchical post, go through the parent tree
539
+ if(is_post_type_hierarchical($post->post_type))
 
 
540
  {
541
+ //Done with the current item, now on to the parents
542
+ $bcn_frontpage = get_option('page_on_front');
543
+ //If there is a parent page let's find it
544
+ if($post->post_parent && $post->ID != $post->post_parent && $bcn_frontpage != $post->post_parent)
545
+ {
546
+ $this->post_parents($post->post_parent, $bcn_frontpage);
547
+ }
548
  }
549
+ //Otherwise we need the follow the taxonomy tree
550
+ else
 
 
 
 
 
 
 
 
 
 
551
  {
552
+ //Handle the post's taxonomy
553
+ $this->post_taxonomy($post->ID, $post->post_type, $post->post_parent);
554
  }
 
 
555
  }
556
  /**
557
  * A Breadcrumb Trail Filling Function
558
  *
559
  * This functions fills a breadcrumb for an attachment page.
560
+ *
561
+ * @TODO Evaluate if this can be merged in with the do_post function
562
  */
563
  function do_attachment()
564
  {
565
  global $post;
566
+ //Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, get a pointer to it in return
567
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title(), $this->opt['Hpost_attachment_template_no_anchor'], array('post-attachment', 'current-item')));
568
+ if($this->opt['bcurrent_item_linked'])
569
+ {
570
+ //Change the template over to the normal, linked one
571
+ $breadcrumb->set_template($this->opt['Hpost_attachment_template']);
572
+ //Add the link
573
+ $breadcrumb->set_url(get_permalink());
574
+ }
575
  //Get the parent's information
576
  $parent = get_post($post->post_parent);
577
  //We need to treat flat and hiearchical post attachment hierachies differently
584
  }
585
  else
586
  {
587
+ //Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, get a pointer to it in return
588
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title($post->post_parent), $this->opt['Hpost_' . $post->post_type . '_template'], array($post->post_type), get_permalink($post->post_parent)));
 
 
 
589
  //Handle the post's taxonomy
590
  $this->post_taxonomy($post->post_parent, $parent->post_type);
591
  }
593
  /**
594
  * A Breadcrumb Trail Filling Function
595
  *
596
+ * This function fills a breadcrumb for any taxonomy archive, was previously two separate functions
597
+ *
598
  */
599
+ function do_archive_by_term()
600
  {
601
  global $wp_query;
602
  //Simmilar to using $post, but for things $post doesn't cover
603
  $term = $wp_query->get_queried_object();
604
  //Run through a filter for good measure
605
  $term->name = apply_filters('get_' . $term->taxonomy, $term->name);
606
+ //Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, get a pointer to it in return
607
+ $breadcrumb = $this->add(new bcn_breadcrumb($term->name, $this->opt['H' . $term->taxonomy . '_template_no_anchor'], array($term->taxonomy, 'current-item')));
 
608
  //If we're paged, let's link to the first page
609
+ if($this->opt['bcurrent_item_linked'] || (is_paged() && $this->opt['bpaged_display']))
610
  {
611
+ $breadcrumb->set_template($this->opt['H' . $term->taxonomy . '_template']);
612
  //Figure out the anchor for current category
613
+ $breadcrumb->set_url(get_term_link($term, $term->taxonomy));
614
  }
615
  //Get parents of current category
616
  if($term->parent)
618
  $this->term_parents($term->parent, $term->taxonomy);
619
  }
620
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  /**
622
  * A Breadcrumb Trail Filling Function
623
  *
624
  * This functions fills a breadcrumb for a date archive.
625
+ *
626
  */
627
  function do_archive_by_date()
628
  {
631
  if(is_day() || is_single())
632
  {
633
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
634
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_time('d'), $this->opt['Hdate_template_no_anchor'], array('date-day')));
635
+ //If this is a day archive, add current-item type
636
+ if(is_day())
637
+ {
638
+ $breadcrumb->add_type('current-item');
639
+ }
640
  //If we're paged, let's link to the first page
641
+ if($this->opt['bcurrent_item_linked'] || is_paged() && $this->opt['bpaged_display'] || is_single())
642
  {
643
+ //We're linking, so set the linked template
644
+ $breadcrumb->set_template($this->opt['Hdate_template']);
645
  //Deal with the anchor
646
+ $breadcrumb->set_url(get_day_link(get_the_time('Y'), get_the_time('m'), get_the_time('d')));
647
  }
648
  }
649
  //Now deal with the month breadcrumb
650
  if(is_month() || is_day() || is_single())
651
  {
652
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
653
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_time('F'), $this->opt['Hdate_template_no_anchor'], array('date-month')));
654
+ //If this is a month archive, add current-item type
655
+ if(is_month())
656
+ {
657
+ $breadcrumb->add_type('current-item');
658
+ }
659
  //If we're paged, or not in the archive by month let's link to the first archive by month page
660
+ if($this->opt['bcurrent_item_linked'] || is_day() || is_single() || (is_month() && is_paged() && $this->opt['bpaged_display']))
661
  {
662
+ //We're linking, so set the linked template
663
+ $breadcrumb->set_template($this->opt['Hdate_template']);
664
  //Deal with the anchor
665
+ $breadcrumb->set_url(get_month_link(get_the_time('Y'), get_the_time('m')));
666
  }
667
  }
668
  //Place the year breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
669
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_time('Y'), $this->opt['Hdate_template_no_anchor'], array('date-year')));
670
+ //If this is a year archive, add current-item type
671
+ if(is_year())
672
+ {
673
+ $breadcrumb->add_type('current-item');
674
+ }
675
  //If we're paged, or not in the archive by year let's link to the first archive by year page
676
+ if($this->opt['bcurrent_item_linked'] || is_day() || is_month() || is_single() || (is_paged() && $this->opt['bpaged_display']))
677
  {
678
+ //We're linking, so set the linked template
679
+ $breadcrumb->set_template($this->opt['Hdate_template']);
680
  //Deal with the anchor
681
+ $breadcrumb->set_url(get_year_link(get_the_time('Y')));
682
+ }
683
+ }
684
+ /**
685
+ * A Breadcrumb Trail Filling Function
686
+ *
687
+ * This functions fills a breadcrumb for a post type archive (WP 3.1 feature)
688
+ */
689
+ function do_archive_by_post_type()
690
+ {
691
+ //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
692
+ $breadcrumb = $this->add(new bcn_breadcrumb(post_type_archive_title('', false), $this->opt['Hpost_' . get_post_type() . '_template_no_anchor'], array('post-' . get_post_type() . '-archive', 'current-item')));
693
+ if($this->opt['bcurrent_item_linked'] || is_paged() && $this->opt['bpaged_display'])
694
+ {
695
+ $breadcrumb->set_template($this->opt['Hpost_' . get_post_type() . '_template']);
696
+ //Deal with the anchor
697
+ $breadcrumb->set_url(get_post_type_archive_link(get_post_type()));
698
  }
699
  }
700
  /**
706
  {
707
  global $post, $current_site;
708
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
709
+ $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['Shome_title'], $this->opt['Hhome_template_no_anchor'], array('site-home', 'current-item')));
710
+ //If we're paged, let's link to the first page
711
+ if($this->opt['bcurrent_item_linked'] || (is_paged() && $this->opt['bpaged_display']))
712
+ {
713
+ $breadcrumb->set_template($this->opt['Hhome_template']);
714
+ //Figure out the anchor for home page
715
+ $breadcrumb->set_url(get_home_url());
716
+ }
717
  //If we have a multi site and are not on the main site we may need to add a breadcrumb for the main site
718
+ if($this->opt['bmainsite_display'] && !is_main_site())
719
  {
720
  //Place the main site breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
721
+ $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['Smainsite_title'], $this->opt['Hmainsite_template_no_anchor'], array('mainsite-home'), get_home_url($current_site->blog_id)));
 
 
722
  }
723
+ }
724
+ /**
725
+ * A Breadcrumb Trail Filling Function
726
+ *
727
+ * This functions fills a breadcrumb for the home page.
728
+ */
729
+ function do_home()
730
+ {
731
+ global $post, $current_site;
732
+ //On everything else we need to link, but no current item (pre/suf)fixes
733
+ if($this->opt['bhome_display'])
734
  {
735
+ //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
736
+ $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['Shome_title'], $this->opt['Hhome_template'], array('site-home'), get_home_url()));
737
+ //If we have a multi site and are not on the main site we need to add a breadcrumb for the main site
738
+ if($this->opt['bmainsite_display'] && !is_main_site())
739
+ {
740
+ //Place the main site breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
741
+ $breadcrumb = $this->add(new bcn_breadcrumb($this->opt['Smainsite_title'], $this->opt['Hmainsite_template_no_anchor'], array('mainsite-home'), get_home_url($current_site->blog_id)));
742
+ }
743
  }
744
  }
745
  /**
746
  * A modified version of WordPress' function of the same name
747
+ *
748
  * @param object $object the post or taxonomy object used to attempt to find the title
749
  * @return string the title
750
  */
767
  return $type->_builtin;
768
  }
769
  /**
770
+ * Determines if a post type has archives enabled or not
771
  *
772
+ * @param string $post_type the name of the post type
773
+ * @return bool
774
  */
775
+ function has_archive($post_type)
776
+ {
777
+ $type = get_post_type_object($post_type);
778
+ return $type->has_archive;
779
+ }
780
+ /**
781
+ * A Breadcrumb Trail Filling Function
782
+ *
783
+ * Handles only the root page stuff for post types, including the "page for posts"
784
+ *
785
+ * TODO: this still needs to be redone, just trying to get it working ATM
786
+ */
787
+ function do_root()
788
  {
789
  global $post, $wp_query, $wp_taxonomies, $current_site;
790
  //Simmilar to using $post, but for things $post doesn't cover
792
  //We need to do special things for custom post types
793
  if(is_singular() && !$this->is_builtin($type->post_type))
794
  {
795
+ //We need the type for later, so save it
796
+ $type_str = $type->post_type;
797
  //This will assign a ID for root page of a custom post
798
+ if(is_numeric($this->opt['apost_' . $type_str . '_root']))
799
  {
800
+ $posts_id = $this->opt['apost_' . $type_str . '_root'];
801
  }
802
  }
803
+ //For CPT archives
804
+ else if(is_post_type_archive())
 
805
  {
806
+ //We need the type for later, so save it
807
+ $type_str = $type->name;
808
  //This will assign a ID for root page of a custom post's taxonomy archive
809
+ if(is_numeric($this->opt['apost_' . $type_str . '_root']))
810
  {
811
+ $posts_id = $this->opt['apost_' . $type_str . '_root'];
812
  }
813
  }
814
+ //We need to do special things for custom post type archives, but not author or date archives
815
+ else if(is_archive() && !is_author() && !is_date() && !$this->is_builtin($wp_taxonomies[$type->taxonomy]->object_type[0]))
816
  {
817
+ //We need the type for later, so save it
818
+ $type_str = $wp_taxonomies[$type->taxonomy]->object_type[0];
819
+ //This will assign a ID for root page of a custom post's taxonomy archive
820
+ if(is_numeric($this->opt['apost_' . $type_str . '_root']))
821
  {
822
+ $posts_id = $this->opt['apost_' . $type_str . '_root'];
 
823
  }
824
  }
825
+ else
826
+ {
827
+ $type_str = "post";
828
+ }
829
+ //These two are for taxonomy archives and for a single custom post type
830
+ if(isset($type->post_type) && !$this->is_builtin($type->post_type) && $this->opt['bpost_' . $type->post_type . '_archive_display'] && $this->has_archive($type->post_type))
831
  {
832
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
833
+ $breadcrumb = $this->add(new bcn_breadcrumb($this->post_type_archive_title(get_post_type_object($type->post_type)), $this->opt['Hpost_' . $type->post_type . '_template'], array('post-' . $type->post_type . '-archive'), get_post_type_archive_link($type->post_type)));
 
 
 
834
  }
835
+ else if(isset($type->taxonomy) && !$this->is_builtin($wp_taxonomies[$type->taxonomy]->object_type[0]) && $this->opt['bpost_' . $wp_taxonomies[$type->taxonomy]->object_type[0] . '_archive_display'] && $this->has_archive($wp_taxonomies[$type->taxonomy]->object_type[0]))
836
  {
837
+ //We end up using the post type in several places, give it a variable
838
+ $post_type = $wp_taxonomies[$type->taxonomy]->object_type[0];
839
  //Place the breadcrumb in the trail, uses the constructor to set the title, prefix, and suffix, get a pointer to it in return
840
+ $breadcrumb = $this->add(new bcn_breadcrumb($this->post_type_archive_title(get_post_type_object($post_type)), $this->opt['Hpost_' . $post_type . '_template'], array('post-' . $post_type . '-archive'), get_post_type_archive_link($post_type)));
 
 
 
841
  }
842
  //We only need the "blog" portion on members of the blog, and only if we're in a static frontpage environment
843
+ //if(isset($posts_id) || $this->opt['blog_display'] && get_option('show_on_front') == 'page' && (is_home() || (is_single() && !is_page()) || (is_archive() && !is_author())))
844
+ if(isset($posts_id) || $this->opt['bblog_display'] && get_option('show_on_front') == 'page' && (is_home() || is_single() || is_tax() || is_category() || is_tag()))
845
  {
846
  //If we entered here with a posts page, we need to set the id
847
  if(!isset($posts_id))
854
  {
855
  //Get the blog page
856
  $bcn_post = get_post($posts_id);
857
+ //Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, we get a pointer to it in return
858
+ $breadcrumb = $this->add(new bcn_breadcrumb(get_the_title($posts_id), $this->opt['Hpost_' . $post->post_type . '_template_no_anchor'], array($type_str . '-root', 'post-' . $post->post_type)));
859
+ //If we are at home, then we need to add the current item type
860
+ if(is_home())
861
  {
862
+ $breadcrumb->add_type('current-item');
863
+ }
864
+ //If we're not on the current item we need to setup the anchor
865
+ if(!is_home() || (is_paged() && $this->opt['bpaged_display']) || (is_home() && $this->opt['bcurrent_item_linked']))
866
+ {
867
+ $breadcrumb->set_template($this->opt['Hpost_' . $post->post_type . '_template']);
868
+ //Figure out the anchor for home page
869
+ $breadcrumb->set_url(get_permalink($posts_id));
 
870
  }
871
  //Done with the "root", now on to the parents
872
  //If there is a parent post let's find it
876
  }
877
  }
878
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
879
  }
880
  /**
881
  * A Breadcrumb Trail Filling Function
885
  function do_404()
886
  {
887
  //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, prefix, and suffix
888
+ $this->trail[] = new bcn_breadcrumb($this->opt['S404_title'], $this->opt['H404_template'], array('404', 'current-item'));
889
  }
890
  /**
891
  * A Breadcrumb Trail Filling Function
905
  $page_number = $page;
906
  }
907
  //Place the breadcrumb in the trail, uses the bcn_breadcrumb constructor to set the title, prefix, and suffix
908
+ $this->trail[] = new bcn_breadcrumb($page_number, $this->opt['Hpaged_template'], array('paged'));
909
  }
910
  /**
911
  * Breadcrumb Trail Filling Function
923
  }
924
  //Do any actions if necessary, we past through the current object instance to keep life simple
925
  do_action('bcn_before_fill', $this);
 
 
926
  //Do specific opperations for the various page types
927
  //Check if this isn't the first of a multi paged item
928
+ if($this->opt['bpaged_display'] && (is_paged() || is_singular() && $page > 0))
929
  {
930
  $this->do_paged();
931
  }
933
  if(is_front_page())
934
  {
935
  //Must have two seperate branches so that we don't evaluate it as a page
936
+ if($this->opt['bhome_display'])
937
  {
938
  $this->do_front_page();
939
  }
941
  //For posts
942
  else if(is_singular())
943
  {
 
 
 
 
 
944
  //For attachments
945
+ if(is_attachment())
946
  {
947
  $this->do_attachment();
948
  }
949
+ //For all other post types
950
  else
951
  {
952
+ $this->do_post();
953
  }
954
  }
955
  //For searches
970
  {
971
  $this->do_archive_by_date();
972
  }
973
+ else if(is_post_type_archive())
974
  {
975
+ $this->do_archive_by_post_type();
976
+ }
977
  //For taxonomy based archives
978
  else if(is_category() || is_tag() || is_tax())
979
  {
980
+ $this->do_archive_by_term();
 
 
 
 
 
 
 
 
 
981
  }
982
  }
983
  //For 404 pages
988
  //We always do the home link last, unless on the frontpage
989
  if(!is_front_page())
990
  {
991
+ $this->do_root();
992
  $this->do_home();
993
  }
994
  //Do any actions if necessary, we past through the current object instance to keep life simple
1013
  krsort($this->trail);
1014
  }
1015
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1016
  /**
1017
  * This functions outputs or returns the breadcrumb trail in string form.
1018
  *
1029
  //Initilize the string which will hold the assembled trail
1030
  $trail_str = '';
1031
  //The main compiling loop
1032
+ foreach($this->trail as $key => $breadcrumb)
1033
  {
1034
  //Must branch if we are reversing the output or not
1035
  if($reverse)
1037
  //Add in the separator only if we are the 2nd or greater element
1038
  if($key > 0)
1039
  {
1040
+ $trail_str .= $this->opt['hseparator'];
1041
  }
1042
  }
1043
  else
1045
  //Only show the separator when necessary
1046
  if($key < count($this->trail) - 1)
1047
  {
1048
+ $trail_str .= $this->opt['hseparator'];
1049
  }
1050
  }
 
 
 
 
 
1051
  //Trim titles, if needed
1052
+ if($this->opt['amax_title_length'] > 0)
1053
  {
1054
  //Trim the breadcrumb's title
1055
+ $breadcrumb->title_trim($this->opt['amax_title_length']);
1056
  }
1057
  //Place in the breadcrumb's assembled elements
1058
  $trail_str .= $breadcrumb->assemble($linked);
1064
  }
1065
  else
1066
  {
1067
+ //Helps track issues, please don't remove it
1068
  $credits = "<!-- Breadcrumb NavXT " . $this->version . " -->\n";
1069
  echo $credits . $trail_str;
1070
  }
1077
  * @param bool $return Whether to return data or to echo it.
1078
  * @param bool $linked[optional] Whether to allow hyperlinks in the trail or not.
1079
  * @param bool $reverse[optional] Whether to reverse the output or not.
1080
+ *
1081
+ * TODO: Can probably write this one in a smarter way now
1082
  */
1083
  function display_list($return = false, $linked = true, $reverse = false)
1084
  {
1087
  //Initilize the string which will hold the assembled trail
1088
  $trail_str = '';
1089
  //The main compiling loop
1090
+ foreach($this->trail as $key => $breadcrumb)
1091
  {
1092
  $trail_str .= '<li';
1093
  //On the first run we need to add in a class for the home breadcrumb
1103
  //If we are on the current item there are some things that must be done
1104
  else if($key === 0)
1105
  {
 
1106
  //Add in a class for current_item
1107
  $trail_str .= ' class="current_item"';
1108
  }
1109
  //Trim titles, if needed
1110
+ if($this->opt['amax_title_length'] > 0)
1111
  {
1112
  //Trim the breadcrumb's title
1113
+ $breadcrumb->title_trim($this->opt['amax_title_length']);
1114
  }
1115
  //Place in the breadcrumb's assembled elements
1116
  $trail_str .= '>' . $breadcrumb->assemble($linked);
1123
  }
1124
  else
1125
  {
1126
+ //Helps track issues, please don't remove it
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1127
  $credits = "<!-- Breadcrumb NavXT " . $this->version . " -->\n";
1128
  echo $credits . $trail_str;
1129
  }
mtekk_admin_class.php → includes/mtekk_adminkit.php RENAMED
@@ -16,8 +16,9 @@
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
  */
19
- abstract class mtekk_admin
20
  {
 
21
  protected $version;
22
  protected $full_name;
23
  protected $short_name;
@@ -27,16 +28,9 @@ abstract class mtekk_admin
27
  protected $unique_prefix;
28
  protected $opt = array();
29
  protected $message;
30
- /**
31
- * whether or not this administration page has contextual help
32
- *
33
- * @var bool
34
- */
35
- protected $_has_contextual_help = false;
36
  function __construct()
37
  {
38
- //We set the plugin basename here, could manually set it
39
- $this->plugin_basename = plugin_basename(__FILE__);
40
  //Admin Init Hook
41
  add_action('admin_init', array($this, 'init'));
42
  //WordPress Admin interface hook
@@ -46,37 +40,64 @@ abstract class mtekk_admin
46
  add_action('activate_' . $this->plugin_basename, array($this, 'install'));
47
  //Initilizes l10n domain
48
  $this->local();
 
 
 
 
 
 
 
 
 
49
  }
 
 
 
50
  function admin_url()
51
  {
52
  return admin_url('options-general.php?page=' . $this->identifier);
53
  }
54
- function undo_anchor($title = '')
 
 
 
 
 
 
 
 
55
  {
56
- //Assemble our url, nonce and all
57
- $url = wp_nonce_url($this->admin_url() . '&' . $this->unique_prefix . '_admin_undo=true', $this->unique_prefix . '_admin_undo');
58
- //Return a valid Undo anchor
59
- return ' <a title="' . $title . '" href="' . $url . '">' . __('Undo', $this->identifier) . '</a>';
60
  }
61
- function upgrade_anchor($title = '', $text = '')
 
 
 
 
 
 
 
 
 
 
 
62
  {
63
  //Assemble our url, nonce and all
64
- $url = wp_nonce_url($this->admin_url() . '&' . $this->unique_prefix . '_admin_upgrade=true', $this->unique_prefix . '_admin_upgrade');
65
- if($text == '')
66
- {
67
- $text = __('Migrate now.', $this->identifier);
68
- }
69
- //Return a valid Undo anchor
70
- return ' <a title="' . $title . '" href="' . $url . '">' . $text . '</a>';
 
 
 
 
 
71
  }
72
  function init()
73
  {
74
- //Admin Options update hook
75
- if(isset($_POST[$this->unique_prefix . '_admin_options']))
76
- {
77
- //Temporarily add update function on init if form has been submitted
78
- $this->opts_update();
79
- }
80
  //Admin Options reset hook
81
  if(isset($_POST[$this->unique_prefix . '_admin_reset']))
82
  {
@@ -101,20 +122,32 @@ abstract class mtekk_admin
101
  //Run the rollback function on init if undo button has been pressed
102
  $this->opts_undo();
103
  }
104
- //Admin Options rollback hook
105
  else if(isset($_GET[$this->unique_prefix . '_admin_upgrade']))
106
  {
107
- //Run the rollback function on init if undo button has been pressed
 
 
 
 
 
 
108
  $this->opts_upgrade_wrapper();
109
  }
110
  //Add in the nice "settings" link to the plugins page
111
  add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2);
 
 
 
 
112
  //Register options
113
  register_setting($this->unique_prefix . '_options', $this->unique_prefix . '_options', '');
 
 
114
  }
115
  /**
116
  * Adds the adminpage the menue and the nice little settings link
117
- *
118
  */
119
  function add_page()
120
  {
@@ -124,9 +157,13 @@ abstract class mtekk_admin
124
  if(current_user_can($this->access_level))
125
  {
126
  //Register admin_head-$hookname callback
127
- add_action('admin_head-' . $hookname, array($this, 'admin_head'));
 
 
 
 
128
  //Register Help Output
129
- add_action('contextual_help', array($this, 'contextual_help'), 10, 2);
130
  }
131
  }
132
  /**
@@ -166,8 +203,50 @@ abstract class mtekk_admin
166
  return $links;
167
  }
168
  /**
169
- * uninstall
170
- *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  * This removes database settings upon deletion of the plugin from WordPress
172
  */
173
  function uninstall()
@@ -181,6 +260,7 @@ abstract class mtekk_admin
181
  }
182
  /**
183
  * Compares the supplided version with the internal version, places an upgrade warning if there is a missmatch
 
184
  */
185
  function version_check($version)
186
  {
@@ -188,7 +268,7 @@ abstract class mtekk_admin
188
  if(version_compare($version, $this->version, '<') && is_array($this->opt))
189
  {
190
  //Throw an error since the DB version is out of date
191
- $this->message['error'][] = __('Your settings are out of date.', $this->identifier) . $this->upgrade_anchor(__('Migrate the settings now.', $this->identifier), __('Migrate now.', $this->identifier));
192
  //Output any messages that there may be
193
  $this->message();
194
  return false;
@@ -196,13 +276,34 @@ abstract class mtekk_admin
196
  else if(!is_array($this->opt))
197
  {
198
  //Throw an error since it appears the options were never registered
199
- $this->message['error'][] = __('Your plugin install is incomplete.', $this->identifier) . $this->upgrade_anchor(__('Load default settings now.', $this->identifier), __('Complete now.', $this->identifier));
 
 
 
 
 
 
 
 
200
  //Output any messages that there may be
201
  $this->message();
202
  return false;
203
  }
204
  return true;
205
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  /**
207
  * Synchronizes the backup options entry with the current options entry
208
  */
@@ -212,10 +313,167 @@ abstract class mtekk_admin
212
  update_option($this->unique_prefix . '_options_bk', get_option($this->unique_prefix . '_options'));
213
  }
214
  /**
215
- * Function prototype to prevent errors
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  */
217
  function opts_update()
218
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  }
220
  /**
221
  * Exports a XML options document
@@ -307,11 +565,12 @@ abstract class mtekk_admin
307
  }
308
  }
309
  }
 
310
  $this->opts_upgrade($opts_temp, $version);
311
  //Commit the loaded options to the database
312
  update_option($this->unique_prefix . '_options', $this->opt);
313
  //Everything was successful, let the user know
314
- $this->message['updated fade'][] = __('Settings successfully imported from the uploaded file.', $this->identifier) . $this->undo_anchor(__('Undo the options import.', $this->identifier));
315
  }
316
  else
317
  {
@@ -335,7 +594,7 @@ abstract class mtekk_admin
335
  //Load in the hard coded default option values
336
  update_option($this->unique_prefix . '_options', $this->opt);
337
  //Reset successful, let the user know
338
- $this->message['updated fade'][] = __('Settings successfully reset to the default values.', $this->identifier) . $this->undo_anchor(__('Undo the options reset.', $this->identifier));
339
  add_action('admin_notices', array($this, 'message'));
340
  }
341
  /**
@@ -352,7 +611,7 @@ abstract class mtekk_admin
352
  //Set the backup options to the undid options
353
  update_option($this->unique_prefix . '_options_bk', $opt);
354
  //Send the success/undo message
355
- $this->message['updated fade'][] = __('Settings successfully undid the last operation.', $this->identifier) . $this->undo_anchor(__('Undo the last undo operation.', $this->identifier));
356
  add_action('admin_notices', array($this, 'message'));
357
  }
358
  /**
@@ -399,47 +658,35 @@ abstract class mtekk_admin
399
  add_action('admin_notices', array($this, 'message'));
400
  }
401
  /**
402
- * contextual_help action hook function
403
  *
404
- * @param string $contextual_help
405
- * @param string $screen_id
406
  * @return string
 
407
  */
408
- function contextual_help($contextual_help, $screen_id)
409
  {
 
410
  //Add contextual help on current screen
411
- if($screen_id == 'settings_page_' . $this->identifier)
412
  {
413
- $contextual_help = $this->_get_contextual_help();
414
- $this->_has_contextual_help = true;
415
  }
416
- return $contextual_help;
417
- }
418
- /**
419
- * get contextual help
420
- *
421
- * @return string
422
- */
423
- protected function _get_contextual_help()
424
- {
425
- $t = $this->_get_help_text();
426
- $t = sprintf('<div class="metabox-prefs">%s</div>', $t);
427
- $title = __($this->full_name, $this->identifier);
428
- $t = sprintf('<h5>%s</h5>%s', sprintf(__('Get help with "%s"'), $title), $t);
429
- return $t;
430
  }
431
  /**
432
  * Prints to screen all of the messages stored in the message member variable
433
  */
434
  function message()
435
  {
436
- //Loop through our message classes
437
- foreach($this->message as $key => $class)
438
  {
439
- //Loop through the messages in the current class
440
- foreach($class as $message)
441
  {
442
- printf('<div class="%s"><p>%s</p></div>', $key, $message);
 
 
 
 
443
  }
444
  }
445
  $this->message = array();
@@ -447,9 +694,16 @@ abstract class mtekk_admin
447
  /**
448
  * Function prototype to prevent errors
449
  */
450
- function install()
451
  {
452
-
 
 
 
 
 
 
 
453
  }
454
  /**
455
  * Function prototype to prevent errors
@@ -463,7 +717,12 @@ abstract class mtekk_admin
463
  */
464
  function admin_page()
465
  {
466
-
 
 
 
 
 
467
  }
468
  /**
469
  * Function prototype to prevent errors
@@ -491,23 +750,23 @@ abstract class mtekk_admin
491
  }
492
  function import_form()
493
  {
494
- printf('<div id="%s_import_export_relocate">', $this->unique_prefix);
495
- printf('<form action="options-general.php?page=%s" method="post" enctype="multipart/form-data" id="%s_admin_upload">', $this->identifier, $this->unique_prefix);
496
- wp_nonce_field($this->unique_prefix . '_admin_import_export');
497
- printf('<fieldset id="import_export" class="%s_options">', $this->unique_prefix);
498
- echo '<h3>' . __('Import/Export/Reset Settings', $this->identifier) . '</h3>';
499
- echo '<p>' . __('Import settings from a XML file, export the current settings to a XML file, or reset to the default settings.', $this->identifier) . '</p>';
500
- echo '<table class="form-table"><tr valign="top"><th scope="row">';
501
- printf('<label for="%s_admin_import_file">', $this->unique_prefix);
502
- _e('Settings File', $this->identifier);
503
- echo '</label></th><td>';
504
- printf('<input type="file" name="%s_admin_import_file" id="%s_admin_import_file" size="32" /><br /><span class="setting-description">', $this->unique_prefix, $this->unique_prefix);
505
- _e('Select a XML settings file to upload and import settings from.', 'breadcrumb_navxt');
506
- echo '</span></td></tr></table><p class="submit">';
507
- printf('<input type="submit" class="button" name="%s_admin_import" value="' . __('Import', $this->identifier) . '"/>', $this->unique_prefix, $this->unique_prefix);
508
- printf('<input type="submit" class="button" name="%s_admin_export" value="' . __('Export', $this->identifier) . '"/>', $this->unique_prefix);
509
- printf('<input type="submit" class="button" name="%s_admin_reset" value="' . __('Reset', $this->identifier) . '"/>', $this->unique_prefix, $this->unique_prefix);
510
- echo '</p></fieldset></form></div>';
511
  }
512
  /**
513
  * This will output a well formed hidden option
@@ -624,16 +883,16 @@ abstract class mtekk_admin
624
  /**
625
  * This will output a singular radio type form input field
626
  *
627
- * @param string $label
628
  * @param string $option
 
629
  * @param string $instruction
630
  * @param object $disable [optional]
631
  * @return
632
  */
633
- function input_radio($option, $value, $instruction, $disable = false, $type = 'radio')
634
  {?>
635
  <label>
636
- <input name="<?php echo $this->unique_prefix . '_options[' . $option;?>]" type="<?php echo $type;?>" <?php if($disable){echo 'disabled="disabled" class="disabled togx"';}else{echo 'class="togx"';}?> value="<?php echo $value;?>" <?php checked($value, $this->opt[$option]);?> />
637
  <?php echo $instruction; ?>
638
  </label><br/>
639
  <?php
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
  */
19
+ abstract class mtekk_adminKit
20
  {
21
+ private $__version = '1.0';
22
  protected $version;
23
  protected $full_name;
24
  protected $short_name;
28
  protected $unique_prefix;
29
  protected $opt = array();
30
  protected $message;
31
+ protected $support_url;
 
 
 
 
 
32
  function __construct()
33
  {
 
 
34
  //Admin Init Hook
35
  add_action('admin_init', array($this, 'init'));
36
  //WordPress Admin interface hook
40
  add_action('activate_' . $this->plugin_basename, array($this, 'install'));
41
  //Initilizes l10n domain
42
  $this->local();
43
+ //Register Help Output
44
+ //add_action('add_screen_help_and_options', array($this, 'help'));
45
+ }
46
+ /**
47
+ * Returns the internal mtekk_admin_class version
48
+ */
49
+ function get_admin_class_version()
50
+ {
51
+ return $__version;
52
  }
53
+ /**
54
+ * Return the URL of the settings page for the plugin
55
+ */
56
  function admin_url()
57
  {
58
  return admin_url('options-general.php?page=' . $this->identifier);
59
  }
60
+ /**
61
+ * A wrapper for nonced_anchor returns a nonced anchor for admin pages
62
+ *
63
+ * @param string $mode The nonce "mode", a unique string at the end of the standardized nonce identifier
64
+ * @param string $title (optional) The text to use in the title portion of the anchor
65
+ * @param string $text (optional) The text that will be surrounded by the anchor tags
66
+ * @return string the assembled anchor
67
+ */
68
+ function admin_anchor($mode, $title = '', $text = '')
69
  {
70
+ return $this->nonced_anchor($this->admin_url(), 'admin_' . $mode, 'true', $title, $text);
 
 
 
71
  }
72
+ /**
73
+ * Returns a properly formed nonced anchor to the specified URI
74
+ *
75
+ * @param string $uri The URI that the anchor should be for
76
+ * @param string $mode The nonce "mode", a unique string at the end of the standardized nonce identifier
77
+ * @param mixed $value (optional) The value to place in the query string
78
+ * @param string $title (optional) The text to use in the title portion of the anchor
79
+ * @param string $text (optional) The text that will be surrounded by the anchor tags
80
+ * @param string $extras (optional) This text is placed within the opening anchor tag, good for adding id, classe, rel field
81
+ * @return string the assembled anchor
82
+ */
83
+ function nonced_anchor($uri, $mode, $value = 'true', $title = '', $text = '', $extras = '')
84
  {
85
  //Assemble our url, nonce and all
86
+ $url = wp_nonce_url($uri . '&' . $this->unique_prefix . '_' . $mode . '=' . $value, $this->unique_prefix . '_' . $mode);
87
+ //Return a valid anchor
88
+ return ' <a title="' . $title . '" href="' . $url . '" '. $extras . '>' . $text . '</a>';
89
+ }
90
+ /**
91
+ * Abstracts the check_admin_referer so that all the end user has to supply is the mode
92
+ *
93
+ * @param string $mode The specific nonce "mode" (see nonced_anchor) that is being checked
94
+ */
95
+ function check_nonce($mode)
96
+ {
97
+ check_admin_referer($this->unique_prefix . '_' . $mode);
98
  }
99
  function init()
100
  {
 
 
 
 
 
 
101
  //Admin Options reset hook
102
  if(isset($_POST[$this->unique_prefix . '_admin_reset']))
103
  {
122
  //Run the rollback function on init if undo button has been pressed
123
  $this->opts_undo();
124
  }
125
+ //Admin Options upgrade hook
126
  else if(isset($_GET[$this->unique_prefix . '_admin_upgrade']))
127
  {
128
+ //Run the upgrade function on init if upgrade button has been pressed
129
+ $this->opts_upgrade_wrapper();
130
+ }
131
+ //Admin Options fix hook
132
+ else if(isset($_GET[$this->unique_prefix . '_admin_fix']))
133
+ {
134
+ //Run the options fix function on init if fix button has been pressed
135
  $this->opts_upgrade_wrapper();
136
  }
137
  //Add in the nice "settings" link to the plugins page
138
  add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2);
139
+ //Register JS for tabs
140
+ wp_register_script('mtekk_adminkit_tabs', plugins_url('/mtekk_adminkit_tabs.js', dirname(__FILE__) . '/mtekk_adminkit_tabs.js'));
141
+ //Register CSS for tabs
142
+ wp_register_style('mtekk_adminkit_tabs', plugins_url('/mtekk_adminkit_tabs.css', dirname(__FILE__) . '/mtekk_adminkit_tabs.css'));
143
  //Register options
144
  register_setting($this->unique_prefix . '_options', $this->unique_prefix . '_options', '');
145
+ //Synchronize up our settings with the database as we're done modifying them now
146
+ $this->opt = $this->parse_args(get_option($this->unique_prefix . '_options'), $this->opt);
147
  }
148
  /**
149
  * Adds the adminpage the menue and the nice little settings link
150
+ * TODO: make this more generic for easier extension
151
  */
152
  function add_page()
153
  {
157
  if(current_user_can($this->access_level))
158
  {
159
  //Register admin_head-$hookname callback
160
+ add_action('admin_head-' . $hookname, array($this, 'admin_head'));
161
+ //Register admin_print_styles-$hookname callback
162
+ add_action('admin_print_styles-' . $hookname, array($this, 'admin_styles'));
163
+ //Register admin_print_scripts-$hookname callback
164
+ add_action('admin_print_scripts-' . $hookname, array($this, 'admin_scripts'));
165
  //Register Help Output
166
+ add_action('load-' . $hookname, array($this, 'help'));
167
  }
168
  }
169
  /**
203
  return $links;
204
  }
205
  /**
206
+ * Checks to see if the plugin has been fully installed
207
+ *
208
+ * @return bool whether or not the plugin has been installed
209
+ */
210
+ function is_installed()
211
+ {
212
+
213
+ }
214
+ /**
215
+ * This sets up and upgrades the database settings, runs on every activation
216
+ */
217
+ function install()
218
+ {
219
+ //Call our little security function
220
+ $this->security();
221
+ //Try retrieving the options from the database
222
+ $opts = get_option($this->unique_prefix . '_options');
223
+ //If there are no settings, copy over the default settings
224
+ if(!is_array($opts))
225
+ {
226
+ //Grab defaults from the object
227
+ $opts = $this->opt;
228
+ //Add the options
229
+ add_option($this->unique_prefix . '_options', $opts);
230
+ add_option($this->unique_prefix . '_options_bk', $opts, '', 'no');
231
+ //Add the version, no need to autoload the db version
232
+ add_option($this->unique_prefix . '_version', $this->version, '', 'no');
233
+ }
234
+ else
235
+ {
236
+ //Retrieve the database version
237
+ $db_version = get_option($this->unique_prefix . '_version');
238
+ if($this->version !== $db_version)
239
+ {
240
+ //Run the settings update script
241
+ $this->opts_upgrade($opts, $db_version);
242
+ //Always have to update the version
243
+ update_option($this->unique_prefix . '_version', $this->version);
244
+ //Store the options
245
+ update_option($this->unique_prefix . '_options', $this->opt);
246
+ }
247
+ }
248
+ }
249
+ /**
250
  * This removes database settings upon deletion of the plugin from WordPress
251
  */
252
  function uninstall()
260
  }
261
  /**
262
  * Compares the supplided version with the internal version, places an upgrade warning if there is a missmatch
263
+ * TODO: change this to being auto called in admin_init action
264
  */
265
  function version_check($version)
266
  {
268
  if(version_compare($version, $this->version, '<') && is_array($this->opt))
269
  {
270
  //Throw an error since the DB version is out of date
271
+ $this->message['error'][] = __('Your settings are out of date.', $this->identifier) . $this->admin_anchor('upgrade', __('Migrate the settings now.', $this->identifier), __('Migrate now.', $this->identifier));
272
  //Output any messages that there may be
273
  $this->message();
274
  return false;
276
  else if(!is_array($this->opt))
277
  {
278
  //Throw an error since it appears the options were never registered
279
+ $this->message['error'][] = __('Your plugin install is incomplete.', $this->identifier) . $this->admin_anchor('upgrade', __('Load default settings now.', $this->identifier), __('Complete now.', $this->identifier));
280
+ //Output any messages that there may be
281
+ $this->message();
282
+ return false;
283
+ }
284
+ else if(!$this->opts_validate($this->opt))
285
+ {
286
+ //Throw an error since it appears the options contain invalid data
287
+ $this->message['error'][] = __('Your plugin settings are invalid.', $this->identifier) . $this->admin_anchor('fix', __('Attempt to fix settings now.', $this->identifier), __('Fix now.', $this->identifier));
288
  //Output any messages that there may be
289
  $this->message();
290
  return false;
291
  }
292
  return true;
293
  }
294
+ /**
295
+ * A prototype function. End user should override if they need this feature.
296
+ */
297
+ function opts_validate(&$opts)
298
+ {
299
+ return true;
300
+ }
301
+ /**
302
+ * A prototype function. End user should override if they need this feature.
303
+ */
304
+ function opts_fix()
305
+ {
306
+ }
307
  /**
308
  * Synchronizes the backup options entry with the current options entry
309
  */
313
  update_option($this->unique_prefix . '_options_bk', get_option($this->unique_prefix . '_options'));
314
  }
315
  /**
316
+ * Runs recursivly through the opts array, sanitizing and merging in updates from the $input array
317
+ *
318
+ * @param array $opts good, clean array
319
+ * @param array $input unsanitzed input array, not trusted at all
320
+ */
321
+ protected function opts_update_loop(&$opts, $input)
322
+ {
323
+ //Loop through all of the existing options (avoids random setting injection)
324
+ foreach($opts as $option => $value)
325
+ {
326
+ //If we have an array, dive into another recursive loop
327
+ if(isset($input[$option]) && is_array($value))
328
+ {
329
+ $this->opts_update_loop($opts[$option], $input[$option]);
330
+ }
331
+ //We must check for unset settings, but booleans are ok to be unset
332
+ else if(isset($input[$option]) || $option[0] == 'b')
333
+ {
334
+ switch($option[0])
335
+ {
336
+ //Handle the boolean options
337
+ case 'b':
338
+ $opts[$option] = isset($input[$option]);
339
+ break;
340
+ //Handle the integer options
341
+ case 'i':
342
+ $opts[$option] = (int) $input[$option];
343
+ break;
344
+ //Handle the absolute integer options
345
+ case 'a':
346
+ $opts[$option] = absint($input[$option]);
347
+ break;
348
+ //Handle the floating point options
349
+ case 'f':
350
+ $opts[$option] = (float) $input[$option];
351
+ break;
352
+ //Handle the HTML options
353
+ case 'h':
354
+ //May be better to use wp_kses here
355
+ $opts[$option] = stripslashes($input[$option]);
356
+ break;
357
+ //Handle the HTML options that must not be null
358
+ case 'H':
359
+ if(isset($input[$option]))
360
+ {
361
+ $opts[$option] = stripslashes($input[$option]);
362
+ }
363
+ break;
364
+ //Handle the text options that must not be null
365
+ case 'S':
366
+ if(isset($input[$option]))
367
+ {
368
+ $opts[$option] = esc_html($input[$option]);
369
+ }
370
+ break;
371
+ //Treat everything else as a normal string
372
+ case 's':
373
+ default:
374
+ $opts[$option] = esc_html($input[$option]);
375
+ }
376
+ }
377
+ }
378
+ }
379
+ /**
380
+ * A better version of parse_args, will recrusivly follow arrays
381
+ *
382
+ * @param mixed $args The arguments to be parsed
383
+ * @param mixed $defaults (optional) The default values to validate against
384
+ * @return mixed
385
+ */
386
+ function parse_args($args, $defaults = '')
387
+ {
388
+ if(is_object($args))
389
+ {
390
+ $r = get_object_vars($args);
391
+ }
392
+ else if(is_array($args))
393
+ {
394
+ $r =& $args;
395
+ }
396
+ else
397
+ {
398
+ wp_parse_str($args, $r);
399
+ }
400
+ if(is_array($defaults))
401
+ {
402
+ return $this->array_merge_recursive($defaults, $r);
403
+ }
404
+ return $r;
405
+ }
406
+ /**
407
+ * An alternate version of array_merge_recursive, less flexible
408
+ * still recursive, ~2x faster than the more flexible version
409
+ *
410
+ * @param array $arg1 first array
411
+ * @param array $arg2 second array to merge into $arg1
412
+ * @return array
413
+ */
414
+ function array_merge_recursive($arg1, $arg2)
415
+ {
416
+ foreach($arg2 as $key => $value)
417
+ {
418
+ if(array_key_exists($key, $arg1) && is_array($value))
419
+ {
420
+ $arg1[$key] = $this->array_merge_recursive($arg1[$key], $value);
421
+ }
422
+ else
423
+ {
424
+ $arg1[$key] = $value;
425
+ }
426
+ }
427
+ return $arg1;
428
+ }
429
+ /**
430
+ * An action that fires just before the options backup, use to add in dynamically detected options
431
+ *
432
+ * @param array $opts the options array, passed in by reference
433
+ * @return null
434
+ */
435
+ function opts_update_prebk(&$opts)
436
+ {
437
+ //Just a prototype function
438
+ }
439
+ /**
440
+ * Updates the database settings from the webform
441
  */
442
  function opts_update()
443
  {
444
+ //Do some security related thigns as we are not using the normal WP settings API
445
+ $this->security();
446
+ //Do a nonce check, prevent malicious link/form problems
447
+ check_admin_referer($this->unique_prefix . '_options-options');
448
+ //Update local options from database
449
+ $this->opt = $this->parse_args(get_option($this->unique_prefix . '_options'), $this->opt);
450
+ $this->opts_update_prebk($this->opt);
451
+ //Update our backup options
452
+ update_option($this->unique_prefix . '_options_bk', $this->opt);
453
+ //Grab our incomming array (the data is dirty)
454
+ $input = $_POST[$this->unique_prefix . '_options'];
455
+ //Run the update loop
456
+ $this->opts_update_loop($this->opt, $input);
457
+ //Commit the option changes
458
+ update_option($this->unique_prefix . '_options', $this->opt);
459
+ //Check if known settings match attempted save
460
+ if(count(array_diff_key($input, $this->opt)) == 0)
461
+ {
462
+ //Let the user know everything went ok
463
+ $this->message['updated fade'][] = __('Settings successfully saved.', $this->identifier) . $this->admin_anchor('undo', __('Undo the options save.', $this->identifier), __('Undo', $this->identifier));
464
+ }
465
+ else
466
+ {
467
+ //Let the user know the following were not saved
468
+ $this->message['updated fade'][] = __('Some settings were not saved.', $this->identifier) . $this->admin_anchor('undo', __('Undo the options save.', $this->identifier), __('Undo', $this->identifier));
469
+ $temp = __('The following settings were not saved:', $this->identifier);
470
+ foreach(array_diff_key($input, $this->opt) as $setting => $value)
471
+ {
472
+ $temp .= '<br />' . $setting;
473
+ }
474
+ $this->message['updated fade'][] = $temp . '<br />' . sprintf(__('Please include this message in your %sbug report%s.', $this->identifier),'<a title="' . sprintf(__('Go to the %s support post for your version.', $this->identifier), $this->short_name) . '" href="' . $this->support_url . $this->version . '/#respond">', '</a>');
475
+ }
476
+ add_action('admin_notices', array($this, 'message'));
477
  }
478
  /**
479
  * Exports a XML options document
565
  }
566
  }
567
  }
568
+ //Make sure we safely import and upgrade settings if needed
569
  $this->opts_upgrade($opts_temp, $version);
570
  //Commit the loaded options to the database
571
  update_option($this->unique_prefix . '_options', $this->opt);
572
  //Everything was successful, let the user know
573
+ $this->message['updated fade'][] = __('Settings successfully imported from the uploaded file.', $this->identifier) . $this->admin_anchor('undo', __('Undo the options import.', $this->identifier), __('Undo', $this->identifier));
574
  }
575
  else
576
  {
594
  //Load in the hard coded default option values
595
  update_option($this->unique_prefix . '_options', $this->opt);
596
  //Reset successful, let the user know
597
+ $this->message['updated fade'][] = __('Settings successfully reset to the default values.', $this->identifier) . $this->admin_anchor('undo', __('Undo the options reset.', $this->identifier), __('Undo', $this->identifier));
598
  add_action('admin_notices', array($this, 'message'));
599
  }
600
  /**
611
  //Set the backup options to the undid options
612
  update_option($this->unique_prefix . '_options_bk', $opt);
613
  //Send the success/undo message
614
+ $this->message['updated fade'][] = __('Settings successfully undid the last operation.', $this->identifier) . $this->admin_anchor('undo', __('Undo the last undo operation.', $this->identifier), __('Undo', $this->identifier));
615
  add_action('admin_notices', array($this, 'message'));
616
  }
617
  /**
658
  add_action('admin_notices', array($this, 'message'));
659
  }
660
  /**
661
+ * help action hook function, meant to be overridden
662
  *
 
 
663
  * @return string
664
+ *
665
  */
666
+ function help()
667
  {
668
+ $screen = get_current_screen();
669
  //Add contextual help on current screen
670
+ if($screen->id == 'settings_page_' . $this->identifier)
671
  {
672
+
 
673
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  }
675
  /**
676
  * Prints to screen all of the messages stored in the message member variable
677
  */
678
  function message()
679
  {
680
+ if(count($this->message))
 
681
  {
682
+ //Loop through our message classes
683
+ foreach($this->message as $key => $class)
684
  {
685
+ //Loop through the messages in the current class
686
+ foreach($class as $message)
687
+ {
688
+ printf('<div class="%s"><p>%s</p></div>', $key, $message);
689
+ }
690
  }
691
  }
692
  $this->message = array();
694
  /**
695
  * Function prototype to prevent errors
696
  */
697
+ function admin_styles()
698
  {
699
+
700
+ }
701
+ /**
702
+ * Function prototype to prevent errors
703
+ */
704
+ function admin_scripts()
705
+ {
706
+
707
  }
708
  /**
709
  * Function prototype to prevent errors
717
  */
718
  function admin_page()
719
  {
720
+ //Admin Options update hook
721
+ if(isset($_POST[$this->unique_prefix . '_admin_options']))
722
+ {
723
+ //Temporarily add update function on init if form has been submitted
724
+ $this->opts_update();
725
+ }
726
  }
727
  /**
728
  * Function prototype to prevent errors
750
  }
751
  function import_form()
752
  {
753
+ $form = '<div id="mtekk_admin_import_export_relocate">';
754
+ $form .= sprintf('<form action="options-general.php?page=%s" method="post" enctype="multipart/form-data" id="%s_admin_upload">', $this->identifier, $this->unique_prefix);
755
+ $form .= wp_nonce_field($this->unique_prefix . '_admin_import_export', '_wpnonce', true, false);
756
+ $form .= sprintf('<fieldset id="import_export" class="%s_options">', $this->unique_prefix);
757
+ $form .= '<p>' . __('Import settings from a XML file, export the current settings to a XML file, or reset to the default settings.', $this->identifier) . '</p>';
758
+ $form .= '<table class="form-table"><tr valign="top"><th scope="row">';
759
+ $form .= sprintf('<label for="%s_admin_import_file">', $this->unique_prefix);
760
+ $form .= __('Settings File', $this->identifier);
761
+ $form .= '</label></th><td>';
762
+ $form .= sprintf('<input type="file" name="%s_admin_import_file" id="%s_admin_import_file" size="32" /><br /><span class="setting-description">', $this->unique_prefix, $this->unique_prefix);
763
+ $form .= __('Select a XML settings file to upload and import settings from.', 'breadcrumb_navxt');
764
+ $form .= '</span></td></tr></table><p class="submit">';
765
+ $form .= sprintf('<input type="submit" class="button" name="%s_admin_import" value="' . __('Import', $this->identifier) . '"/>', $this->unique_prefix, $this->unique_prefix);
766
+ $form .= sprintf('<input type="submit" class="button" name="%s_admin_export" value="' . __('Export', $this->identifier) . '"/>', $this->unique_prefix);
767
+ $form .= sprintf('<input type="submit" class="button" name="%s_admin_reset" value="' . __('Reset', $this->identifier) . '"/>', $this->unique_prefix, $this->unique_prefix);
768
+ $form .= '</p></fieldset></form></div>';
769
+ return $form;
770
  }
771
  /**
772
  * This will output a well formed hidden option
883
  /**
884
  * This will output a singular radio type form input field
885
  *
 
886
  * @param string $option
887
+ * @param string $value
888
  * @param string $instruction
889
  * @param object $disable [optional]
890
  * @return
891
  */
892
+ function input_radio($option, $value, $instruction, $disable = false)
893
  {?>
894
  <label>
895
+ <input name="<?php echo $this->unique_prefix . '_options[' . $option;?>]" type="radio" <?php if($disable){echo 'disabled="disabled" class="disabled togx"';}else{echo 'class="togx"';}?> value="<?php echo $value;?>" <?php checked($value, $this->opt[$option]);?> />
896
  <?php echo $instruction; ?>
897
  </label><br/>
898
  <?php
includes/mtekk_adminkit_tabs.css ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Tabbed Admin Page (CSS)
3
+ *
4
+ * @author Tom Klingenberg
5
+ * @colordef #dfdfdf light-grey (tabs border color)
6
+ * @colordef #f9f9f9 very-light-grey (admin standard background color)
7
+ */
8
+ #hasadmintabs ul.ui-tabs-nav {border-bottom:1px solid #dfdfdf; font-size:12px; height:29px; list-style-image:none; list-style-position:outside; list-style-type:none; margin:13px 0 0; overflow:visible; padding:0 0 0 8px;}
9
+ #hasadmintabs ul.ui-tabs-nav li {display:block; float:left; line-height:200%; list-style-image:none; list-style-position:outside; list-style-type:none; margin:0; padding:0; position:relative; text-align:center; white-space:nowrap; width:auto;}
10
+ #hasadmintabs ul.ui-tabs-nav li a {background:transparent none no-repeat scroll 0 50%; border-bottom:1px solid #dfdfdf; display:block; float:left; line-height:28px; padding:1px 13px 0; position:relative; text-decoration:none;}
11
+ #hasadmintabs ul.ui-tabs-nav li.ui-tabs-selected a{border-top-left-radius:4px; border-top-right-radius:4px;border:1px solid #dfdfdf; border-bottom-color:#f9f9f9; color:#333333; font-weight:normal; padding:0 12px;}
12
+ #hasadmintabs ul.ui-tabs-nav a:focus, a:active {outline-color:-moz-use-text-color; outline-style:none; outline-width:medium;}
13
+ #screen-options-wrap p.submit {margin:0; padding:0;}
includes/mtekk_adminkit_tabs.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function()
2
+ {
3
+ mtekk_admin_tabulator_init();
4
+ });
5
+ /**
6
+ * Tabulator Bootup
7
+ */
8
+ function mtekk_admin_tabulator_init(){
9
+ if(!jQuery("#hasadmintabs").length) return;
10
+ /* init markup for tabs */
11
+ jQuery('#hasadmintabs').prepend("<ul><\/ul>");
12
+ jQuery('#hasadmintabs > fieldset').each(function(i){
13
+ id = jQuery(this).attr('id');
14
+ cssc = jQuery(this).attr('class');
15
+ caption = jQuery(this).find('h3').text();
16
+ jQuery('#hasadmintabs > ul').append('<li><a href="#'+id+'" class="'+cssc+'"><span>'+caption+"<\/span><\/a><\/li>");
17
+ jQuery(this).find('h3').hide();
18
+ });
19
+ /* init the tabs plugin */
20
+ var tabs = jQuery("#hasadmintabs").tabs();
21
+ var form = jQuery('#'+objectL10n.mtad_uid+'-options');
22
+ var action = form.attr("action").split('#', 1) + '#' + jQuery('#hasadmintabs > fieldset').eq(tabs.tabs('option', 'selected')).attr('id');
23
+ form.get(0).setAttribute("action", action);
24
+ /* handler for opening the last tab after submit (compability version) */
25
+ jQuery('#hasadmintabs ul a').click(function(i){
26
+ var form = jQuery('#'+objectL10n.mtad_uid+'-options');
27
+ var action = form.attr("action").split('#', 1) + jQuery(this).attr('href');
28
+ form.get(0).setAttribute("action", action);
29
+ });
30
+ }
languages/breadcrumb_navxt-by_BY.mo DELETED
Binary file
languages/breadcrumb_navxt-by_BY.po DELETED
@@ -1,496 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: Breadcrumb NavXT\n"
4
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/breadcrumb-navxt\n"
5
- "POT-Creation-Date: 2009-04-24 03:05+0000\n"
6
- "PO-Revision-Date: 2009-05-14 23:07+0300\n"
7
- "Last-Translator: Илья <mrilyuha@gmail.com>\n"
8
- "Language-Team: John Havlik <mtekkmonkey@gmail.com>\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Poedit-Language: Belarusian\n"
13
- "X-Poedit-KeywordsList: __;_e\n"
14
- "X-Poedit-Basepath: .\n"
15
- "X-Poedit-Country: BELARUS\n"
16
- "X-Poedit-SourceCharset: utf-8\n"
17
- "X-Poedit-SearchPath-0: C:\\Users\\John\\Documents\\Aptana Studio\\Breadcrumb NavXT\\trunk\n"
18
-
19
- #: breadcrumb_navxt_admin.php:134
20
- msgid "Insufficient privileges to proceed."
21
- msgstr "Недастаткова прывілегій для працягвання."
22
-
23
- #: breadcrumb_navxt_admin.php:190
24
- #: breadcrumb_navxt_class.php:165
25
- msgid "<a title=\"Go to the first page of search results for %title%.\" href=\"%link%\">"
26
- msgstr "<a title=\"Перайсці да першай старонкі, каб убачыць рэзультат для %title%.\" href=\"%link%\">"
27
-
28
- #: breadcrumb_navxt_admin.php:537
29
- msgid "Settings"
30
- msgstr "Налады"
31
-
32
- #: breadcrumb_navxt_admin.php:632
33
- msgid "All of your current Breadcrumb NavXT settings will be overwritten with the default values. Are you sure you want to continue?"
34
- msgstr "Усе цякучыя налады Breadcrumb NavXT будуць перазапісаны звычайнымі наладымі. Вы хочаце працягнуць?"
35
-
36
- #: breadcrumb_navxt_admin.php:636
37
- msgid "All of your current Breadcrumb NavXT settings will be overwritten with the imported values. Are you sure you want to continue?"
38
- msgstr "Усе цякучыя налады Breadcrumb NavXT будуць перазапісаны імпартаванымі наладымі. Вы хочаце працягнуць?"
39
-
40
- #: breadcrumb_navxt_admin.php:699
41
- msgid "Warning, your version of Breadcrumb NavXT does not match the version supported by this administrative interface. As a result, settings may not work as expected."
42
- msgstr "Папярэджанне: ваша версія Breadcrumb NavXT не адпавядае версіі, якая падтрымліваецца адміністратыўным інтэрфейсам. У выніку, налады могуць не працаваць, як патрабуецца."
43
-
44
- #: breadcrumb_navxt_admin.php:700
45
- msgid "Your Breadcrumb NavXT Administration interface version is "
46
- msgstr "Версія адміністратыўнага інтэрфэйсу Breadcrumb NavXT Administration - "
47
-
48
- #: breadcrumb_navxt_admin.php:701
49
- msgid "Your Breadcrumb NavXT version is "
50
- msgstr "Версія Breadcrumb NavXT Administration - "
51
-
52
- #: breadcrumb_navxt_admin.php:705
53
- msgid "Breadcrumb NavXT Settings"
54
- msgstr "Налады Breadcrumb NavXT"
55
-
56
- #: breadcrumb_navxt_admin.php:707
57
- #, php-format
58
- msgid "Tips for the settings are located below select options. Please refer to the %sdocumentation%s for more information."
59
- msgstr "Парады для налад знаходзяцца ніжэй. калі ласка, перайдзіце да %sdocumentation%s для інфармацыі."
60
-
61
- #: breadcrumb_navxt_admin.php:708
62
- msgid "Go to the Breadcrumb NavXT online documentation"
63
- msgstr "Перайсці да Breadcrumb NavXT онлайн-дакументацыі"
64
-
65
- #: breadcrumb_navxt_admin.php:718
66
- msgid "General"
67
- msgstr "Галоўныя"
68
-
69
- #: breadcrumb_navxt_admin.php:722
70
- msgid "Breadcrumb Separator"
71
- msgstr "Раздзяляльнік Breadcrumb"
72
-
73
- #: breadcrumb_navxt_admin.php:726
74
- msgid "Placed in between each breadcrumb."
75
- msgstr "Знаходзіцца паміж кожнай хлебнай дробкай."
76
-
77
- #: breadcrumb_navxt_admin.php:731
78
- msgid "Breadcrumb Max Title Length"
79
- msgstr "Максімальная даўжыня загалоўка хлебнай дробкі"
80
-
81
- #: breadcrumb_navxt_admin.php:739
82
- msgid "Home Breadcrumb"
83
- msgstr "Хлебныя дробкі галоўнай старонкі"
84
-
85
- #: breadcrumb_navxt_admin.php:744
86
- msgid "Place the home breadcrumb in the trail."
87
- msgstr "Размяцціць хатнія хлебныя дробкі ў трэйле (trail)."
88
-
89
- #: breadcrumb_navxt_admin.php:749
90
- msgid "Home Title: "
91
- msgstr "Загаловак галоўнай старонкі:"
92
-
93
- #: breadcrumb_navxt_admin.php:758
94
- msgid "Home Prefix"
95
- msgstr "Home-прэфікс"
96
-
97
- #: breadcrumb_navxt_admin.php:766
98
- msgid "Home Suffix"
99
- msgstr "Home-суфікс"
100
-
101
- #: breadcrumb_navxt_admin.php:774
102
- msgid "Home Anchor"
103
- msgstr "Home-якар"
104
-
105
- #: breadcrumb_navxt_admin.php:778
106
- msgid "The anchor template for the home breadcrumb."
107
- msgstr "Якарныя шаблон для хлебных дробак."
108
-
109
- #: breadcrumb_navxt_admin.php:783
110
- msgid "Blog Anchor"
111
- msgstr "Blog-якар"
112
-
113
- #: breadcrumb_navxt_admin.php:787
114
- msgid "The anchor template for the blog breadcrumb, used only in static front page environments."
115
- msgstr "Якарныя шаблон для хлебных дробак блогу. выкарыстоўваецца толькі на статычных пярэдніх старонках. "
116
-
117
- #: breadcrumb_navxt_admin.php:793
118
- msgid "Current Item"
119
- msgstr "Дадзены элемент"
120
-
121
- #: breadcrumb_navxt_admin.php:797
122
- msgid "Link Current Item"
123
- msgstr "Дадзеная спасылка элементу"
124
-
125
- #: breadcrumb_navxt_admin.php:802
126
- msgid "Yes"
127
- msgstr "Так"
128
-
129
- #: breadcrumb_navxt_admin.php:808
130
- msgid "Current Item Prefix"
131
- msgstr "Дадзены прэфікс элементу"
132
-
133
- #: breadcrumb_navxt_admin.php:812
134
- msgid "This is always placed in front of the last breadcrumb in the trail, before any other prefixes for that breadcrumb."
135
- msgstr "Гэта заўсёды знаходзіцца ў пачатку хлебных дробак, перад усімі прэфіксамі для хлебных дробак."
136
-
137
- #: breadcrumb_navxt_admin.php:817
138
- msgid "Current Item Suffix"
139
- msgstr "Дадзены суфікс элементу"
140
-
141
- #: breadcrumb_navxt_admin.php:821
142
- msgid "This is always placed after the last breadcrumb in the trail, and after any other prefixes for that breadcrumb."
143
- msgstr "Гэта заўсёды знаходзіцца пасля хлебных дробак і пасля ўсіх прэфіксаў для хлебных дробак."
144
-
145
- #: breadcrumb_navxt_admin.php:826
146
- msgid "Current Item Anchor"
147
- msgstr "Дадзены якар элементу"
148
-
149
- #: breadcrumb_navxt_admin.php:830
150
- msgid "The anchor template for current item breadcrumbs."
151
- msgstr "Якарны шаблон для цякучага элементу хлебных драбніц."
152
-
153
- #: breadcrumb_navxt_admin.php:835
154
- msgid "Paged Breadcrumb"
155
- msgstr "Старонкавыя хлебныя дробкі"
156
-
157
- #: breadcrumb_navxt_admin.php:840
158
- msgid "Include the paged breadcrumb in the breadcrumb trail."
159
- msgstr "Уключыць старонкавыя хлебныя дробкі ў радок хлебных дробак."
160
-
161
- #: breadcrumb_navxt_admin.php:842
162
- msgid "Indicates that the user is on a page other than the first on paginated posts/pages."
163
- msgstr "Указваць, што наведвальнік не на першай старонцы, ў пастах і старонках."
164
-
165
- #: breadcrumb_navxt_admin.php:847
166
- msgid "Paged Prefix"
167
- msgstr "Старонкавы прэфікс"
168
-
169
- #: breadcrumb_navxt_admin.php:855
170
- msgid "Paged Suffix"
171
- msgstr "Суфікс старонак"
172
-
173
- #: breadcrumb_navxt_admin.php:864
174
- msgid "Posts &amp; Pages"
175
- msgstr "Пасты &amp; Старонкі"
176
-
177
- #: breadcrumb_navxt_admin.php:868
178
- msgid "Post Prefix"
179
- msgstr "Прэфікс паста"
180
-
181
- #: breadcrumb_navxt_admin.php:876
182
- msgid "Post Suffix"
183
- msgstr "Суфікс паста"
184
-
185
- #: breadcrumb_navxt_admin.php:884
186
- msgid "Post Anchor"
187
- msgstr "Якар паста"
188
-
189
- #: breadcrumb_navxt_admin.php:888
190
- msgid "The anchor template for post breadcrumbs."
191
- msgstr "Якарны шаблон для хлебных дробак паста."
192
-
193
- #: breadcrumb_navxt_admin.php:893
194
- msgid "Post Taxonomy Display"
195
- msgstr "Паказваць таксанамію паста"
196
-
197
- #: breadcrumb_navxt_admin.php:898
198
- msgid "Show the taxonomy leading to a post in the breadcrumb trail."
199
- msgstr "Паказваць таксанамію ў хлебных дробках."
200
-
201
- #: breadcrumb_navxt_admin.php:904
202
- msgid "Post Taxonomy"
203
- msgstr "Таксанамія паста"
204
-
205
- #: breadcrumb_navxt_admin.php:909
206
- #: breadcrumb_navxt_admin.php:964
207
- msgid "Categories"
208
- msgstr "Катэгорыі"
209
-
210
- #: breadcrumb_navxt_admin.php:914
211
- #: breadcrumb_navxt_admin.php:1014
212
- msgid "Tags"
213
- msgstr "Тэгі"
214
-
215
- #: breadcrumb_navxt_admin.php:917
216
- msgid "The taxonomy which the breadcrumb trail will show."
217
- msgstr "Паказваць таксанамію, калі ёсцьхлебныя дробкі."
218
-
219
- #: breadcrumb_navxt_admin.php:922
220
- msgid "Page Prefix"
221
- msgstr "Прэфікс старонкі"
222
-
223
- #: breadcrumb_navxt_admin.php:930
224
- msgid "Page Suffix"
225
- msgstr "Суфік старонкі"
226
-
227
- #: breadcrumb_navxt_admin.php:938
228
- msgid "Page Anchor"
229
- msgstr "Якар старонкі"
230
-
231
- #: breadcrumb_navxt_admin.php:942
232
- msgid "The anchor template for page breadcrumbs."
233
- msgstr "Паказваць якарны шаблон для хлебных дробак старонкі."
234
-
235
- #: breadcrumb_navxt_admin.php:947
236
- msgid "Attachment Prefix"
237
- msgstr "Прэфікс дадатка"
238
-
239
- #: breadcrumb_navxt_admin.php:955
240
- msgid "Attachment Suffix"
241
- msgstr "Суфікс дадатка"
242
-
243
- #: breadcrumb_navxt_admin.php:968
244
- msgid "Category Prefix"
245
- msgstr "Прэфікс катэгорыі"
246
-
247
- #: breadcrumb_navxt_admin.php:972
248
- msgid "Applied before the anchor on all category breadcrumbs."
249
- msgstr "Прызначаць перад якарам ўва ўсіх катэгорыях хлебных дробак."
250
-
251
- #: breadcrumb_navxt_admin.php:977
252
- msgid "Category Suffix"
253
- msgstr "Суфікс катэгорый"
254
-
255
- #: breadcrumb_navxt_admin.php:981
256
- msgid "Applied after the anchor on all category breadcrumbs."
257
- msgstr "Прызначаць пасля якара ўва ўсіх катэгорыях хлебных дробак."
258
-
259
- #: breadcrumb_navxt_admin.php:986
260
- msgid "Category Anchor"
261
- msgstr "Якар катэгорыі"
262
-
263
- #: breadcrumb_navxt_admin.php:990
264
- msgid "The anchor template for category breadcrumbs."
265
- msgstr "Якарны шаблон для катэгорыі хлебных дробак."
266
-
267
- #: breadcrumb_navxt_admin.php:995
268
- msgid "Archive by Category Prefix"
269
- msgstr "Архіў па прэфіксам катэгорый"
270
-
271
- #: breadcrumb_navxt_admin.php:999
272
- msgid "Applied before the title of the current item breadcrumb on an archive by cateogry page."
273
- msgstr "Прызначаць перад загалоўкам цякучых хлебных дробак у архіве па катэгорыям старонак."
274
-
275
- #: breadcrumb_navxt_admin.php:1004
276
- msgid "Archive by Category Suffix"
277
- msgstr "Архіў па суфіксам катэгорый"
278
-
279
- #: breadcrumb_navxt_admin.php:1008
280
- msgid "Applied after the title of the current item breadcrumb on an archive by cateogry page."
281
- msgstr "Прызначаць пасля загалоўка цякучых хлебных дробак у архіве па катэгорыям старонак."
282
-
283
- #: breadcrumb_navxt_admin.php:1018
284
- msgid "Tag Prefix"
285
- msgstr "Прэфікс тэга"
286
-
287
- #: breadcrumb_navxt_admin.php:1022
288
- msgid "Applied before the anchor on all tag breadcrumbs."
289
- msgstr "Прызначаць перад якарам ўва ўсіх катэгорыях хлебных дробак."
290
-
291
- #: breadcrumb_navxt_admin.php:1027
292
- msgid "Tag Suffix"
293
- msgstr "Суфікс тэга"
294
-
295
- #: breadcrumb_navxt_admin.php:1031
296
- msgid "Applied after the anchor on all tag breadcrumbs."
297
- msgstr "Прызначаць пасля якара ўва ўсіх тэгах хлебных дробак."
298
-
299
- #: breadcrumb_navxt_admin.php:1036
300
- msgid "Tag Anchor"
301
- msgstr "Якар тэга"
302
-
303
- #: breadcrumb_navxt_admin.php:1040
304
- msgid "The anchor template for tag breadcrumbs."
305
- msgstr "Якарны шаблон для тэга хлебных дробак."
306
-
307
- #: breadcrumb_navxt_admin.php:1045
308
- msgid "Archive by Tag Prefix"
309
- msgstr "Архіў па тэгу прэфікса"
310
-
311
- #: breadcrumb_navxt_admin.php:1049
312
- msgid "Applied before the title of the current item breadcrumb on an archive by tag page."
313
- msgstr "Прызначаць перад загалоўкам цякучых хлебных дробак у архіве па тэгам старонак."
314
-
315
- #: breadcrumb_navxt_admin.php:1054
316
- msgid "Archive by Tag Suffix"
317
- msgstr "Архіў па суфіксам тэгаў"
318
-
319
- #: breadcrumb_navxt_admin.php:1058
320
- msgid "Applied after the title of the current item breadcrumb on an archive by tag page."
321
- msgstr "Прызначаць пасля загалоўка цякучых хлебных дробак у архіве па тэгам старонак."
322
-
323
- #: breadcrumb_navxt_admin.php:1064
324
- msgid "Date Archives"
325
- msgstr "Каляндарны архіў"
326
-
327
- #: breadcrumb_navxt_admin.php:1068
328
- msgid "Archive by Date Prefix"
329
- msgstr "Архіў па прэфіксу даты"
330
-
331
- #: breadcrumb_navxt_admin.php:1072
332
- msgid "Applied before the anchor on all date breadcrumbs."
333
- msgstr "Прызначаць перад якарам ўва ўсіх датах хлебных дробак."
334
-
335
- #: breadcrumb_navxt_admin.php:1077
336
- msgid "Archive by Date Suffix"
337
- msgstr "Архіў па суфіксе даты"
338
-
339
- #: breadcrumb_navxt_admin.php:1081
340
- msgid "Applied after the anchor on all date breadcrumbs."
341
- msgstr "Прызначаць пасля якара ўва ўсіх датах хлебных дробак."
342
-
343
- #: breadcrumb_navxt_admin.php:1086
344
- msgid "Date Anchor"
345
- msgstr "Якар даты"
346
-
347
- #: breadcrumb_navxt_admin.php:1090
348
- msgid "The anchor template for date breadcrumbs."
349
- msgstr "Якарны шаблон для даты хлебных дробак."
350
-
351
- #: breadcrumb_navxt_admin.php:1096
352
- msgid "Miscellaneous"
353
- msgstr "Рознае"
354
-
355
- #: breadcrumb_navxt_admin.php:1100
356
- msgid "Author Prefix"
357
- msgstr "Прэфікс аўтара"
358
-
359
- #: breadcrumb_navxt_admin.php:1108
360
- msgid "Author Suffix"
361
- msgstr "Суфікс аўтара"
362
-
363
- #: breadcrumb_navxt_admin.php:1116
364
- msgid "Author Display Format"
365
- msgstr "Фармат паказу аўтара"
366
-
367
- #: breadcrumb_navxt_admin.php:1122
368
- msgid "display_name uses the name specified in \"Display name publicly as\" under the user profile the others correspond to options in the user profile."
369
- msgstr "display_name выкарыстоўвае імя, вызначанае ў \"Display name publicly as\"."
370
-
371
- #: breadcrumb_navxt_admin.php:1127
372
- msgid "Search Prefix"
373
- msgstr "Прэфікс пошуку"
374
-
375
- #: breadcrumb_navxt_admin.php:1135
376
- msgid "Search Suffix"
377
- msgstr "Суфікс пошуку"
378
-
379
- #: breadcrumb_navxt_admin.php:1143
380
- msgid "Search Anchor"
381
- msgstr "Пошукавы якар"
382
-
383
- #: breadcrumb_navxt_admin.php:1147
384
- msgid "The anchor template for search breadcrumbs, used only when the search results span several pages."
385
- msgstr "Якарны шаблон для хлебных дробак пошуку, толькі тады, каклі рэзультаты пошуку размяшчаюцца на некалькіх старонках."
386
-
387
- #: breadcrumb_navxt_admin.php:1152
388
- msgid "404 Title"
389
- msgstr "404-загаловак"
390
-
391
- #: breadcrumb_navxt_admin.php:1160
392
- msgid "404 Prefix"
393
- msgstr "404-суфікс"
394
-
395
- #: breadcrumb_navxt_admin.php:1168
396
- msgid "404 Suffix"
397
- msgstr "404-суфікс"
398
-
399
- #: breadcrumb_navxt_admin.php:1177
400
- msgid "Save Changes"
401
- msgstr "Налады захаваныя"
402
-
403
- #: breadcrumb_navxt_admin.php:1182
404
- msgid "Import/Export/Reset Settings"
405
- msgstr "Налады імпарту/экспарту/збіцця налад"
406
-
407
- #: breadcrumb_navxt_admin.php:1183
408
- msgid "Import Breadcrumb NavXT settings from a XML file, export the current settings to a XML file, or reset to the default Breadcrumb NavXT settings."
409
- msgstr "Імпартаваць налады Breadcrumb NavXT з XML-файла, экспартаваць цякучыя налады ў XML-файл або збіць звычайныя налады Breadcrumb NavXT."
410
-
411
- #: breadcrumb_navxt_admin.php:1187
412
- msgid "Settings File"
413
- msgstr "Файл налад"
414
-
415
- #: breadcrumb_navxt_admin.php:1191
416
- msgid "Select a XML settings file to upload and import settings from."
417
- msgstr "Выберыце XML-налады для імпарту налад."
418
-
419
- #: breadcrumb_navxt_admin.php:1196
420
- msgid "Import"
421
- msgstr "Імпартаваць"
422
-
423
- #: breadcrumb_navxt_admin.php:1197
424
- msgid "Export"
425
- msgstr "Экспартаваць"
426
-
427
- #: breadcrumb_navxt_admin.php:1198
428
- msgid "Reset"
429
- msgstr "Збіць"
430
-
431
- #: breadcrumb_navxt_admin.php:1327
432
- msgid "Importing settings from file failed."
433
- msgstr "Імпартаванне налад з файла пацярпела няўдачу."
434
-
435
- #: breadcrumb_navxt_admin.php:1331
436
- msgid "The Breadcrumb NavXT settings were successfully imported from file."
437
- msgstr "Налады Breadcrumb NavXT поўнасцю імпартаваныя з файла."
438
-
439
- #: breadcrumb_navxt_admin.php:1335
440
- msgid "The Breadcrumb NavXT settings were reset to the default values."
441
- msgstr "Налады Breadcrumb NavXT збітыя да звычайных."
442
-
443
- #: breadcrumb_navxt_class.php:100
444
- msgid "Blog"
445
- msgstr "Блог"
446
-
447
- #: breadcrumb_navxt_class.php:102
448
- #: breadcrumb_navxt_class.php:104
449
- #: breadcrumb_navxt_class.php:128
450
- #: breadcrumb_navxt_class.php:142
451
- msgid "<a title=\"Go to %title%.\" href=\"%link%\">"
452
- msgstr "<a title=\"Перайсці да %title%.\" href=\"%link%\">"
453
-
454
- #: breadcrumb_navxt_class.php:117
455
- msgid "<a title=\"Reload the current page.\" href=\"%link%\">"
456
- msgstr "<a title=\"Reload the current page.\" href=\"%link%\">"
457
-
458
- #: breadcrumb_navxt_class.php:158
459
- msgid "404"
460
- msgstr "404 "
461
-
462
- #: breadcrumb_navxt_class.php:161
463
- msgid "Search results for &#39;"
464
- msgstr "Рэзультат пошуку для &#39;"
465
-
466
- #: breadcrumb_navxt_class.php:172
467
- msgid "<a title=\"Go to the %title% tag archives.\" href=\"%link%\">"
468
- msgstr "<a title=\"Перайсці да %title% тэгаў архіваў.\" href=\"%link%\">"
469
-
470
- #: breadcrumb_navxt_class.php:175
471
- msgid "Articles by: "
472
- msgstr "Артыкулы па:"
473
-
474
- #: breadcrumb_navxt_class.php:186
475
- msgid "<a title=\"Go to the %title% category archives.\" href=\"%link%\">"
476
- msgstr "<a title=\"Перайсці да %title% катэгорый архіваў.\" href=\"%link%\">"
477
-
478
- #: breadcrumb_navxt_class.php:189
479
- msgid "Archive by category &#39;"
480
- msgstr "Архіў па катэгорыям &#39;"
481
-
482
- #: breadcrumb_navxt_class.php:193
483
- msgid "Archive by tag &#39;"
484
- msgstr "Архіў па тэгам &#39;"
485
-
486
- #: breadcrumb_navxt_class.php:196
487
- msgid "<a title=\"Go to the %title% archives.\" href=\"%link%\">"
488
- msgstr "<a title=\"Перайсці да %title% архіваў.\" href=\"%link%\">"
489
-
490
- #: breadcrumb_navxt_class.php:464
491
- msgid "Untagged"
492
- msgstr "Без тэгаў"
493
-
494
- #~ msgid "Leave the home breadcrumb out of the trail."
495
- #~ msgstr "Soll nicht dargestellt werden."
496
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: mtekk, hakre
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=FD5XEU783BR8U&lc=US&item_name=Breadcrumb%20NavXT%20Donation&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
4
  Tags: breadcrumb, breadcrumbs, trail, navigation, menu, widget
5
- Requires at least: 3.1
6
- Tested up to: 3.2
7
  Stable tag: 3.9.0
8
  Adds breadcrumb navigation showing the visitor's path to their current location.
9
 
2
  Contributors: mtekk, hakre
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=FD5XEU783BR8U&lc=US&item_name=Breadcrumb%20NavXT%20Donation&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
4
  Tags: breadcrumb, breadcrumbs, trail, navigation, menu, widget
5
+ Requires at least: 3.2
6
+ Tested up to: 3.3
7
  Stable tag: 3.9.0
8
  Adds breadcrumb navigation showing the visitor's path to their current location.
9