The SEO Framework - Version 2.9.0

Version Description

  • Equitable Erudition =

Courage is found in unlikely places - J.R.R. Tolkien

Release date:

  • 25th March 2017

Summarized:

  • This update focuses on fixing bugs and expanding the API for developers.
  • To expand the API for per page (in-post) SEO settings, tabs had to be added in the SEO settings metabox.
  • The JavaScript code has also been overhauled to improve performance and allow third party implementation.
  • Moreover, the home page settings now allow you to upload a social image.
  • Structured data markup has also been improved, like the inclusion of an alternative Sitename and fixes for Breadcrumb images.
  • The sitemap can now include the blog page. The lastmod value of which listens to multiple pages to automatically determines what's best.
  • Unfortunately, Twitter has removed support for photo cards. This update makes sure that the regarding settings correctly convert to the current format.

Only one week left for the earliest of early-bird discounts:

  • With The SEO Framework - Extension Manager's release, a celebratory discount has been introduced.
  • If you wish to benefit from this lifetime discount, visit the shop for more information.
  • More awesome extensions are coming soon!

Survey:

  • After updating, please fill in our Update Survey: tell us what you like or can be done better.

For everyone: Tabbed In-post SEO layout

  • This release brings tabbed layout to the in-post SEO settings.
  • With this change I've also altered the overall looks, with the help from Daniel.
  • This layout allows extensions from the Extension Manager to be implemented much easier.
  • This layout is self-responsive! This means it's not dependent on the browser-size, but on how much content will fit.
  • This layout therefore allows the SEO settings to be placed in the right sidebar! Take a look at the new screenshots.

For everyone: Browser support

  • This release brings CSS Flexbox to the new in-post SEO settings metabox.
  • The flexbox module is still experimental, in a way that not all browsers correctly support this to the fullest extend.
  • However, support for as many browsers feasible has been implemented. Check out the list. Enjoy!
  • The gist is that Chrome, Firefox, IE10 and Safari 6 or later are supported.

SEO Tip of the Update - Trust in layout

  • Is your website glitchy and has placeholder images, unmatched colors or weirdly contrasting borders all over the place?
  • Consider going for a more modern and clean layout. Strip out what isn't necessary. A clean layout implies professionalism and increases visitors' trust.
  • Even if you're just starting out with your website, remove all that could be but really isn't. Because if you leave in placeholders for the future, it implies amateurism.
  • People want their truth to be confirmed or their problems to be solved. If you can't confirm or solve the layout of your website, then they won't trust you to do so for their issues.
  • Simply put: It doesn't have to be perfect, it just must be done.

Detailed log:

It is some miles, but it will shorten your journey tomorrow.

Download this release

Release Info

Developer Cybr
Plugin Icon 128x128 The SEO Framework
Version 2.9.0
Comparing to
See all releases

Code changes from version 2.8.2 to 2.9.0

Files changed (50) hide show
  1. autodescription.php +3 -3
  2. inc/classes/admin-init.class.php +196 -15
  3. inc/classes/admin-pages.class.php +43 -3
  4. inc/classes/cache.class.php +27 -3
  5. inc/classes/core.class.php +25 -21
  6. inc/classes/debug.class.php +6 -3
  7. inc/classes/deprecated.class.php +240 -1
  8. inc/classes/detect.class.php +36 -0
  9. inc/classes/doing-it-right.class.php +42 -21
  10. inc/classes/feed.class.php +93 -52
  11. inc/classes/generate-description.class.php +47 -8
  12. inc/classes/generate-image.class.php +110 -76
  13. inc/classes/generate-ldjson.class.php +195 -82
  14. inc/classes/generate-title.class.php +2 -2
  15. inc/classes/generate-url.class.php +29 -19
  16. inc/classes/generate.class.php +57 -19
  17. inc/classes/init.class.php +60 -34
  18. inc/classes/inpost.class.php +351 -70
  19. inc/classes/load.class.php +5 -5
  20. inc/classes/metaboxes.class.php +17 -9
  21. inc/classes/post-data.class.php +2 -2
  22. inc/classes/query.class.php +64 -27
  23. inc/classes/render.class.php +5 -4
  24. inc/classes/sanitize.class.php +47 -0
  25. inc/classes/site-options.class.php +185 -209
  26. inc/classes/sitemaps.class.php +114 -24
  27. inc/classes/term-data.class.php +8 -6
  28. inc/compat/plugin-bbpress.php +173 -0
  29. inc/compat/plugin-wpmudev-dm.php +7 -0
  30. inc/functions/upgrade.php +68 -2
  31. inc/views/debug/output.php +1 -1
  32. inc/views/inpost/seo-settings-singular.php +286 -0
  33. inc/views/inpost/seo-settings-tt.php +157 -0
  34. inc/views/inpost/seo-settings.php +0 -423
  35. inc/views/metaboxes/feed-metabox.php +3 -3
  36. inc/views/metaboxes/homepage-metabox.php +64 -0
  37. inc/views/metaboxes/sitemaps-metabox.php +14 -5
  38. inc/views/metaboxes/social-metabox.php +22 -17
  39. language/autodescription.pot +336 -293
  40. lib/css/tsf-rtl.css +283 -12
  41. lib/css/tsf-rtl.min.css +1 -1
  42. lib/css/tsf.css +280 -8
  43. lib/css/tsf.min.css +1 -1
  44. lib/js/tsf.externs.js +5 -0
  45. lib/js/tsf.externs.protected.js +0 -6
  46. lib/js/tsf.js +578 -159
  47. lib/js/tsf.min.js +37 -32
  48. load.php +3 -3
  49. readme.txt +62 -160
  50. seotips/seotips.txt +8 -0
autodescription.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: The SEO Framework
4
  * Plugin URI: https://theseoframework.com/
5
  * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
- * Version: 2.8.2
7
  * Author: Sybre Waaijer
8
  * Author URI: https://cyberwire.nl/
9
  * License: GPLv3
@@ -46,13 +46,13 @@ defined( 'ABSPATH' ) or die;
46
  * Not many caching plugins use CDN in dashboard. What a shame. Firefox does cache.
47
  * @since 1.0.0
48
  */
49
- define( 'THE_SEO_FRAMEWORK_VERSION', '2.8.2' );
50
 
51
  /**
52
  * Plugin Database version for lightweight version upgrade comparing.
53
  * @since 2.7.0
54
  */
55
- define( 'THE_SEO_FRAMEWORK_DB_VERSION', '2804' );
56
 
57
  /**
58
  * Plugin options filter.
3
  * Plugin Name: The SEO Framework
4
  * Plugin URI: https://theseoframework.com/
5
  * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
+ * Version: 2.9.0
7
  * Author: Sybre Waaijer
8
  * Author URI: https://cyberwire.nl/
9
  * License: GPLv3
46
  * Not many caching plugins use CDN in dashboard. What a shame. Firefox does cache.
47
  * @since 1.0.0
48
  */
49
+ define( 'THE_SEO_FRAMEWORK_VERSION', '2.9.0' );
50
 
51
  /**
52
  * Plugin Database version for lightweight version upgrade comparing.
53
  * @since 2.7.0
54
  */
55
+ define( 'THE_SEO_FRAMEWORK_DB_VERSION', '2903' );
56
 
57
  /**
58
  * Plugin options filter.
inc/classes/admin-init.class.php CHANGED
@@ -210,6 +210,7 @@ class Admin_Init extends Init {
210
  * 2. Reworked output.
211
  * 3. Removed unused caching.
212
  * 4. Added dynamic output control.
 
213
  *
214
  * @return array $strings The l10n strings.
215
  */
@@ -227,10 +228,10 @@ class Admin_Init extends Init {
227
  $counter_type = (int) $this->get_user_option( 0, 'counter_type', 3 );
228
 
229
  //* Enunciate the lenghts of Titles and Descriptions.
230
- $good = __( 'Good', 'autodescription' );
231
- $okay = __( 'Okay', 'autodescription' );
232
- $bad = __( 'Bad', 'autodescription' );
233
- $unknown = __( 'Unknown', 'autodescription' );
234
 
235
  $title_separator = $this->get_separator( 'title' );
236
  $description_separator = $this->get_separator( 'description' );
@@ -305,10 +306,21 @@ class Admin_Init extends Init {
305
  $additions = $home_tagline ?: $description;
306
  }
307
 
 
308
  $nonce = \wp_create_nonce( 'autodescription-ajax-nonce' );
309
 
 
 
 
 
 
 
 
 
 
310
  return array(
311
  'nonce' => $nonce,
 
312
  'i18n' => array(
313
  'saveAlert' => \esc_html__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
314
  'confirmReset' => \esc_html__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
@@ -323,6 +335,7 @@ class Admin_Init extends Init {
323
  'hasInput' => $this->is_term_edit() || $this->is_post_edit() || $this->is_seo_settings_page(),
324
  'counterType' => \absint( $counter_type ),
325
  'titleTagline' => $tagline,
 
326
  ),
327
  'params' => array(
328
  'siteTitle' => \esc_html( \wp_kses_decode_entities( $title ) ),
@@ -339,13 +352,13 @@ class Admin_Init extends Init {
339
  /**
340
  * Maintains and Returns additional JS l10n.
341
  *
342
- * They are put under object 'tsfemL10n.other.$key.[ $val ]'.
343
  *
344
  * @since 2.8.0
345
  * @staticvar object $strings The cached strings object.
346
  *
347
- * @param null|string $key The object key. Requires escape.
348
- * @param null|array $val The object val. Requires escape.
349
  * @param bool $get Whether to return the cached strings.
350
  * @param bool $escape Whether to escape the input.
351
  * @return object Early when $get is true
@@ -369,6 +382,73 @@ class Admin_Init extends Init {
369
  $strings->$key = $val;
370
  }
371
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  /**
373
  * CSS for the AutoDescription Bar
374
  *
@@ -442,9 +522,9 @@ class Admin_Init extends Init {
442
  *
443
  * @since 2.2.2
444
  *
445
- * @param string $page Menu slug.
446
- * @param array $query_args Optional. Associative array of query string arguments
447
- * (key => value). Default is an empty array.
448
  * @return null Return early if first argument is false.
449
  */
450
  public function admin_redirect( $page, array $query_args = array() ) {
@@ -469,17 +549,24 @@ class Admin_Init extends Init {
469
  * Handles counter option update on AJAX request.
470
  *
471
  * @since 2.6.0
 
 
472
  * @access private
473
  */
474
  public function wp_ajax_update_counter_type() {
475
 
476
- if ( $this->is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
477
 
 
478
  //* If current user isn't allowed to edit posts, don't do anything and kill PHP.
479
- if ( ! \current_user_can( 'publish_posts' ) )
480
- exit;
 
481
 
482
- \check_ajax_referer( 'autodescription-ajax-nonce', 'nonce' );
 
 
 
483
 
484
  /**
485
  * Count up, reset to 0 if needed. We have 4 options: 0, 1, 2, 3
@@ -507,6 +594,100 @@ class Admin_Init extends Init {
507
 
508
  //* Kill PHP.
509
  exit;
510
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  }
512
  }
210
  * 2. Reworked output.
211
  * 3. Removed unused caching.
212
  * 4. Added dynamic output control.
213
+ * @since 2.9.0 Added boolean $returnValue['states']['isSettingsPage']
214
  *
215
  * @return array $strings The l10n strings.
216
  */
228
  $counter_type = (int) $this->get_user_option( 0, 'counter_type', 3 );
229
 
230
  //* Enunciate the lenghts of Titles and Descriptions.
231
+ $good = \__( 'Good', 'autodescription' );
232
+ $okay = \__( 'Okay', 'autodescription' );
233
+ $bad = \__( 'Bad', 'autodescription' );
234
+ $unknown = \__( 'Unknown', 'autodescription' );
235
 
236
  $title_separator = $this->get_separator( 'title' );
237
  $description_separator = $this->get_separator( 'description' );
306
  $additions = $home_tagline ?: $description;
307
  }
308
 
309
+ //* @TODO deprecate
310
  $nonce = \wp_create_nonce( 'autodescription-ajax-nonce' );
311
 
312
+ $this->set_js_nonces( array(
313
+ /**
314
+ * Use $this->settings_capability() ?... might conflict with other nonces.
315
+ */
316
+ // 'manage_options' => \current_user_can( 'manage_options' ) ? \wp_create_nonce( 'tsf-ajax-manage_options' ) : false,
317
+ 'upload_files' => \current_user_can( 'upload_files' ) ? \wp_create_nonce( 'tsf-ajax-upload_files' ) : false,
318
+ 'edit_posts' => \current_user_can( 'edit_posts' ) ? \wp_create_nonce( 'tsf-ajax-edit_posts' ) : false,
319
+ ) );
320
+
321
  return array(
322
  'nonce' => $nonce,
323
+ 'nonces' => $this->get_js_nonces(),
324
  'i18n' => array(
325
  'saveAlert' => \esc_html__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
326
  'confirmReset' => \esc_html__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
335
  'hasInput' => $this->is_term_edit() || $this->is_post_edit() || $this->is_seo_settings_page(),
336
  'counterType' => \absint( $counter_type ),
337
  'titleTagline' => $tagline,
338
+ 'isSettingsPage' => $this->is_seo_settings_page(),
339
  ),
340
  'params' => array(
341
  'siteTitle' => \esc_html( \wp_kses_decode_entities( $title ) ),
352
  /**
353
  * Maintains and Returns additional JS l10n.
354
  *
355
+ * They are put under object 'tsfemL10n.other[ $key ] = $val'.
356
  *
357
  * @since 2.8.0
358
  * @staticvar object $strings The cached strings object.
359
  *
360
+ * @param null|string $key The object key.
361
+ * @param array $val The object val.
362
  * @param bool $get Whether to return the cached strings.
363
  * @param bool $escape Whether to escape the input.
364
  * @return object Early when $get is true
382
  $strings->$key = $val;
383
  }
384
 
385
+ /**
386
+ * Sets up additional JS l10n values for nonces.
387
+ *
388
+ * They are put under object 'tsfemL10n.nonces[ $key ] = $val'.
389
+ *
390
+ * @since 2.9.0
391
+ *
392
+ * @param string|array $key Required. The object key or array of keys and values. Requires escape.
393
+ * @param mixed $val The object value if $key is string. Requires escape.
394
+ */
395
+ public function set_js_nonces( $key, $val = null ) {
396
+ $this->get_js_nonces( $key, $val, false );
397
+ }
398
+
399
+ /**
400
+ * Maintains and Returns additional JS l10n.
401
+ *
402
+ * They are put under object 'tsfemL10n.nonces[ $key ] = $val'.
403
+ *
404
+ * If $key is an array, $val is ignored and $key's values are used instead.
405
+ *
406
+ * @since 2.9.0
407
+ * @staticvar object $nonces The cached nonces object.
408
+ *
409
+ * @param string|array $key The object key or array of keys and values. Requires escape.
410
+ * @param mixed $val The object value if $key is string. Requires escape.
411
+ * @param bool $get Whether to return the cached nonces.
412
+ * @return object Early when $get is true
413
+ */
414
+ public function get_js_nonces( $key = null, $val = null, $get = true ) {
415
+
416
+ static $nonces = null;
417
+
418
+ if ( null === $nonces )
419
+ $nonces = new \stdClass();
420
+
421
+ if ( $get )
422
+ return $nonces;
423
+
424
+ if ( is_string( $key ) ) {
425
+ $nonces->$key = $val;
426
+ } elseif ( is_array( $key ) ) {
427
+ foreach ( $key as $k => $v ) {
428
+ $nonces->$k = $v;
429
+ }
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Checks ajax referred set by set_js_nonces based on capability.
435
+ *
436
+ * Performs die() on fail.
437
+ *
438
+ * @since 2.9.0
439
+ * @access private
440
+ * It uses an internally and manually created prefix.
441
+ * @uses WP Core check_ajax_referer()
442
+ * @see @link https://developer.wordpress.org/reference/functions/check_ajax_referer/
443
+ *
444
+ * @return false|int False if the nonce is invalid, 1 if the nonce is valid
445
+ * and generated between 0-12 hours ago, 2 if the nonce is
446
+ * valid and generated between 12-24 hours ago.
447
+ */
448
+ public function check_tsf_ajax_referer( $capability ) {
449
+ return \check_ajax_referer( 'tsf-ajax-' . $capability, 'nonce' );
450
+ }
451
+
452
  /**
453
  * CSS for the AutoDescription Bar
454
  *
522
  *
523
  * @since 2.2.2
524
  *
525
+ * @param string $page Menu slug.
526
+ * @param array $query_args Optional. Associative array of query string arguments
527
+ * (key => value). Default is an empty array.
528
  * @return null Return early if first argument is false.
529
  */
530
  public function admin_redirect( $page, array $query_args = array() ) {
549
  * Handles counter option update on AJAX request.
550
  *
551
  * @since 2.6.0
552
+ * @since 2.9.0 : 1. Changed capability from 'publish_posts' to 'edit_posts'.
553
+ * 2. Added json header.
554
  * @access private
555
  */
556
  public function wp_ajax_update_counter_type() {
557
 
558
+ if ( $this->is_admin() && $this->doing_ajax() ) :
559
 
560
+ $this->check_tsf_ajax_referer( 'edit_posts' );
561
  //* If current user isn't allowed to edit posts, don't do anything and kill PHP.
562
+ if ( ! \current_user_can( 'edit_posts' ) ) {
563
+ //* Remove output buffer.
564
+ $this->clean_reponse_header();
565
 
566
+ //* Encode and echo results. Requires JSON decode within JS.
567
+ echo json_encode( array( 'type' => 'failure', 'value' => '' ) );
568
+ exit;
569
+ }
570
 
571
  /**
572
  * Count up, reset to 0 if needed. We have 4 options: 0, 1, 2, 3
594
 
595
  //* Kill PHP.
596
  exit;
597
+ endif;
598
+ }
599
+
600
+ /**
601
+ * Handles cropping of images on AJAX request.
602
+ *
603
+ * Copied from WordPress Core wp_ajax_crop_image.
604
+ * Adjusted: 1. It accepts capability 'upload_files', instead of 'customize'.
605
+ * 2. It now only accepts TSF own AJAX nonces.
606
+ * 3. It now only accepts context 'tsf-image'
607
+ * 4. It no longer accepts a default context.
608
+ *
609
+ * @since 2.9.0
610
+ * @access private
611
+ */
612
+ public function wp_ajax_crop_image() {
613
+
614
+ $this->check_tsf_ajax_referer( 'upload_files' );
615
+ if ( ! \current_user_can( 'upload_files' ) )
616
+ \wp_send_json_error();
617
+
618
+ $attachment_id = \absint( $_POST['id'] );
619
+
620
+ $context = str_replace( '_', '-', $_POST['context'] );
621
+ $data = array_map( 'absint', $_POST['cropDetails'] );
622
+ $cropped = \wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] );
623
+
624
+ if ( ! $cropped || \is_wp_error( $cropped ) )
625
+ \wp_send_json_error( array( 'message' => \esc_js__( 'Image could not be processed.', 'autodescription' ) ) );
626
+
627
+ switch ( $context ) :
628
+ case 'tsf-image':
629
+
630
+ /**
631
+ * Fires before a cropped image is saved.
632
+ *
633
+ * Allows to add filters to modify the way a cropped image is saved.
634
+ *
635
+ * @since 4.3.0 WordPress Core
636
+ *
637
+ * @param string $context The Customizer control requesting the cropped image.
638
+ * @param int $attachment_id The attachment ID of the original image.
639
+ * @param string $cropped Path to the cropped image file.
640
+ */
641
+ \do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped );
642
+
643
+ /** This filter is documented in wp-admin/custom-header.php */
644
+ $cropped = \apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
645
+
646
+ $parent_url = \wp_get_attachment_url( $attachment_id );
647
+ $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
648
+
649
+ $size = @getimagesize( $cropped );
650
+ $image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
651
+
652
+ $object = array(
653
+ 'post_title' => basename( $cropped ),
654
+ 'post_content' => $url,
655
+ 'post_mime_type' => $image_type,
656
+ 'guid' => $url,
657
+ 'context' => $context,
658
+ );
659
+
660
+ $attachment_id = \wp_insert_attachment( $object, $cropped );
661
+ $metadata = \wp_generate_attachment_metadata( $attachment_id, $cropped );
662
+
663
+ /**
664
+ * Filters the cropped image attachment metadata.
665
+ *
666
+ * @since 4.3.0 WordPress Core
667
+ *
668
+ * @see wp_generate_attachment_metadata()
669
+ *
670
+ * @param array $metadata Attachment metadata.
671
+ */
672
+ $metadata = \apply_filters( 'wp_ajax_cropped_attachment_metadata', $metadata );
673
+ \wp_update_attachment_metadata( $attachment_id, $metadata );
674
+
675
+ /**
676
+ * Filters the attachment ID for a cropped image.
677
+ *
678
+ * @since 4.3.0 WordPress Core
679
+ *
680
+ * @param int $attachment_id The attachment ID of the cropped image.
681
+ * @param string $context The Customizer control requesting the cropped image.
682
+ */
683
+ $attachment_id = \apply_filters( 'wp_ajax_cropped_attachment_id', $attachment_id, $context );
684
+ break;
685
+
686
+ default :
687
+ \wp_send_json_error( array( 'message' => \esc_js__( 'Image could not be processed.', 'autodescription' ) ) );
688
+ break;
689
+ endswitch;
690
+
691
+ \wp_send_json_success( \wp_prepare_attachment_for_js( $attachment_id ) );
692
  }
693
  }
inc/classes/admin-pages.class.php CHANGED
@@ -344,6 +344,7 @@ class Admin_Pages extends Inpost {
344
  * Create a 'settings_boxes' method to add metaboxes.
345
  *
346
  * @since 2.2.2
 
347
  */
348
  public function admin() {
349
 
@@ -394,6 +395,7 @@ class Admin_Pages extends Inpost {
394
  * Display notices on the save or reset of settings.
395
  *
396
  * @since 2.2.2
 
397
  *
398
  * @return void
399
  */
@@ -463,8 +465,8 @@ class Admin_Pages extends Inpost {
463
  * @since 2.2.2
464
  * @uses $this->get_field_id() Constructs id attributes for use in form fields.
465
  *
466
- * @param string $id Field id base
467
- * @param boolean $echo echo or return
468
  * @return string Full field id
469
  */
470
  public function field_id( $id, $echo = true ) {
@@ -508,7 +510,7 @@ class Admin_Pages extends Inpost {
508
  * @since 2.6.0
509
  *
510
  * @param string $input The input to wrap. Should already be escaped.
511
- * @param bool $echo Whether to echo or return.
512
  * @return Wrapped $input.
513
  */
514
  public function wrap_fields( $input = '', $echo = false ) {
@@ -815,4 +817,42 @@ class Admin_Pages extends Inpost {
815
  return $class;
816
  }
817
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
818
  }
344
  * Create a 'settings_boxes' method to add metaboxes.
345
  *
346
  * @since 2.2.2
347
+ * @todo deprecate (method name is arbitrary) and convert to view.
348
  */
349
  public function admin() {
350
 
395
  * Display notices on the save or reset of settings.
396
  *
397
  * @since 2.2.2
398
+ * @todo convert the "request" into secure "error_notice" option. See TSF Extension Manager.
399
  *
400
  * @return void
401
  */
465
  * @since 2.2.2
466
  * @uses $this->get_field_id() Constructs id attributes for use in form fields.
467
  *
468
+ * @param string $id Field id base.
469
+ * @param boolean $echo Whether to escape echo or just return.
470
  * @return string Full field id
471
  */
472
  public function field_id( $id, $echo = true ) {
510
  * @since 2.6.0
511
  *
512
  * @param string $input The input to wrap. Should already be escaped.
513
+ * @param boolean $echo Whether to escape echo or just return.
514
  * @return Wrapped $input.
515
  */
516
  public function wrap_fields( $input = '', $echo = false ) {
817
  return $class;
818
  }
819
  }
820
+
821
+ /**
822
+ * Returns social image uploader form button.
823
+ * Also registers additional i18n strings for JS.
824
+ *
825
+ * @since 2.8.0
826
+ * @todo optimize? Sanitation and translations are duplicated -> microseconds...
827
+ *
828
+ * @param string $input_id Required. The HTML input id to pass URL into.
829
+ * @return string The image uploader button.
830
+ */
831
+ public function get_social_image_uploader_form( $input_id ) {
832
+
833
+ if ( ! $input_id )
834
+ return '';
835
+
836
+ $content = sprintf( '<a href="%1$s" class="tsf-set-social-image button button-primary button-small" title="%2$s" id="%3$s-select" data-inputid="%3$s">%4$s</a>',
837
+ \esc_url( \get_upload_iframe_src( 'image', $this->get_the_real_ID() ) ),
838
+ \esc_attr_x( 'Select social image', 'Button hover', 'autodescription' ),
839
+ \esc_attr( $input_id ),
840
+ \esc_html__( 'Select Image', 'autodescription' )
841
+ );
842
+
843
+ $button_labels = array(
844
+ 'select' => \esc_attr__( 'Select Image', 'autodescription' ),
845
+ 'select_title' => \esc_attr_x( 'Select social image', 'Button hover', 'autodescription' ),
846
+ 'change' => \esc_attr__( 'Change Image', 'autodescription' ),
847
+ 'remove' => \esc_attr__( 'Remove Image', 'autodescription' ),
848
+ 'remove_title' => \esc_attr__( 'Remove selected social image', 'autodescription' ),
849
+ 'frame_title' => \esc_attr_x( 'Select Social Image', 'Frame title', 'autodescription' ),
850
+ 'frame_button' => \esc_attr__( 'Use this image', 'autodescription' ),
851
+ );
852
+
853
+ //* Already escaped. Turn off escaping.
854
+ $this->additional_js_l10n( \esc_attr( $input_id ), $button_labels, false, false );
855
+
856
+ return $content;
857
+ }
858
  }
inc/classes/cache.class.php CHANGED
@@ -155,11 +155,14 @@ class Cache extends Sitemaps {
155
  * Flushes front-page and global transients that can be affected by options.
156
  *
157
  * @since 2.8.0
 
 
158
  */
159
  public function delete_main_cache() {
160
  $this->delete_cache( 'front' );
161
  $this->delete_cache( 'sitemap' );
162
  $this->delete_cache( 'robots' );
 
163
  }
164
 
165
  /**
@@ -191,11 +194,25 @@ class Cache extends Sitemaps {
191
  * @since 2.8.0
192
  *
193
  * @param int $user_id The User ID that has been updated.
 
194
  */
195
  public function delete_author_cache( $user_id ) {
196
  return $this->delete_cache( 'author', $user_id );
197
  }
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  /**
200
  * Handles all kinds of cache for removal.
201
  * Main cache deletion function handler.
@@ -275,9 +292,14 @@ class Cache extends Sitemaps {
275
  /**
276
  * Flush whole object cache group.
277
  * Set here for external functions to use. It works because of magic methods.
 
 
 
 
278
  */
279
  case 'objectflush' :
280
- if ( $this->use_object_cache ) {
 
281
  if ( isset( $GLOBALS['wp_object_cache']->cache['the_seo_framework'] ) ) {
282
  $_cache = $GLOBALS['wp_object_cache']->cache;
283
  unset( $_cache['the_seo_framework'] );
@@ -560,7 +582,7 @@ class Cache extends Sitemaps {
560
 
561
  if ( $this->is_404() ) {
562
  $the_id = '_404_';
563
- } elseif ( ( $this->is_front_page( $page_id ) ) || ( $this->is_admin() && $this->is_seo_settings_page( true ) ) ) {
564
  //* Front/HomePage.
565
  $the_id = $this->generate_front_page_cache_key();
566
  } elseif ( $this->is_blog_page( $page_id ) ) {
@@ -838,7 +860,7 @@ class Cache extends Sitemaps {
838
 
839
  if ( isset( $_POST['permalink_structure'] ) || isset( $_POST['category_base'] ) ) {
840
 
841
- if ( check_admin_referer( 'update-permalink' ) )
842
  return $this->delete_cache( 'sitemap' );
843
  }
844
 
@@ -965,6 +987,8 @@ class Cache extends Sitemaps {
965
  *
966
  * @since 2.5.2
967
  * @since 2.7.0 : Will always set "doing it wrong" transient, even if it was "doing it right" earlier.
 
 
968
  *
969
  * @NOTE: Ignores transient debug constant and options.
970
  *
155
  * Flushes front-page and global transients that can be affected by options.
156
  *
157
  * @since 2.8.0
158
+ * @since 2.9.0 : Added object cache flush.
159
+ * @TODO make 2.9 note work.
160
  */
161
  public function delete_main_cache() {
162
  $this->delete_cache( 'front' );
163
  $this->delete_cache( 'sitemap' );
164
  $this->delete_cache( 'robots' );
165
+ // $this->delete_cache( 'objectflush' );
166
  }
167
 
168
  /**
194
  * @since 2.8.0
195
  *
196
  * @param int $user_id The User ID that has been updated.
197
+ * @return bool True on success, false on failure.
198
  */
199
  public function delete_author_cache( $user_id ) {
200
  return $this->delete_cache( 'author', $user_id );
201
  }
202
 
203
+ /**
204
+ * Deletes object cache.
205
+ *
206
+ * @since 2.9.0
207
+ * @TODO make this work.
208
+ *
209
+ * @return bool True on success, false on failure.
210
+ */
211
+ public function delete_object_cache() {
212
+ return false;
213
+ // return $this->delete_cache( 'objectflush' );
214
+ }
215
+
216
  /**
217
  * Handles all kinds of cache for removal.
218
  * Main cache deletion function handler.
292
  /**
293
  * Flush whole object cache group.
294
  * Set here for external functions to use. It works because of magic methods.
295
+ *
296
+ * @NOTE Other caching plugins can override these groups. Therefore this
297
+ * does NOT work.
298
+ * @TODO make this work.
299
  */
300
  case 'objectflush' :
301
+ //* @NOTE false can't pass.
302
+ if ( false && $this->use_object_cache ) {
303
  if ( isset( $GLOBALS['wp_object_cache']->cache['the_seo_framework'] ) ) {
304
  $_cache = $GLOBALS['wp_object_cache']->cache;
305
  unset( $_cache['the_seo_framework'] );
582
 
583
  if ( $this->is_404() ) {
584
  $the_id = '_404_';
585
+ } elseif ( ( $this->is_real_front_page() || $this->is_front_page_by_id( $page_id ) ) || ( $this->is_admin() && $this->is_seo_settings_page( true ) ) ) {
586
  //* Front/HomePage.
587
  $the_id = $this->generate_front_page_cache_key();
588
  } elseif ( $this->is_blog_page( $page_id ) ) {
860
 
861
  if ( isset( $_POST['permalink_structure'] ) || isset( $_POST['category_base'] ) ) {
862
 
863
+ if ( \check_admin_referer( 'update-permalink' ) )
864
  return $this->delete_cache( 'sitemap' );
865
  }
866
 
987
  *
988
  * @since 2.5.2
989
  * @since 2.7.0 : Will always set "doing it wrong" transient, even if it was "doing it right" earlier.
990
+ * WordPress get_all_options will prevent multiple DB writes.
991
+ * Returning false on set_transient() as it was already set to '0'.
992
  *
993
  * @NOTE: Ignores transient debug constant and options.
994
  *
inc/classes/core.class.php CHANGED
@@ -133,13 +133,17 @@ class Core {
133
  * Destroys output buffer, if any. To be used with AJAX and XML to clear any PHP errors or dumps.
134
  *
135
  * @since 2.8.0
 
136
  *
137
  * @return bool True on clear. False otherwise.
138
  */
139
  protected function clean_reponse_header() {
140
 
141
- if ( ob_get_level() && ob_get_contents() ) {
142
- ob_clean();
 
 
 
143
  return true;
144
  }
145
 
@@ -152,13 +156,12 @@ class Core {
152
  *
153
  * @since 2.7.0
154
  * @access private
 
155
  *
156
  * @param string $view The file name.
157
  * @param array $args The arguments to be supplied within the file name.
158
  * Each array key is converted to a variable with its value attached.
159
  * @param string $instance The instance suffix to call back upon.
160
- *
161
- * @credits Akismet For some code.
162
  */
163
  public function get_view( $view, array $args = array(), $instance = 'main' ) {
164
 
@@ -721,6 +724,7 @@ class Core {
721
  * Calculates the relative font color according to the background.
722
  *
723
  * @since 2.8.0
 
724
  *
725
  * @param string $hex The 3 to 6 character RGB hex. '#' prefix is supported.
726
  * @return string The hexadecimal RGB relative font color, without '#' prefix.
@@ -747,12 +751,10 @@ class Core {
747
  $rel_lum = 1 - ( $sr + $sg + $sb ) / 255;
748
 
749
  //* Convert to relative intvals between 1 and 0 for L from HSL
750
- /*
751
- $rr = $r / 255;
752
- $rg = $g / 255;
753
- $rb = $b / 255;
754
- $luminance = ( min( $rr, $rg, $rb ) + max( $rr, $rg, $rb ) ) / 2;
755
- */
756
 
757
  //* Get perceptive luminance (greyscale) according to W3C.
758
  $gr = 0.2989 * $r;
@@ -763,14 +765,14 @@ class Core {
763
  //* Invert colors if they hit luminance boundaries.
764
  if ( $rel_lum < 0.5 ) {
765
  //* Build dark. Add softness.
766
- $gr = $gr * $per_lum / 8 / 0.2989 + 8 * 0.2989;
767
- $gg = $gg * $per_lum / 8 / 0.5870 + 8 * 0.5870;
768
- $gb = $gb * $per_lum / 8 / 0.1140 + 8 * 0.1140;
769
  } else {
770
  //* Build light. Add (subtract) softness.
771
- $gr = 255 - $gr * $per_lum / 8 * 0.2989 - 8 * 0.2989;
772
- $gg = 255 - $gg * $per_lum / 8 * 0.5870 - 8 * 0.5870;
773
- $gb = 255 - $gb * $per_lum / 8 * 0.1140 - 8 * 0.1140;
774
  }
775
 
776
  //* Complete hexvals.
@@ -788,6 +790,9 @@ class Core {
788
  * Note: This code has been rightfully stolen from the Extension Manager plugin (sorry Sybre!).
789
  *
790
  * @since 2.8.0
 
 
 
791
  * @link https://wordpress.org/plugins/about/readme.txt
792
  *
793
  * @param string $text The text that might contain markdown. Expected to be escaped.
@@ -827,8 +832,7 @@ class Core {
827
  foreach ( $md_types as $type ) :
828
  switch ( $type ) :
829
  case 'strong' :
830
- //* Considers word boundary. @TODO consider removing this?
831
- $count = preg_match_all( '/(?:\*{2})\b([^\*{2}]+)(?:\*{2})/', $text, $matches, PREG_PATTERN_ORDER );
832
 
833
  for ( $i = 0; $i < $count; $i++ ) {
834
  $text = str_replace(
@@ -840,7 +844,7 @@ class Core {
840
  break;
841
 
842
  case 'em' :
843
- $count = preg_match_all( '/(?:\*{1})([^\*{1}]+)(?:\*{1})/', $text, $matches, PREG_PATTERN_ORDER );
844
 
845
  for ( $i = 0; $i < $count; $i++ ) {
846
  $text = str_replace(
@@ -852,7 +856,7 @@ class Core {
852
  break;
853
 
854
  case 'code' :
855
- $count = preg_match_all( '/(?:`{1})([^`{1}]+)(?:`{1})/', $text, $matches, PREG_PATTERN_ORDER );
856
 
857
  for ( $i = 0; $i < $count; $i++ ) {
858
  $text = str_replace(
@@ -871,7 +875,7 @@ class Core {
871
  case 'h1' :
872
  $amount = filter_var( $type, FILTER_SANITIZE_NUMBER_INT );
873
  //* Considers word non-boundary. @TODO consider removing this?
874
- $expression = "/(?:={{$amount}})\B([^={{$amount}}]+?)\B(?:={{$amount}})/";
875
  $count = preg_match_all( $expression, $text, $matches, PREG_PATTERN_ORDER );
876
 
877
  for ( $i = 0; $i < $count; $i++ ) {
133
  * Destroys output buffer, if any. To be used with AJAX and XML to clear any PHP errors or dumps.
134
  *
135
  * @since 2.8.0
136
+ * @since 2.9.0 : Now flushes all levels rather than just the latest one.
137
  *
138
  * @return bool True on clear. False otherwise.
139
  */
140
  protected function clean_reponse_header() {
141
 
142
+ if ( $level = ob_get_level() ) {
143
+ while ( $level ) {
144
+ ob_end_clean();
145
+ $level--;
146
+ }
147
  return true;
148
  }
149
 
156
  *
157
  * @since 2.7.0
158
  * @access private
159
+ * @credits Akismet For some code.
160
  *
161
  * @param string $view The file name.
162
  * @param array $args The arguments to be supplied within the file name.
163
  * Each array key is converted to a variable with its value attached.
164
  * @param string $instance The instance suffix to call back upon.
 
 
165
  */
166
  public function get_view( $view, array $args = array(), $instance = 'main' ) {
167
 
724
  * Calculates the relative font color according to the background.
725
  *
726
  * @since 2.8.0
727
+ * @since 2.9.0 Now adds a little more relative softness based on rel_lum.
728
  *
729
  * @param string $hex The 3 to 6 character RGB hex. '#' prefix is supported.
730
  * @return string The hexadecimal RGB relative font color, without '#' prefix.
751
  $rel_lum = 1 - ( $sr + $sg + $sb ) / 255;
752
 
753
  //* Convert to relative intvals between 1 and 0 for L from HSL
754
+ // $rr = $r / 255;
755
+ // $rg = $g / 255;
756
+ // $rb = $b / 255;
757
+ // $luminance = ( min( $rr, $rg, $rb ) + max( $rr, $rg, $rb ) ) / 2;
 
 
758
 
759
  //* Get perceptive luminance (greyscale) according to W3C.
760
  $gr = 0.2989 * $r;
765
  //* Invert colors if they hit luminance boundaries.
766
  if ( $rel_lum < 0.5 ) {
767
  //* Build dark. Add softness.
768
+ $gr = $gr * $per_lum / 8 / 0.2989 + 8 * 0.2989 / $rel_lum;
769
+ $gg = $gg * $per_lum / 8 / 0.5870 + 8 * 0.5870 / $rel_lum;
770
+ $gb = $gb * $per_lum / 8 / 0.1140 + 8 * 0.1140 / $rel_lum;
771
  } else {
772
  //* Build light. Add (subtract) softness.
773
+ $gr = 255 - $gr * $per_lum / 8 * 0.2989 - 8 * 0.2989 / $rel_lum;
774
+ $gg = 255 - $gg * $per_lum / 8 * 0.5870 - 8 * 0.5870 / $rel_lum;
775
+ $gb = 255 - $gb * $per_lum / 8 * 0.1140 - 8 * 0.1140 / $rel_lum;
776
  }
777
 
778
  //* Complete hexvals.
790
  * Note: This code has been rightfully stolen from the Extension Manager plugin (sorry Sybre!).
791
  *
792
  * @since 2.8.0
793
+ * @since 2.9.0 : 1. Removed word boundary requirement for strong.
794
+ * 2. Now accepts regex count their numeric values in string.
795
+ * 3. Fixed header 1~6 calculation.
796
  * @link https://wordpress.org/plugins/about/readme.txt
797
  *
798
  * @param string $text The text that might contain markdown. Expected to be escaped.
832
  foreach ( $md_types as $type ) :
833
  switch ( $type ) :
834
  case 'strong' :
835
+ $count = preg_match_all( '/(?:\*{2})([^\*{\2}]+)(?:\*{2})/', $text, $matches, PREG_PATTERN_ORDER );
 
836
 
837
  for ( $i = 0; $i < $count; $i++ ) {
838
  $text = str_replace(
844
  break;
845
 
846
  case 'em' :
847
+ $count = preg_match_all( '/(?:\*{1})([^\*{\1}]+)(?:\*{1})/', $text, $matches, PREG_PATTERN_ORDER );
848
 
849
  for ( $i = 0; $i < $count; $i++ ) {
850
  $text = str_replace(
856
  break;
857
 
858
  case 'code' :
859
+ $count = preg_match_all( '/(?:`{1})([^`{\1}]+)(?:`{1})/', $text, $matches, PREG_PATTERN_ORDER );
860
 
861
  for ( $i = 0; $i < $count; $i++ ) {
862
  $text = str_replace(
875
  case 'h1' :
876
  $amount = filter_var( $type, FILTER_SANITIZE_NUMBER_INT );
877
  //* Considers word non-boundary. @TODO consider removing this?
878
+ $expression = sprintf( '/(?:\={%1$s})\B([^\={\%1$s}]+)\B(?:\={%1$s})/', $amount );
879
  $count = preg_match_all( $expression, $text, $matches, PREG_PATTERN_ORDER );
880
 
881
  for ( $i = 0; $i < $count; $i++ ) {
inc/classes/debug.class.php CHANGED
@@ -895,7 +895,8 @@ final class Debug implements Debug_Interface {
895
  //* Don't register this output.
896
  $this->add_debug_output = false;
897
 
898
- $output = $tsf->the_description()
 
899
  . $tsf->og_image()
900
  . $tsf->og_locale()
901
  . $tsf->og_type()
@@ -925,7 +926,7 @@ final class Debug implements Debug_Interface {
925
 
926
  $timer = '<div style="display:inline-block;width:100%;padding:20px;border-bottom:1px solid #ccc;">Generated in: ' . number_format( $this->timer(), 5 ) . ' seconds</div>' ;
927
 
928
- $title = $tsf->is_admin() ? 'Expected SEO Output' : 'Current SEO Output';
929
  $title = '<div style="display:inline-block;width:100%;padding:20px;margin:0 auto;border-bottom:1px solid #ccc;"><h2 style="color:#ddd;font-size:22px;padding:0;margin:0">' . $title . '</h2></div>';
930
 
931
  //* Escape it, replace EOL with breaks, and style everything between quotes (which are ending with space).
@@ -1020,6 +1021,7 @@ final class Debug implements Debug_Interface {
1020
  $tsf = \the_seo_framework();
1021
 
1022
  //* Only get true/false values.
 
1023
  $is_404 = $tsf->is_404();
1024
  $is_admin = $tsf->is_admin();
1025
  $is_attachment = $tsf->is_attachment();
@@ -1034,7 +1036,8 @@ final class Debug implements Debug_Interface {
1034
  $is_date = $tsf->is_date();
1035
  $is_day = $tsf->is_day();
1036
  $is_feed = $tsf->is_feed();
1037
- $is_front_page = $tsf->is_front_page();
 
1038
  $is_home = $tsf->is_home();
1039
  $is_month = $tsf->is_month();
1040
  $is_page = $tsf->is_page();
895
  //* Don't register this output.
896
  $this->add_debug_output = false;
897
 
898
+ $output = $tsf->robots()
899
+ . $tsf->the_description()
900
  . $tsf->og_image()
901
  . $tsf->og_locale()
902
  . $tsf->og_type()
926
 
927
  $timer = '<div style="display:inline-block;width:100%;padding:20px;border-bottom:1px solid #ccc;">Generated in: ' . number_format( $this->timer(), 5 ) . ' seconds</div>' ;
928
 
929
+ $title = $tsf->is_admin() ? 'Expected SEO Output' : 'Determined SEO Output';
930
  $title = '<div style="display:inline-block;width:100%;padding:20px;margin:0 auto;border-bottom:1px solid #ccc;"><h2 style="color:#ddd;font-size:22px;padding:0;margin:0">' . $title . '</h2></div>';
931
 
932
  //* Escape it, replace EOL with breaks, and style everything between quotes (which are ending with space).
1021
  $tsf = \the_seo_framework();
1022
 
1023
  //* Only get true/false values.
1024
+ $page_id = $tsf->get_the_real_ID();
1025
  $is_404 = $tsf->is_404();
1026
  $is_admin = $tsf->is_admin();
1027
  $is_attachment = $tsf->is_attachment();
1036
  $is_date = $tsf->is_date();
1037
  $is_day = $tsf->is_day();
1038
  $is_feed = $tsf->is_feed();
1039
+ $is_real_front_page = $tsf->is_real_front_page();
1040
+ $is_front_page_by_id = $tsf->is_front_page_by_id( $tsf->get_the_real_ID() );
1041
  $is_home = $tsf->is_home();
1042
  $is_month = $tsf->is_month();
1043
  $is_page = $tsf->is_page();
inc/classes/deprecated.class.php CHANGED
@@ -97,7 +97,7 @@ final class Deprecated {
97
 
98
  \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'The_SEO_Framework_Transients::delete_auto_description_frontpage_transient()' );
99
 
100
- \the_seo_framework()->delete_auto_description_transient( the_seo_framework()->get_the_front_page_ID(), '', 'frontpage' );
101
 
102
  return $old_option;
103
  }
@@ -502,4 +502,243 @@ final class Deprecated {
502
 
503
  return $data;
504
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  }
97
 
98
  \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'The_SEO_Framework_Transients::delete_auto_description_frontpage_transient()' );
99
 
100
+ \the_seo_framework()->delete_auto_description_transient( \the_seo_framework()->get_the_front_page_ID(), '', 'frontpage' );
101
 
102
  return $old_option;
103
  }
502
 
503
  return $data;
504
  }
505
+
506
+ /**
507
+ * Fetches og:image URL.
508
+ *
509
+ * @since 2.2.2
510
+ * @since 2.2.8 : Added theme icon detection.
511
+ * @since 2.5.2 : Added args filters.
512
+ * @since 2.8.0 : 1. Added theme logo detection.
513
+ * 2. Added inpost image selection detection.
514
+ * @since 2.8.2 : 1. Now returns something on post ID 0.
515
+ * 2. Added SEO settings fallback image selection detection.
516
+ * @since 2.9.0 : 1. Added 'skip_fallback' option to arguments.
517
+ * 2. Added 'escape' option to arguments.
518
+ * 3. First parameter is now arguments. Fallback for integer is added.
519
+ * 4. Second parameter is now deprecated.
520
+ * 5. Deprecated.
521
+ * @deprecated Use get_social_image instead.
522
+ *
523
+ * @param int|array $args The image arguments.
524
+ * Was: $post_id.
525
+ * Warning: Integer usage is only used for backwards compat.
526
+ * @param array $depr_args, Deprecated;
527
+ * Was $args The image arguments.
528
+ * @param bool $escape Whether to escape the image URL.
529
+ * Deprecated: You should use $args['escape'].
530
+ * @return string the image URL.
531
+ */
532
+ public function get_image( $args = array(), $depr_args = '', $depr_escape = true ) {
533
+
534
+ $tsf = \the_seo_framework();
535
+
536
+ $tsf->_deprecated_function( 'the_seo_framework()->get_image()', '2.9.0', 'the_seo_framework()->get_social_image()' );
537
+
538
+ if ( is_int( $args ) || is_array( $depr_args ) ) {
539
+ $tsf->_doing_it_wrong( __METHOD__, 'First parameter is now used for arguments. Second parameter is deprecated.', '2.9.0' );
540
+
541
+ $post_id = $args;
542
+ $args = array();
543
+
544
+ /**
545
+ * Backwards compat with parse args.
546
+ * @since 2.5.0
547
+ */
548
+ if ( ! isset( $depr_args['post_id'] ) ) {
549
+ $args['post_id'] = $post_id ?: ( $tsf->is_singular( $post_id ) ? $tsf->get_the_real_ID() : 0 );
550
+ }
551
+
552
+ if ( is_array( $depr_args ) ) {
553
+ $args = \wp_parse_args( $depr_args, $args );
554
+ }
555
+ }
556
+
557
+ if ( false === $depr_escape ) {
558
+ $tsf->_doing_it_wrong( __METHOD__, 'Third parameter has been deprecated. Use `$args["escape"] => false` instead.', '2.9.0' );
559
+ $args['escape'] = false;
560
+ }
561
+
562
+ $args = $tsf->reparse_image_args( $args );
563
+
564
+ //* 0. Image from argument.
565
+ pre_0 : {
566
+ if ( $image = $args['image'] )
567
+ goto end;
568
+ }
569
+
570
+ //* Check if there are no disallowed arguments.
571
+ $all_allowed = empty( $args['disallowed'] );
572
+
573
+ //* 1. Fetch image from homepage SEO meta upload.
574
+ if ( $all_allowed || false === in_array( 'homemeta', $args['disallowed'], true ) ) {
575
+ if ( $image = $tsf->get_social_image_url_from_home_meta( $args['post_id'], true ) )
576
+ goto end;
577
+ }
578
+
579
+ if ( $args['post_id'] ) {
580
+ //* 2. Fetch image from SEO meta upload.
581
+ if ( $all_allowed || false === in_array( 'postmeta', $args['disallowed'], true ) ) {
582
+ if ( $image = $tsf->get_social_image_url_from_post_meta( $args['post_id'], true ) )
583
+ goto end;
584
+ }
585
+
586
+ //* 3. Fetch image from featured.
587
+ if ( $all_allowed || false === in_array( 'featured', $args['disallowed'], true ) ) {
588
+ if ( $image = $tsf->get_image_from_post_thumbnail( $args, true ) )
589
+ goto end;
590
+ }
591
+ }
592
+
593
+ if ( $args['skip_fallback'] )
594
+ goto end;
595
+
596
+ //* 4. Fetch image from SEO settings
597
+ if ( $all_allowed || false === in_array( 'option', $args['disallowed'], true ) ) {
598
+ if ( $image = $tsf->get_social_image_url_from_seo_settings( true ) )
599
+ goto end;
600
+ }
601
+
602
+ //* 5. Fetch image from fallback filter 1
603
+ /**
604
+ * Applies filters 'the_seo_framework_og_image_after_featured' : string
605
+ * @since 2.5.2
606
+ */
607
+ fallback_1 : {
608
+ if ( $image = (string) \apply_filters( 'the_seo_framework_og_image_after_featured', '', $args['post_id'] ) )
609
+ goto end;
610
+ }
611
+
612
+ //* 6. Fallback: Get header image if exists
613
+ if ( ( $all_allowed || false === in_array( 'header', $args['disallowed'], true ) ) && \current_theme_supports( 'custom-header', 'default-image' ) ) {
614
+ if ( $image = $tsf->get_header_image( true ) )
615
+ goto end;
616
+ }
617
+
618
+ //* 7. Fetch image from fallback filter 2
619
+ /**
620
+ * Applies filters 'the_seo_framework_og_image_after_header' : string
621
+ * @since 2.5.2
622
+ */
623
+ fallback_2 : {
624
+ if ( $image = (string) \apply_filters( 'the_seo_framework_og_image_after_header', '', $args['post_id'] ) )
625
+ goto end;
626
+ }
627
+
628
+ //* 8. Get the WP 4.5 Site Logo
629
+ if ( ( $all_allowed || false === in_array( 'logo', $args['disallowed'], true ) ) && $tsf->can_use_logo() ) {
630
+ if ( $image = $tsf->get_site_logo( true ) )
631
+ goto end;
632
+ }
633
+
634
+ //* 9. Get the WP 4.3 Site Icon
635
+ if ( $all_allowed || false === in_array( 'icon', $args['disallowed'], true ) ) {
636
+ if ( $image = $tsf->get_site_icon( 'full', true ) )
637
+ goto end;
638
+ }
639
+
640
+ end :;
641
+
642
+ if ( $args['escape'] && $image )
643
+ $image = \esc_url( $image );
644
+
645
+ return (string) $image;
646
+ }
647
+
648
+ /**
649
+ * Fetches image from post thumbnail.
650
+ * Resizes the image between 1500px if bigger. Then it saves the image and
651
+ * Keeps dimensions relative.
652
+ *
653
+ * @since 2.3.0
654
+ * @since 2.9.0 Changed parameters.
655
+ * @since 2.9.0 Deprecated.
656
+ * @deprecated
657
+ *
658
+ * @param array $args The image args.
659
+ * Was: int $id The post/page ID.
660
+ * @param bool $set_og_dimensions Whether to set Open Graph image dimensions.
661
+ * Was: array $depr_args Deprecated. Image arguments.
662
+ * @return string|null the image url.
663
+ */
664
+ public function get_image_from_post_thumbnail( $args = array(), $set_og_dimensions = false ) {
665
+
666
+ $tsf = \the_seo_framework();
667
+
668
+ $tsf->_deprecated_function( 'the_seo_framework()->get_image_from_post_thumbnail()', '2.9.0', 'the_seo_framework()->get_social_image_url_from_post_thumbnail()' );
669
+
670
+ if ( is_array( $set_og_dimensions ) ) {
671
+ $tsf->_doing_it_wrong( __METHOD__, 'First parameter are now arguments, second parameter is for setting og dimensions.', '2.9.0' );
672
+ $args = $set_og_dimensions;
673
+ $set_og_dimensions = false;
674
+ }
675
+
676
+ $args = $tsf->reparse_image_args( $args );
677
+
678
+ $id = \get_post_thumbnail_id( $args['post_id'] );
679
+
680
+ $args['get_the_real_ID'] = true;
681
+
682
+ $image = $id ? $tsf->parse_og_image( $id, $args, $set_og_dimensions ) : '';
683
+
684
+ return $image;
685
+ }
686
+
687
+ /**
688
+ * Detects front page.
689
+ *
690
+ * Returns true on SEO settings page if ID is 0.
691
+ *
692
+ * @since 2.6.0
693
+ * @since 2.9.0: Deprecated.
694
+ * @deprecated
695
+ *
696
+ * @param int $id The Page or Post ID.
697
+ * @return bool
698
+ */
699
+ public function is_front_page( $id = 0 ) {
700
+
701
+ $tsf = \the_seo_framework();
702
+
703
+ $tsf->_deprecated_function( 'the_seo_framework()->is_front_page()', '2.9.0', 'the_seo_framework()->is_real_front_page() or the_seo_framework()->is_front_page_by_id()' );
704
+
705
+ static $cache = array();
706
+
707
+ if ( null !== $cache = $tsf->get_query_cache( __METHOD__, null, $id ) )
708
+ return $cache;
709
+
710
+ $is_front_page = false;
711
+
712
+ if ( \is_front_page() && empty( $id ) )
713
+ $is_front_page = true;
714
+
715
+ //* Elegant Themes Support. Yay.
716
+ if ( false === $is_front_page && empty( $id ) && $tsf->is_home() ) {
717
+ $sof = \get_option( 'show_on_front' );
718
+
719
+ if ( 'page' !== $sof && 'posts' !== $sof )
720
+ $is_front_page = true;
721
+ }
722
+
723
+ //* Compare against $id
724
+ if ( false === $is_front_page && $id ) {
725
+ $sof = \get_option( 'show_on_front' );
726
+
727
+ if ( 'page' === $sof && (int) \get_option( 'page_on_front' ) === $id )
728
+ $is_front_page = true;
729
+
730
+ if ( 'posts' === $sof && (int) \get_option( 'page_for_posts' ) === $id )
731
+ $is_front_page = true;
732
+ } elseif ( empty( $id ) && $tsf->is_seo_settings_page() ) {
733
+ $is_front_page = true;
734
+ }
735
+
736
+ $tsf->set_query_cache(
737
+ __METHOD__,
738
+ $is_front_page,
739
+ $id
740
+ );
741
+
742
+ return $is_front_page;
743
+ }
744
  }
inc/classes/detect.class.php CHANGED
@@ -41,6 +41,23 @@ class Detect extends Render {
41
  parent::__construct();
42
  }
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  /**
45
  * Returns list of active plugins.
46
  *
@@ -500,6 +517,7 @@ class Detect extends Render {
500
  *
501
  * @since 2.6.0
502
  * @since 2.8.0 Added check_option parameter.
 
503
  *
504
  * @param bool $check_option Whether to check for sitemap option.
505
  * @return bool True when no conflicting plugins are detected or when The SEO Framework's Sitemaps are output.
@@ -520,6 +538,9 @@ class Detect extends Render {
520
  return false;
521
  }
522
 
 
 
 
523
  return true;
524
  }
525
 
@@ -1033,4 +1054,19 @@ class Detect extends Render {
1033
 
1034
  return isset( $cache ) ? $cache : $this->wp_version( '4.5.0', '>=' ) && \current_theme_supports( 'custom-logo' );
1035
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1036
  }
41
  parent::__construct();
42
  }
43
 
44
+ /**
45
+ * Determines if we're doing ajax.
46
+ *
47
+ * @since 2.9.0
48
+ * @staticvar bool $cache
49
+ *
50
+ * @return bool True if AJAX
51
+ */
52
+ public function doing_ajax() {
53
+
54
+ static $cache = null;
55
+
56
+ null === $cache and $cache = defined( 'DOING_AJAX' ) && DOING_AJAX;
57
+
58
+ return $cache;
59
+ }
60
+
61
  /**
62
  * Returns list of active plugins.
63
  *
517
  *
518
  * @since 2.6.0
519
  * @since 2.8.0 Added check_option parameter.
520
+ * @since 2.9.0 Now also checks for subdirectory installations.
521
  *
522
  * @param bool $check_option Whether to check for sitemap option.
523
  * @return bool True when no conflicting plugins are detected or when The SEO Framework's Sitemaps are output.
538
  return false;
539
  }
540
 
541
+ if ( $this->is_subdirectory_installation() )
542
+ return false;
543
+
544
  return true;
545
  }
546
 
1054
 
1055
  return isset( $cache ) ? $cache : $this->wp_version( '4.5.0', '>=' ) && \current_theme_supports( 'custom-logo' );
1056
  }
1057
+
1058
+ /**
1059
+ * Determines if the current installation is on a subdirectory.
1060
+ *
1061
+ * @since 2.9.0-
1062
+ * @staticvar $bool $cache
1063
+ *
1064
+ * @return bool
1065
+ */
1066
+ public function is_subdirectory_installation() {
1067
+
1068
+ static $cache = null;
1069
+
1070
+ return isset( $cache ) ? $cache : '' !== $this->get_home_path();
1071
+ }
1072
  }
inc/classes/doing-it-right.class.php CHANGED
@@ -95,7 +95,7 @@ class Doing_It_Right extends Generate_Ldjson {
95
  /**
96
  * Securely check the referrer, instead of leaving holes everywhere.
97
  */
98
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX && \check_ajax_referer( 'add-tag', '_wpnonce_add-tag', false ) ) {
99
 
100
  $taxonomy = ! empty( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : 'post_tag';
101
  $tax = \get_taxonomy( $taxonomy );
@@ -106,28 +106,38 @@ class Doing_It_Right extends Generate_Ldjson {
106
  }
107
 
108
  /**
109
- * Initializes columns
110
- *
111
- * Applies filter the_seo_framework_show_seo_column : Boolean Show the SEO column in edit.php
112
  *
113
  * @since 2.1.9
114
  *
115
  * @param object|empty $screen WP_Screen
116
  * @param bool $doing_ajax Whether we're doing an AJAX response.
 
117
  */
118
  public function init_columns( $screen = '', $doing_ajax = false ) {
119
 
 
 
 
 
 
 
 
120
  $show_seo_column = (bool) \apply_filters( 'the_seo_framework_show_seo_column', true );
121
 
 
 
 
122
  if ( $doing_ajax ) {
123
  $post_type = isset( $_POST['post_type'] ) ? $_POST['post_type'] : '';
124
  } else {
125
  $post_type = isset( $screen->post_type ) ? $screen->post_type : '';
126
  }
127
 
128
- if ( $show_seo_column && $this->post_type_supports_custom_seo( $post_type ) ) {
129
  if ( $doing_ajax ) {
130
 
 
131
  $id = isset( $_POST['screen'] ) ? $_POST['screen'] : false;
132
  $taxonomy = isset( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : false;
133
 
@@ -509,7 +519,7 @@ class Doing_It_Right extends Generate_Ldjson {
509
 
510
  $data = $this->get_term_data( $term, $term->term_id );
511
 
512
- $noindex = isset( $data['noindex'] ) && $this->is_checked( $data['noindex'] );
513
  $redirect = false; // We don't apply redirect on taxonomies (yet)
514
 
515
  //* Blocked SEO, return simple bar.
@@ -549,14 +559,11 @@ class Doing_It_Right extends Generate_Ldjson {
549
  $is_term = false;
550
  $is_front_page = $this->is_static_frontpage( $post_id );
551
 
552
- $redirect = $this->get_custom_field( 'redirect', $post_id );
553
- $redirect = empty( $redirect ) ? false : true;
554
-
555
- $noindex = $this->get_custom_field( '_genesis_noindex', $post_id );
556
- $noindex = $this->is_checked( $noindex );
557
 
558
  if ( $is_front_page )
559
- $noindex = $this->is_option_checked( 'homepage_noindex' ) ? true : $noindex;
560
 
561
  if ( $redirect || $noindex )
562
  return $this->the_seo_bar_blocked( array( 'is_term' => $is_term, 'redirect' => $redirect, 'noindex' => $noindex, 'post_i18n' => $post ) );
@@ -609,6 +616,7 @@ class Doing_It_Right extends Generate_Ldjson {
609
  * Fetch the term data for The SEO Bar.
610
  *
611
  * @since 2.6.0
 
612
  * @staticvar array $data
613
  *
614
  * @param array $args The term args.
@@ -617,6 +625,7 @@ class Doing_It_Right extends Generate_Ldjson {
617
  * 'title_is_from_custom_field' => $title_is_from_custom_field,
618
  * 'description' => $description,
619
  * 'description_is_from_custom_field' => $description_is_from_custom_field,
 
620
  * 'nofollow' => $nofollow,
621
  * 'noarchive' => $noarchive
622
  * }
@@ -631,6 +640,7 @@ class Doing_It_Right extends Generate_Ldjson {
631
 
632
  $title_custom_field = isset( $data['doctitle'] ) ? $data['doctitle'] : '';
633
  $description_custom_field = isset( $data['description'] ) ? $data['description'] : '';
 
634
  $nofollow = isset( $data['nofollow'] ) ? $data['nofollow'] : '';
635
  $noarchive = isset( $data['noarchive'] ) ? $data['noarchive'] : '';
636
 
@@ -654,14 +664,19 @@ class Doing_It_Right extends Generate_Ldjson {
654
  $description = $this->generate_description( '', $description_args );
655
  }
656
 
657
- $nofollow = $this->is_checked( $nofollow );
658
- $noarchive = $this->is_checked( $noarchive );
 
 
 
 
659
 
660
  return array(
661
  'title' => $title,
662
  'title_is_from_custom_field' => $title_is_from_custom_field,
663
  'description' => $description,
664
  'description_is_from_custom_field' => $description_is_from_custom_field,
 
665
  'nofollow' => $nofollow,
666
  'noarchive' => $noarchive,
667
  );
@@ -671,6 +686,7 @@ class Doing_It_Right extends Generate_Ldjson {
671
  * Fetch the post data for The SEO Bar.
672
  *
673
  * @since 2.6.0
 
674
  * @staticvar array $data
675
  *
676
  * @param array $args The post args.
@@ -679,6 +695,7 @@ class Doing_It_Right extends Generate_Ldjson {
679
  * 'title_is_from_custom_field' => $title_is_from_custom_field,
680
  * 'description' => $description,
681
  * 'description_is_from_custom_field' => $description_is_from_custom_field,
 
682
  * 'nofollow' => $nofollow,
683
  * 'noarchive' => $noarchive
684
  * }
@@ -690,14 +707,16 @@ class Doing_It_Right extends Generate_Ldjson {
690
 
691
  $title_custom_field = $this->get_custom_field( '_genesis_title', $post_id );
692
  $description_custom_field = $this->get_custom_field( '_genesis_description', $post_id );
 
693
  $nofollow = $this->get_custom_field( '_genesis_nofollow', $post_id );
694
  $noarchive = $this->get_custom_field( '_genesis_noarchive', $post_id );
695
 
696
  if ( $page_on_front ) {
697
- $title_custom_field = $this->get_option( 'homepage_title' ) ? $this->get_option( 'homepage_title' ) : $title_custom_field;
698
- $description_custom_field = $this->get_option( 'homepage_description' ) ? $this->get_option( 'homepage_description' ) : $description_custom_field;
699
- $nofollow = $this->get_option( 'homepage_nofollow' ) ? $this->get_option( 'homepage_nofollow' ) : $nofollow;
700
- $noarchive = $this->get_option( 'homepage_noarchive' ) ? $this->get_option( 'homepage_noarchive' ) : $noarchive;
 
701
  }
702
 
703
  $title_is_from_custom_field = (bool) $title_custom_field;
@@ -714,14 +733,16 @@ class Doing_It_Right extends Generate_Ldjson {
714
  $description = $this->generate_description( '', array( 'id' => $post_id, 'get_custom_field' => false ) );
715
  }
716
 
717
- $nofollow = $this->is_checked( $nofollow );
718
- $noarchive = $this->is_checked( $noarchive );
 
719
 
720
  return array(
721
  'title' => $title,
722
  'title_is_from_custom_field' => $title_is_from_custom_field,
723
  'description' => $description,
724
  'description_is_from_custom_field' => $description_is_from_custom_field,
 
725
  'nofollow' => $nofollow,
726
  'noarchive' => $noarchive,
727
  );
@@ -1548,7 +1569,7 @@ class Doing_It_Right extends Generate_Ldjson {
1548
  '20%' => 'tsf-20',
1549
  '16%' => 'tsf-16',
1550
  '12.5%' => 'tsf-12-5',
1551
- '11%' => 'ad-11',
1552
  '10%' => 'tsf-10',
1553
  );
1554
  }
95
  /**
96
  * Securely check the referrer, instead of leaving holes everywhere.
97
  */
98
+ if ( $this->doing_ajax() && \check_ajax_referer( 'add-tag', '_wpnonce_add-tag', false ) ) {
99
 
100
  $taxonomy = ! empty( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : 'post_tag';
101
  $tax = \get_taxonomy( $taxonomy );
106
  }
107
 
108
  /**
109
+ * Initializes SEO bar columns.
 
 
110
  *
111
  * @since 2.1.9
112
  *
113
  * @param object|empty $screen WP_Screen
114
  * @param bool $doing_ajax Whether we're doing an AJAX response.
115
+ * @return void If filter is set to false.
116
  */
117
  public function init_columns( $screen = '', $doing_ajax = false ) {
118
 
119
+ /**
120
+ * Applies filters 'the_seo_framework_show_seo_column' : bool
121
+ *
122
+ * @since ???
123
+ *
124
+ * @param bool $show_seo_column
125
+ */
126
  $show_seo_column = (bool) \apply_filters( 'the_seo_framework_show_seo_column', true );
127
 
128
+ if ( false === $show_seo_column )
129
+ return;
130
+
131
  if ( $doing_ajax ) {
132
  $post_type = isset( $_POST['post_type'] ) ? $_POST['post_type'] : '';
133
  } else {
134
  $post_type = isset( $screen->post_type ) ? $screen->post_type : '';
135
  }
136
 
137
+ if ( $this->post_type_supports_custom_seo( $post_type ) ) {
138
  if ( $doing_ajax ) {
139
 
140
+ //* Nonce is done in $this->init_columns_ajax()
141
  $id = isset( $_POST['screen'] ) ? $_POST['screen'] : false;
142
  $taxonomy = isset( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : false;
143
 
519
 
520
  $data = $this->get_term_data( $term, $term->term_id );
521
 
522
+ $noindex = isset( $data['noindex'] ) && $data['noindex'];
523
  $redirect = false; // We don't apply redirect on taxonomies (yet)
524
 
525
  //* Blocked SEO, return simple bar.
559
  $is_term = false;
560
  $is_front_page = $this->is_static_frontpage( $post_id );
561
 
562
+ $redirect = (bool) $this->get_custom_field( 'redirect', $post_id );
563
+ $noindex = (bool) $this->get_custom_field( '_genesis_noindex', $post_id );
 
 
 
564
 
565
  if ( $is_front_page )
566
+ $noindex = $this->is_option_checked( 'homepage_noindex' ) ?: $noindex;
567
 
568
  if ( $redirect || $noindex )
569
  return $this->the_seo_bar_blocked( array( 'is_term' => $is_term, 'redirect' => $redirect, 'noindex' => $noindex, 'post_i18n' => $post ) );
616
  * Fetch the term data for The SEO Bar.
617
  *
618
  * @since 2.6.0
619
+ * @since 2.9.0 Now also returns noindex value.
620
  * @staticvar array $data
621
  *
622
  * @param array $args The term args.
625
  * 'title_is_from_custom_field' => $title_is_from_custom_field,
626
  * 'description' => $description,
627
  * 'description_is_from_custom_field' => $description_is_from_custom_field,
628
+ * 'noindex' => $noindex,
629
  * 'nofollow' => $nofollow,
630
  * 'noarchive' => $noarchive
631
  * }
640
 
641
  $title_custom_field = isset( $data['doctitle'] ) ? $data['doctitle'] : '';
642
  $description_custom_field = isset( $data['description'] ) ? $data['description'] : '';
643
+ $noindex = isset( $data['noindex'] ) ? $data['noindex'] : '';
644
  $nofollow = isset( $data['nofollow'] ) ? $data['nofollow'] : '';
645
  $noarchive = isset( $data['noarchive'] ) ? $data['noarchive'] : '';
646
 
664
  $description = $this->generate_description( '', $description_args );
665
  }
666
 
667
+ /**
668
+ * No longer uses is_checked. As it strict checks 1/0 strings.
669
+ */
670
+ $noindex = (bool) $noindex;
671
+ $nofollow = (bool) $nofollow;
672
+ $noarchive = (bool) $noarchive;
673
 
674
  return array(
675
  'title' => $title,
676
  'title_is_from_custom_field' => $title_is_from_custom_field,
677
  'description' => $description,
678
  'description_is_from_custom_field' => $description_is_from_custom_field,
679
+ 'noindex' => $noindex,
680
  'nofollow' => $nofollow,
681
  'noarchive' => $noarchive,
682
  );
686
  * Fetch the post data for The SEO Bar.
687
  *
688
  * @since 2.6.0
689
+ * @since 2.9.0 Now also returns noindex value.
690
  * @staticvar array $data
691
  *
692
  * @param array $args The post args.
695
  * 'title_is_from_custom_field' => $title_is_from_custom_field,
696
  * 'description' => $description,
697
  * 'description_is_from_custom_field' => $description_is_from_custom_field,
698
+ * 'noindex' => $noindex,
699
  * 'nofollow' => $nofollow,
700
  * 'noarchive' => $noarchive
701
  * }
707
 
708
  $title_custom_field = $this->get_custom_field( '_genesis_title', $post_id );
709
  $description_custom_field = $this->get_custom_field( '_genesis_description', $post_id );
710
+ $noindex = $this->get_custom_field( '_genesis_noindex', $post_id );
711
  $nofollow = $this->get_custom_field( '_genesis_nofollow', $post_id );
712
  $noarchive = $this->get_custom_field( '_genesis_noarchive', $post_id );
713
 
714
  if ( $page_on_front ) {
715
+ $title_custom_field = $this->get_option( 'homepage_title' ) ?: $title_custom_field;
716
+ $description_custom_field = $this->get_option( 'homepage_description' ) ?: $description_custom_field;
717
+ $noindex = $this->get_option( 'homepage_noindex' ) ?: $nofollow;
718
+ $nofollow = $this->get_option( 'homepage_nofollow' ) ?: $nofollow;
719
+ $noarchive = $this->get_option( 'homepage_noarchive' ) ?: $noarchive;
720
  }
721
 
722
  $title_is_from_custom_field = (bool) $title_custom_field;
733
  $description = $this->generate_description( '', array( 'id' => $post_id, 'get_custom_field' => false ) );
734
  }
735
 
736
+ $noindex = (bool) $noindex;
737
+ $nofollow = (bool) $nofollow;
738
+ $noarchive = (bool) $noarchive;
739
 
740
  return array(
741
  'title' => $title,
742
  'title_is_from_custom_field' => $title_is_from_custom_field,
743
  'description' => $description,
744
  'description_is_from_custom_field' => $description_is_from_custom_field,
745
+ 'noindex' => $noindex,
746
  'nofollow' => $nofollow,
747
  'noarchive' => $noarchive,
748
  );
1569
  '20%' => 'tsf-20',
1570
  '16%' => 'tsf-16',
1571
  '12.5%' => 'tsf-12-5',
1572
+ '11%' => 'tsf-11',
1573
  '10%' => 'tsf-10',
1574
  );
1575
  }
inc/classes/feed.class.php CHANGED
@@ -43,9 +43,15 @@ class Feed extends Cache {
43
  /**
44
  * Initializes feed actions and hooks.
45
  *
46
- * @since 2.6.0
 
 
 
47
  */
48
- public function init_feed() {
 
 
 
49
 
50
  \add_filter( 'the_content_feed', array( $this, 'the_content_feed' ), 10, 2 );
51
 
@@ -67,75 +73,110 @@ class Feed extends Cache {
67
  }
68
 
69
  /**
70
- * Changes feed's content.
71
  *
72
- * @param $content The feed's content.
73
- * @param $feed_type The feed type (not used in excerpted content)
74
  *
75
  * @since 2.5.2
 
 
 
 
76
  */
77
- public function the_content_feed( $content, $feed_type = null ) {
78
 
79
- if ( $content ) :
 
80
 
81
- /**
82
- * Don't alter already-excerpts or descriptions.
83
- * $feed_type is only set on 'the_content_feed' filter.
84
- */
85
- if ( isset( $feed_type ) && $this->get_option( 'excerpt_the_feed' ) ) {
86
- //* Strip all code and lines.
87
- $excerpt = $this->s_excerpt_raw( $content, false );
88
 
89
- $excerpt_len = (int) mb_strlen( $excerpt );
90
- /**
91
- * Applies filters the_seo_framework_max_content_feed_length : The max excerpt length.
92
- * @since 2.5.2
93
- */
94
- $max_len = (int) \apply_filters( 'the_seo_framework_max_content_feed_length', 400 );
95
 
96
- //* Generate excerpt.
97
- $excerpt = $this->trim_excerpt( $excerpt, $excerpt_len, $max_len );
98
 
99
- $h2_output = '';
 
 
 
 
 
 
 
 
100
 
101
- if ( 0 === strpos( $content, '<h2>' ) ) {
102
- //* Add the h2 title back
103
- $h2_end = mb_strpos( $content, '</h2>' );
104
 
105
- if ( false !== $h2_end ) {
106
- //* Start of content, plus <h2>
107
- $h2_start = 4;
108
- //* Remove the length of <h2>, again.
109
- $h2_end = $h2_end - $h2_start;
110
 
111
- //* Fetch h2 content.
112
- $h2_content = mb_substr( $content, $h2_start, $h2_end );
 
 
 
 
113
 
114
- //* Remove the H2 content from the excerpt.
115
- $count = 1;
116
- $excerpt = str_replace( $h2_content, '', $excerpt, $count );
117
 
118
- //* Wrap h2 content in h2 tags.
119
- $h2_output = '<h2>' . $h2_content . '</h2>' . PHP_EOL;
120
- }
121
- }
122
 
123
- $content = $h2_output . '<p>' . trim( $excerpt ) . '</p>';
124
- }
 
 
 
 
 
 
 
125
 
126
- if ( $this->get_option( 'source_the_feed' ) ) {
 
127
 
128
- //* Fetch permalink and add it to the content. Already escaped.
129
- $permalink = $this->the_url();
 
130
 
131
- /**
132
- * Applies filters 'the_seo_framework_feed_source_link' : string
133
- * @since 2.6.0
134
- */
135
- $source_i18n = (string) apply_filters( 'the_seo_framework_feed_source_link_text', \_x( 'Source', 'The content source', 'autodescription' ) );
136
- $content .= PHP_EOL . '<p><a href="' . $permalink . '" rel="external nofollow">' . \esc_html( $source_i18n ) . '</a></p>';
137
  }
138
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
  return $content;
141
  }
43
  /**
44
  * Initializes feed actions and hooks.
45
  *
46
+ * @since 2.9.0
47
+ * @access private
48
+ *
49
+ * @return void Early if this request isn't for a feed.
50
  */
51
+ public function _init_feed_output() {
52
+
53
+ if ( ! $this->is_feed() )
54
+ return;
55
 
56
  \add_filter( 'the_content_feed', array( $this, 'the_content_feed' ), 10, 2 );
57
 
73
  }
74
 
75
  /**
76
+ * Changes feed's content based on options.
77
  *
78
+ * This method converts the input $content to an excerpt and is able to add
79
+ * a nofollow backlink at the end of the feed.
80
  *
81
  * @since 2.5.2
82
+ *
83
+ * @param $content The feed's content.
84
+ * @param $feed_type The feed type (not used in excerpted content)
85
+ * @return string The modified feed entry.
86
  */
87
+ public function the_content_feed( $content = '', $feed_type = null ) {
88
 
89
+ if ( ! $content )
90
+ return '';
91
 
92
+ /**
93
+ * Don't alter already-excerpts or descriptions.
94
+ * $feed_type is only set on 'the_content_feed' filter.
95
+ */
96
+ if ( isset( $feed_type ) && $this->get_option( 'excerpt_the_feed' ) ) {
97
+ $content = $this->convert_feed_entry_to_excerpt( $content );
98
+ }
99
 
100
+ if ( $this->get_option( 'source_the_feed' ) ) {
101
+ $content .= PHP_EOL . $this->get_feed_entry_source_link();
102
+ }
 
 
 
103
 
104
+ return $content;
105
+ }
106
 
107
+ /**
108
+ * Converts feed content to excerpt.
109
+ *
110
+ * @since 2.9.0
111
+ *
112
+ * @param string $content The full feed entry content.
113
+ * @return string The excerpted feed.
114
+ */
115
+ protected function convert_feed_entry_to_excerpt( $content = '' ) {
116
 
117
+ if ( ! $content )
118
+ return '';
 
119
 
120
+ //* Strip all code and lines.
121
+ $excerpt = $this->s_excerpt_raw( $content, false );
 
 
 
122
 
123
+ $excerpt_len = (int) mb_strlen( $excerpt );
124
+ /**
125
+ * Applies filters the_seo_framework_max_content_feed_length : The max excerpt length.
126
+ * @since 2.5.2
127
+ */
128
+ $max_len = (int) \apply_filters( 'the_seo_framework_max_content_feed_length', 400 );
129
 
130
+ //* Generate excerpt.
131
+ $excerpt = $this->trim_excerpt( $excerpt, $excerpt_len, $max_len );
 
132
 
133
+ $h2_output = '';
 
 
 
134
 
135
+ if ( 0 === strpos( $content, '<h2>' ) ) {
136
+ //* Add the h2 title back
137
+ $h2_end = mb_strpos( $content, '</h2>' );
138
+
139
+ if ( false !== $h2_end ) {
140
+ //* Start of content, plus <h2>
141
+ $h2_start = 4;
142
+ //* Remove the length of <h2>, again.
143
+ $h2_end = $h2_end - $h2_start;
144
 
145
+ //* Fetch h2 content.
146
+ $h2_content = mb_substr( $content, $h2_start, $h2_end );
147
 
148
+ //* Remove the H2 content from the excerpt.
149
+ $count = 1;
150
+ $excerpt = str_replace( $h2_content, '', $excerpt, $count );
151
 
152
+ //* Wrap h2 content in h2 tags.
153
+ $h2_output = '<h2>' . $h2_content . '</h2>' . PHP_EOL;
 
 
 
 
154
  }
155
+ }
156
+
157
+ $content = $h2_output . '<p>' . trim( $excerpt ) . '</p>';
158
+
159
+ return $content;
160
+ }
161
+
162
+ /**
163
+ * Generates and returns feed source link.
164
+ *
165
+ * @since 2.9.0
166
+ *
167
+ * @return string The translatable feed entry source link.
168
+ */
169
+ protected function get_feed_entry_source_link() {
170
+
171
+ //* Fetch permalink and add it to the content. Already escaped.
172
+ $permalink = $this->the_url();
173
+
174
+ /**
175
+ * Applies filters 'the_seo_framework_feed_source_link' : string
176
+ * @since 2.6.0
177
+ */
178
+ $source_i18n = (string) \apply_filters( 'the_seo_framework_feed_source_link_text', \_x( 'Source', 'The content source', 'autodescription' ) );
179
+ $content = '<p><a href="' . $permalink . '" rel="external nofollow">' . \esc_html( $source_i18n ) . '</a></p>';
180
 
181
  return $content;
182
  }
inc/classes/generate-description.class.php CHANGED
@@ -43,6 +43,7 @@ class Generate_Description extends Generate {
43
  * Creates description. Base function.
44
  *
45
  * @since 1.0.0
 
46
  *
47
  * @param string $description The optional description to simply parse.
48
  * @param array $args description args : {
@@ -64,16 +65,41 @@ class Generate_Description extends Generate {
64
 
65
  if ( $args['get_custom_field'] && empty( $description ) ) {
66
  //* Fetch from options, if any.
67
- $description = (string) $this->description_from_custom_field( $args, false );
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  //* We've already checked the custom fields, so let's remove the check in the generation.
70
  $args['get_custom_field'] = false;
71
  }
72
 
73
  //* Still no description found? Create an auto description based on content.
74
- if ( empty( $description ) || false === is_scalar( $description ) )
75
  $description = $this->generate_description_from_id( $args, false );
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  /**
78
  * Applies filters 'the_seo_framework_do_shortcodes_in_description' : Boolean
79
  * @since 2.6.6
@@ -206,6 +232,8 @@ class Generate_Description extends Generate {
206
  * Fetches HomePage Description from custom field.
207
  *
208
  * @since 2.6.0
 
 
209
  * Use $this->description_from_custom_field() instead.
210
  *
211
  * @param array $args Description args.
@@ -215,9 +243,8 @@ class Generate_Description extends Generate {
215
 
216
  $description = '';
217
 
218
- if ( $args['is_home'] || $this->is_front_page() || ( empty( $args['taxonomy'] ) && $this->is_static_frontpage( $args['id'] ) ) ) {
219
  $description = $this->get_option( 'homepage_description' ) ?: '';
220
- }
221
 
222
  return $description;
223
  }
@@ -333,7 +360,7 @@ class Generate_Description extends Generate {
333
  $args = $this->reparse_description_args( $args );
334
 
335
  //* Home Page description
336
- if ( $args['is_home'] || $this->is_front_page() || $this->is_static_frontpage( $args['id'] ) )
337
  return $this->generate_home_page_description( $args['get_custom_field'], $escape );
338
 
339
  /**
@@ -638,14 +665,14 @@ class Generate_Description extends Generate {
638
  * $sep => The separator
639
  * }
640
  */
641
- public function generate_description_additions( $id = '', $term = '', $ignore = false ) {
642
 
643
  static $title = array();
644
 
645
  if ( $ignore || $this->add_description_additions( $id, $term ) ) {
646
 
647
  if ( ! isset( $title[ $id ] ) ) {
648
- $title[ $id ] = $this->generate_description_title( $id, $term, $this->is_front_page( $id ) );
649
  }
650
 
651
  if ( $ignore || $this->is_option_checked( 'description_blogname' ) ) {
@@ -695,7 +722,7 @@ class Generate_Description extends Generate {
695
  if ( '' === $id )
696
  $id = $this->get_the_real_ID();
697
 
698
- if ( $page_on_front || $this->is_static_frontpage( $id ) ) :
699
  $title = $this->get_option( 'homepage_title_tagline' ) ?: $this->get_blogdescription();
700
  else :
701
  /**
@@ -779,6 +806,18 @@ class Generate_Description extends Generate {
779
  $excerpt = '';
780
  }
781
 
 
 
 
 
 
 
 
 
 
 
 
 
782
  $excerpt_cache[ $page_id ][ $term_id ] = $excerpt;
783
  }
784
 
43
  * Creates description. Base function.
44
  *
45
  * @since 1.0.0
46
+ * @since 2.9.0 Added two filters.
47
  *
48
  * @param string $description The optional description to simply parse.
49
  * @param array $args description args : {
65
 
66
  if ( $args['get_custom_field'] && empty( $description ) ) {
67
  //* Fetch from options, if any.
68
+ $description = $this->description_from_custom_field( $args, false );
69
+
70
+ /**
71
+ * Applies filters 'the_seo_framework_custom_field_description' : string
72
+ *
73
+ * Filters the description from custom field, if any.
74
+ *
75
+ * @since 2.9.0
76
+ *
77
+ * @param string $description The description.
78
+ * @param array $args The description arguments.
79
+ */
80
+ $description = (string) \apply_filters( 'the_seo_framework_custom_field_description', $description, $args );
81
 
82
  //* We've already checked the custom fields, so let's remove the check in the generation.
83
  $args['get_custom_field'] = false;
84
  }
85
 
86
  //* Still no description found? Create an auto description based on content.
87
+ if ( empty( $description ) || false === is_scalar( $description ) ) {
88
  $description = $this->generate_description_from_id( $args, false );
89
 
90
+ /**
91
+ * Applies filters 'the_seo_framework_generated_description' : string
92
+ *
93
+ * Filters the generated description, if any.
94
+ *
95
+ * @since 2.9.0
96
+ *
97
+ * @param string $description The description.
98
+ * @param array $args The description arguments.
99
+ */
100
+ $description = (string) \apply_filters( 'the_seo_framework_generated_description', $description, $args );
101
+ }
102
+
103
  /**
104
  * Applies filters 'the_seo_framework_do_shortcodes_in_description' : Boolean
105
  * @since 2.6.6
232
  * Fetches HomePage Description from custom field.
233
  *
234
  * @since 2.6.0
235
+ * @since 2.9.0 1. Removed $args['taxonomy'] check.
236
+ * 2. Added $this->is_archive() check.
237
  * Use $this->description_from_custom_field() instead.
238
  *
239
  * @param array $args Description args.
243
 
244
  $description = '';
245
 
246
+ if ( $args['is_home'] || $this->is_real_front_page() || ( ! $this->is_archive() && $this->is_static_frontpage( $args['id'] ) ) )
247
  $description = $this->get_option( 'homepage_description' ) ?: '';
 
248
 
249
  return $description;
250
  }
360
  $args = $this->reparse_description_args( $args );
361
 
362
  //* Home Page description
363
+ if ( $args['is_home'] || $this->is_real_front_page() || $this->is_front_page_by_id( $args['id'] ) )
364
  return $this->generate_home_page_description( $args['get_custom_field'], $escape );
365
 
366
  /**
665
  * $sep => The separator
666
  * }
667
  */
668
+ public function generate_description_additions( $id = 0, $term = '', $ignore = false ) {
669
 
670
  static $title = array();
671
 
672
  if ( $ignore || $this->add_description_additions( $id, $term ) ) {
673
 
674
  if ( ! isset( $title[ $id ] ) ) {
675
+ $title[ $id ] = $this->generate_description_title( $id, $term, $this->is_real_front_page() );
676
  }
677
 
678
  if ( $ignore || $this->is_option_checked( 'description_blogname' ) ) {
722
  if ( '' === $id )
723
  $id = $this->get_the_real_ID();
724
 
725
+ if ( $page_on_front || $this->is_front_page_by_id( $id ) ) :
726
  $title = $this->get_option( 'homepage_title_tagline' ) ?: $this->get_blogdescription();
727
  else :
728
  /**
806
  $excerpt = '';
807
  }
808
 
809
+ /**
810
+ * Applies filters 'the_seo_framework_fetched_description_excerpt' : string
811
+ *
812
+ * @since 2.9.0
813
+ *
814
+ * @param string $excerpt The excerpt to use.
815
+ * @param bool $page_id The current page/term ID
816
+ * @param object|mixed $term The current term.
817
+ * @param int $max_char_length Determines the maximum length of excerpt after trimming.
818
+ */
819
+ $excerpt = (string) \apply_filters( 'the_seo_framework_fetched_description_excerpt', $excerpt, $page_id, $term, $max_char_length );
820
+
821
  $excerpt_cache[ $page_id ][ $term_id ] = $excerpt;
822
  }
823
 
inc/classes/generate-image.class.php CHANGED
@@ -49,33 +49,18 @@ class Generate_Image extends Generate_Url {
49
  }
50
 
51
  /**
52
- * Fetches og:image URL.
53
  *
54
- * @since 2.2.2
55
- * @since 2.2.8 : Added theme icon detection.
56
- * @since 2.5.2 : Added args filters.
57
- * @since 2.8.0 : 1. Added theme logo detection.
58
- * 2. Added inpost image selection detection.
59
- * @since 2.8.2 : 1. Now returns something on post ID 0.
60
- * 2. Added SEO settings fallback image selection detection.
61
  *
62
  * @todo listen to attached images within post.
63
- * @todo set archive and front page image listener, now it simply fail on some calls.
64
- * @priority medium 2.7.0+
65
  *
66
- * @param string $post_id The post ID.
67
  * @param array $args The image arguments.
68
- * @param bool $escape Whether to escape the image URL.
69
- * @return string the image URL.
70
  */
71
- public function get_image( $post_id = '', $args = array(), $escape = true ) {
72
-
73
- /**
74
- * Backwards compat with parse args.
75
- * @since 2.5.0
76
- */
77
- if ( ! isset( $args['post_id'] ) )
78
- $args['post_id'] = $post_id ?: ( $this->is_singular() ? $this->get_the_real_ID() : 0 );
79
 
80
  $args = $this->reparse_image_args( $args );
81
 
@@ -88,27 +73,36 @@ class Generate_Image extends Generate_Url {
88
  //* Check if there are no disallowed arguments.
89
  $all_allowed = empty( $args['disallowed'] );
90
 
 
 
 
 
 
 
91
  if ( $args['post_id'] ) {
92
- //* 1. Fetch image from SEO meta upload.
93
  if ( $all_allowed || false === in_array( 'postmeta', $args['disallowed'], true ) ) {
94
  if ( $image = $this->get_social_image_url_from_post_meta( $args['post_id'], true ) )
95
  goto end;
96
  }
97
 
98
- //* 2. Fetch image from featured
99
  if ( $all_allowed || false === in_array( 'featured', $args['disallowed'], true ) ) {
100
- if ( $image = $this->get_image_from_post_thumbnail( $args ) )
101
  goto end;
102
  }
103
  }
104
 
105
- //* 3. Fetch image from SEO settings
 
 
 
106
  if ( $all_allowed || false === in_array( 'option', $args['disallowed'], true ) ) {
107
  if ( $image = $this->get_social_image_url_from_seo_settings( true ) )
108
  goto end;
109
  }
110
 
111
- //* 4. Fetch image from fallback filter 1
112
  /**
113
  * Applies filters 'the_seo_framework_og_image_after_featured' : string
114
  * @since 2.5.2
@@ -118,13 +112,13 @@ class Generate_Image extends Generate_Url {
118
  goto end;
119
  }
120
 
121
- //* 5. Fallback: Get header image if exists
122
  if ( ( $all_allowed || false === in_array( 'header', $args['disallowed'], true ) ) && \current_theme_supports( 'custom-header', 'default-image' ) ) {
123
  if ( $image = $this->get_header_image( true ) )
124
  goto end;
125
  }
126
 
127
- //* 6. Fetch image from fallback filter 2
128
  /**
129
  * Applies filters 'the_seo_framework_og_image_after_header' : string
130
  * @since 2.5.2
@@ -134,13 +128,13 @@ class Generate_Image extends Generate_Url {
134
  goto end;
135
  }
136
 
137
- //* 7. Get the WP 4.5 Site Logo
138
  if ( ( $all_allowed || false === in_array( 'logo', $args['disallowed'], true ) ) && $this->can_use_logo() ) {
139
  if ( $image = $this->get_site_logo( true ) )
140
  goto end;
141
  }
142
 
143
- //* 8. Get the WP 4.3 Site Icon
144
  if ( $all_allowed || false === in_array( 'icon', $args['disallowed'], true ) ) {
145
  if ( $image = $this->get_site_icon( 'full', true ) )
146
  goto end;
@@ -148,16 +142,19 @@ class Generate_Image extends Generate_Url {
148
 
149
  end :;
150
 
151
- if ( $escape && $image )
152
- return \esc_url( $image );
153
 
154
- return $image;
155
  }
156
 
157
  /**
158
  * Parse and sanitize image args.
159
  *
160
  * @since 2.5.0
 
 
 
161
  *
162
  * The image set in the filter will always be used as fallback
163
  *
@@ -175,8 +172,9 @@ class Generate_Image extends Generate_Url {
175
  'image' => '',
176
  'size' => 'full',
177
  'icon' => false,
178
- 'attr' => array(),
179
  'disallowed' => array(),
 
180
  );
181
 
182
  /**
@@ -184,7 +182,7 @@ class Generate_Image extends Generate_Url {
184
  * @param string $image The image url
185
  * @param mixed $size The image size
186
  * @param bool $icon Fetch Image icon
187
- * @param array $attr Image attributes
188
  * @param array $disallowed Disallowed image types : {
189
  * array (
190
  * string 'featured'
@@ -192,6 +190,7 @@ class Generate_Image extends Generate_Url {
192
  * string 'icon'
193
  * )
194
  * }
 
195
  * }
196
  *
197
  * @since 2.0.1
@@ -207,12 +206,13 @@ class Generate_Image extends Generate_Url {
207
  return $defaults;
208
 
209
  //* Array merge doesn't support sanitation. We're simply type casting here.
210
- $args['post_id'] = isset( $args['post_id'] ) ? (int) $args['post_id'] : $defaults['post_id'];
211
- $args['image'] = isset( $args['image'] ) ? (string) $args['image'] : $defaults['image'];
212
- $args['size'] = isset( $args['size'] ) ? $args['size'] : $defaults['size']; // Mixed.
213
- $args['icon'] = isset( $args['icon'] ) ? (bool) $args['icon'] : $defaults['icon'];
214
- $args['attr'] = isset( $args['attr'] ) ? (array) $args['attr'] : $defaults['attr'];
215
- $args['disallowed'] = isset( $args['disallowed'] ) ? (array) $args['disallowed'] : $defaults['disallowed'];
 
216
 
217
  return $args;
218
  }
@@ -229,43 +229,72 @@ class Generate_Image extends Generate_Url {
229
 
230
  $default_args = $this->parse_image_args( '', '', true );
231
 
232
- if ( is_array( $args ) ) {
233
- if ( empty( $args ) ) {
234
- $args = $default_args;
235
- } else {
236
- $args = $this->parse_image_args( $args, $default_args );
237
- }
238
- } else {
239
- //* Old style parameters are used. Doing it wrong.
240
- $this->_doing_it_wrong( __METHOD__, 'Use $args = array() for parameters.', '2.5.0' );
241
  $args = $default_args;
 
 
242
  }
243
 
244
  return $args;
245
  }
246
 
247
  /**
248
- * Returns unescaped URL from post ID input.
249
  *
250
- * @since 2.8.0
251
  * @uses $this->image_dimensions
252
  *
253
  * @param int $id The post ID.
254
- * @param bool $set_og_dimensions Whether to set open graph and twitter dimensions.
255
- * @return string The unescaped social image URL.
256
  */
257
- public function get_social_image_url_from_post_meta( $id = 0, $set_og_dimensions = false ) {
258
 
259
- if ( empty( $id ) )
260
- $id = $this->get_the_real_ID();
 
261
 
262
- $src = $this->get_custom_field( '_social_image_url', $id );
263
 
264
  if ( ! $src )
265
  return '';
266
 
267
  //* Calculate image sizes.
268
- if ( $img_id = $this->get_custom_field( '_social_image_id', $id ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  $_src = \wp_get_attachment_image_src( $img_id, 'full' );
270
 
271
  $i = $_src[0]; // Source URL
@@ -312,27 +341,28 @@ class Generate_Image extends Generate_Url {
312
 
313
  /**
314
  * Fetches image from post thumbnail.
 
315
  * Resizes the image between 1500px if bigger. Then it saves the image and
316
  * Keeps dimensions relative.
317
  *
318
- * @since 2.3.0
319
  *
320
- * @param array $args Image arguments.
321
- * @return string|null the image url.
 
 
322
  */
323
- public function get_image_from_post_thumbnail( $args = array() ) {
324
-
325
- if ( empty( $args ) )
326
- $args = $this->reparse_image_args( $args );
327
 
328
- if ( ! isset( $args['post_id'] ) )
329
- $args['post_id'] = $this->get_the_real_ID();
330
 
331
- $id = \get_post_thumbnail_id( $args['post_id'] );
 
332
 
 
333
  $args['get_the_real_ID'] = true;
334
 
335
- $image = $id ? $this->parse_og_image( $id, $args ) : '';
336
 
337
  return $image;
338
  }
@@ -372,24 +402,26 @@ class Generate_Image extends Generate_Url {
372
  * @since 2.5.0
373
  * @since 2.8.0 : 1. Removed staticvar.
374
  * 2. Now adds ID call to OG image called listener.
 
375
  *
376
  * @todo create formula to fetch transient.
377
  * @priority high 2.7.0
378
  *
379
  * @param int $id The attachment ID.
380
  * @param array $args The image args
 
381
  * @return string|empty Parsed image url or empty if already called
382
  */
383
- public function parse_og_image( $id, $args = array() ) {
384
 
385
  //* Don't do anything if $id isn't given.
386
- if ( ! isset( $id ) || empty( $id ) )
387
  return;
388
 
389
  if ( empty( $args ) )
390
  $args = $this->reparse_image_args( $args );
391
 
392
- $src = \wp_get_attachment_image_src( $id, $args['size'], $args['icon'], $args['attr'] );
393
 
394
  $i = $src[0]; // Source URL
395
  $w = $src[1]; // Width
@@ -451,10 +483,12 @@ class Generate_Image extends Generate_Url {
451
  }
452
  endif;
453
 
454
- //* Whether to use the post ID (Post Thumbnail) or input ID (ID was known beforehand)
455
- $usage_id = isset( $args['get_the_real_ID'] ) && $args['get_the_real_ID'] ? $this->get_the_real_ID() : $id;
 
456
 
457
- $this->image_dimensions = $this->image_dimensions + array( $usage_id => array( 'width' => $w, 'height' => $h ) );
 
458
 
459
  return $i;
460
  }
49
  }
50
 
51
  /**
52
+ * Returns social image URL and sets $this->image_dimensions.
53
  *
54
+ * @since 2.9.0
 
 
 
 
 
 
55
  *
56
  * @todo listen to attached images within post.
57
+ * @todo listen to archive images.
 
58
  *
 
59
  * @param array $args The image arguments.
60
+ * @param bool $set_og_dimension Whether to set open graph dimensions.
61
+ * @return string The social image.
62
  */
63
+ public function get_social_image( $args = array(), $set_og_dimension = false ) {
 
 
 
 
 
 
 
64
 
65
  $args = $this->reparse_image_args( $args );
66
 
73
  //* Check if there are no disallowed arguments.
74
  $all_allowed = empty( $args['disallowed'] );
75
 
76
+ //* 1. Fetch image from homepage SEO meta upload.
77
+ if ( $all_allowed || false === in_array( 'homemeta', $args['disallowed'], true ) ) {
78
+ if ( $image = $this->get_social_image_url_from_home_meta( $args['post_id'], true ) )
79
+ goto end;
80
+ }
81
+
82
  if ( $args['post_id'] ) {
83
+ //* 2. Fetch image from SEO meta upload.
84
  if ( $all_allowed || false === in_array( 'postmeta', $args['disallowed'], true ) ) {
85
  if ( $image = $this->get_social_image_url_from_post_meta( $args['post_id'], true ) )
86
  goto end;
87
  }
88
 
89
+ //* 3. Fetch image from featured.
90
  if ( $all_allowed || false === in_array( 'featured', $args['disallowed'], true ) ) {
91
+ if ( $image = $this->get_social_image_url_from_post_thumbnail( $args['post_id'], $args, true ) )
92
  goto end;
93
  }
94
  }
95
 
96
+ if ( $args['skip_fallback'] )
97
+ goto end;
98
+
99
+ //* 4. Fetch image from SEO settings
100
  if ( $all_allowed || false === in_array( 'option', $args['disallowed'], true ) ) {
101
  if ( $image = $this->get_social_image_url_from_seo_settings( true ) )
102
  goto end;
103
  }
104
 
105
+ //* 5. Fetch image from fallback filter 1
106
  /**
107
  * Applies filters 'the_seo_framework_og_image_after_featured' : string
108
  * @since 2.5.2
112
  goto end;
113
  }
114
 
115
+ //* 6. Fallback: Get header image if exists
116
  if ( ( $all_allowed || false === in_array( 'header', $args['disallowed'], true ) ) && \current_theme_supports( 'custom-header', 'default-image' ) ) {
117
  if ( $image = $this->get_header_image( true ) )
118
  goto end;
119
  }
120
 
121
+ //* 7. Fetch image from fallback filter 2
122
  /**
123
  * Applies filters 'the_seo_framework_og_image_after_header' : string
124
  * @since 2.5.2
128
  goto end;
129
  }
130
 
131
+ //* 8. Get the WP 4.5 Site Logo
132
  if ( ( $all_allowed || false === in_array( 'logo', $args['disallowed'], true ) ) && $this->can_use_logo() ) {
133
  if ( $image = $this->get_site_logo( true ) )
134
  goto end;
135
  }
136
 
137
+ //* 9. Get the WP 4.3 Site Icon
138
  if ( $all_allowed || false === in_array( 'icon', $args['disallowed'], true ) ) {
139
  if ( $image = $this->get_site_icon( 'full', true ) )
140
  goto end;
142
 
143
  end :;
144
 
145
+ if ( $args['escape'] && $image )
146
+ $image = \esc_url( $image );
147
 
148
+ return (string) $image;
149
  }
150
 
151
  /**
152
  * Parse and sanitize image args.
153
  *
154
  * @since 2.5.0
155
+ * @since 2.9.0 : 1. Removed 'attr' index, it was unused.
156
+ * 2. Added 'skip_fallback' option.
157
+ * 3. Added 'escape' option.
158
  *
159
  * The image set in the filter will always be used as fallback
160
  *
172
  'image' => '',
173
  'size' => 'full',
174
  'icon' => false,
175
+ 'skip_fallback' => false,
176
  'disallowed' => array(),
177
+ 'escape' => true,
178
  );
179
 
180
  /**
182
  * @param string $image The image url
183
  * @param mixed $size The image size
184
  * @param bool $icon Fetch Image icon
185
+ * @param bool 'skip_fallback' Whether to skip fallback images.
186
  * @param array $disallowed Disallowed image types : {
187
  * array (
188
  * string 'featured'
190
  * string 'icon'
191
  * )
192
  * }
193
+ * @param bool 'escape' Whether to escape output.
194
  * }
195
  *
196
  * @since 2.0.1
206
  return $defaults;
207
 
208
  //* Array merge doesn't support sanitation. We're simply type casting here.
209
+ $args['post_id'] = isset( $args['post_id'] ) ? (int) $args['post_id'] : $defaults['post_id'];
210
+ $args['image'] = isset( $args['image'] ) ? (string) $args['image'] : $defaults['image'];
211
+ $args['size'] = isset( $args['size'] ) ? $args['size'] : $defaults['size']; // Mixed.
212
+ $args['icon'] = isset( $args['icon'] ) ? (bool) $args['icon'] : $defaults['icon'];
213
+ $args['skip_fallback'] = isset( $args['skip_fallback'] ) ? (bool) $args['skip_fallback'] : $defaults['skip_fallback'];
214
+ $args['disallowed'] = isset( $args['disallowed'] ) ? (array) $args['disallowed'] : $defaults['disallowed'];
215
+ $args['escape'] = isset( $args['escape'] ) ? (bool) $args['escape'] : $defaults['escape'];
216
 
217
  return $args;
218
  }
229
 
230
  $default_args = $this->parse_image_args( '', '', true );
231
 
232
+ if ( empty( $args ) ) {
 
 
 
 
 
 
 
 
233
  $args = $default_args;
234
+ } else {
235
+ $args = $this->parse_image_args( $args, $default_args );
236
  }
237
 
238
  return $args;
239
  }
240
 
241
  /**
242
+ * Returns unescaped HomePage settings image URL from post ID input.
243
  *
244
+ * @since 2.9.0
245
  * @uses $this->image_dimensions
246
  *
247
  * @param int $id The post ID.
248
+ * @param bool $set_og_dimensions Whether to set Open Graph and Twitter dimensions.
249
+ * @return string The unescaped HomePage social image URL.
250
  */
251
+ public function get_social_image_url_from_home_meta( $id = 0, $set_og_dimensions = false ) {
252
 
253
+ //* Don't output if not front page.
254
+ if ( false === $this->is_front_page_by_id( $id ) )
255
+ return '';
256
 
257
+ $src = $this->get_option( 'homepage_social_image_url' );
258
 
259
  if ( ! $src )
260
  return '';
261
 
262
  //* Calculate image sizes.
263
+ if ( $set_og_dimensions && $img_id = $this->get_option( 'homepage_social_image_id' ) ) {
264
+ $_src = \wp_get_attachment_image_src( $img_id, 'full' );
265
+
266
+ $i = $_src[0]; // Source URL
267
+ $w = $_src[1]; // Width
268
+ $h = $_src[2]; // Height
269
+
270
+ if ( \esc_url( $this->set_preferred_url_scheme( $i ) ) === \esc_url( $this->set_preferred_url_scheme( $src ) ) )
271
+ $this->image_dimensions = $this->image_dimensions + array( $id => array( 'width' => $w, 'height' => $h ) );
272
+ }
273
+
274
+ return $src;
275
+ }
276
+
277
+ /**
278
+ * Returns unescaped Post settings image URL from post ID input.
279
+ *
280
+ * @since 2.8.0
281
+ * @since 2.9.0 1. The second parameter now works.
282
+ * 2. Fallback image ID has been removed.
283
+ * @uses $this->image_dimensions
284
+ *
285
+ * @param int $id The post ID. Required.
286
+ * @param bool $set_og_dimensions Whether to set Open Graph and Twitter dimensions.
287
+ * @return string The unescaped social image URL.
288
+ */
289
+ public function get_social_image_url_from_post_meta( $id, $set_og_dimensions = false ) {
290
+
291
+ $src = $id ? $this->get_custom_field( '_social_image_url', $id ) : '';
292
+
293
+ if ( ! $src )
294
+ return '';
295
+
296
+ //* Calculate image sizes.
297
+ if ( $set_og_dimensions && $img_id = $this->get_custom_field( '_social_image_id', $id ) ) {
298
  $_src = \wp_get_attachment_image_src( $img_id, 'full' );
299
 
300
  $i = $_src[0]; // Source URL
341
 
342
  /**
343
  * Fetches image from post thumbnail.
344
+ *
345
  * Resizes the image between 1500px if bigger. Then it saves the image and
346
  * Keeps dimensions relative.
347
  *
348
+ * @since 2.9.0
349
  *
350
+ * @param int $id The post ID. Required.
351
+ * @param array $args The image args.
352
+ * @param bool $set_og_dimensions Whether to set Open Graph image dimensions.
353
+ * @return string The social image URL.
354
  */
355
+ public function get_social_image_url_from_post_thumbnail( $id, $args = array(), $set_og_dimensions = false ) {
 
 
 
356
 
357
+ $image_id = $id ? \get_post_thumbnail_id( $id ) : '';
 
358
 
359
+ if ( ! $image_id )
360
+ return '';
361
 
362
+ $args = $this->reparse_image_args( $args );
363
  $args['get_the_real_ID'] = true;
364
 
365
+ $image = $this->parse_og_image( $image_id, $args, $set_og_dimensions );
366
 
367
  return $image;
368
  }
402
  * @since 2.5.0
403
  * @since 2.8.0 : 1. Removed staticvar.
404
  * 2. Now adds ID call to OG image called listener.
405
+ * @since 2.9.0 : Added $set_og_dimension parameter
406
  *
407
  * @todo create formula to fetch transient.
408
  * @priority high 2.7.0
409
  *
410
  * @param int $id The attachment ID.
411
  * @param array $args The image args
412
+ * @param bool $set_og_dimensions Whether to set OG dimensions.
413
  * @return string|empty Parsed image url or empty if already called
414
  */
415
+ public function parse_og_image( $id, $args = array(), $set_og_dimensions = false ) {
416
 
417
  //* Don't do anything if $id isn't given.
418
+ if ( empty( $id ) )
419
  return;
420
 
421
  if ( empty( $args ) )
422
  $args = $this->reparse_image_args( $args );
423
 
424
+ $src = \wp_get_attachment_image_src( $id, $args['size'], $args['icon'] );
425
 
426
  $i = $src[0]; // Source URL
427
  $w = $src[1]; // Width
483
  }
484
  endif;
485
 
486
+ if ( $set_og_dimensions ) {
487
+ //* Whether to use the post ID (Post Thumbnail) or input ID (ID was known beforehand)
488
+ $usage_id = ! empty( $args['get_the_real_ID'] ) ? $this->get_the_real_ID() : $id;
489
 
490
+ $this->image_dimensions = $this->image_dimensions + array( $usage_id => array( 'width' => $w, 'height' => $h ) );
491
+ }
492
 
493
  return $i;
494
  }
inc/classes/generate-ldjson.class.php CHANGED
@@ -53,17 +53,17 @@ class Generate_Ldjson extends Generate_Image {
53
 
54
  $this->setup_ld_json_transient( $this->get_the_real_ID() );
55
 
56
- if ( $this->the_seo_framework_debug ) $this->debug_init( __METHOD__, false, $debug_key = microtime( true ), array( 'LD Json transient' => $this->ld_json_transient, 'Output from transient' => false !== $this->get_transient( $this->ld_json_transient ) ) );
57
 
58
  $use_cache = $this->is_option_checked( 'cache_meta_schema' );
59
 
60
  $output = $use_cache ? $this->get_transient( $this->ld_json_transient ) : false;
61
- if ( false === $output ) {
62
 
63
  $output = '';
64
 
65
  //* Only display search helper and knowledge graph on front page.
66
- if ( $this->is_front_page() ) {
67
 
68
  $sitename = $this->ld_json_name();
69
  $sitelinks = $this->ld_json_search();
@@ -97,13 +97,9 @@ class Generate_Ldjson extends Generate_Image {
97
 
98
  $this->set_transient( $this->ld_json_transient, $output, $expiration );
99
  }
100
- }
101
 
102
- /**
103
- * Debug output.
104
- * @since 2.4.2
105
- */
106
- if ( $this->the_seo_framework_debug ) $this->debug_init( __METHOD__, false, $debug_key, array( 'LD Json transient output' => $output ) );
107
 
108
  return $output;
109
  }
@@ -221,8 +217,8 @@ class Generate_Ldjson extends Generate_Image {
221
  *
222
  * @staticvar array $images
223
  * @since 2.7.0
224
- * @todo implement blog page image.
225
- * @priority low 2.7.0+ extension.
226
  *
227
  * @param int|string $id The page, post, product or term ID.
228
  * @param bool $singular Whether the ID is singular.
@@ -239,12 +235,32 @@ class Generate_Ldjson extends Generate_Image {
239
  $image = '';
240
 
241
  if ( $singular ) {
242
- if ( $id === $this->get_the_real_ID() ) {
243
- $image = $this->get_image_from_cache( $id );
244
- } elseif ( $id ) {
245
- //* No ID (0) results in the home page being a blog. This will be handled in the future.
246
- $image = $this->get_image( $id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
 
248
  } else {
249
  //* Placeholder.
250
  $image = '';
@@ -318,7 +334,7 @@ class Generate_Ldjson extends Generate_Image {
318
 
319
  if ( $this->is_single() || $this->is_wc_product() ) {
320
  $output = $this->ld_json_breadcrumbs_post();
321
- } elseif ( false === $this->is_front_page() && $this->is_page() ) {
322
  $output = $this->ld_json_breadcrumbs_page();
323
  }
324
 
@@ -329,6 +345,7 @@ class Generate_Ldjson extends Generate_Image {
329
  * Generate post breadcrumb.
330
  *
331
  * @since 2.6.0
 
332
  *
333
  * @return string $output The breadcrumb script.
334
  */
@@ -372,7 +389,7 @@ class Generate_Ldjson extends Generate_Image {
372
  $parents_merge = array();
373
 
374
  //* Fetch cats children id's, if any.
375
- foreach ( $cats as $term_id => $parent_id ) {
376
  //* Warning: This makes database calls...
377
  if ( ! \term_exists( $term_id, $cat_type, $parent_id ) )
378
  continue;
@@ -387,11 +404,11 @@ class Generate_Ldjson extends Generate_Image {
387
  //* Save children id's as kittens.
388
  $kittens[ $term_id ] = $children;
389
  $parents[ $term_id ] = $ancestors;
390
- }
391
  unset( $cats );
392
 
393
- foreach ( $kittens as $kit_id => $child_id ) {
394
- foreach ( $child_id as $ckey => $cid ) {
395
 
396
  /**
397
  * Seed out children that aren't assigned.
@@ -421,8 +438,8 @@ class Generate_Ldjson extends Generate_Image {
421
  $parents_merge[ $kit_id ] = $parents[ $kit_id ];
422
  unset( $kittens[ $kit_id ] );
423
  }
424
- }
425
- }
426
 
427
  /**
428
  * Build category ID trees for kittens.
@@ -432,7 +449,7 @@ class Generate_Ldjson extends Generate_Image {
432
  //* Empty parents.
433
  $parents = array();
434
 
435
- if ( ! empty( $parents_merge ) ) {
436
  foreach ( $parents_merge as $child_id => $parents_ids ) {
437
 
438
  //* Reset kitten.
@@ -459,12 +476,12 @@ class Generate_Ldjson extends Generate_Image {
459
  $trees = $this->build_breadcrumb_trees( $parents_ids, $trees );
460
  }
461
  }
462
- }
463
 
464
  /**
465
  * Sort by number of id's. Provides a cleaner layout, better Search Engine understanding and more consistent cache.
466
  */
467
- if ( count( $trees ) > 1 ) {
468
  /**
469
  * Applies filter 'the_seo_framework_breadcrumb_post_sorting_callback' : string|array
470
  * @since 2.8.0
@@ -478,15 +495,13 @@ class Generate_Ldjson extends Generate_Image {
478
  } else {
479
  array_multisort( array_map( 'count', $trees ), SORT_DESC, SORT_REGULAR, $trees );
480
  }
481
- }
482
 
483
- $context = $this->schema_context();
484
- $context_type = $this->schema_breadcrumblist();
485
  $item_type = $this->schema_listitem();
486
 
487
  //* For each of the tree items, create a separated script.
488
- if ( $trees ) {
489
- foreach ( $trees as $tree_ids ) {
490
 
491
  if ( is_array( $tree_ids ) ) {
492
  //* Term has assigned children.
@@ -501,8 +516,8 @@ class Generate_Ldjson extends Generate_Image {
501
  //* Put the children in the right order.
502
  $tree_ids = array_reverse( $tree_ids, false );
503
 
504
- foreach ( $tree_ids as $position => $child_id ) {
505
- if ( in_array( $child_id, $assigned_ids, true ) ) {
506
  //* Cat has been assigned, continue.
507
 
508
  //* Fetch item from cache if available.
@@ -518,8 +533,13 @@ class Generate_Ldjson extends Generate_Image {
518
 
519
  $id = json_encode( $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'is_term' => true, 'term' => $cat ) ) );
520
 
521
- //* Note: WordPress Core translation.
522
- $cat_name = empty( $data['doctitle'] ) ? ( empty( $cat->name ) ? __( 'Uncategorized' ) : $cat->name ) : $data['doctitle'];
 
 
 
 
 
523
  $name = json_encode( $cat_name );
524
 
525
  $image = $this->schema_image( $child_id );
@@ -535,22 +555,16 @@ class Generate_Ldjson extends Generate_Image {
535
 
536
  $items .= $this->make_breadcrumb( $item_cache[ $child_id ], true );
537
  }
538
- }
539
- }
540
 
541
  if ( $items ) {
542
-
543
  $items = $this->ld_json_breadcrumb_first( $item_type ) . $items . $this->ld_json_breadcrumb_last( $item_type, $pos, $post_id );
544
-
545
- //* Put it all together.
546
- $breadcrumbhelper = sprintf( '{"@context":%s,"@type":%s,"itemListElement":[%s]}', $context, $context_type, $items );
547
- $output .= '<script type="application/ld+json">' . $breadcrumbhelper . '</script>' . "\r\n";
548
  }
549
  } else {
550
  //* No assigned children, single term item.
551
 
552
- $items = '';
553
-
554
  //* The position of the current item is always static here.
555
  $pos = '2';
556
 
@@ -562,23 +576,32 @@ class Generate_Ldjson extends Generate_Image {
562
 
563
  $id = json_encode( $this->the_url( '', array( 'get_custom_field' => false, 'is_term' => true, 'external' => true, 'term' => $cat ) ) );
564
 
565
- //* Note: WordPress Core translation.
566
- $cat_name = empty( $data['doctitle'] ) ? ( empty( $cat->name ) ? \__( 'Uncategorized' ) : $cat->name ) : $data['doctitle'];
 
 
 
 
 
567
  $name = json_encode( $cat_name );
568
 
569
- $items .= sprintf( '{"@type":%s,"position":%s,"item":{"@id":%s,"name":%s,"image":%s}},', $item_type, (string) $pos, $id, $name, $image );
 
 
 
 
 
 
570
 
571
- if ( $items ) {
572
 
 
573
  $items = $this->ld_json_breadcrumb_first( $item_type ) . $items . $this->ld_json_breadcrumb_last( $item_type, $pos, $post_id );
574
-
575
- //* Put it all together.
576
- $breadcrumbhelper = sprintf( '{"@context":%s,"@type":%s,"itemListElement":[%s]}', $context, $context_type, $items );
577
- $output .= '<script type="application/ld+json">' . $breadcrumbhelper . '</script>' . "\r\n";
578
  }
579
  }
580
- }
581
- }
582
 
583
  return $output;
584
  }
@@ -587,6 +610,7 @@ class Generate_Ldjson extends Generate_Image {
587
  * Generate page breadcrumb.
588
  *
589
  * @since 2.6.0
 
590
  *
591
  * @return string $output The breadcrumb script.
592
  */
@@ -601,8 +625,6 @@ class Generate_Ldjson extends Generate_Image {
601
 
602
  if ( $parents ) :
603
 
604
- $context = $this->schema_context();
605
- $context_type = $this->schema_breadcrumblist();
606
  $item_type = $this->schema_listitem();
607
 
608
  $items = '';
@@ -614,10 +636,23 @@ class Generate_Ldjson extends Generate_Image {
614
 
615
  $id = json_encode( $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'id' => $parent_id ) ) );
616
 
617
- $parent_name = $this->get_custom_field( '_genesis_title', $parent_id ) ?: $this->title( '', '', '', array( 'term_id' => $parent_id, 'meta' => true, 'get_custom_field' => false, 'placeholder' => true, 'notagline' => true, 'description_title' => true ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
618
 
619
  $name = json_encode( $parent_name );
620
- $image = $this->schema_image( $parent_id );
621
 
622
  $breadcrumb = array(
623
  'type' => $item_type,
@@ -633,10 +668,7 @@ class Generate_Ldjson extends Generate_Image {
633
  if ( $items ) {
634
 
635
  $items = $this->ld_json_breadcrumb_first( $item_type ) . $items . $this->ld_json_breadcrumb_last( $item_type, $pos, $page_id );
636
-
637
- //* Put it all together.
638
- $breadcrumbhelper = sprintf( '{"@context":%s,"@type":%s,"itemListElement":[%s]}', $context, $context_type, $items );
639
- $output = '<script type="application/ld+json">' . $breadcrumbhelper . '</script>' . "\r\n";
640
  }
641
  endif;
642
 
@@ -646,12 +678,11 @@ class Generate_Ldjson extends Generate_Image {
646
  /**
647
  * Return home page item for LD Json Breadcrumbs.
648
  *
649
- * @staticvar string $first_item.
650
- *
651
  * @since 2.4.2
 
 
652
  *
653
  * @param string|null $item_type the breadcrumb item type.
654
- *
655
  * @return string Home Breadcrumb item
656
  */
657
  public function ld_json_breadcrumb_first( $item_type = null ) {
@@ -666,14 +697,19 @@ class Generate_Ldjson extends Generate_Image {
666
 
667
  $id = json_encode( $this->the_home_url_from_cache() );
668
 
669
- $home_title = $this->get_option( 'homepage_title' );
670
 
671
- if ( $home_title ) {
672
- $custom_name = $home_title;
673
- } elseif ( $this->has_page_on_front() ) {
674
- $home_id = (int) get_option( 'page_on_front' );
675
 
676
- $custom_name = $this->get_custom_field( '_genesis_title', $home_id ) ?: $this->get_blogname();
 
 
 
 
 
 
 
 
677
  } else {
678
  $custom_name = $this->get_blogname();
679
  }
@@ -696,6 +732,7 @@ class Generate_Ldjson extends Generate_Image {
696
  * Return current page item for LD Json Breadcrumbs.
697
  *
698
  * @since 2.4.2
 
699
  * @staticvar string $last_item.
700
  * @staticvar string $type The breadcrumb item type.
701
  * @staticvar string $id The current post/page/archive url.
@@ -736,8 +773,21 @@ class Generate_Ldjson extends Generate_Image {
736
  if ( ! isset( $id ) )
737
  $id = json_encode( $this->the_url_from_cache() );
738
 
 
 
 
 
 
 
 
 
 
739
  if ( ! isset( $name ) ) {
740
- $name = $this->get_custom_field( '_genesis_title', $post_id ) ?: $this->title( '', '', '', array( 'term_id' => $post_id, 'placeholder' => true, 'meta' => true, 'notagline' => true, 'description_title' => true ) );
 
 
 
 
741
  $name = json_encode( $name );
742
  }
743
 
@@ -758,21 +808,49 @@ class Generate_Ldjson extends Generate_Image {
758
  * Builds a breadcrumb.
759
  *
760
  * @since 2.6.0
 
761
  * @param array $item : {
762
- * 'type',
763
- * 'pos',
764
- * 'id',
765
- * 'name'
766
  * }
767
  * @param bool $comma Whether to add a trailing comma.
768
- *
769
  * @return string The LD+Json breadcrumb.
770
  */
771
  public function make_breadcrumb( $item, $comma = true ) {
772
 
773
  $comma = $comma ? ',' : '';
774
 
775
- return sprintf( '{"@type":%s,"position":%s,"item":{"@id":%s,"name":%s,"image":%s}}%s', $item['type'], $item['pos'], $item['id'], $item['name'], $item['image'], $comma );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
776
  }
777
 
778
  /**
@@ -817,6 +895,31 @@ class Generate_Ldjson extends Generate_Image {
817
  return $trees;
818
  }
819
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
820
  /**
821
  * Return LD+Json Knowledge Graph helper.
822
  *
@@ -845,9 +948,7 @@ class Generate_Ldjson extends Generate_Image {
845
  $logo = '';
846
 
847
  if ( $this->get_option( 'knowledge_logo' ) && 'organization' === $knowledge_type ) {
848
- $_logo = $this->get_site_logo();
849
- if ( ! $_logo )
850
- $_logo = $this->get_site_icon();
851
 
852
  if ( $_logo ) {
853
  $logourl = \esc_url_raw( $_logo );
@@ -922,8 +1023,20 @@ class Generate_Ldjson extends Generate_Image {
922
  $webtype = $this->schema_type();
923
  $url = $this->schema_home_url();
924
  $name = $this->schema_blog_name();
 
925
 
926
- $json = sprintf( '{"@context":%s,"@type":%s,"name":%s,"url":%s}', $context, $webtype, $name, $url );
 
 
 
 
 
 
 
 
 
 
 
927
 
928
  $output = '';
929
  if ( $json )
53
 
54
  $this->setup_ld_json_transient( $this->get_the_real_ID() );
55
 
56
+ $this->the_seo_framework_debug and $this->debug_init( __METHOD__, false, $debug_key = microtime( true ), array( 'LD Json transient' => $this->ld_json_transient, 'Output from transient' => false !== $this->get_transient( $this->ld_json_transient ) ) );
57
 
58
  $use_cache = $this->is_option_checked( 'cache_meta_schema' );
59
 
60
  $output = $use_cache ? $this->get_transient( $this->ld_json_transient ) : false;
61
+ if ( false === $output ) :
62
 
63
  $output = '';
64
 
65
  //* Only display search helper and knowledge graph on front page.
66
+ if ( $this->is_real_front_page() ) {
67
 
68
  $sitename = $this->ld_json_name();
69
  $sitelinks = $this->ld_json_search();
97
 
98
  $this->set_transient( $this->ld_json_transient, $output, $expiration );
99
  }
100
+ endif;
101
 
102
+ $this->the_seo_framework_debug and $this->debug_init( __METHOD__, false, $debug_key, array( 'LD Json transient output' => $output ) );
 
 
 
 
103
 
104
  return $output;
105
  }
217
  *
218
  * @staticvar array $images
219
  * @since 2.7.0
220
+ * @since 2.9.0 : 1. No longer uses image from cache, instead: it skips fallback images.
221
+ * 2. Can now fetch home-page as blog set image.
222
  *
223
  * @param int|string $id The page, post, product or term ID.
224
  * @param bool $singular Whether the ID is singular.
235
  $image = '';
236
 
237
  if ( $singular ) {
238
+ if ( $id === $this->get_the_front_page_ID() ) {
239
+ if ( $this->has_page_on_front() ) {
240
+ $image_args = array(
241
+ 'post_id' => $id,
242
+ 'skip_fallback' => true,
243
+ );
244
+ } else {
245
+ $image_args = array(
246
+ 'post_id' => $id,
247
+ 'skip_fallback' => true,
248
+ 'disallowed' => array(
249
+ 'postmeta',
250
+ 'featured',
251
+ ),
252
+ );
253
+ }
254
+ } else {
255
+ $image_args = array(
256
+ 'post_id' => $id,
257
+ 'skip_fallback' => true,
258
+ 'disallowed' => array(
259
+ 'homemeta'
260
+ ),
261
+ );
262
  }
263
+ $image = $this->get_social_image( $image_args );
264
  } else {
265
  //* Placeholder.
266
  $image = '';
334
 
335
  if ( $this->is_single() || $this->is_wc_product() ) {
336
  $output = $this->ld_json_breadcrumbs_post();
337
+ } elseif ( false === $this->is_real_front_page() && $this->is_page() ) {
338
  $output = $this->ld_json_breadcrumbs_page();
339
  }
340
 
345
  * Generate post breadcrumb.
346
  *
347
  * @since 2.6.0
348
+ * @since 2.9.0 Now uses $this->ld_json_breadcrumbs_use_seo_title()
349
  *
350
  * @return string $output The breadcrumb script.
351
  */
389
  $parents_merge = array();
390
 
391
  //* Fetch cats children id's, if any.
392
+ foreach ( $cats as $term_id => $parent_id ) :
393
  //* Warning: This makes database calls...
394
  if ( ! \term_exists( $term_id, $cat_type, $parent_id ) )
395
  continue;
404
  //* Save children id's as kittens.
405
  $kittens[ $term_id ] = $children;
406
  $parents[ $term_id ] = $ancestors;
407
+ endforeach;
408
  unset( $cats );
409
 
410
+ foreach ( $kittens as $kit_id => $child_id ) :
411
+ foreach ( $child_id as $ckey => $cid ) :
412
 
413
  /**
414
  * Seed out children that aren't assigned.
438
  $parents_merge[ $kit_id ] = $parents[ $kit_id ];
439
  unset( $kittens[ $kit_id ] );
440
  }
441
+ endforeach;
442
+ endforeach;
443
 
444
  /**
445
  * Build category ID trees for kittens.
449
  //* Empty parents.
450
  $parents = array();
451
 
452
+ if ( ! empty( $parents_merge ) ) :
453
  foreach ( $parents_merge as $child_id => $parents_ids ) {
454
 
455
  //* Reset kitten.
476
  $trees = $this->build_breadcrumb_trees( $parents_ids, $trees );
477
  }
478
  }
479
+ endif;
480
 
481
  /**
482
  * Sort by number of id's. Provides a cleaner layout, better Search Engine understanding and more consistent cache.
483
  */
484
+ if ( count( $trees ) > 1 ) :
485
  /**
486
  * Applies filter 'the_seo_framework_breadcrumb_post_sorting_callback' : string|array
487
  * @since 2.8.0
495
  } else {
496
  array_multisort( array_map( 'count', $trees ), SORT_DESC, SORT_REGULAR, $trees );
497
  }
498
+ endif;
499
 
 
 
500
  $item_type = $this->schema_listitem();
501
 
502
  //* For each of the tree items, create a separated script.
503
+ if ( $trees ) :
504
+ foreach ( $trees as $tree_ids ) :
505
 
506
  if ( is_array( $tree_ids ) ) {
507
  //* Term has assigned children.
516
  //* Put the children in the right order.
517
  $tree_ids = array_reverse( $tree_ids, false );
518
 
519
+ foreach ( $tree_ids as $position => $child_id ) :
520
+ if ( in_array( $child_id, $assigned_ids, true ) ) :
521
  //* Cat has been assigned, continue.
522
 
523
  //* Fetch item from cache if available.
533
 
534
  $id = json_encode( $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'is_term' => true, 'term' => $cat ) ) );
535
 
536
+ if ( $this->ld_json_breadcrumbs_use_seo_title() ) {
537
+ //* Note: WordPress Core translation.
538
+ $cat_name = empty( $data['doctitle'] ) ? ( empty( $cat->name ) ? \__( 'Uncategorized' ) : $cat->name ) : $data['doctitle'];
539
+ } else {
540
+ //* Note: WordPress Core translation.
541
+ $cat_name = empty( $cat->name ) ? \__( 'Uncategorized' ) : $cat->name;
542
+ }
543
  $name = json_encode( $cat_name );
544
 
545
  $image = $this->schema_image( $child_id );
555
 
556
  $items .= $this->make_breadcrumb( $item_cache[ $child_id ], true );
557
  }
558
+ endif;
559
+ endforeach;
560
 
561
  if ( $items ) {
 
562
  $items = $this->ld_json_breadcrumb_first( $item_type ) . $items . $this->ld_json_breadcrumb_last( $item_type, $pos, $post_id );
563
+ $output .= $this->make_breadcrumb_script( $items );
 
 
 
564
  }
565
  } else {
566
  //* No assigned children, single term item.
567
 
 
 
568
  //* The position of the current item is always static here.
569
  $pos = '2';
570
 
576
 
577
  $id = json_encode( $this->the_url( '', array( 'get_custom_field' => false, 'is_term' => true, 'external' => true, 'term' => $cat ) ) );
578
 
579
+ if ( $this->ld_json_breadcrumbs_use_seo_title() ) {
580
+ //* Note: WordPress Core translation.
581
+ $cat_name = empty( $data['doctitle'] ) ? ( empty( $cat->name ) ? \__( 'Uncategorized' ) : $cat->name ) : $data['doctitle'];
582
+ } else {
583
+ //* Note: WordPress Core translation.
584
+ $cat_name = empty( $cat->name ) ? \__( 'Uncategorized' ) : $cat->name;
585
+ }
586
  $name = json_encode( $cat_name );
587
 
588
+ $item = array(
589
+ 'type' => $item_type,
590
+ 'pos' => (string) $pos,
591
+ 'id' => $id,
592
+ 'name' => $name,
593
+ 'image' => $image,
594
+ );
595
 
596
+ $items = $this->make_breadcrumb( $item, true );
597
 
598
+ if ( $items ) {
599
  $items = $this->ld_json_breadcrumb_first( $item_type ) . $items . $this->ld_json_breadcrumb_last( $item_type, $pos, $post_id );
600
+ $output .= $this->make_breadcrumb_script( $items );
 
 
 
601
  }
602
  }
603
+ endforeach;
604
+ endif;
605
 
606
  return $output;
607
  }
610
  * Generate page breadcrumb.
611
  *
612
  * @since 2.6.0
613
+ * @since 2.9.0 Now uses $this->ld_json_breadcrumbs_use_seo_title()
614
  *
615
  * @return string $output The breadcrumb script.
616
  */
625
 
626
  if ( $parents ) :
627
 
 
 
628
  $item_type = $this->schema_listitem();
629
 
630
  $items = '';
636
 
637
  $id = json_encode( $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'id' => $parent_id ) ) );
638
 
639
+ $title_args = array(
640
+ 'term_id' => $parent_id,
641
+ 'meta' => true,
642
+ 'placeholder' => true,
643
+ 'notagline' => true,
644
+ 'description_title' => true,
645
+ 'get_custom_field' => false,
646
+ );
647
+
648
+ if ( $this->ld_json_breadcrumbs_use_seo_title() ) {
649
+ $parent_name = $this->get_custom_field( '_genesis_title', $parent_id ) ?: $this->title( '', '', '', $title_args );
650
+ } else {
651
+ $parent_name = $this->title( '', '', '', $title_args );
652
+ }
653
 
654
  $name = json_encode( $parent_name );
655
+ $image = $this->schema_image( $parent_id, true );
656
 
657
  $breadcrumb = array(
658
  'type' => $item_type,
668
  if ( $items ) {
669
 
670
  $items = $this->ld_json_breadcrumb_first( $item_type ) . $items . $this->ld_json_breadcrumb_last( $item_type, $pos, $page_id );
671
+ $output = $this->make_breadcrumb_script( $items );
 
 
 
672
  }
673
  endif;
674
 
678
  /**
679
  * Return home page item for LD Json Breadcrumbs.
680
  *
 
 
681
  * @since 2.4.2
682
+ * @since 2.9.0 Now uses $this->ld_json_breadcrumbs_use_seo_title()
683
+ * @staticvar string $first_item.
684
  *
685
  * @param string|null $item_type the breadcrumb item type.
 
686
  * @return string Home Breadcrumb item
687
  */
688
  public function ld_json_breadcrumb_first( $item_type = null ) {
697
 
698
  $id = json_encode( $this->the_home_url_from_cache() );
699
 
700
+ if ( $this->ld_json_breadcrumbs_use_seo_title() ) {
701
 
702
+ $home_title = $this->get_option( 'homepage_title' );
 
 
 
703
 
704
+ if ( $home_title ) {
705
+ $custom_name = $home_title;
706
+ } elseif ( $this->has_page_on_front() ) {
707
+ $home_id = (int) \get_option( 'page_on_front' );
708
+
709
+ $custom_name = $this->get_custom_field( '_genesis_title', $home_id ) ?: $this->get_blogname();
710
+ } else {
711
+ $custom_name = $this->get_blogname();
712
+ }
713
  } else {
714
  $custom_name = $this->get_blogname();
715
  }
732
  * Return current page item for LD Json Breadcrumbs.
733
  *
734
  * @since 2.4.2
735
+ * @since 2.9.0 Now uses $this->ld_json_breadcrumbs_use_seo_title()
736
  * @staticvar string $last_item.
737
  * @staticvar string $type The breadcrumb item type.
738
  * @staticvar string $id The current post/page/archive url.
773
  if ( ! isset( $id ) )
774
  $id = json_encode( $this->the_url_from_cache() );
775
 
776
+ $title_args = array(
777
+ 'term_id' => $post_id,
778
+ 'placeholder' => true,
779
+ 'meta' => true,
780
+ 'notagline' => true,
781
+ 'description_title' => true,
782
+ 'get_custom_field' => false,
783
+ );
784
+
785
  if ( ! isset( $name ) ) {
786
+ if ( $this->ld_json_breadcrumbs_use_seo_title() ) {
787
+ $name = $this->get_custom_field( '_genesis_title', $post_id ) ?: $this->title( '', '', '', $title_args );
788
+ } else {
789
+ $name = $this->title( '', '', '', $title_args );
790
+ }
791
  $name = json_encode( $name );
792
  }
793
 
808
  * Builds a breadcrumb.
809
  *
810
  * @since 2.6.0
811
+ * @since 2.9.0 : No longer outputs image if it's not present.
812
  * @param array $item : {
813
+ * 'type',
814
+ * 'pos',
815
+ * 'id',
816
+ * 'name'
817
  * }
818
  * @param bool $comma Whether to add a trailing comma.
 
819
  * @return string The LD+Json breadcrumb.
820
  */
821
  public function make_breadcrumb( $item, $comma = true ) {
822
 
823
  $comma = $comma ? ',' : '';
824
 
825
+ if ( $item['image'] && '""' !== $item['image'] ) {
826
+ $retval = sprintf( '{"@type":%s,"position":%s,"item":{"@id":%s,"name":%s,"image":%s}}%s', $item['type'], $item['pos'], $item['id'], $item['name'], $item['image'], $comma );
827
+ } else {
828
+ $retval = sprintf( '{"@type":%s,"position":%s,"item":{"@id":%s,"name":%s}}%s', $item['type'], $item['pos'], $item['id'], $item['name'], $comma );
829
+ }
830
+
831
+ return $retval;
832
+ }
833
+
834
+ /**
835
+ * Puts breadcrumb items in script wrapper.
836
+ *
837
+ * @since 2.9.0
838
+ *
839
+ * @param string $items The breadcrumb items
840
+ * @return string The breadcrumb script tag.
841
+ */
842
+ protected function make_breadcrumb_script( $items = '' ) {
843
+
844
+ if ( $items ) {
845
+ $context = $this->schema_context();
846
+ $context_type = $this->schema_breadcrumblist();
847
+
848
+ //* Put it all together.
849
+ $breadcrumbhelper = sprintf( '{"@context":%s,"@type":%s,"itemListElement":[%s]}', $context, $context_type, $items );
850
+ return '<script type="application/ld+json">' . $breadcrumbhelper . '</script>' . "\r\n";
851
+ }
852
+
853
+ return '';
854
  }
855
 
856
  /**
895
  return $trees;
896
  }
897
 
898
+ /**
899
+ * Determines whether to use the SEO title or only the fallback page title.
900
+ *
901
+ * Does not affect cache.
902
+ *
903
+ * @since 2.9.0
904
+ * @staticvar bool $cache
905
+ *
906
+ * @return bool
907
+ */
908
+ public function ld_json_breadcrumbs_use_seo_title() {
909
+
910
+ static $cache = null;
911
+
912
+ /**
913
+ * Applies filters 'the_seo_framework_use_breadcrumb_seo_title' : boolean
914
+ *
915
+ * Determines whether to use the SEO title or only the fallback page title
916
+ * in breadcrumbs.
917
+ *
918
+ * @param $retval bool
919
+ */
920
+ return isset( $cache ) ? $cache : $cache = (bool) \apply_filters( 'the_seo_framework_use_breadcrumb_seo_title', true );
921
+ }
922
+
923
  /**
924
  * Return LD+Json Knowledge Graph helper.
925
  *
948
  $logo = '';
949
 
950
  if ( $this->get_option( 'knowledge_logo' ) && 'organization' === $knowledge_type ) {
951
+ $_logo = $this->get_site_logo() ?: $this->get_site_icon();
 
 
952
 
953
  if ( $_logo ) {
954
  $logourl = \esc_url_raw( $_logo );
1023
  $webtype = $this->schema_type();
1024
  $url = $this->schema_home_url();
1025
  $name = $this->schema_blog_name();
1026
+ $alternate = '';
1027
 
1028
+ $blogname = $this->get_blogname();
1029
+ $knowledge_name = $this->get_option( 'knowledge_name' );
1030
+
1031
+ if ( $knowledge_name && $knowledge_name !== $blogname ) {
1032
+ $alternate = json_encode( \esc_html( $knowledge_name ) );
1033
+ }
1034
+
1035
+ if ( $alternate ) {
1036
+ $json = sprintf( '{"@context":%s,"@type":%s,"name":%s,"alternateName":%s,"url":%s}', $context, $webtype, $name, $alternate, $url );
1037
+ } else {
1038
+ $json = sprintf( '{"@context":%s,"@type":%s,"name":%s,"url":%s}', $context, $webtype, $name, $url );
1039
+ }
1040
 
1041
  $output = '';
1042
  if ( $json )
inc/classes/generate-title.class.php CHANGED
@@ -302,7 +302,7 @@ class Generate_Title extends Generate_Description {
302
  * Moved up and return early to reduce processing.
303
  * @since 2.3.8
304
  */
305
- if ( $this->is_front_page() )
306
  return $title = '';
307
 
308
  $args = $this->reparse_title_args( $args );
@@ -442,7 +442,7 @@ class Generate_Title extends Generate_Description {
442
  $title = $this->do_title_pre_filter( '', $args, false );
443
  $blogname = '';
444
 
445
- $is_front_page = $this->is_front_page() || $args['page_on_front'] || $this->is_static_frontpage( $args['term_id'] );
446
 
447
  $seplocation = $this->get_title_seplocation( $seplocation );
448
 
302
  * Moved up and return early to reduce processing.
303
  * @since 2.3.8
304
  */
305
+ if ( $this->is_real_front_page() )
306
  return $title = '';
307
 
308
  $args = $this->reparse_title_args( $args );
442
  $title = $this->do_title_pre_filter( '', $args, false );
443
  $blogname = '';
444
 
445
+ $is_front_page = $args['page_on_front'] || $this->is_real_front_page() || ( $this->is_front_page_by_id( $args['term_id'] ) && ! $this->is_archive() );
446
 
447
  $seplocation = $this->get_title_seplocation( $seplocation );
448
 
inc/classes/generate-url.class.php CHANGED
@@ -65,6 +65,7 @@ class Generate_Url extends Generate_Title {
65
  * @since 2.0.0
66
  * @since 2.4.2 : Refactored arguments
67
  * @since 2.8.0 : No longer tolerates $id as Post object.
 
68
  *
69
  * @param string $url the url
70
  * @param array $args : accepted args : {
@@ -121,6 +122,8 @@ class Generate_Url extends Generate_Title {
121
 
122
  if ( empty( $url ) )
123
  $path = $this->generate_url_path( $args );
 
 
124
  }
125
 
126
  /**
@@ -144,20 +147,21 @@ class Generate_Url extends Generate_Title {
144
  * @param int $id The current post, page or term ID.
145
  * @param bool $external Whether the call is made from outside the current ID scope. Like from the Sitemap.
146
  */
147
- $filter = (array) \apply_filters( 'the_seo_framework_url_output_args', array(), $path, $args['id'], $args['external'] );
148
 
149
- if ( $filter ) {
150
- $url = $filter['url'];
151
- $scheme = $filter['scheme'];
152
  }
153
 
154
- //* Non-domainmap URL
155
  if ( empty( $url ) ) {
 
156
  if ( $args['home'] )
157
  $this->unset_current_subdomain();
158
 
159
  $url = $this->add_url_host( $path );
160
- $scheme = $this->is_ssl() ? 'https' : 'http';
161
 
162
  $url = $this->add_url_subdomain( $url );
163
  }
@@ -245,7 +249,6 @@ class Generate_Url extends Generate_Title {
245
  $args['get_custom_field'] = isset( $args['get_custom_field'] ) ? (bool) $args['get_custom_field'] : $defaults['get_custom_field'];
246
  $args['external'] = isset( $args['external'] ) ? (bool) $args['external'] : $defaults['external'];
247
  $args['is_term'] = isset( $args['is_term'] ) ? (bool) $args['is_term'] : $defaults['is_term'];
248
- $args['get_custom_field'] = isset( $args['get_custom_field'] ) ? (bool) $args['get_custom_field'] : $defaults['get_custom_field'];
249
  $args['post'] = isset( $args['post'] ) ? (object) $args['post'] : $defaults['post'];
250
  $args['term'] = isset( $args['term'] ) ? (object) $args['term'] : $defaults['term'];
251
  $args['home'] = isset( $args['home'] ) ? (bool) $args['home'] : $defaults['home'];
@@ -360,9 +363,9 @@ class Generate_Url extends Generate_Title {
360
 
361
  $args = $this->reparse_url_args( $args );
362
 
363
- if ( $args['external'] || ! $this->is_front_page() ) {
364
  $url = \get_permalink( $post_id );
365
- } elseif ( $this->is_front_page() ) {
366
  $url = \get_home_url();
367
  } elseif ( ! $args['external'] ) {
368
  if ( isset( $GLOBALS['wp']->request ) )
@@ -485,10 +488,10 @@ class Generate_Url extends Generate_Title {
485
  else :
486
  if ( $t->rewrite['hierarchical'] ) {
487
  $hierarchical_slugs = array();
488
- $ancestors = get_ancestors( $term->term_id, $taxonomy, 'taxonomy' );
489
 
490
  foreach ( (array) $ancestors as $ancestor ) {
491
- $ancestor_term = get_term( $ancestor, $taxonomy );
492
  $hierarchical_slugs[] = $ancestor_term->slug;
493
  }
494
 
@@ -507,7 +510,7 @@ class Generate_Url extends Generate_Title {
507
  endif;
508
 
509
  //* Add plausible domain subdirectories.
510
- $url = \trailingslashit( get_option( 'home' ) ) . ltrim( $path, ' \\/' );
511
  $path = $this->set_url_scheme( $url, 'relative' );
512
 
513
  return $path;
@@ -551,7 +554,7 @@ class Generate_Url extends Generate_Title {
551
  *
552
  * @param string $scheme The current URL scheme.
553
  */
554
- return $scheme = (string) apply_filters( 'the_seo_framework_preferred_url_scheme', $scheme );
555
  }
556
 
557
  /**
@@ -609,6 +612,8 @@ class Generate_Url extends Generate_Title {
609
  * Set URL scheme based on filter.
610
  *
611
  * @since 2.6.0
 
 
612
  *
613
  * @param string $url The url with scheme.
614
  * @param string $scheme The current scheme.
@@ -627,10 +632,12 @@ class Generate_Url extends Generate_Title {
627
  * (string) 'relative' : Scheme relative
628
  * (void) null : Do nothing
629
  *
630
- * @param string $current_scheme the current used scheme.
631
  *
632
  * @since 2.4.2
633
  * @since 2.8.0 Deprecated.
 
 
 
634
  */
635
  $scheme_settings = \apply_filters( 'the_seo_framework_canonical_force_scheme', null, $current_scheme );
636
 
@@ -663,7 +670,7 @@ class Generate_Url extends Generate_Title {
663
  if ( ! $this->get_option( 'shortlink_tag' ) )
664
  return '';
665
 
666
- if ( $this->is_front_page() )
667
  return '';
668
 
669
  $path = '';
@@ -777,8 +784,11 @@ class Generate_Url extends Generate_Title {
777
  $next = '';
778
 
779
  if ( $this->is_singular() ) {
780
-
781
- $output_singular_paged = $this->is_front_page() ? $this->is_option_checked( 'prev_next_frontpage' ) : $this->is_option_checked( 'prev_next_posts' );
 
 
 
782
 
783
  if ( $output_singular_paged ) {
784
 
@@ -797,7 +807,7 @@ class Generate_Url extends Generate_Title {
797
  } elseif ( $this->is_archive() || $this->is_home() ) {
798
 
799
  $output_archive_paged = false;
800
- if ( $this->is_front_page() ) {
801
  //* Only home.
802
  $output_archive_paged = $this->is_option_checked( 'prev_next_frontpage' );
803
  } else {
@@ -999,7 +1009,7 @@ class Generate_Url extends Generate_Title {
999
  if ( isset( $structure ) )
1000
  return $structure;
1001
 
1002
- return $structure = get_option( 'permalink_structure' );
1003
  }
1004
 
1005
  /**
65
  * @since 2.0.0
66
  * @since 2.4.2 : Refactored arguments
67
  * @since 2.8.0 : No longer tolerates $id as Post object.
68
+ * @since 2.9.0 : When using 'home => true' args parameter, the home path is added when set.
69
  *
70
  * @param string $url the url
71
  * @param array $args : accepted args : {
122
 
123
  if ( empty( $url ) )
124
  $path = $this->generate_url_path( $args );
125
+ } elseif ( $args['home'] ) {
126
+ $path = $this->get_home_path();
127
  }
128
 
129
  /**
147
  * @param int $id The current post, page or term ID.
148
  * @param bool $external Whether the call is made from outside the current ID scope. Like from the Sitemap.
149
  */
150
+ $url_filter = (array) \apply_filters( 'the_seo_framework_url_output_args', array(), $path, $args['id'], $args['external'] );
151
 
152
+ if ( $url_filter ) {
153
+ $url = $url_filter['url'];
154
+ $scheme = $url_filter['scheme'];
155
  }
156
 
157
+ //* Non-custom URL
158
  if ( empty( $url ) ) {
159
+ //* Reset cache if request is for the home URL.
160
  if ( $args['home'] )
161
  $this->unset_current_subdomain();
162
 
163
  $url = $this->add_url_host( $path );
164
+ $scheme = '';
165
 
166
  $url = $this->add_url_subdomain( $url );
167
  }
249
  $args['get_custom_field'] = isset( $args['get_custom_field'] ) ? (bool) $args['get_custom_field'] : $defaults['get_custom_field'];
250
  $args['external'] = isset( $args['external'] ) ? (bool) $args['external'] : $defaults['external'];
251
  $args['is_term'] = isset( $args['is_term'] ) ? (bool) $args['is_term'] : $defaults['is_term'];
 
252
  $args['post'] = isset( $args['post'] ) ? (object) $args['post'] : $defaults['post'];
253
  $args['term'] = isset( $args['term'] ) ? (object) $args['term'] : $defaults['term'];
254
  $args['home'] = isset( $args['home'] ) ? (bool) $args['home'] : $defaults['home'];
363
 
364
  $args = $this->reparse_url_args( $args );
365
 
366
+ if ( $args['external'] || ! $this->is_real_front_page() || ! $this->is_front_page_by_id( $post_id ) ) {
367
  $url = \get_permalink( $post_id );
368
+ } elseif ( $this->is_real_front_page() || $this->is_front_page_by_id( $post_id ) ) {
369
  $url = \get_home_url();
370
  } elseif ( ! $args['external'] ) {
371
  if ( isset( $GLOBALS['wp']->request ) )
488
  else :
489
  if ( $t->rewrite['hierarchical'] ) {
490
  $hierarchical_slugs = array();
491
+ $ancestors = \get_ancestors( $term->term_id, $taxonomy, 'taxonomy' );
492
 
493
  foreach ( (array) $ancestors as $ancestor ) {
494
+ $ancestor_term = \get_term( $ancestor, $taxonomy );
495
  $hierarchical_slugs[] = $ancestor_term->slug;
496
  }
497
 
510
  endif;
511
 
512
  //* Add plausible domain subdirectories.
513
+ $url = \trailingslashit( \get_option( 'home' ) ) . ltrim( $path, ' \\/' );
514
  $path = $this->set_url_scheme( $url, 'relative' );
515
 
516
  return $path;
554
  *
555
  * @param string $scheme The current URL scheme.
556
  */
557
+ return $scheme = (string) \apply_filters( 'the_seo_framework_preferred_url_scheme', $scheme );
558
  }
559
 
560
  /**
612
  * Set URL scheme based on filter.
613
  *
614
  * @since 2.6.0
615
+ * @since 2.8.0 Deprecated.
616
+ * @deprecated
617
  *
618
  * @param string $url The url with scheme.
619
  * @param string $scheme The current scheme.
632
  * (string) 'relative' : Scheme relative
633
  * (void) null : Do nothing
634
  *
 
635
  *
636
  * @since 2.4.2
637
  * @since 2.8.0 Deprecated.
638
+ * @deprecated
639
+ *
640
+ * @param string $current_scheme the current used scheme.
641
  */
642
  $scheme_settings = \apply_filters( 'the_seo_framework_canonical_force_scheme', null, $current_scheme );
643
 
670
  if ( ! $this->get_option( 'shortlink_tag' ) )
671
  return '';
672
 
673
+ if ( $this->is_real_front_page() || $this->is_front_page_by_id( $post_id ) )
674
  return '';
675
 
676
  $path = '';
784
  $next = '';
785
 
786
  if ( $this->is_singular() ) {
787
+ if ( $this->is_real_front_page() || $this->is_front_page_by_id( $post_id ) ) {
788
+ $output_singular_paged = $this->is_option_checked( 'prev_next_frontpage' );
789
+ } else {
790
+ $output_singular_paged = $this->is_option_checked( 'prev_next_posts' );
791
+ }
792
 
793
  if ( $output_singular_paged ) {
794
 
807
  } elseif ( $this->is_archive() || $this->is_home() ) {
808
 
809
  $output_archive_paged = false;
810
+ if ( $this->is_real_front_page() || $this->is_front_page_by_id( $post_id ) ) {
811
  //* Only home.
812
  $output_archive_paged = $this->is_option_checked( 'prev_next_frontpage' );
813
  } else {
1009
  if ( isset( $structure ) )
1010
  return $structure;
1011
 
1012
+ return $structure = \get_option( 'permalink_structure' );
1013
  }
1014
 
1015
  /**
inc/classes/generate.class.php CHANGED
@@ -69,11 +69,11 @@ class Generate extends Term_Data {
69
  if ( $this->is_archive() && $this->paged() > 1 )
70
  $meta['noindex'] = $this->get_option( 'paged_noindex' ) ? 'noindex' : $meta['noindex'];
71
 
72
- if ( $this->is_front_page() && ( $this->page() > 1 || $this->paged() > 1 ) )
73
  $meta['noindex'] = $this->get_option( 'home_paged_noindex' ) ? 'noindex' : $meta['noindex'];
74
 
75
  //* Check home page SEO settings, set noindex, nofollow and noarchive
76
- if ( $this->is_front_page() ) {
77
  $meta['noindex'] = empty( $meta['noindex'] ) && $this->is_option_checked( 'homepage_noindex' ) ? 'noindex' : $meta['noindex'];
78
  $meta['nofollow'] = empty( $meta['nofollow'] ) && $this->is_option_checked( 'homepage_nofollow' ) ? 'nofollow' : $meta['nofollow'];
79
  $meta['noarchive'] = empty( $meta['noarchive'] ) && $this->is_option_checked( 'homepage_noarchive' ) ? 'noarchive' : $meta['noarchive'];
@@ -310,7 +310,7 @@ class Generate extends Term_Data {
310
  $type = 'article';
311
  } elseif ( $this->is_author() ) {
312
  $type = 'profile';
313
- } elseif ( $this->is_blog_page() || ( $this->is_front_page() && ! $this->has_page_on_front() ) ) {
314
  $type = 'blog';
315
  } else {
316
  $type = 'website';
@@ -343,36 +343,75 @@ class Generate extends Term_Data {
343
  }
344
 
345
  /**
346
- * Generates the Twitter Card type. When there's an image found, it will
347
- * take the said option. Otherwise, it will fall back to 'summary'.
 
 
348
  *
349
  * @since 2.7.0
350
  * @since 2.8.2 : Now considers description output.
 
351
  *
352
  * @return string The Twitter Card type.
353
  */
354
  public function generate_twitter_card_type() {
355
 
356
- if ( $this->get_image_from_cache() ) {
357
 
358
- $option = $this->get_option( 'twitter_card' );
 
 
359
 
360
- //* Photo will always work with an image.
361
- if ( 'photo' === $option )
362
- return 'photo';
363
 
364
- //* Only output 'summary' or 'summary_large_image' if there's a description.
365
- if ( $this->description_from_cache( true ) )
366
- return trim( \esc_attr( $option ) );
 
367
 
368
- //* Output photo otherwise.
369
- return 'photo';
370
  }
371
 
372
- if ( $this->description_from_cache( true ) )
373
- return 'summary';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
- return '';
376
  }
377
 
378
  /**
@@ -416,7 +455,6 @@ class Generate extends Term_Data {
416
  return array(
417
  'summary' => 'summary',
418
  'summary_large_image' => 'summary-large-image',
419
- 'photo' => 'photo',
420
  );
421
  }
422
  }
69
  if ( $this->is_archive() && $this->paged() > 1 )
70
  $meta['noindex'] = $this->get_option( 'paged_noindex' ) ? 'noindex' : $meta['noindex'];
71
 
72
+ if ( $this->is_real_front_page() && ( $this->page() > 1 || $this->paged() > 1 ) )
73
  $meta['noindex'] = $this->get_option( 'home_paged_noindex' ) ? 'noindex' : $meta['noindex'];
74
 
75
  //* Check home page SEO settings, set noindex, nofollow and noarchive
76
+ if ( $this->is_real_front_page() ) {
77
  $meta['noindex'] = empty( $meta['noindex'] ) && $this->is_option_checked( 'homepage_noindex' ) ? 'noindex' : $meta['noindex'];
78
  $meta['nofollow'] = empty( $meta['nofollow'] ) && $this->is_option_checked( 'homepage_nofollow' ) ? 'nofollow' : $meta['nofollow'];
79
  $meta['noarchive'] = empty( $meta['noarchive'] ) && $this->is_option_checked( 'homepage_noarchive' ) ? 'noarchive' : $meta['noarchive'];
310
  $type = 'article';
311
  } elseif ( $this->is_author() ) {
312
  $type = 'profile';
313
+ } elseif ( $this->is_blog_page() || ( $this->is_real_front_page() && ! $this->has_page_on_front() ) ) {
314
  $type = 'blog';
315
  } else {
316
  $type = 'website';
343
  }
344
 
345
  /**
346
+ * Generates the Twitter Card type.
347
+ *
348
+ * When there's an image found, it will take the said option.
349
+ * Otherwise, it will return 'summary' or ''.
350
  *
351
  * @since 2.7.0
352
  * @since 2.8.2 : Now considers description output.
353
+ * @since 2.9.0 : Now listens to $this->get_available_twitter_cards().
354
  *
355
  * @return string The Twitter Card type.
356
  */
357
  public function generate_twitter_card_type() {
358
 
359
+ $available_cards = $this->get_available_twitter_cards();
360
 
361
+ //* No valid Twitter cards have been found.
362
+ if ( false === $available_cards )
363
+ return '';
364
 
365
+ $option = $this->get_option( 'twitter_card' );
366
+ $option = trim( \esc_attr( $option ) );
 
367
 
368
+ //* Option is equal to found cards. Output option.
369
+ if ( in_array( $option, $available_cards, true ) ) {
370
+ if ( 'summary_large_image' === $option )
371
+ return 'summary_large_image';
372
 
373
+ if ( 'summary' === $option )
374
+ return 'summary';
375
  }
376
 
377
+ return 'summary';
378
+ }
379
+
380
+ /**
381
+ * Determines which Twitter cards can be used.
382
+ *
383
+ * @since 2.9.0
384
+ * @staticvar bool|array $cache
385
+ *
386
+ * @return bool|array False when it shouldn't be used. True otherwise.
387
+ */
388
+ public function get_available_twitter_cards() {
389
+
390
+ static $cache = null;
391
+
392
+ if ( isset( $cache ) )
393
+ return $cache;
394
+
395
+ if ( ! $this->description_from_cache( true ) ) {
396
+ $retval = array();
397
+ } elseif ( ! $this->title_from_cache( '', '', '', true ) ) {
398
+ $retval = array();
399
+ } else {
400
+ $retval = $this->get_image_from_cache() ? array( 'summary_large_image', 'summary' ) : array( 'summary' );
401
+ }
402
+
403
+ /**
404
+ * Applies filters 'the_seo_framework_available_twitter_cards' : array()
405
+ *
406
+ * The available Twitter cards.
407
+ *
408
+ * @since 2.9.0
409
+ *
410
+ * @param array $retval Use empty array to invalidate Twitter card.
411
+ */
412
+ $retval = (array) \apply_filters( 'the_seo_framework_available_twitter_cards', $retval );
413
 
414
+ return $cache = $retval ?: false;
415
  }
416
 
417
  /**
455
  return array(
456
  'summary' => 'summary',
457
  'summary_large_image' => 'summary-large-image',
 
458
  );
459
  }
460
  }
inc/classes/init.class.php CHANGED
@@ -176,7 +176,7 @@ class Init extends Query {
176
  \add_action( 'wp_ajax_add-tag', array( $this, 'init_columns_ajax' ), -1 );
177
  }
178
 
179
- if ( $this->load_options ) {
180
  // Enqueue i18n defaults.
181
  \add_action( 'admin_init', array( $this, 'enqueue_page_defaults' ), 1 );
182
 
@@ -207,14 +207,20 @@ class Init extends Query {
207
  //* Admin AJAX for counter options.
208
  \add_action( 'wp_ajax_the_seo_framework_update_counter', array( $this, 'wp_ajax_update_counter_type' ) );
209
 
 
 
 
 
210
  \add_filter( 'removable_query_args', array( $this, 'add_removable_query_args' ) );
211
- }
212
  }
213
 
214
  /**
215
  * Initializes front-end actions.
216
  * Disregards other SEO plugins, the meta output does look at detection.
217
  *
 
 
218
  * @since 2.5.2
219
  */
220
  protected function init_front_end_actions() {
@@ -248,15 +254,11 @@ class Init extends Query {
248
  \add_action( 'template_redirect', array( $this, 'maybe_output_sitemap' ), 1 );
249
  \add_action( 'template_redirect', array( $this, 'maybe_output_sitemap_stylesheet' ), 1 );
250
 
251
- if ( $this->is_singular() ) {
252
- //* Initialize 301 redirects.
253
- \add_action( 'template_redirect', array( $this, 'custom_field_redirect' ) );
254
- }
255
 
256
- if ( $this->is_feed() ) {
257
- //* Initialize feed alteration.
258
- \add_action( 'template_redirect', array( $this, 'init_feed' ) );
259
- }
260
 
261
  \add_action( 'wp_head', array( $this, 'html_output' ), 1 );
262
  }
@@ -298,7 +300,7 @@ class Init extends Query {
298
  * @since 2.2.6
299
  * @uses The_SEO_Framework_Load::call_function()
300
  *
301
- * @param string|array $args the arguments that will be passed
302
  * @param bool $before if the header actions should be before or after the SEO Frameworks output
303
  * @return string|empty The filter output.
304
  */
@@ -438,7 +440,7 @@ class Init extends Query {
438
 
439
  $output = $robots . $before . $before_actions . $output . $after_actions . $after . $generator;
440
 
441
- $this->use_object_cache and $this->object_cache_set( $cache_key, $output, 86400 );
442
  endif;
443
 
444
  /**
@@ -467,8 +469,8 @@ class Init extends Query {
467
  */
468
  $sybre = (bool) \apply_filters( 'sybre_waaijer_<3', true );
469
 
470
- $start = \esc_html__( 'Start The Seo Framework', 'autodescription' );
471
- $end = \esc_html__( 'End The Seo Framework', 'autodescription' );
472
  $me = $sybre ? ' ' . \esc_html__( 'by Sybre Waaijer', 'autodescription' ) : '';
473
 
474
  $indicatorbefore = '<!-- ' . $start . $me . ' -->' . "\r\n";
@@ -496,38 +498,62 @@ class Init extends Query {
496
  /**
497
  * Redirects singular page to an alternate URL.
498
  *
499
- * @since 2.0.9
500
- * @since 2.8.0 Redirect status code is now filterable.
501
  *
502
  * @return void early on non-singular pages.
503
  */
504
- public function custom_field_redirect() {
505
 
506
- if ( $url = $this->get_custom_field( 'redirect' ) ) {
 
507
 
508
- $allow_external = $this->allow_external_redirect();
509
 
510
- /**
511
- * Applies filters 'the_seo_framework_redirect_status_code' : Absolute integer.
512
- * @since 2.8.0
513
- */
514
- $redirect_type = absint( apply_filters( 'the_seo_framework_redirect_status_code', 301 ) );
 
 
 
 
515
 
516
- if ( $redirect_type > 399 || $redirect_type < 300 )
517
- $this->_doing_it_wrong( __METHOD__, 'You should use 3xx HTTP Status Codes. Recommended 301 and 302.', '2.8.0' );
 
 
518
 
519
- if ( false === $allow_external ) {
520
- $url = $this->set_url_scheme( $url, 'relative' );
521
- $url = $this->add_url_host( $url );
522
- $scheme = $this->is_ssl() ? 'https' : 'http';
523
 
524
- \wp_safe_redirect( \esc_url_raw( $url, array( $scheme ) ), $redirect_type );
525
- exit;
526
- }
 
 
 
527
 
528
- \wp_redirect( \esc_url_raw( $url ), $redirect_type );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
  exit;
530
  }
 
 
 
531
  }
532
 
533
  /**
176
  \add_action( 'wp_ajax_add-tag', array( $this, 'init_columns_ajax' ), -1 );
177
  }
178
 
179
+ if ( $this->load_options ) :
180
  // Enqueue i18n defaults.
181
  \add_action( 'admin_init', array( $this, 'enqueue_page_defaults' ), 1 );
182
 
207
  //* Admin AJAX for counter options.
208
  \add_action( 'wp_ajax_the_seo_framework_update_counter', array( $this, 'wp_ajax_update_counter_type' ) );
209
 
210
+ //* Admin AJAX for TSF Cropper
211
+ \add_action( 'wp_ajax_tsf-crop-image', array( $this, 'wp_ajax_crop_image' ) );
212
+
213
+ // Add extra removable query arguments to the list.
214
  \add_filter( 'removable_query_args', array( $this, 'add_removable_query_args' ) );
215
+ endif;
216
  }
217
 
218
  /**
219
  * Initializes front-end actions.
220
  * Disregards other SEO plugins, the meta output does look at detection.
221
  *
222
+ * WARNING: Do not use query functions here.
223
+ *
224
  * @since 2.5.2
225
  */
226
  protected function init_front_end_actions() {
254
  \add_action( 'template_redirect', array( $this, 'maybe_output_sitemap' ), 1 );
255
  \add_action( 'template_redirect', array( $this, 'maybe_output_sitemap_stylesheet' ), 1 );
256
 
257
+ //* Initialize 301 redirects.
258
+ \add_action( 'template_redirect', array( $this, '_init_custom_field_redirect' ) );
 
 
259
 
260
+ //* Initialize feed alteration.
261
+ \add_action( 'template_redirect', array( $this, '_init_feed_output' ) );
 
 
262
 
263
  \add_action( 'wp_head', array( $this, 'html_output' ), 1 );
264
  }
300
  * @since 2.2.6
301
  * @uses The_SEO_Framework_Load::call_function()
302
  *
303
+ * @param string|array $args the arguments that will be passed onto the callback.
304
  * @param bool $before if the header actions should be before or after the SEO Frameworks output
305
  * @return string|empty The filter output.
306
  */
440
 
441
  $output = $robots . $before . $before_actions . $output . $after_actions . $after . $generator;
442
 
443
+ $this->use_object_cache and $this->object_cache_set( $cache_key, $output, DAY_IN_SECONDS );
444
  endif;
445
 
446
  /**
469
  */
470
  $sybre = (bool) \apply_filters( 'sybre_waaijer_<3', true );
471
 
472
+ $start = \esc_html__( 'Start The SEO Framework', 'autodescription' );
473
+ $end = \esc_html__( 'End The SEO Framework', 'autodescription' );
474
  $me = $sybre ? ' ' . \esc_html__( 'by Sybre Waaijer', 'autodescription' ) : '';
475
 
476
  $indicatorbefore = '<!-- ' . $start . $me . ' -->' . "\r\n";
498
  /**
499
  * Redirects singular page to an alternate URL.
500
  *
501
+ * @since 2.9.0
502
+ * @access private
503
  *
504
  * @return void early on non-singular pages.
505
  */
506
+ public function _init_custom_field_redirect() {
507
 
508
+ if ( $this->is_singular() && $url = $this->get_custom_field( 'redirect' ) )
509
+ $this->do_redirect( $url );
510
 
511
+ }
512
 
513
+ /**
514
+ * Redirects vistor to input $url.
515
+ *
516
+ * @since 2.9.0
517
+ *
518
+ * @param string $url The redirection URL
519
+ * @return void Early if no URL is supplied.
520
+ */
521
+ public function do_redirect( $url = '' ) {
522
 
523
+ if ( 'template_redirect' !== \current_action() ) {
524
+ $this->_doing_it_wrong( __METHOD__, 'Only use this method on action "template_redirect".', '2.9.0' );
525
+ return;
526
+ }
527
 
528
+ $url = \esc_url_raw( $url );
 
 
 
529
 
530
+ if ( empty( $url ) ) {
531
+ $this->_doing_it_wrong( __METHOD__, 'You need to supply an input URL.', '2.9.0' );
532
+ return;
533
+ }
534
+
535
+ $allow_external = $this->allow_external_redirect();
536
 
537
+ /**
538
+ * Applies filters 'the_seo_framework_redirect_status_code' : Absolute integer.
539
+ * @since 2.8.0
540
+ */
541
+ $redirect_type = \absint( \apply_filters( 'the_seo_framework_redirect_status_code', 301 ) );
542
+
543
+ if ( $redirect_type > 399 || $redirect_type < 300 )
544
+ $this->_doing_it_wrong( __METHOD__, 'You should use 3xx HTTP Status Codes. Recommended 301 and 302.', '2.8.0' );
545
+
546
+ if ( false === $allow_external ) {
547
+ $url = $this->set_url_scheme( $url, 'relative' );
548
+ $url = $this->add_url_host( $url );
549
+ $scheme = $this->is_ssl() ? 'https' : 'http';
550
+
551
+ \wp_safe_redirect( $this->set_url_scheme( $url, $scheme ), $redirect_type );
552
  exit;
553
  }
554
+
555
+ \wp_redirect( $url, $redirect_type );
556
+ exit;
557
  }
558
 
559
  /**
inc/classes/inpost.class.php CHANGED
@@ -80,6 +80,121 @@ class Inpost extends Doing_It_Right {
80
 
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  /**
84
  * Adds the SEO meta box to post edit screens.
85
  *
@@ -141,40 +256,52 @@ class Inpost extends Doing_It_Right {
141
  * @uses $this->post_type_supports_custom_seo()
142
  * @since 2.3.9
143
  */
144
- if ( $this->post_type_supports_custom_seo( $post_type ) ) {
145
 
146
  $post = \get_post_type_object( $post_type );
147
-
148
- if ( is_object( $post ) ) {
149
- $labels = isset( $post->labels ) ? $post->labels : '';
150
-
151
- if ( $labels ) {
152
- //* Title and type are used interchangeably.
153
- $title = isset( $labels->singular_name ) ? $labels->singular_name : $labels->name;
154
- $args = array( $title, 'is_post_page' );
155
-
156
- /**
157
- * Applies filters the_seo_framework_metabox_id : string The metabox priority and class ID.
158
- * @since 2.6.0
159
- * @NOTE warning: might cause CSS and JS conflicts.
160
- * @TODO solve note.
161
- * @priority medium 2.7.0
162
- */
163
- $id = (string) \apply_filters( 'the_seo_framework_metabox_id', 'tsf-inpost-box' );
164
- $context = 'normal';
165
-
166
- /**
167
- * High priority, this box is seen right below the post/page edit screen.
168
- * Applies filters 'the_seo_framework_metabox_priority' : string
169
- * @since 2.6.0
170
- * @param string $default Accepts 'high', 'default', 'low'
171
- */
172
- $priority = (string) \apply_filters( 'the_seo_framework_metabox_priority', 'high' );
173
-
174
- \add_meta_box( $id, sprintf( \__( '%s SEO Settings', 'autodescription' ), $title ), array( $this, 'pre_seo_box' ), $post_type, $context, $priority, $args );
175
- }
176
- }
177
- }
 
 
 
 
 
 
 
 
 
 
 
 
178
  }
179
 
180
  /**
@@ -214,8 +341,8 @@ class Inpost extends Doing_It_Right {
214
  * @access private
215
  * @uses $this->get_custom_field() Get custom field value.
216
  *
217
- * @param object $object the page/post/taxonomy object
218
- * @param array $args the page/post arguments or taxonomy slug
219
  */
220
  public function inpost_seo_box( $object, $args ) {
221
 
@@ -266,7 +393,7 @@ class Inpost extends Doing_It_Right {
266
  /**
267
  * Callback function for Taxonomy and Terms inpost box.
268
  *
269
- * @since 2.3.5
270
  * @access private
271
  *
272
  * @param string $type The TT type name.
@@ -274,59 +401,213 @@ class Inpost extends Doing_It_Right {
274
  */
275
  public function tt_inpost_box( $type, $object ) {
276
  \do_action( 'the_seo_framework_pre_tt_inpost_box' );
277
- $this->get_view( 'inpost/seo-settings', get_defined_vars(), 'term' );
278
  \do_action( 'the_seo_framework_pro_tt_inpost_box' );
279
  }
280
 
281
  /**
 
 
282
  * Callback function for Post and Pages inpost metabox.
283
  *
284
- * @since 2.3.5
285
  * @access private
286
  *
287
  * @param string $type The post type name.
288
  */
289
  public function singular_inpost_box( $type ) {
290
  \do_action( 'the_seo_framework_pre_page_inpost_box' );
291
- $this->get_view( 'inpost/seo-settings', get_defined_vars(), 'singular' );
292
  \do_action( 'the_seo_framework_pro_page_inpost_box' );
293
  }
294
 
295
  /**
296
- * Returns social image uploader form button.
297
- * Also registers additional i18n strings for JS.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  *
299
- * @since 2.8.0
300
- * @todo optimize? Sanitation and translations are duplicated -> microseconds...
 
 
301
  *
302
- * @param string $input_id Required. The HTML input id to pass URL into.
303
- * @return string The image uploader button.
 
 
 
 
 
 
 
304
  */
305
- public function get_social_image_uploader_form( $input_id ) {
306
-
307
- if ( ! $input_id )
308
- return '';
309
-
310
- $content = sprintf( '<a href="%1$s" class="tsf-set-social-image button button-primary button-small" title="%2$s" id="%3$s-select" data-inputid="%3$s">%4$s</a>',
311
- \esc_url( \get_upload_iframe_src( 'image', $this->get_the_real_ID() ) ),
312
- \esc_attr__( 'Select social image', 'autodescription' ),
313
- \esc_attr( $input_id ),
314
- \esc_html__( 'Select Image', 'autodescription' )
315
- );
316
-
317
- $button_labels = array(
318
- 'select' => \esc_attr__( 'Select Image', 'autodescription' ),
319
- 'select_title' => \esc_attr__( 'Select social image', 'autodescription' ),
320
- 'change' => \esc_attr__( 'Change Image', 'autodescription' ),
321
- 'remove' => \esc_attr__( 'Remove Image', 'autodescription' ),
322
- 'remove_title' => \esc_attr__( 'Remove selected social image', 'autodescription' ),
323
- 'frame_title' => \esc_attr__( 'Select Social Image', 'autodescription' ),
324
- 'frame_button' => \esc_attr__( 'Use this image', 'autodescription' ),
325
- );
326
-
327
- //* Already escaped. Turn off escaping.
328
- $this->additional_js_l10n( \esc_attr( $input_id ), $button_labels, false, false );
329
-
330
- return $content;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  }
332
  }
80
 
81
  }
82
 
83
+ /**
84
+ * Inpost setting nav tab wrappers.
85
+ * Outputs Tabs and settings content.
86
+ *
87
+ * @since 2.9.0
88
+ *
89
+ * @param string $id The Nav Tab ID
90
+ * @param array $tabs the tab content {
91
+ * $tabs = tab ID key = array(
92
+ * $tabs['name'] => tab name
93
+ * $tabs['callback'] => string|array callback function
94
+ * $tabs['dashicon'] => string Dashicon
95
+ * $tabs['args'] => mixed optional callback function args
96
+ * )
97
+ * }
98
+ * @param string $version the The SEO Framework version for debugging. May be emptied.
99
+ * @param bool $use_tabs Whether to output tabs, only works when $tabs is greater than 1.
100
+ */
101
+ public function inpost_flex_nav_tab_wrapper( $id, $tabs = array(), $version = '2.3.6', $use_tabs = true ) {
102
+
103
+ //* Whether tabs are active.
104
+ $use_tabs = $use_tabs && count( $tabs ) > 1;
105
+
106
+ /**
107
+ * Start navigational tabs.
108
+ *
109
+ * Don't output navigation if $use_tabs is false and the amount of tabs is 1 or lower.
110
+ */
111
+ if ( $use_tabs ) :
112
+ ?>
113
+ <div class="tsf-flex tsf-flex-nav-tab-wrapper tsf-flex-hide-if-no-js" id="<?php echo \esc_attr( 'tsf-flex-' . $id . '-tabs-wrapper' ); ?>">
114
+ <div class="tsf-flex tsf-flex-nav-tab-inner">
115
+ <?php
116
+ $count = 1;
117
+ foreach ( $tabs as $tab => $value ) :
118
+ $dashicon = isset( $value['dashicon'] ) ? $value['dashicon'] : '';
119
+ $label_name = isset( $value['name'] ) ? $value['name'] : '';
120
+
121
+ $wrapper_id = \esc_attr( 'tsf-flex-nav-tab-' . $tab );
122
+ $wrapper_active = 1 === $count ? ' tsf-flex-nav-tab-active' : '';
123
+
124
+ $input_checked = 1 === $count ? 'checked' : '';
125
+ $input_id = \esc_attr( 'tsf-flex-' . $id . '-tab-' . $tab );
126
+ $input_name = \esc_attr( 'tsf-flex-' . $id . '-tabs' );
127
+
128
+ //* All output below is escaped.
129
+ ?>
130
+ <div class="tsf-flex tsf-flex-nav-tab tsf-flex<?php echo $wrapper_active ?>" id="<?php echo $wrapper_id ?>">
131
+ <input type="radio" class="tsf-flex-nav-tab-radio" id="<?php echo $input_id; ?>" name="<?php echo $input_name; ?>" <?php echo $input_checked; ?>>
132
+ <label for="<?php echo $input_id; ?>" class="tsf-flex tsf-flex-nav-tab-label">
133
+ <?php
134
+ echo $dashicon ? '<span class="tsf-flex dashicons dashicons-' . \esc_attr( $dashicon ) . ' tsf-flex-nav-dashicon"></span>' : '';
135
+ echo $label_name ? '<span class="tsf-flex tsf-flex-nav-name">' . \esc_attr( $label_name ) . '</span>' : '';
136
+ ?>
137
+ </label>
138
+ </div>
139
+ <?php
140
+
141
+ $count++;
142
+ endforeach;
143
+ ?>
144
+ </div>
145
+ </div>
146
+ <?php
147
+ endif;
148
+
149
+ /**
150
+ * Start Content.
151
+ *
152
+ * The content is relative to the navigation, and uses CSS to become visible.
153
+ */
154
+ $count = 1;
155
+ foreach ( $tabs as $tab => $value ) :
156
+
157
+ $radio_id = \esc_attr( 'tsf-flex-' . $id . '-tab-' . $tab . '-content' );
158
+ $radio_class = \esc_attr( 'tsf-flex-' . $id . '-tabs-content' );
159
+
160
+ //* Current tab for JS.
161
+ $current_class = 1 === $count ? ' tsf-flex-tab-content-active' : '';
162
+
163
+ ?>
164
+ <div class="tsf-flex tsf-flex-tab-content <?php echo \esc_attr( $radio_class . $current_class ); ?>" id="<?php echo \esc_attr( $radio_id ); ?>" >
165
+ <?php
166
+ //* No-JS tabs.
167
+ if ( $use_tabs ) :
168
+ $dashicon = isset( $value['dashicon'] ) ? $value['dashicon'] : '';
169
+ $label_name = isset( $value['name'] ) ? $value['name'] : '';
170
+
171
+ ?>
172
+ <div class="tsf-flex tsf-flex-hide-if-js tsf-flex-tabs-content-no-js">
173
+ <div class="tsf-flex tsf-flex-nav-tab tsf-flex-tab-no-js">
174
+ <span class="tsf-flex tsf-flex-nav-tab">
175
+ <?php echo $dashicon ? '<span class="tsf-flex dashicons dashicons-' . \esc_attr( $dashicon ) . ' tsf-flex-nav-dashicon"></span>' : ''; ?>
176
+ <?php echo $label_name ? '<span class="tsf-flex tsf-flex-nav-name">' . \esc_attr( $label_name ) . '</span>' : ''; ?>
177
+ </span>
178
+ </div>
179
+ </div>
180
+ <?php
181
+ endif;
182
+
183
+ $callback = isset( $value['callback'] ) ? $value['callback'] : '';
184
+
185
+ if ( $callback ) {
186
+ $params = isset( $value['args'] ) ? $value['args'] : '';
187
+ //* Should already be escaped.
188
+ echo $this->call_function( $callback, $version, $params );
189
+ }
190
+ ?>
191
+ </div>
192
+ <?php
193
+
194
+ $count++;
195
+ endforeach;
196
+ }
197
+
198
  /**
199
  * Adds the SEO meta box to post edit screens.
200
  *
256
  * @uses $this->post_type_supports_custom_seo()
257
  * @since 2.3.9
258
  */
259
+ if ( $this->post_type_supports_custom_seo( $post_type ) ) :
260
 
261
  $post = \get_post_type_object( $post_type );
262
+ $labels = is_object( $post ) && isset( $post->labels ) ? $post->labels : '';
263
+
264
+ if ( $labels ) :
265
+ //* Title and type are used interchangeably.
266
+ $title = isset( $labels->singular_name ) ? $labels->singular_name : $labels->name;
267
+ $args = array( $title, 'is_post_page' );
268
+
269
+ /**
270
+ * Applies filters 'the_seo_framework_metabox_id' : string
271
+ *
272
+ * Alters The metabox class and ID.
273
+ *
274
+ * @since 2.6.0
275
+ * @NOTE warning: might cause CSS and JS conflicts.
276
+ * @TODO solve note.
277
+ * @priority medium 2.7.0
278
+ *
279
+ * @param string $id The metabox class/ID.
280
+ */
281
+ $id = (string) \apply_filters( 'the_seo_framework_metabox_id', 'tsf-inpost-box' );
282
+
283
+ /**
284
+ * Applies filters 'the_seo_framework_metabox_id' : string
285
+ *
286
+ * Alters the inpost metabox priority and class ID.
287
+ *
288
+ * @since 2.9.0
289
+ *
290
+ * @param string $context, default 'normal'. Accepts 'normal', 'side' and 'advanced'.
291
+ */
292
+ $context = (string) \apply_filters( 'the_seo_framework_metabox_context', 'normal' );
293
+
294
+ /**
295
+ * High priority, this box is seen right below the post/page edit screen.
296
+ * Applies filters 'the_seo_framework_metabox_priority' : string
297
+ * @since 2.6.0
298
+ * @param string $default Accepts 'high', 'default', 'low'
299
+ */
300
+ $priority = (string) \apply_filters( 'the_seo_framework_metabox_priority', 'high' );
301
+
302
+ \add_meta_box( $id, sprintf( \__( '%s SEO Settings', 'autodescription' ), $title ), array( $this, 'pre_seo_box' ), $post_type, $context, $priority, $args );
303
+ endif;
304
+ endif;
305
  }
306
 
307
  /**
341
  * @access private
342
  * @uses $this->get_custom_field() Get custom field value.
343
  *
344
+ * @param object $object the page/post/taxonomy object
345
+ * @param array $args the page/post arguments or taxonomy slug
346
  */
347
  public function inpost_seo_box( $object, $args ) {
348
 
393
  /**
394
  * Callback function for Taxonomy and Terms inpost box.
395
  *
396
+ * @since 2.9.0
397
  * @access private
398
  *
399
  * @param string $type The TT type name.
401
  */
402
  public function tt_inpost_box( $type, $object ) {
403
  \do_action( 'the_seo_framework_pre_tt_inpost_box' );
404
+ $this->get_view( 'inpost/seo-settings-tt', get_defined_vars() );
405
  \do_action( 'the_seo_framework_pro_tt_inpost_box' );
406
  }
407
 
408
  /**
409
+ * Outputs the singular inpost SEO box.
410
+ *
411
  * Callback function for Post and Pages inpost metabox.
412
  *
413
+ * @since 2.9.0
414
  * @access private
415
  *
416
  * @param string $type The post type name.
417
  */
418
  public function singular_inpost_box( $type ) {
419
  \do_action( 'the_seo_framework_pre_page_inpost_box' );
420
+ $this->get_view( 'inpost/seo-settings-singular', get_defined_vars() );
421
  \do_action( 'the_seo_framework_pro_page_inpost_box' );
422
  }
423
 
424
  /**
425
+ * Outputs the singular inpost SEO box general tab.
426
+ *
427
+ * Callback function for Post and Pages inpost metabox.
428
+ *
429
+ * @since 2.9.0
430
+ * @access private
431
+ *
432
+ * @param string $type The post type name.
433
+ */
434
+ public function singular_inpost_box_general_tab( $type ) {
435
+ \do_action( 'the_seo_framework_pre_page_inpost_general_tab' );
436
+ $this->get_view( 'inpost/seo-settings-singular', get_defined_vars(), 'general' );
437
+ \do_action( 'the_seo_framework_pro_page_inpost_general_tab' );
438
+ }
439
+
440
+ /**
441
+ * Outputs the singular inpost SEO box visibility tab.
442
+ *
443
+ * Callback function for Post and Pages inpost metabox.
444
+ *
445
+ * @since 2.9.0
446
+ * @access private
447
+ *
448
+ * @param string $type The post type name.
449
+ */
450
+ public function singular_inpost_box_visibility_tab( $type ) {
451
+ \do_action( 'the_seo_framework_pre_page_inpost_visibility_tab' );
452
+ $this->get_view( 'inpost/seo-settings-singular', get_defined_vars(), 'visibility' );
453
+ \do_action( 'the_seo_framework_pro_page_inpost_visibility_tab' );
454
+ }
455
+
456
+ /**
457
+ * Outputs the singular inpost SEO box social tab.
458
+ *
459
+ * Callback function for Post and Pages inpost metabox.
460
+ *
461
+ * @since 2.9.0
462
+ * @access private
463
+ *
464
+ * @param string $type The post type name.
465
+ */
466
+ public function singular_inpost_box_social_tab( $type ) {
467
+ \do_action( 'the_seo_framework_pre_page_inpost_social_tab' );
468
+ $this->get_view( 'inpost/seo-settings-singular', get_defined_vars(), 'social' );
469
+ \do_action( 'the_seo_framework_pro_page_inpost_social_tab' );
470
+ }
471
+
472
+ /**
473
+ * Fills in input variables by call for general tabs.
474
+ *
475
+ * Placeholder method that's used prior to upgrade merge 2.9 -> 3.0+.
476
+ * Do not use. It will take a little too much time to perfect this.
477
  *
478
+ * Will anyone even notice this?
479
+ * If so: Hi there, do not forget to smile!
480
+ * Do send me an email @ sybre at theseoframework.com.
481
+ * Subject: CAUGHT! Content: Hi Sybre :D, noob.
482
  *
483
+ * @since 2.9.0
484
+ * @access private
485
+ * @ignore
486
+ * @todo Remove and refactor caller.
487
+ *
488
+ * @param int $tit_len_parsed. Passed by reference.
489
+ * @param string $doctitle_placeholder. Passed by reference.
490
+ * @param int $desc_len_parsed. Passed by reference.
491
+ * @param string $description_placeholder. Passed by reference.
492
  */
493
+ public function _get_inpost_general_tab_vars( &$tit_len_parsed, &$doctitle_placeholder, &$desc_len_parsed, &$description_placeholder ) {
494
+
495
+ $post_id = $this->get_the_real_ID();
496
+ $is_static_frontpage = $this->is_static_frontpage( $post_id );
497
+
498
+ /**
499
+ * Generate static placeholders
500
+ */
501
+ if ( $is_static_frontpage ) {
502
+ //* Front page.
503
+ $generated_doctitle_args = array(
504
+ 'page_on_front' => true,
505
+ 'placeholder' => true,
506
+ 'meta' => true,
507
+ 'get_custom_field' => false,
508
+ );
509
+
510
+ $generated_description_args = array(
511
+ 'id' => $post_id,
512
+ 'is_home' => true,
513
+ 'get_custom_field' => true,
514
+ );
515
+ } elseif ( $this->is_blog_page( $post_id ) ) {
516
+ //* Page for posts.
517
+ $generated_doctitle_args = array(
518
+ 'placeholder' => true,
519
+ 'meta' => true,
520
+ 'get_custom_field' => false,
521
+ );
522
+
523
+ $generated_description_args = array(
524
+ 'id' => $post_id,
525
+ 'page_for_posts' => true,
526
+ );
527
+ } else {
528
+ $generated_doctitle_args = array(
529
+ 'placeholder' => true,
530
+ 'meta' => true,
531
+ 'get_custom_field' => false,
532
+ );
533
+
534
+ $generated_description_args = array(
535
+ 'id' => $post_id,
536
+ );
537
+ }
538
+ $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
539
+ $generated_description = $this->generate_description_from_id( $generated_description_args );
540
+
541
+ /**
542
+ * Start Title vars
543
+ */
544
+ $title = $this->get_custom_field( '_genesis_title', $post_id );
545
+
546
+ /**
547
+ * Special check for home page.
548
+ *
549
+ * @since 2.3.4
550
+ */
551
+ if ( $is_static_frontpage ) {
552
+ if ( $this->get_option( 'homepage_tagline' ) ) {
553
+ $tit_len_pre = $title ? $title . ' | ' . $this->get_blogdescription() : $generated_doctitle;
554
+ } else {
555
+ $tit_len_pre = $title ?: $generated_doctitle;
556
+ }
557
+ } else {
558
+ /**
559
+ * Separator doesn't matter. Since html_entity_decode is used.
560
+ * Order doesn't matter either. Since it's just used for length calculation.
561
+ *
562
+ * @since 2.3.4
563
+ */
564
+ if ( $this->add_title_additions() ) {
565
+ $tit_len_pre = $title ? $title . ' | ' . $this->get_blogname() : $generated_doctitle;
566
+ } else {
567
+ $tit_len_pre = $title ?: $generated_doctitle;
568
+ }
569
+ }
570
+
571
+ /**
572
+ * Start Description vars
573
+ */
574
+
575
+ //* Fetch description from option.
576
+ $description = $this->get_custom_field( '_genesis_description' );
577
+
578
+ /**
579
+ * Calculate current description length
580
+ *
581
+ * Reworked.
582
+ * @since 2.3.4
583
+ */
584
+ if ( $is_static_frontpage ) {
585
+ //* The homepage description takes precedence.
586
+ if ( $description ) {
587
+ $desc_len_pre = $this->get_option( 'homepage_description' ) ?: $description;
588
+ } else {
589
+ $desc_len_pre = $this->get_option( 'homepage_description' ) ?: $generated_description;
590
+ }
591
+ } else {
592
+ $desc_len_pre = $description ?: $generated_description;
593
+ }
594
+
595
+ /**
596
+ * Convert to what Google outputs.
597
+ *
598
+ * This will convert e.g. &raquo; to a single length character.
599
+ * @since 2.3.4
600
+ */
601
+ $tit_len_parsed = html_entity_decode( $tit_len_pre );
602
+ $desc_len_parsed = html_entity_decode( $desc_len_pre );
603
+
604
+ /**
605
+ * Generate static placeholder for when title or description is emptied
606
+ *
607
+ * Now within aptly named vars.
608
+ * @since 2.3.4
609
+ */
610
+ $doctitle_placeholder = $generated_doctitle;
611
+ $description_placeholder = $generated_description;
612
  }
613
  }
inc/classes/load.class.php CHANGED
@@ -77,10 +77,10 @@ final class Load extends Feed implements Debug_Interface {
77
  */
78
  public function init_debug_vars() {
79
 
80
- $this->the_seo_framework_debug = defined( 'THE_SEO_FRAMEWORK_DEBUG' ) && THE_SEO_FRAMEWORK_DEBUG ? true : $this->the_seo_framework_debug;
81
  if ( $this->the_seo_framework_debug ) {
82
  //* No need to set these to true if no debugging is enabled.
83
- $this->the_seo_framework_debug_hidden = defined( 'THE_SEO_FRAMEWORK_DEBUG_HIDDEN' ) && THE_SEO_FRAMEWORK_DEBUG_HIDDEN ? true : $this->the_seo_framework_debug_hidden;
84
 
85
  $instance = \The_SEO_Framework\Debug::set_instance( $this->the_seo_framework_debug, $this->the_seo_framework_debug_hidden );
86
  }
@@ -88,7 +88,7 @@ final class Load extends Feed implements Debug_Interface {
88
  $this->the_seo_framework_use_transients = defined( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS' ) && THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS ? false : $this->the_seo_framework_use_transients;
89
 
90
  //* WP Core definition.
91
- $this->script_debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? true : $this->script_debug;
92
 
93
  }
94
 
@@ -231,8 +231,8 @@ final class Load extends Feed implements Debug_Interface {
231
  * @since 2.7.0
232
  * @access private
233
  *
234
- * @param string $p_or_m The Property or Method.
235
- * @param string $message A message explaining what has been done incorrectly.
236
  */
237
  public function _inaccessible_p_or_m( $p_or_m, $message = '' ) {
238
  $instance = \The_SEO_Framework\Debug::get_instance();
77
  */
78
  public function init_debug_vars() {
79
 
80
+ $this->the_seo_framework_debug = defined( 'THE_SEO_FRAMEWORK_DEBUG' ) && THE_SEO_FRAMEWORK_DEBUG ?: $this->the_seo_framework_debug;
81
  if ( $this->the_seo_framework_debug ) {
82
  //* No need to set these to true if no debugging is enabled.
83
+ $this->the_seo_framework_debug_hidden = defined( 'THE_SEO_FRAMEWORK_DEBUG_HIDDEN' ) && THE_SEO_FRAMEWORK_DEBUG_HIDDEN ?: $this->the_seo_framework_debug_hidden;
84
 
85
  $instance = \The_SEO_Framework\Debug::set_instance( $this->the_seo_framework_debug, $this->the_seo_framework_debug_hidden );
86
  }
88
  $this->the_seo_framework_use_transients = defined( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS' ) && THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS ? false : $this->the_seo_framework_use_transients;
89
 
90
  //* WP Core definition.
91
+ $this->script_debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ?: $this->script_debug;
92
 
93
  }
94
 
231
  * @since 2.7.0
232
  * @access private
233
  *
234
+ * @param string $p_or_m The Property or Method.
235
+ * @param string $message A message explaining what has been done incorrectly.
236
  */
237
  public function _inaccessible_p_or_m( $p_or_m, $message = '' ) {
238
  $instance = \The_SEO_Framework\Debug::get_instance();
inc/classes/metaboxes.class.php CHANGED
@@ -44,9 +44,7 @@ class Metaboxes extends Site_Options {
44
  * Outputs Tabs and settings content.
45
  *
46
  * @since 2.3.6
47
- *
48
- * @refactored
49
- * @since 2.6.0
50
  *
51
  * @param string $id The Nav Tab ID
52
  * @param array $tabs the tab content {
@@ -58,7 +56,7 @@ class Metaboxes extends Site_Options {
58
  * )
59
  * }
60
  * @param string $version the The SEO Framework version for debugging. May be emptied.
61
- * @param bool $use_tabs Whether to output tabs, only works when $tabs only has one count.
62
  */
63
  public function nav_tab_wrapper( $id, $tabs = array(), $version = '2.3.6', $use_tabs = true ) {
64
 
@@ -104,7 +102,7 @@ class Metaboxes extends Site_Options {
104
  /**
105
  * Start Content.
106
  *
107
- * The content is relative to the navigation, and uses CSS to become visible.
108
  */
109
  $count = 1;
110
  foreach ( $tabs as $tab => $value ) :
@@ -137,11 +135,11 @@ class Metaboxes extends Site_Options {
137
 
138
  $callback = isset( $value['callback'] ) ? $value['callback'] : '';
139
 
140
- if ( $callback ) :
141
  $params = isset( $value['args'] ) ? $value['args'] : '';
142
- $output = $this->call_function( $callback, $version, $params );
143
- echo $output;
144
- endif;
145
  ?>
146
  </div>
147
  <?php
@@ -377,6 +375,16 @@ class Metaboxes extends Site_Options {
377
  $this->get_view( 'metaboxes/homepage-metabox', array(), 'robots' );
378
  }
379
 
 
 
 
 
 
 
 
 
 
 
380
  /**
381
  * Social meta box on the Site SEO Settings page.
382
  *
44
  * Outputs Tabs and settings content.
45
  *
46
  * @since 2.3.6
47
+ * @since 2.6.0 Refactored.
 
 
48
  *
49
  * @param string $id The Nav Tab ID
50
  * @param array $tabs the tab content {
56
  * )
57
  * }
58
  * @param string $version the The SEO Framework version for debugging. May be emptied.
59
+ * @param bool $use_tabs Whether to output tabs, only works when $tabs is greater than 1.
60
  */
61
  public function nav_tab_wrapper( $id, $tabs = array(), $version = '2.3.6', $use_tabs = true ) {
62
 
102
  /**
103
  * Start Content.
104
  *
105
+ * The content is relative to the navigation and outputs navigational tabs too, but uses CSS to become invisible on JS.
106
  */
107
  $count = 1;
108
  foreach ( $tabs as $tab => $value ) :
135
 
136
  $callback = isset( $value['callback'] ) ? $value['callback'] : '';
137
 
138
+ if ( $callback ) {
139
  $params = isset( $value['args'] ) ? $value['args'] : '';
140
+ //* Should already be escaped.
141
+ echo $this->call_function( $callback, $version, $params );
142
+ }
143
  ?>
144
  </div>
145
  <?php
375
  $this->get_view( 'metaboxes/homepage-metabox', array(), 'robots' );
376
  }
377
 
378
+ /**
379
+ * HomePage Metabox Social Tab Output
380
+ *
381
+ * @since 2.9.0
382
+ * @see $this->homepage_metabox() Callback for HomePage Settings box.
383
+ */
384
+ public function homepage_metabox_social_tab() {
385
+ $this->get_view( 'metaboxes/homepage-metabox', array(), 'social' );
386
+ }
387
+
388
  /**
389
  * Social meta box on the Site SEO Settings page.
390
  *
inc/classes/post-data.class.php CHANGED
@@ -184,7 +184,7 @@ class Post_Data extends Detect {
184
  public function save_custom_fields( array $data, $nonce_action, $nonce_name, $post ) {
185
 
186
  //* Verify the nonce
187
- if ( ! isset( $_POST[ $nonce_name ] ) || ! wp_verify_nonce( $_POST[ $nonce_name ], $nonce_action ) )
188
  return;
189
 
190
  /**
@@ -195,7 +195,7 @@ class Post_Data extends Detect {
195
  */
196
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
197
  return;
198
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
199
  return;
200
  if ( defined( 'DOING_CRON' ) && DOING_CRON )
201
  return;
184
  public function save_custom_fields( array $data, $nonce_action, $nonce_name, $post ) {
185
 
186
  //* Verify the nonce
187
+ if ( ! isset( $_POST[ $nonce_name ] ) || ! \wp_verify_nonce( $_POST[ $nonce_name ], $nonce_action ) )
188
  return;
189
 
190
  /**
195
  */
196
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
197
  return;
198
+ if ( $this->doing_ajax() )
199
  return;
200
  if ( defined( 'DOING_CRON' ) && DOING_CRON )
201
  return;
inc/classes/query.class.php CHANGED
@@ -43,6 +43,7 @@ class Query extends Compat {
43
  * Checks whether $wp_query or $current_screen is set.
44
  *
45
  * @since 2.6.1
 
46
  * @access private
47
  * @staticvar bool $cache : Always true if set.
48
  * @global object $wp_query
@@ -60,6 +61,8 @@ class Query extends Compat {
60
  if ( isset( $GLOBALS['wp_query']->query ) || isset( $GLOBALS['current_screen'] ) )
61
  return $cache = true;
62
 
 
 
63
  return false;
64
  }
65
 
@@ -114,6 +117,8 @@ class Query extends Compat {
114
  *
115
  * @since 2.7.0
116
  * @since 2.8.0 Removed WP 3.9 compat
 
 
117
  */
118
  public function get_the_real_admin_ID() {
119
 
@@ -123,7 +128,7 @@ class Query extends Compat {
123
  if ( empty( $id ) && $this->is_archive_admin() )
124
  $id = $this->get_admin_term_id();
125
 
126
- return $id;
127
  }
128
 
129
  /**
@@ -134,7 +139,7 @@ class Query extends Compat {
134
  *
135
  * @since 2.5.0
136
  *
137
- * @return int|empty the ID.
138
  */
139
  public function check_the_real_ID() {
140
 
@@ -525,25 +530,57 @@ class Query extends Compat {
525
  /**
526
  * Detects front page.
527
  *
528
- * @since 2.6.0
529
  *
530
- * @param int $id The Page or Post ID.
531
  * @return bool
532
  */
533
- public function is_front_page( $id = 0 ) {
534
-
535
- static $cache = array();
536
 
537
- if ( null !== $cache = $this->get_query_cache( __METHOD__, null, $id ) )
538
  return $cache;
539
 
540
  $is_front_page = false;
541
 
542
- if ( \is_front_page() && empty( $id ) )
543
  $is_front_page = true;
544
 
545
  //* Elegant Themes Support. Yay.
546
- if ( false === $is_front_page && empty( $id ) && $this->is_home() ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
  $sof = \get_option( 'show_on_front' );
548
 
549
  if ( 'page' !== $sof && 'posts' !== $sof )
@@ -551,7 +588,7 @@ class Query extends Compat {
551
  }
552
 
553
  //* Compare against $id
554
- if ( false === $is_front_page && $id ) {
555
  $sof = \get_option( 'show_on_front' );
556
 
557
  if ( 'page' === $sof && (int) \get_option( 'page_on_front' ) === $id )
@@ -559,10 +596,11 @@ class Query extends Compat {
559
 
560
  if ( 'posts' === $sof && (int) \get_option( 'page_for_posts' ) === $id )
561
  $is_front_page = true;
562
- } elseif ( empty( $id ) && $this->is_seo_settings_page() ) {
563
- $is_front_page = true;
564
  }
565
 
 
 
 
566
  $this->set_query_cache(
567
  __METHOD__,
568
  $is_front_page,
@@ -787,9 +825,9 @@ class Query extends Compat {
787
  * @param int $id the Page ID to check. If empty, the current ID will be fetched.
788
  * @return bool true if is blog page. Always false if the homepage is a blog.
789
  */
790
- public function is_static_frontpage( $id = '' ) {
791
 
792
- if ( empty( $id ) )
793
  $id = $this->get_the_real_ID();
794
 
795
  if ( 'page' === \get_option( 'show_on_front' ) )
@@ -952,25 +990,24 @@ class Query extends Compat {
952
  *
953
  * @since 2.6.0
954
  * @since 2.7.0 Added secure parameter.
 
955
  *
956
  * @param bool $secure Whether to ignore the use of the second (insecure) parameter.
957
  * @return bool
958
  */
959
  public function is_seo_settings_page( $secure = true ) {
960
 
961
- if ( null !== $cache = $this->get_query_cache( __METHOD__, null, $secure ) )
 
 
 
962
  return $cache;
963
 
964
- if ( $secure ) {
965
- $page = $this->is_menu_page( $this->seo_settings_page_hook );
966
- } else {
967
- $page = $this->is_menu_page( $this->seo_settings_page_hook, $this->seo_settings_page_slug );
968
- }
969
 
970
  $this->set_query_cache(
971
  __METHOD__,
972
- $page,
973
- $secure
974
  );
975
 
976
  return $page;
@@ -1038,7 +1075,7 @@ class Query extends Compat {
1038
 
1039
  $_pages = $pages;
1040
 
1041
- $post = $this->is_singular() || $this->is_front_page() ? get_post( $this->get_the_real_ID() ) : null;
1042
 
1043
  if ( is_object( $post ) ) {
1044
  $content = $post->post_content;
@@ -1111,12 +1148,12 @@ class Query extends Compat {
1111
  * @since 2.7.0
1112
  * @staticvar bool $can_cache_query : True when this function can run.
1113
  * @staticvar mixed $cache : The cached query.
1114
- * @see AutoDescritpion_Query::set_query_cache(); to set query cache.
1115
  *
1116
  * @param string $key The key to set or get.
1117
  * @param mixed $value_to_set The value to set.
1118
  * @param array|mixed $hash Extra arguments, that will be used to generate an alternative cache key.
1119
- * Must always be inside a single array when $value_to_set is set. @see AutoDescritpion_Query::set_query_cache()
1120
  * Must always be separated parameters otherwise.
1121
  * @return mixed : {
1122
  * mixed The cached value if set and $value_to_set is null.
@@ -1166,7 +1203,7 @@ class Query extends Compat {
1166
  * Object cache handler for the query class.
1167
  *
1168
  * @since 2.7.0
1169
- * @see The_SEO_Framework_Query::get_query_cache()
1170
  *
1171
  * @param string $key The key to set.
1172
  * @param mixed $value_to_set If null, no cache will be set.
43
  * Checks whether $wp_query or $current_screen is set.
44
  *
45
  * @since 2.6.1
46
+ * @since 2.9.0: Added doing it wrong notice.
47
  * @access private
48
  * @staticvar bool $cache : Always true if set.
49
  * @global object $wp_query
61
  if ( isset( $GLOBALS['wp_query']->query ) || isset( $GLOBALS['current_screen'] ) )
62
  return $cache = true;
63
 
64
+ $this->_doing_it_wrong( __METHOD__, "You've initiated a method that uses queries too early.", '2.9.0' );
65
+
66
  return false;
67
  }
68
 
117
  *
118
  * @since 2.7.0
119
  * @since 2.8.0 Removed WP 3.9 compat
120
+ *
121
+ * @return int The admin ID.
122
  */
123
  public function get_the_real_admin_ID() {
124
 
128
  if ( empty( $id ) && $this->is_archive_admin() )
129
  $id = $this->get_admin_term_id();
130
 
131
+ return (int) \apply_filters( 'the_seo_framework_current_admin_id', $id );
132
  }
133
 
134
  /**
139
  *
140
  * @since 2.5.0
141
  *
142
+ * @return int The admin ID.
143
  */
144
  public function check_the_real_ID() {
145
 
530
  /**
531
  * Detects front page.
532
  *
533
+ * @since 2.9.0
534
  *
 
535
  * @return bool
536
  */
537
+ public function is_real_front_page() {
 
 
538
 
539
+ if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
540
  return $cache;
541
 
542
  $is_front_page = false;
543
 
544
+ if ( \is_front_page() )
545
  $is_front_page = true;
546
 
547
  //* Elegant Themes Support. Yay.
548
+ if ( false === $is_front_page && 0 === $this->get_the_real_ID() && $this->is_home() ) {
549
+ $sof = \get_option( 'show_on_front' );
550
+
551
+ if ( 'page' !== $sof && 'posts' !== $sof )
552
+ $is_front_page = true;
553
+ }
554
+
555
+ $this->set_query_cache(
556
+ __METHOD__,
557
+ $is_front_page
558
+ );
559
+
560
+ return $is_front_page;
561
+ }
562
+
563
+ /**
564
+ * Checks for front page by input ID.
565
+ *
566
+ * Returns true if on SEO settings page and when ID is 0.
567
+ *
568
+ * @since 2.9.0
569
+ *
570
+ * @param int The page ID, required.
571
+ * @return bool True if ID if for the home page.
572
+ */
573
+ public function is_front_page_by_id( $id ) {
574
+
575
+ $id = (int) $id;
576
+
577
+ if ( null !== $cache = $this->get_query_cache( __METHOD__, null, $id ) )
578
+ return $cache;
579
+
580
+ $is_front_page = false;
581
+
582
+ //* Elegant Themes Support. Yay.
583
+ if ( 0 === $id && $this->is_home() ) {
584
  $sof = \get_option( 'show_on_front' );
585
 
586
  if ( 'page' !== $sof && 'posts' !== $sof )
588
  }
589
 
590
  //* Compare against $id
591
+ if ( false === $is_front_page ) {
592
  $sof = \get_option( 'show_on_front' );
593
 
594
  if ( 'page' === $sof && (int) \get_option( 'page_on_front' ) === $id )
596
 
597
  if ( 'posts' === $sof && (int) \get_option( 'page_for_posts' ) === $id )
598
  $is_front_page = true;
 
 
599
  }
600
 
601
+ if ( false === $is_front_page && 0 === $id && $this->is_seo_settings_page() )
602
+ $is_front_page = true;
603
+
604
  $this->set_query_cache(
605
  __METHOD__,
606
  $is_front_page,
825
  * @param int $id the Page ID to check. If empty, the current ID will be fetched.
826
  * @return bool true if is blog page. Always false if the homepage is a blog.
827
  */
828
+ public function is_static_frontpage( $id = 0 ) {
829
 
830
+ if ( ! $id )
831
  $id = $this->get_the_real_ID();
832
 
833
  if ( 'page' === \get_option( 'show_on_front' ) )
990
  *
991
  * @since 2.6.0
992
  * @since 2.7.0 Added secure parameter.
993
+ * @since 2.9.0 If $secure is false, the cache is no longer used.
994
  *
995
  * @param bool $secure Whether to ignore the use of the second (insecure) parameter.
996
  * @return bool
997
  */
998
  public function is_seo_settings_page( $secure = true ) {
999
 
1000
+ if ( ! $secure )
1001
+ return $this->is_menu_page( $this->seo_settings_page_hook, $this->seo_settings_page_slug );
1002
+
1003
+ if ( null !== $cache = $this->get_query_cache( __METHOD__, null ) )
1004
  return $cache;
1005
 
1006
+ $page = $this->is_menu_page( $this->seo_settings_page_hook );
 
 
 
 
1007
 
1008
  $this->set_query_cache(
1009
  __METHOD__,
1010
+ $page
 
1011
  );
1012
 
1013
  return $page;
1075
 
1076
  $_pages = $pages;
1077
 
1078
+ $post = $this->is_singular() || $this->is_real_front_page() ? \get_post( $this->get_the_real_ID() ) : null;
1079
 
1080
  if ( is_object( $post ) ) {
1081
  $content = $post->post_content;
1148
  * @since 2.7.0
1149
  * @staticvar bool $can_cache_query : True when this function can run.
1150
  * @staticvar mixed $cache : The cached query.
1151
+ * @see $this->set_query_cache(); to set query cache.
1152
  *
1153
  * @param string $key The key to set or get.
1154
  * @param mixed $value_to_set The value to set.
1155
  * @param array|mixed $hash Extra arguments, that will be used to generate an alternative cache key.
1156
+ * Must always be inside a single array when $value_to_set is set. @see $this->set_query_cache()
1157
  * Must always be separated parameters otherwise.
1158
  * @return mixed : {
1159
  * mixed The cached value if set and $value_to_set is null.
1203
  * Object cache handler for the query class.
1204
  *
1205
  * @since 2.7.0
1206
+ * @see $this->get_query_cache()
1207
  *
1208
  * @param string $key The key to set.
1209
  * @param mixed $value_to_set If null, no cache will be set.
inc/classes/render.class.php CHANGED
@@ -98,6 +98,7 @@ class Render extends Admin_Init {
98
  * Cache home URL in static variable
99
  *
100
  * @since 2.5.0
 
101
  * @staticvar array $url_cache
102
  *
103
  * @param bool $force_slash Force slash
@@ -179,7 +180,7 @@ class Render extends Admin_Init {
179
 
180
  static $cache = null;
181
 
182
- return isset( $cache ) ? $cache : $cache = $this->get_image( $this->get_the_real_ID() );
183
  }
184
 
185
  /**
@@ -403,7 +404,7 @@ class Render extends Admin_Init {
403
  continue;
404
 
405
  //* Parse 1500px url.
406
- $img = $this->parse_og_image( $id );
407
 
408
  if ( $img ) {
409
  $output .= '<meta property="og:image" content="' . \esc_attr( $img ) . '" />' . "\r\n";
@@ -727,7 +728,7 @@ class Render extends Admin_Init {
727
  if ( 'product' === $this->get_og_type() )
728
  return '';
729
 
730
- if ( $this->is_front_page() ) {
731
  //* If it's the frontpage, but the option is disabled, don't do anything.
732
  if ( ! $this->get_option( 'home_publish_time' ) )
733
  return '';
@@ -775,7 +776,7 @@ class Render extends Admin_Init {
775
  if ( 'product' === $this->get_og_type() )
776
  return '';
777
 
778
- if ( $this->is_front_page() ) {
779
  //* If it's the frontpage, but the option is disabled, don't do anything.
780
  if ( ! $this->get_option( 'home_modify_time' ) )
781
  return '';
98
  * Cache home URL in static variable
99
  *
100
  * @since 2.5.0
101
+ * @since 2.9.0 Now returns subdirectory installations paths too.
102
  * @staticvar array $url_cache
103
  *
104
  * @param bool $force_slash Force slash
180
 
181
  static $cache = null;
182
 
183
+ return isset( $cache ) ? $cache : $cache = $this->get_social_image( array(), true );
184
  }
185
 
186
  /**
404
  continue;
405
 
406
  //* Parse 1500px url.
407
+ $img = $this->parse_og_image( $id, array(), true );
408
 
409
  if ( $img ) {
410
  $output .= '<meta property="og:image" content="' . \esc_attr( $img ) . '" />' . "\r\n";
728
  if ( 'product' === $this->get_og_type() )
729
  return '';
730
 
731
+ if ( $this->is_real_front_page() ) {
732
  //* If it's the frontpage, but the option is disabled, don't do anything.
733
  if ( ! $this->get_option( 'home_publish_time' ) )
734
  return '';
776
  if ( 'product' === $this->get_og_type() )
777
  return '';
778
 
779
+ if ( $this->is_real_front_page() ) {
780
  //* If it's the frontpage, but the option is disabled, don't do anything.
781
  if ( ! $this->get_option( 'home_modify_time' ) )
782
  return '';
inc/classes/sanitize.class.php CHANGED
@@ -91,8 +91,10 @@ class Sanitize extends Admin_Pages {
91
  return;
92
 
93
  //* Update hidden options.
 
94
  $this->update_hidden_options_to_default();
95
 
 
96
  $this->init_sanitizer_filters();
97
 
98
  //* Flush transients after options have changed.
@@ -183,6 +185,14 @@ class Sanitize extends Admin_Pages {
183
  's_one_zero',
184
  $this->settings_field,
185
  array(
 
 
 
 
 
 
 
 
186
  'title_rem_additions',
187
  'title_rem_prefixes',
188
 
@@ -277,14 +287,18 @@ class Sanitize extends Admin_Pages {
277
  $this->settings_field,
278
  array(
279
  'social_image_fb_id',
 
 
280
  )
281
  );
282
 
 
283
  $this->add_option_filter(
284
  's_no_html',
285
  $this->settings_field,
286
  array()
287
  );
 
288
 
289
  /**
290
  * @todo create content="code" stripper
@@ -328,6 +342,8 @@ class Sanitize extends Admin_Pages {
328
  array(
329
  'knowledge_linkedin',
330
  'social_image_fb_url',
 
 
331
  )
332
  );
333
 
@@ -348,6 +364,14 @@ class Sanitize extends Admin_Pages {
348
  )
349
  );
350
 
 
 
 
 
 
 
 
 
351
  $this->add_option_filter(
352
  's_color_hex',
353
  $this->settings_field,
@@ -520,6 +544,7 @@ class Sanitize extends Admin_Pages {
520
  's_url_query' => array( $this, 's_url_query' ),
521
  's_twitter_name' => array( $this, 's_twitter_name' ),
522
  's_twitter_card' => array( $this, 's_twitter_card' ),
 
523
  );
524
 
525
  /**
@@ -1209,4 +1234,26 @@ class Sanitize extends Admin_Pages {
1209
  public function s_bsol( $new_value ) {
1210
  return str_replace( '\\', '&#92;', stripslashes( $new_value ) );
1211
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1212
  }
91
  return;
92
 
93
  //* Update hidden options.
94
+ //* @TODO remove this and use a better upgrade handler.
95
  $this->update_hidden_options_to_default();
96
 
97
+ //* Initialize sanitation filters parsed on each option update.
98
  $this->init_sanitizer_filters();
99
 
100
  //* Flush transients after options have changed.
185
  's_one_zero',
186
  $this->settings_field,
187
  array(
188
+ 'cache_meta_description',
189
+ 'cache_meta_schema',
190
+ 'cache_sitemap',
191
+ 'cache_object',
192
+
193
+ 'display_seo_bar_tables',
194
+ 'display_seo_bar_metabox',
195
+
196
  'title_rem_additions',
197
  'title_rem_prefixes',
198
 
287
  $this->settings_field,
288
  array(
289
  'social_image_fb_id',
290
+ 'homepage_social_image_id',
291
+ 'knowledge_logo_id',
292
  )
293
  );
294
 
295
+ /*
296
  $this->add_option_filter(
297
  's_no_html',
298
  $this->settings_field,
299
  array()
300
  );
301
+ */
302
 
303
  /**
304
  * @todo create content="code" stripper
342
  array(
343
  'knowledge_linkedin',
344
  'social_image_fb_url',
345
+ 'homepage_social_image_url',
346
+ 'knowledge_logo_url',
347
  )
348
  );
349
 
364
  )
365
  );
366
 
367
+ $this->add_option_filter(
368
+ 's_canonical_scheme',
369
+ $this->settings_field,
370
+ array(
371
+ 'canonical_scheme',
372
+ )
373
+ );
374
+
375
  $this->add_option_filter(
376
  's_color_hex',
377
  $this->settings_field,
544
  's_url_query' => array( $this, 's_url_query' ),
545
  's_twitter_name' => array( $this, 's_twitter_name' ),
546
  's_twitter_card' => array( $this, 's_twitter_card' ),
547
+ 's_canonical_scheme' => array( $this, 's_canonical_scheme' ),
548
  );
549
 
550
  /**
1234
  public function s_bsol( $new_value ) {
1235
  return str_replace( '\\', '&#92;', stripslashes( $new_value ) );
1236
  }
1237
+
1238
+ /**
1239
+ * Sanitizes canonical scheme settings.
1240
+ *
1241
+ * @since 2.9.0
1242
+ *
1243
+ * @param string $new_value String with potentially unwanted values.
1244
+ * @return string A correct canonical scheme setting value.
1245
+ */
1246
+ public function s_canonical_scheme( $new_value ) {
1247
+
1248
+ $values = array(
1249
+ 'automatic',
1250
+ 'https',
1251
+ 'http',
1252
+ );
1253
+
1254
+ if ( in_array( $new_value, $values, true ) )
1255
+ return (string) $new_value;
1256
+
1257
+ return 'automatic';
1258
+ }
1259
  }
inc/classes/site-options.class.php CHANGED
@@ -105,163 +105,171 @@ class Site_Options extends Sanitize {
105
  */
106
  return array(
107
  // General. Performance.
108
- 'cache_meta_description' => 1, // Description transient cache.
109
- 'cache_meta_schema' => 1, // Schema.org transient cache.
110
- 'cache_sitemap' => 1, // Sitemap transient cache.
111
- 'cache_object' => 1, // Object caching.
112
 
113
  // General. Layout.
114
- 'display_seo_bar_tables' => 1, // SEO Bar post-list tables.
115
- 'display_seo_bar_metabox' => 0, // SEO Bar post SEO Settings.
116
 
117
  // General. Canonical.
118
- 'canonical_scheme' => 'automatic', // Canonical URL scheme.
119
 
120
  // Title.
121
- 'title_seperator' => 'pipe', // Title separator (note: TYPO), dropdown
122
- 'title_location' => $titleloc, // Title separation location
123
- 'title_rem_additions' => 0, // Remove title additions
124
- 'title_rem_prefixes' => 0, // Remove title prefixes
125
 
126
  // Description.
127
- 'description_separator' => 'pipe', // Description separator, dropdown
128
- 'description_additions' => 1, // "Title on Blogname" within Description
129
- 'description_blogname' => 1, // "on Blogname" within Description
130
- // 'description_custom' => '', // Custom prefix
131
 
132
  // Robots directory.
133
- 'noodp' => 1, // Site noopd robots settings
134
- 'noydir' => 1, // Site noydir robots settings
135
 
136
  // Robots index.
137
- 'category_noindex' => 0, // Category Archive robots noindex
138
- 'tag_noindex' => 0, // Tag Archive robots noindex
139
- 'author_noindex' => 0, // Author Archive robots noindex
140
- 'date_noindex' => 1, // Date Archive robots noindex
141
- 'search_noindex' => 1, // Search Page robots noindex
142
- 'attachment_noindex' => 1, // Attachment Pages robots noindex
143
- 'site_noindex' => 0, // Site Page robots noindex
144
 
145
  // Robots follow.
146
- 'category_nofollow' => 0, // Category Archive robots nofollow
147
- 'tag_nofollow' => 0, // Tag Archive robots nofollow
148
- 'author_nofollow' => 0, // Author Archive robots nofollow
149
- 'date_nofollow' => 0, // Date Archive robots nofollow
150
- 'search_nofollow' => 0, // Search Page robots nofollow
151
- 'attachment_nofollow' => 0, // Attachment Pages robots noindex
152
- 'site_nofollow' => 0, // Site Page robots nofollow
153
 
154
  // Robots archive.
155
- 'category_noarchive' => 0, // Category Archive robots noarchive
156
- 'tag_noarchive' => 0, // Tag Archive robots noarchive
157
- 'author_noarchive' => 0, // Author Archive robots noarchive
158
- 'date_noarchive' => 0, // Date Archive robots noarchive
159
- 'search_noarchive' => 0, // Search Page robots noarchive
160
- 'attachment_noarchive' => 0, // Attachment Page robots noarchive
161
- 'site_noarchive' => 0, // Site Page robots noarchive
162
 
163
  // Robots pagination index.
164
- 'paged_noindex' => 1, // Every second or later page noindex
165
- 'home_paged_noindex' => 0, // Every second or later homepage noindex
166
 
167
  // Robots home.
168
- 'homepage_noindex' => 0, // Home Page robots noindex
169
- 'homepage_nofollow' => 0, // Home Page robots noarchive
170
- 'homepage_noarchive' => 0, // Home Page robots nofollow
171
 
172
  // Home meta.
173
- 'homepage_title' => '', // Home Page Title string
174
- 'homepage_tagline' => 1, // Home Page add blog Tagline
175
- 'homepage_description' => '', // Home Page Description string
176
- 'homepage_title_tagline' => '', // Home Page Tagline string
177
- 'home_title_location' => $h_titleloc, // Title separation location
 
 
 
 
178
 
179
  // Relationships
180
- 'shortlink_tag' => 0, // Adds shortlink tag
181
- 'prev_next_posts' => 0, // Adds next/prev tags
182
- 'prev_next_archives' => 1, // Adds next/prev tags
183
- 'prev_next_frontpage' => 1, // Adds next/prev tags
184
 
185
  // Facebook.
186
- 'facebook_publisher' => '', // Facebook Business Url
187
- 'facebook_author' => '', // Facebook User URl
188
- 'facebook_appid' => '', // Facebook App ID
189
 
190
  // Dates.
191
- 'post_publish_time' => 1, // Article Published Time
192
- 'post_modify_time' => 1, // Article Modified Time
193
 
194
- 'page_publish_time' => 0, // Article Published Time
195
- 'page_modify_time' => 0, // Article Modified Time
196
 
197
- 'home_publish_time' => 0, // Article Modified Time
198
- 'home_modify_time' => 0, // Article Modified Time
199
 
200
  // Twitter.
201
- 'twitter_card' => 'summary_large_image', // Twitter Card layout. If no twitter:image image is found, it'll change to 'summary', dropdown
202
- 'twitter_site' => '', // Twitter business @username
203
- 'twitter_creator' => '', // Twitter user @username
204
 
205
  // Social on/off.
206
- 'og_tags' => 1, // Output of Open Graph meta tags
207
- 'facebook_tags' => 1, // Output the Facebook meta tags
208
- 'twitter_tags' => 1, // Output the Twitter meta tags
209
- // 'googleplus_tags' => 1, // Output the Google+ meta tags
210
 
211
- // Social FallBack images
212
- 'social_image_fb_url' => '',
213
- 'social_image_fb_id' => 0,
214
 
215
  // Webmasters.
216
- 'google_verification' => '', // Google Verification Code
217
- 'bing_verification' => '', // Bing Verification Code
218
- 'yandex_verification' => '', // Yandex Verification Code
219
- 'pint_verification' => '', // Pinterest Verification Code
220
 
221
  // Knowledge general. https://developers.google.com/structured-data/customize/contact-points - This is extremely extended and valuable. Expect a premium version.
222
- 'knowledge_output' => 1, // Default for outputing the Knowledge SEO.
223
- 'knowledge_type' => 'organization', // Organization or Person, dropdown
224
 
225
  // Knowledge business. https://developers.google.com/structured-data/customize/logos
226
- 'knowledge_logo' => 1, // Fetch logo from WP Favicon
227
- 'knowledge_name' => '', // Person or Organization name
 
 
 
 
228
 
229
  // Knowledge sameas locations
230
- 'knowledge_facebook' => '', // Facebook Account
231
- 'knowledge_twitter' => '', // Twitter Account
232
- 'knowledge_gplus' => '', // Google Plus Account
233
- 'knowledge_instagram' => '', // Instagram Account
234
- 'knowledge_youtube' => '', // Youtube Account
235
- 'knowledge_linkedin' => '', // Linkedin Account
236
- // 'knowledge_myspace' => '', // MySpace Account // meh.
237
- 'knowledge_pinterest' => '', // Pinterest Account
238
- 'knowledge_soundcloud' => '', // SoundCloud Account
239
- 'knowledge_tumblr' => '', // Tumblr Account
240
 
241
  // Sitemaps.
242
- 'sitemaps_output' => 1, // Output of sitemaps
243
- 'sitemaps_modified' => 1, // Add sitemaps modified time
244
- 'sitemap_timestamps' => '1', // Sitemaps modified time format, dropdown
245
- 'sitemaps_robots' => 1, // Add sitemaps location to robots.txt
246
- 'ping_google' => 1, // Ping Google
247
- 'ping_bing' => 1, // Ping Bing
248
- 'ping_yandex' => 1, // Ping Yandex
249
- 'sitemap_styles' => 1, // Whether to style the sitemap
250
- 'sitemap_logo' => 1, // Whether to add logo to sitemap
251
- 'sitemap_color_main' => '333', // Sitemap main color
252
- 'sitemap_color_accent' => '00cd98', // Sitemap accent color
253
 
254
  // Feed.
255
- 'excerpt_the_feed' => 1, // Generate feed Excerpts
256
- 'source_the_feed' => 1, // Add backlink at the end of the feed
257
 
258
  // Schema
259
- 'ld_json_searchbox' => 1, // LD+Json Sitelinks Searchbox
260
- 'ld_json_sitename' => 1, // LD+Json Sitename
261
- 'ld_json_breadcrumbs' => 1, // LD+Json Breadcrumbs
262
 
263
  // Cache.
264
- $this->o_plugin_updated => 1, // Plugin update cache.
265
  );
266
  }
267
 
@@ -269,6 +277,7 @@ class Site_Options extends Sanitize {
269
  * Holds warned site options array.
270
  *
271
  * @since 2.6.0
 
272
  *
273
  * @return array $options.
274
  */
@@ -283,102 +292,19 @@ class Site_Options extends Sanitize {
283
  * Only used within the SEO Settings page.
284
  */
285
  return array(
286
- 'cache_meta_description' => 0, // Description transient cache.
287
- 'cache_meta_schema' => 0, // Schema.org transient cache.
288
- 'cache_sitemap' => 0, // Sitemap transient cache.
289
- 'cache_object' => 0, // Object caching.
290
-
291
- 'display_seo_bar_tables' => 0, // SEO Bar post-list tables.
292
- 'display_seo_bar_metabox' => 0, // SEO Bar post SEO Settings.
293
-
294
- 'title_rem_additions' => 1, // Title remove additions.
295
- 'title_rem_prefixes' => 0, // Title remove prefixes.
296
-
297
- 'noodp' => 0, // Site noopd robots settings
298
- 'noydir' => 0, // Site noydir robots settings
299
-
300
- 'description_additions' => 0, // "Title on Blogname" within Description
301
- 'description_blogname' => 0, // "on Blogname" within Description
302
-
303
- 'category_noindex' => 0, // Category Archive robots noindex
304
- 'tag_noindex' => 0, // Tag Archive robots noindex
305
- 'author_noindex' => 0, // Author Archive robots noindex
306
- 'date_noindex' => 0, // Date Archive robots noindex
307
- 'search_noindex' => 0, // Search Page robots noindex
308
- 'attachment_noindex' => 0, // Attachment Pages robots noindex
309
- 'site_noindex' => 1, // Site Page robots noindex
310
-
311
- 'category_nofollow' => 0, // Category Archive robots nofollow
312
- 'tag_nofollow' => 0, // Tag Archive robots nofollow
313
- 'author_nofollow' => 0, // Author Archive robots nofollow
314
- 'date_nofollow' => 0, // Date Archive robots nofollow
315
- 'search_nofollow' => 0, // Search Page robots nofollow
316
- 'attachment_nofollow' => 0, // Attachment Pages robots noindex
317
- 'site_nofollow' => 1, // Site Page robots nofollow
318
-
319
- 'category_noarchive' => 0, // Category Archive robots noarchive
320
- 'tag_noarchive' => 0, // Tag Archive robots noarchive
321
- 'author_noarchive' => 0, // Author Archive robots noarchive
322
- 'date_noarchive' => 0, // Date Archive robots noarchive
323
- 'search_noarchive' => 0, // Search Page robots noarchive
324
- 'attachment_noarchive' => 0, // Attachment Page robots noarchive
325
- 'site_noarchive' => 0, // Site Page robots noarchive
326
-
327
- 'paged_noindex' => 0, // Every second or later page noindex
328
- 'home_paged_noindex' => 0, // Every second or later homepage noindex
329
-
330
- 'homepage_noindex' => 1, // Home Page robots noindex
331
- 'homepage_nofollow' => 1, // Home Page robots noarchive
332
- 'homepage_noarchive' => 0, // Home Page robots nofollow
333
-
334
- 'homepage_tagline' => 0, // Home Page add blog Tagline
335
-
336
- 'shortlink_tag' => 0, // Adds shortlink tag
337
-
338
- 'prev_next_posts' => 0, // Adds next/prev tags
339
- 'prev_next_archives' => 0, // Adds next/prev tags
340
- 'prev_next_frontpage' => 0, // Adds next/prev tags
341
-
342
- 'post_publish_time' => 0, // Article Published Time
343
- 'post_modify_time' => 0, // Article Modified Time
344
-
345
- 'page_publish_time' => 0, // Article Published Time
346
- 'page_modify_time' => 0, // Article Modified Time
347
-
348
- 'home_publish_time' => 0, // Article Modified Time
349
- 'home_modify_time' => 0, // Article Modified Time
350
-
351
- 'og_tags' => 0, // Output of Open Graph meta tags
352
- 'facebook_tags' => 0, // Output the Facebook meta tags
353
- 'twitter_tags' => 0, // Output the Twitter meta tags
354
- // 'googleplus_tags' => 0, // Output the Google+ meta tags
355
-
356
- 'knowledge_output' => 0, // Default for outputing the Knowledge SEO.
357
- 'knowledge_logo' => 0, // Fetch logo from WP Favicon
358
-
359
- 'sitemaps_output' => 0, // Output of sitemaps
360
- 'sitemaps_modified' => 0, // Add sitemaps modified time
361
- 'sitemaps_robots' => 0, // Add sitemaps location to robots.txt
362
- 'ping_google' => 0, // Ping Google
363
- 'ping_bing' => 0, // Ping Bing
364
- 'ping_yandex' => 0, // Ping Yandex
365
- 'sitemap_styles' => 0, // Whether to style the sitemap
366
- 'sitemap_logo' => 0, // Whether to add a logo to the sitemap
367
-
368
- 'excerpt_the_feed' => 0, // Generate feed Excerpts
369
- 'source_the_feed' => 0, // Add backlink at the end of the feed
370
-
371
- 'ld_json_searchbox' => 0, // LD+Json Sitelinks Searchbox
372
- 'ld_json_sitename' => 0, // LD+Json Sitename
373
- 'ld_json_breadcrumbs' => 0, // LD+Json Breadcrumbs
374
  );
375
-
376
  }
377
 
378
  /**
379
  * Updates special hidden values to default on settings save.
380
  *
381
  * @since 2.6.0
 
382
  */
383
  protected function update_hidden_options_to_default() {
384
 
@@ -395,6 +321,7 @@ class Site_Options extends Sanitize {
395
  * Updates option from default options at plugin update.
396
  *
397
  * @since 2.6.0
 
398
  * @access private
399
  *
400
  * @return void early if already has been updated.
@@ -404,6 +331,13 @@ class Site_Options extends Sanitize {
404
  if ( false === $this->is_admin() )
405
  return;
406
 
 
 
 
 
 
 
 
407
  $plugin_updated = $this->o_plugin_updated;
408
 
409
  /**
@@ -417,13 +351,6 @@ class Site_Options extends Sanitize {
417
  if ( ! \current_user_can( $this->settings_capability() ) )
418
  return;
419
 
420
- /**
421
- * Applies filters 'the_seo_framework_update_options_at_update' : bool
422
- * @since 2.6.0
423
- */
424
- if ( ! \apply_filters( 'the_seo_framework_update_options_at_update', true ) )
425
- return;
426
-
427
  $updated = false;
428
  $options = $this->get_all_options();
429
  $new_options = $this->default_site_options();
@@ -435,10 +362,23 @@ class Site_Options extends Sanitize {
435
  $new_options[ $plugin_updated ] = 1;
436
  $options[ $plugin_updated ] = 1;
437
 
 
 
 
 
 
 
 
 
 
438
  //* Merge the options. Add to if it's non-existent.
439
  foreach ( $new_options as $key => $value ) {
440
  if ( ! isset( $options[ $key ] ) ) {
441
- $options[ $key ] = $value;
 
 
 
 
442
 
443
  if ( ! empty( $value ) )
444
  $updated = true;
@@ -516,6 +456,7 @@ class Site_Options extends Sanitize {
516
  * Return current option array.
517
  *
518
  * @since 2.6.0
 
519
  * @staticvar array $cache The option cache.
520
  *
521
  * @param string $setting The setting key.
@@ -671,6 +612,7 @@ class Site_Options extends Sanitize {
671
  * Register the database settings for storage.
672
  *
673
  * @since 2.2.2
 
674
  * @thanks StudioPress (http://www.studiopress.com/) for some code.
675
  *
676
  * @return void Early if settings can't be registered.
@@ -684,11 +626,23 @@ class Site_Options extends Sanitize {
684
  \register_setting( $this->settings_field, $this->settings_field );
685
  \add_option( $this->settings_field, $this->default_site_options() );
686
 
687
- //* If this page isn't the SEO Settings page, there's no need to check for a reset.
 
 
 
 
 
 
 
 
 
 
 
 
688
  if ( false === $this->is_seo_settings_page( false ) )
689
  return;
690
 
691
- if ( $this->get_option( 'tsf-settings-reset', $this->settings_field ) ) {
692
  if ( \update_option( $this->settings_field, $this->default_site_options() ) ) {
693
  $this->admin_redirect( $this->seo_settings_page_slug, array( 'tsf-settings-reset' => 'true' ) );
694
  exit;
@@ -699,6 +653,27 @@ class Site_Options extends Sanitize {
699
  }
700
  }
701
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
  /**
703
  * Allows updating of settings.
704
  *
@@ -820,10 +795,11 @@ class Site_Options extends Sanitize {
820
 
821
  $warned_options = $this->warned_site_options();
822
 
823
- if ( ! is_array( $warned_options ) || ! array_key_exists( $key, (array) $warned_options ) )
824
- $warned_cache[ $key ] = -1;
825
-
826
- $warned_cache[ $key ] = $this->s_one_zero( $warned_options[ $key ] );
 
827
 
828
  return $warned_cache[ $key ];
829
  }
105
  */
106
  return array(
107
  // General. Performance.
108
+ 'cache_meta_description' => 1, // Description transient cache.
109
+ 'cache_meta_schema' => 1, // Schema.org transient cache.
110
+ 'cache_sitemap' => 1, // Sitemap transient cache.
111
+ 'cache_object' => 1, // Object caching.
112
 
113
  // General. Layout.
114
+ 'display_seo_bar_tables' => 1, // SEO Bar post-list tables.
115
+ 'display_seo_bar_metabox' => 0, // SEO Bar post SEO Settings.
116
 
117
  // General. Canonical.
118
+ 'canonical_scheme' => 'automatic', // Canonical URL scheme.
119
 
120
  // Title.
121
+ 'title_seperator' => 'pipe', // Title separator (note: TYPO), dropdown
122
+ 'title_location' => $titleloc, // Title separation location
123
+ 'title_rem_additions' => 0, // Remove title additions
124
+ 'title_rem_prefixes' => 0, // Remove title prefixes
125
 
126
  // Description.
127
+ 'description_separator' => 'pipe', // Description separator, dropdown
128
+ 'description_additions' => 1, // "Title on Blogname" within Description
129
+ 'description_blogname' => 1, // "on Blogname" within Description
130
+ // 'description_custom' => '', // Custom prefix
131
 
132
  // Robots directory.
133
+ 'noodp' => 1, // Site noopd robots settings
134
+ 'noydir' => 1, // Site noydir robots settings
135
 
136
  // Robots index.
137
+ 'category_noindex' => 0, // Category Archive robots noindex
138
+ 'tag_noindex' => 0, // Tag Archive robots noindex
139
+ 'author_noindex' => 0, // Author Archive robots noindex
140
+ 'date_noindex' => 1, // Date Archive robots noindex
141
+ 'search_noindex' => 1, // Search Page robots noindex
142
+ 'attachment_noindex' => 1, // Attachment Pages robots noindex
143
+ 'site_noindex' => 0, // Site Page robots noindex
144
 
145
  // Robots follow.
146
+ 'category_nofollow' => 0, // Category Archive robots nofollow
147
+ 'tag_nofollow' => 0, // Tag Archive robots nofollow
148
+ 'author_nofollow' => 0, // Author Archive robots nofollow
149
+ 'date_nofollow' => 0, // Date Archive robots nofollow
150
+ 'search_nofollow' => 0, // Search Page robots nofollow
151
+ 'attachment_nofollow' => 0, // Attachment Pages robots noindex
152
+ 'site_nofollow' => 0, // Site Page robots nofollow
153
 
154
  // Robots archive.
155
+ 'category_noarchive' => 0, // Category Archive robots noarchive
156
+ 'tag_noarchive' => 0, // Tag Archive robots noarchive
157
+ 'author_noarchive' => 0, // Author Archive robots noarchive
158
+ 'date_noarchive' => 0, // Date Archive robots noarchive
159
+ 'search_noarchive' => 0, // Search Page robots noarchive
160
+ 'attachment_noarchive' => 0, // Attachment Page robots noarchive
161
+ 'site_noarchive' => 0, // Site Page robots noarchive
162
 
163
  // Robots pagination index.
164
+ 'paged_noindex' => 1, // Every second or later page noindex
165
+ 'home_paged_noindex' => 0, // Every second or later homepage noindex
166
 
167
  // Robots home.
168
+ 'homepage_noindex' => 0, // Home Page robots noindex
169
+ 'homepage_nofollow' => 0, // Home Page robots noarchive
170
+ 'homepage_noarchive' => 0, // Home Page robots nofollow
171
 
172
  // Home meta.
173
+ 'homepage_title' => '', // Home Page Title string
174
+ 'homepage_tagline' => 1, // Home Page add blog Tagline
175
+ 'homepage_description' => '', // Home Page Description string
176
+ 'homepage_title_tagline' => '', // Home Page Tagline string
177
+ 'home_title_location' => $h_titleloc, // Title separation location
178
+
179
+ // Homepage Social FallBack image
180
+ 'homepage_social_image_url' => '',
181
+ 'homepage_social_image_id' => 0,
182
 
183
  // Relationships
184
+ 'shortlink_tag' => 0, // Adds shortlink tag
185
+ 'prev_next_posts' => 0, // Adds next/prev tags
186
+ 'prev_next_archives' => 1, // Adds next/prev tags
187
+ 'prev_next_frontpage' => 1, // Adds next/prev tags
188
 
189
  // Facebook.
190
+ 'facebook_publisher' => '', // Facebook Business Url
191
+ 'facebook_author' => '', // Facebook User URl
192
+ 'facebook_appid' => '', // Facebook App ID
193
 
194
  // Dates.
195
+ 'post_publish_time' => 1, // Article Published Time
196
+ 'post_modify_time' => 1, // Article Modified Time
197
 
198
+ 'page_publish_time' => 0, // Article Published Time
199
+ 'page_modify_time' => 0, // Article Modified Time
200
 
201
+ 'home_publish_time' => 0, // Article Modified Time
202
+ 'home_modify_time' => 0, // Article Modified Time
203
 
204
  // Twitter.
205
+ 'twitter_card' => 'summary_large_image', // Twitter Card layout. If no twitter:image image is found, it'll change to 'summary', radio
206
+ 'twitter_site' => '', // Twitter business @username
207
+ 'twitter_creator' => '', // Twitter user @username
208
 
209
  // Social on/off.
210
+ 'og_tags' => 1, // Output of Open Graph meta tags
211
+ 'facebook_tags' => 1, // Output the Facebook meta tags
212
+ 'twitter_tags' => 1, // Output the Twitter meta tags
213
+ // 'googleplus_tags' => 1, // Output the Google+ meta tags
214
 
215
+ // Social FallBack images (fb = fallback)
216
+ 'social_image_fb_url' => '', // Fallback image URL
217
+ 'social_image_fb_id' => 0, // Fallback image ID
218
 
219
  // Webmasters.
220
+ 'google_verification' => '', // Google Verification Code
221
+ 'bing_verification' => '', // Bing Verification Code
222
+ 'yandex_verification' => '', // Yandex Verification Code
223
+ 'pint_verification' => '', // Pinterest Verification Code
224
 
225
  // Knowledge general. https://developers.google.com/structured-data/customize/contact-points - This is extremely extended and valuable. Expect a premium version.
226
+ 'knowledge_output' => 1, // Default for outputing the Knowledge SEO.
227
+ 'knowledge_type' => 'organization', // Organization or Person, dropdown
228
 
229
  // Knowledge business. https://developers.google.com/structured-data/customize/logos
230
+ 'knowledge_logo' => 1, // Fetch logo from WP Favicon
231
+ 'knowledge_name' => '', // Person or Organization name
232
+
233
+ // Knowledge Logo image
234
+ // 'knowledge_logo_url' => '', // TODO
235
+ // 'knowledge_logo_id' => 0, // TODO
236
 
237
  // Knowledge sameas locations
238
+ 'knowledge_facebook' => '', // Facebook Account
239
+ 'knowledge_twitter' => '', // Twitter Account
240
+ 'knowledge_gplus' => '', // Google Plus Account
241
+ 'knowledge_instagram' => '', // Instagram Account
242
+ 'knowledge_youtube' => '', // Youtube Account
243
+ 'knowledge_linkedin' => '', // Linkedin Account
244
+ // 'knowledge_myspace' => '', // MySpace Account // meh.
245
+ 'knowledge_pinterest' => '', // Pinterest Account
246
+ 'knowledge_soundcloud' => '', // SoundCloud Account
247
+ 'knowledge_tumblr' => '', // Tumblr Account
248
 
249
  // Sitemaps.
250
+ 'sitemaps_output' => 1, // Output of sitemaps
251
+ 'sitemaps_modified' => 1, // Add sitemaps modified time
252
+ 'sitemap_timestamps' => '1', // Sitemaps modified time format, dropdown
253
+ 'sitemaps_robots' => 1, // Add sitemaps location to robots.txt
254
+ 'ping_google' => 1, // Ping Google
255
+ 'ping_bing' => 1, // Ping Bing
256
+ 'ping_yandex' => 1, // Ping Yandex
257
+ 'sitemap_styles' => 1, // Whether to style the sitemap
258
+ 'sitemap_logo' => 1, // Whether to add logo to sitemap
259
+ 'sitemap_color_main' => '333', // Sitemap main color
260
+ 'sitemap_color_accent' => '00cd98', // Sitemap accent color
261
 
262
  // Feed.
263
+ 'excerpt_the_feed' => 1, // Generate feed Excerpts
264
+ 'source_the_feed' => 1, // Add backlink at the end of the feed
265
 
266
  // Schema
267
+ 'ld_json_searchbox' => 1, // LD+Json Sitelinks Searchbox
268
+ 'ld_json_sitename' => 1, // LD+Json Sitename
269
+ 'ld_json_breadcrumbs' => 1, // LD+Json Breadcrumbs
270
 
271
  // Cache.
272
+ $this->o_plugin_updated => 1, // Plugin update cache.
273
  );
274
  }
275
 
277
  * Holds warned site options array.
278
  *
279
  * @since 2.6.0
280
+ * @since 2.9.0 Removed all non-warned settings.
281
  *
282
  * @return array $options.
283
  */
292
  * Only used within the SEO Settings page.
293
  */
294
  return array(
295
+ 'title_rem_additions' => 1, // Title remove additions.
296
+ 'site_noindex' => 1, // Site Page robots noindex
297
+ 'site_nofollow' => 1, // Site Page robots nofollow
298
+ 'homepage_noindex' => 1, // Home Page robots noindex
299
+ 'homepage_nofollow' => 1, // Home Page robots noarchive
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  );
 
301
  }
302
 
303
  /**
304
  * Updates special hidden values to default on settings save.
305
  *
306
  * @since 2.6.0
307
+ * @TODO REMOVE THIS and use a better upgrade handler. Source for code debt.
308
  */
309
  protected function update_hidden_options_to_default() {
310
 
321
  * Updates option from default options at plugin update.
322
  *
323
  * @since 2.6.0
324
+ * @since 2.9.0 Added excluded options check.
325
  * @access private
326
  *
327
  * @return void early if already has been updated.
331
  if ( false === $this->is_admin() )
332
  return;
333
 
334
+ /**
335
+ * Applies filters 'the_seo_framework_update_options_at_update' : bool
336
+ * @since 2.6.0
337
+ */
338
+ if ( ! \apply_filters( 'the_seo_framework_update_options_at_update', true ) )
339
+ return;
340
+
341
  $plugin_updated = $this->o_plugin_updated;
342
 
343
  /**
351
  if ( ! \current_user_can( $this->settings_capability() ) )
352
  return;
353
 
 
 
 
 
 
 
 
354
  $updated = false;
355
  $options = $this->get_all_options();
356
  $new_options = $this->default_site_options();
362
  $new_options[ $plugin_updated ] = 1;
363
  $options[ $plugin_updated ] = 1;
364
 
365
+ $plausible_missing_options = array(
366
+ 'cache_meta_description',
367
+ 'cache_meta_schema',
368
+ 'cache_sitemap',
369
+ 'cache_object',
370
+ 'display_seo_bar_tables',
371
+ 'display_seo_bar_metabox',
372
+ );
373
+
374
  //* Merge the options. Add to if it's non-existent.
375
  foreach ( $new_options as $key => $value ) {
376
  if ( ! isset( $options[ $key ] ) ) {
377
+ if ( in_array( $key, $plausible_missing_options, true ) ) {
378
+ $options[ $key ] = 0;
379
+ } else {
380
+ $options[ $key ] = $value;
381
+ }
382
 
383
  if ( ! empty( $value ) )
384
  $updated = true;
456
  * Return current option array.
457
  *
458
  * @since 2.6.0
459
+ * @since 2.9.0 Added $use_cache parameter.
460
  * @staticvar array $cache The option cache.
461
  *
462
  * @param string $setting The setting key.
612
  * Register the database settings for storage.
613
  *
614
  * @since 2.2.2
615
+ * @since 2.9.0 Removed reset options check, see check_options_reset().
616
  * @thanks StudioPress (http://www.studiopress.com/) for some code.
617
  *
618
  * @return void Early if settings can't be registered.
626
  \register_setting( $this->settings_field, $this->settings_field );
627
  \add_option( $this->settings_field, $this->default_site_options() );
628
 
629
+ //* Check whether the Options Reset initialization has been added.
630
+ $this->check_options_reset();
631
+ }
632
+
633
+ /**
634
+ * Checks for options reset, and reset them.
635
+ *
636
+ * @since 2.9.0
637
+ *
638
+ * @return void Early if not on SEO settings page.
639
+ */
640
+ protected function check_options_reset() {
641
+
642
  if ( false === $this->is_seo_settings_page( false ) )
643
  return;
644
 
645
+ if ( $this->get_option( 'tsf-settings-reset', false ) ) {
646
  if ( \update_option( $this->settings_field, $this->default_site_options() ) ) {
647
  $this->admin_redirect( $this->seo_settings_page_slug, array( 'tsf-settings-reset' => 'true' ) );
648
  exit;
653
  }
654
  }
655
 
656
+ /**
657
+ * Updates a single option.
658
+ *
659
+ * Can return false if option is unchanged.
660
+ *
661
+ * @since 2.9.0
662
+ *
663
+ * @param string $key The option key.
664
+ * @param string $vlaue The option value.
665
+ * @return bool True on success, false on failure.
666
+ */
667
+ public function update_option( $key = '', $value = '' ) {
668
+
669
+ if ( ! $key ) {
670
+ $this->_doing_it_wrong( __METHOD__, 'No option key has been specified.', '2.9.0' );
671
+ return false;
672
+ }
673
+
674
+ return $this->update_settings( array( $key => $value ) );
675
+ }
676
+
677
  /**
678
  * Allows updating of settings.
679
  *
795
 
796
  $warned_options = $this->warned_site_options();
797
 
798
+ if ( ! array_key_exists( $key, (array) $warned_options ) ) {
799
+ $warned_cache[ $key ] = 0;
800
+ } else {
801
+ $warned_cache[ $key ] = $this->s_one_zero( $warned_options[ $key ] );
802
+ }
803
 
804
  return $warned_cache[ $key ];
805
  }
inc/classes/sitemaps.class.php CHANGED
@@ -305,7 +305,7 @@ class Sitemaps extends Metaboxes {
305
  if ( $this->the_seo_framework_debug ) {
306
  echo "\r\n" . '<!-- Site estimated peak usage: ' . number_format( memory_get_peak_usage() / 1024 / 1024, 3 ) . ' MB -->';
307
  echo "\r\n" . '<!-- System estimated peak usage: ' . number_format( memory_get_peak_usage( true ) / 1024 / 1024, 3 ) . ' MB -->';
308
- echo "\r\n" . '<!-- Freed memory prior to generation: ' . number_format( $this->clean_up_globals( true ) / 1024, 3 ) . ' kB -->';
309
  echo "\r\n" . '<!-- Sitemap generation time: ' . ( number_format( microtime( true ) - $timer_start, 6 ) ) . ' seconds -->';
310
  }
311
  }
@@ -474,6 +474,8 @@ class Sitemaps extends Metaboxes {
474
  * Maximum pages and posts to fetch.
475
  * A total of 2100, consisting of 3 times $max_posts
476
  *
 
 
477
  * Applies filters the_seo_framework_sitemap_pages_count : int max pages
478
  * Applies filters the_seo_framework_sitemap_posts_count : int max posts
479
  * Applies filters the_seo_framework_sitemap_custom_posts_count : int max posts
@@ -548,11 +550,109 @@ class Sitemaps extends Metaboxes {
548
  $wp_query->query = $wp_query->query_vars = \wp_parse_args( $args, $defaults );
549
  $latest_pages = $wp_query->get_posts();
550
  }
551
- $latest_pages_amount = (int) count( $latest_pages );
552
 
553
  if ( $latest_pages_amount > 0 ) :
554
 
555
- $id_on_front = $this->has_page_on_front() ? (int) \get_option( 'page_on_front' ) : (int) \get_option( 'page_for_posts' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
 
557
  /**
558
  * This can be heavy.
@@ -571,28 +671,18 @@ class Sitemaps extends Metaboxes {
571
 
572
  //* Continue if indexed.
573
  if ( $indexed ) {
574
- //* Is this the front page?
575
- $page_is_front = $page_id === $id_on_front;
576
-
577
  $content .= "\t<url>\r\n";
578
- if ( $page_is_front ) {
579
- $content .= "\t\t<loc>" . $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'home' => true ) ) . "</loc>\r\n";
580
- } else {
581
- $content .= "\t\t<loc>" . $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'post' => $page, 'id' => $page_id ) ) . "</loc>\r\n";
582
- }
583
 
584
  // Keep it consistent. Only parse if page_lastmod is true.
585
- if ( $page_lastmod || ( $page_is_front && $home_lastmod ) ) {
586
  $page_modified_gmt = $page->post_modified_gmt;
587
 
588
  if ( '0000-00-00 00:00:00' !== $page_modified_gmt )
589
  $content .= "\t\t<lastmod>" . $this->gmt2date( $timestamp_format, $page_modified_gmt ) . "</lastmod>\r\n";
590
  }
591
 
592
- // Give higher priority to the home page.
593
- $priority_page = $page_is_front ? 1 : 0.9;
594
-
595
- $content .= "\t\t<priority>" . number_format( $priority_page, 1 ) . "</priority>\r\n";
596
  $content .= "\t</url>\r\n";
597
  }
598
  }
@@ -630,7 +720,7 @@ class Sitemaps extends Metaboxes {
630
  $wp_query->query = $wp_query->query_vars = \wp_parse_args( $args, $defaults );
631
  $latest_posts = $wp_query->get_posts();
632
  }
633
- $latest_posts_amount = (int) count( $latest_posts );
634
 
635
  if ( $latest_posts_amount > 0 ) :
636
  /**
@@ -650,11 +740,11 @@ class Sitemaps extends Metaboxes {
650
  */
651
  $prioritydiff = 0;
652
 
653
- if ( $latest_posts_amount > (int) 1 )
654
  $prioritydiff = 0.9 / $latest_posts_amount;
655
 
656
  // Keep it consistent. Only remove 0.1 when we only have a few posts.
657
- if ( $latest_posts_amount <= (int) 9 && $latest_posts_amount > (int) 1 )
658
  $prioritydiff = 0.1;
659
 
660
  /**
@@ -694,7 +784,7 @@ class Sitemaps extends Metaboxes {
694
  $priority = $priority - $prioritydiff;
695
 
696
  // Cast away negative numbers.
697
- $priority = $priority <= (int) 0 ? (int) 0 : (float) $priority;
698
  }
699
  }
700
  endif;
@@ -753,7 +843,7 @@ class Sitemaps extends Metaboxes {
753
  $latest_cpt_posts = $wp_query->get_posts();
754
  }
755
  endif;
756
- $latest_cpt_posts_amount = (int) count( $latest_cpt_posts );
757
 
758
  if ( $latest_cpt_posts_amount > 0 ) :
759
 
@@ -767,11 +857,11 @@ class Sitemaps extends Metaboxes {
767
 
768
  $prioritydiff_cpt = 0;
769
 
770
- if ( $latest_cpt_posts_amount > (int) 1 )
771
  $prioritydiff_cpt = 0.9 / $latest_cpt_posts_amount;
772
 
773
  // Keep it consistent. Only remove 0.1 when we only have a few posts.
774
- if ( $latest_cpt_posts_amount <= (int) 9 && $latest_cpt_posts_amount > (int) 1 )
775
  $prioritydiff_cpt = 0.1;
776
 
777
  /**
@@ -812,7 +902,7 @@ class Sitemaps extends Metaboxes {
812
  $priority_cpt = $priority_cpt - $prioritydiff_cpt;
813
 
814
  // Cast away negative numbers.
815
- $priority_cpt = $priority_cpt <= (int) 0 ? (int) 0 : (float) $priority_cpt;
816
  }
817
  }
818
  endif;
305
  if ( $this->the_seo_framework_debug ) {
306
  echo "\r\n" . '<!-- Site estimated peak usage: ' . number_format( memory_get_peak_usage() / 1024 / 1024, 3 ) . ' MB -->';
307
  echo "\r\n" . '<!-- System estimated peak usage: ' . number_format( memory_get_peak_usage( true ) / 1024 / 1024, 3 ) . ' MB -->';
308
+ echo "\r\n" . '<!-- Freed memory prior to generation: ' . number_format( $this->clean_up_globals_for_sitemap( true ) / 1024, 3 ) . ' kB -->';
309
  echo "\r\n" . '<!-- Sitemap generation time: ' . ( number_format( microtime( true ) - $timer_start, 6 ) ) . ' seconds -->';
310
  }
311
  }
474
  * Maximum pages and posts to fetch.
475
  * A total of 2100, consisting of 3 times $max_posts
476
  *
477
+ * @since 2.2.9
478
+ *
479
  * Applies filters the_seo_framework_sitemap_pages_count : int max pages
480
  * Applies filters the_seo_framework_sitemap_posts_count : int max posts
481
  * Applies filters the_seo_framework_sitemap_custom_posts_count : int max posts
550
  $wp_query->query = $wp_query->query_vars = \wp_parse_args( $args, $defaults );
551
  $latest_pages = $wp_query->get_posts();
552
  }
553
+ $latest_pages_amount = count( $latest_pages );
554
 
555
  if ( $latest_pages_amount > 0 ) :
556
 
557
+ $page_on_front = $this->has_page_on_front();
558
+ $page_on_front_id = (int) \get_option( 'page_on_front' );
559
+ $page_for_posts_id = (int) \get_option( 'page_for_posts' );
560
+
561
+ $id_on_front = $page_on_front ? $page_on_front_id : (int) $page_for_posts_id;
562
+
563
+ //* Remove ID on front from list and add frontpage to list.
564
+ if ( $page_on_front && false !== $key_on_front = array_search( $id_on_front, $latest_pages, true ) ) {
565
+ unset( $latest_pages[ $key_on_front ] );
566
+ }
567
+
568
+ //* Render frontpage.
569
+ if ( '' === $excluded || empty( $excluded[ $id_on_front ] ) ) :
570
+ //* Fetch the noindex option from the page and homepage.
571
+ $indexed = ! $this->get_option( 'homepage_noindex' ) && ( ! $id_on_front || ! $this->get_custom_field( '_genesis_noindex', $id_on_front ) );
572
+
573
+ //* Continue if indexed.
574
+ if ( $indexed ) {
575
+ $content .= "\t<url>\r\n";
576
+ $content .= "\t\t<loc>" . $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'home' => true ) ) . "</loc>\r\n";
577
+
578
+ // Keep it consistent. Only parse if page_lastmod is true.
579
+ if ( $home_lastmod ) {
580
+ if ( $page_on_front ) {
581
+ $front_object = \get_post( $id_on_front );
582
+ $front_modified_gmt = isset( $front_object->post_modified_gmt ) ? $front_object->post_modified_gmt : '0000-00-00 00:00:00';
583
+ } else {
584
+ $args = array(
585
+ 'numberposts' => 1,
586
+ 'post_type' => 'post',
587
+ 'post_status' => 'publish',
588
+ 'orderby' => 'post_date',
589
+ 'order' => 'DESC',
590
+ 'offset' => 0,
591
+ );
592
+ $post = \wp_get_recent_posts( $args, OBJECT );
593
+ $front_object = isset( $post[0] ) ? $post[0] : null;
594
+ unset( $post );
595
+ $front_modified_gmt = isset( $front_object->post_date_gmt ) ? $front_object->post_date_gmt : '0000-00-00 00:00:00';
596
+ }
597
+
598
+ if ( '0000-00-00 00:00:00' !== $front_modified_gmt )
599
+ $content .= "\t\t<lastmod>" . $this->gmt2date( $timestamp_format, $front_modified_gmt ) . "</lastmod>\r\n";
600
+ }
601
+
602
+ $content .= "\t\t<priority>1.0</priority>\r\n";
603
+ $content .= "\t</url>\r\n";
604
+ }
605
+ endif;
606
+
607
+ //* Render the page for posts.
608
+ if ( $page_on_front && $page_for_posts_id ) :
609
+
610
+ //* Remove ID for blog from list and add frontpage to list.
611
+ if ( false !== $key_for_posts = array_search( $page_for_posts_id, $latest_pages, true ) ) {
612
+ unset( $latest_pages[ $key_for_posts ] );
613
+ }
614
+
615
+ if ( '' === $excluded || empty( $excluded[ $page_for_posts_id ] ) ) :
616
+ //* Fetch the noindex option from the page and homepage.
617
+ $indexed = ! $this->get_custom_field( '_genesis_noindex', $page_for_posts_id );
618
+ $page = \get_post( $page_for_posts_id );
619
+
620
+ //* Continue if indexed.
621
+ if ( $indexed && isset( $page->ID ) ) {
622
+ $content .= "\t<url>\r\n";
623
+ $content .= "\t\t<loc>" . $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'post' => $page, 'id' => $page_for_posts_id ) ) . "</loc>\r\n";
624
+
625
+ // Keep it consistent. Only parse if page_lastmod is true.
626
+ if ( $page_lastmod ) {
627
+ $args = array(
628
+ 'numberposts' => 1,
629
+ 'post_type' => 'post',
630
+ 'post_status' => 'publish',
631
+ 'orderby' => 'post_date',
632
+ 'order' => 'DESC',
633
+ 'offset' => 0,
634
+ );
635
+ $post = \wp_get_recent_posts( $args, OBJECT );
636
+ $lastest_post = isset( $post[0] ) ? $post[0] : null;
637
+ $latest_post_published_gmt = isset( $lastest_post->post_date_gmt ) ? $lastest_post->post_date_gmt : '0000-00-00 00:00:00';
638
+ $page_for_posts_modified_gmt = $page->post_modified_gmt;
639
+
640
+ if ( strtotime( $latest_post_published_gmt ) > strtotime( $page_for_posts_modified_gmt ) ) {
641
+ $page_modified_gmt = $latest_post_published_gmt;
642
+ } else {
643
+ $page_modified_gmt = $page_for_posts_modified_gmt;
644
+ }
645
+
646
+ if ( '0000-00-00 00:00:00' !== $page_modified_gmt )
647
+ $content .= "\t\t<lastmod>" . $this->gmt2date( $timestamp_format, $page_modified_gmt ) . "</lastmod>\r\n";
648
+ }
649
+
650
+ $content .= "\t\t<priority>0.9</priority>\r\n";
651
+ $content .= "\t</url>\r\n";
652
+ }
653
+ endif;
654
+
655
+ endif;
656
 
657
  /**
658
  * This can be heavy.
671
 
672
  //* Continue if indexed.
673
  if ( $indexed ) {
 
 
 
674
  $content .= "\t<url>\r\n";
675
+ $content .= "\t\t<loc>" . $this->the_url( '', array( 'get_custom_field' => false, 'external' => true, 'post' => $page, 'id' => $page_id ) ) . "</loc>\r\n";
 
 
 
 
676
 
677
  // Keep it consistent. Only parse if page_lastmod is true.
678
+ if ( $page_lastmod ) {
679
  $page_modified_gmt = $page->post_modified_gmt;
680
 
681
  if ( '0000-00-00 00:00:00' !== $page_modified_gmt )
682
  $content .= "\t\t<lastmod>" . $this->gmt2date( $timestamp_format, $page_modified_gmt ) . "</lastmod>\r\n";
683
  }
684
 
685
+ $content .= "\t\t<priority>0.9</priority>\r\n";
 
 
 
686
  $content .= "\t</url>\r\n";
687
  }
688
  }
720
  $wp_query->query = $wp_query->query_vars = \wp_parse_args( $args, $defaults );
721
  $latest_posts = $wp_query->get_posts();
722
  }
723
+ $latest_posts_amount = count( $latest_posts );
724
 
725
  if ( $latest_posts_amount > 0 ) :
726
  /**
740
  */
741
  $prioritydiff = 0;
742
 
743
+ if ( $latest_posts_amount > 1 )
744
  $prioritydiff = 0.9 / $latest_posts_amount;
745
 
746
  // Keep it consistent. Only remove 0.1 when we only have a few posts.
747
+ if ( $latest_posts_amount <= 9 && $latest_posts_amount > 1 )
748
  $prioritydiff = 0.1;
749
 
750
  /**
784
  $priority = $priority - $prioritydiff;
785
 
786
  // Cast away negative numbers.
787
+ $priority = $priority <= 0 ? 0 : (float) $priority;
788
  }
789
  }
790
  endif;
843
  $latest_cpt_posts = $wp_query->get_posts();
844
  }
845
  endif;
846
+ $latest_cpt_posts_amount = count( $latest_cpt_posts );
847
 
848
  if ( $latest_cpt_posts_amount > 0 ) :
849
 
857
 
858
  $prioritydiff_cpt = 0;
859
 
860
+ if ( $latest_cpt_posts_amount > 1 )
861
  $prioritydiff_cpt = 0.9 / $latest_cpt_posts_amount;
862
 
863
  // Keep it consistent. Only remove 0.1 when we only have a few posts.
864
+ if ( $latest_cpt_posts_amount <= 9 && $latest_cpt_posts_amount > 1 )
865
  $prioritydiff_cpt = 0.1;
866
 
867
  /**
902
  $priority_cpt = $priority_cpt - $prioritydiff_cpt;
903
 
904
  // Cast away negative numbers.
905
+ $priority_cpt = $priority_cpt <= 0 ? 0 : (float) $priority_cpt;
906
  }
907
  }
908
  endif;
inc/classes/term-data.class.php CHANGED
@@ -101,12 +101,13 @@ class Term_Data extends Post_Data {
101
  *
102
  * @since 2.7.0
103
  *
104
- * @since 2.1.8:
105
- * Applies filters array the_seo_framework_term_meta_defaults : Array of default term SEO options
106
- *
107
  * @return array The Term Metadata default options.
108
  */
109
  public function get_term_meta_defaults() {
 
 
 
 
110
  return (array) \apply_filters( 'the_seo_framework_term_meta_defaults', array(
111
  'doctitle' => '',
112
  'description' => '',
@@ -129,11 +130,12 @@ class Term_Data extends Post_Data {
129
  */
130
  public function update_term_meta( $term_id, $tt_id, $taxonomy = '' ) {
131
 
132
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
133
  return;
134
 
135
  //* Check again against ambiguous injection.
136
- if ( isset( $_POST['_wpnonce'] ) && \wp_verify_nonce( $_POST['_wpnonce'], 'update-tag_' . $term_id ) ) {
 
137
  $data = isset( $_POST['autodescription-meta'] ) ? (array) $_POST['autodescription-meta'] : array();
138
  $data = \wp_parse_args( $data, $this->get_term_meta_defaults() );
139
 
@@ -160,7 +162,7 @@ class Term_Data extends Post_Data {
160
  endforeach;
161
 
162
  \update_term_meta( $term_id, THE_SEO_FRAMEWORK_TERM_OPTIONS, $data );
163
- }
164
  }
165
 
166
  /**
101
  *
102
  * @since 2.7.0
103
  *
 
 
 
104
  * @return array The Term Metadata default options.
105
  */
106
  public function get_term_meta_defaults() {
107
+ /**
108
+ * Applies filters 'the_seo_framework_term_meta_defaults' : Array
109
+ * @since 2.1.8
110
+ */
111
  return (array) \apply_filters( 'the_seo_framework_term_meta_defaults', array(
112
  'doctitle' => '',
113
  'description' => '',
130
  */
131
  public function update_term_meta( $term_id, $tt_id, $taxonomy = '' ) {
132
 
133
+ if ( $this->doing_ajax() )
134
  return;
135
 
136
  //* Check again against ambiguous injection.
137
+ if ( isset( $_POST['_wpnonce'] ) && \wp_verify_nonce( $_POST['_wpnonce'], 'update-tag_' . $term_id ) ) :
138
+
139
  $data = isset( $_POST['autodescription-meta'] ) ? (array) $_POST['autodescription-meta'] : array();
140
  $data = \wp_parse_args( $data, $this->get_term_meta_defaults() );
141
 
162
  endforeach;
163
 
164
  \update_term_meta( $term_id, THE_SEO_FRAMEWORK_TERM_OPTIONS, $data );
165
+ endif;
166
  }
167
 
168
  /**
inc/compat/plugin-bbpress.php CHANGED
@@ -33,3 +33,176 @@ function _bbpress_filter_order_keys( $current_keys = array() ) {
33
 
34
  return array_merge( $current_keys, $new_keys );
35
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  return array_merge( $current_keys, $new_keys );
35
  }
36
+
37
+ \add_filter( 'the_seo_framework_pre_add_title', __NAMESPACE__ . '\\_bbpress_filter_pre_title', 10, 3 );
38
+ /**
39
+ * Fixes bbPress Titles.
40
+ *
41
+ * bbPress has a hard time maintaining WordPress' query after the original query.
42
+ * Reasons unknown.
43
+ * This function fixes the Title part.
44
+ *
45
+ * @since 2.9.0
46
+ * @access private
47
+ *
48
+ * @param string $title The filter title.
49
+ * @param array $args The title arguments.
50
+ * @param bool $escape Whether the output will be sanitized.
51
+ * @return string $title The bbPress title.
52
+ */
53
+ function _bbpress_filter_pre_title( $title = '', $args = array(), $escape = true ) {
54
+
55
+ if ( \is_bbpress() ) {
56
+
57
+ if ( \bbp_is_topic_tag() ) {
58
+
59
+ $term = \get_queried_object();
60
+ $data = \the_seo_framework()->get_term_data( $term, $term->term_id );
61
+
62
+ if ( ! empty( $data['doctitle'] ) ) {
63
+ $title = $data['doctitle'];
64
+ } else {
65
+ $title = $term->name ?: \the_seo_framework()->untitled();
66
+ }
67
+ }
68
+ }
69
+
70
+ return $title;
71
+ }
72
+
73
+ \add_filter( 'the_seo_framework_url_path', __NAMESPACE__ . '\\_bbpress_filter_url_path', 10, 3 );
74
+ /**
75
+ * Fixes bbPress URLs.
76
+ *
77
+ * bbPress has a hard time maintaining WordPress' query after the original query.
78
+ * Reasons unknown.
79
+ * This function fixes the URl path part.
80
+ *
81
+ * @since 2.9.0
82
+ * @access private
83
+ *
84
+ * @param string $path The current path.
85
+ * @param int $id The page/post ID.
86
+ * @param bool $external Whether the request is external (i.e. sitemap)
87
+ * @return string The URL path.
88
+ */
89
+ function _bbpress_filter_url_path( $path, $id = 0, $external = false ) {
90
+
91
+ if ( $external || ! $id )
92
+ return $path;
93
+
94
+ if ( '' !== \the_seo_framework()->permalink_structure() && \is_bbpress() ) :
95
+
96
+ if ( \bbp_is_single_user_topics() ) {
97
+ // User's topics
98
+ $base = \bbp_get_user_topics_created_url( \bbp_get_displayed_user_id() );
99
+
100
+ } elseif ( \bbp_is_favorites() ) {
101
+ // User's favorites
102
+ $base = \bbp_get_favorites_permalink( \bbp_get_displayed_user_id() );
103
+
104
+ } elseif ( \bbp_is_subscriptions() ) {
105
+ // User's subscriptions
106
+ $base = \bbp_get_subscriptions_permalink( \bbp_get_displayed_user_id() );
107
+
108
+ } elseif ( \bbp_is_single_user() ) {
109
+ // Root profile page
110
+ $base = \bbp_get_user_profile_url( \bbp_get_displayed_user_id() );
111
+
112
+ } elseif ( \bbp_is_single_view() ) {
113
+ // View
114
+ $base = \bbp_get_view_url();
115
+
116
+ } elseif ( \bbp_is_topic_tag() ) {
117
+ // Topic tag
118
+ $base = \bbp_get_topic_tag_link();
119
+
120
+ } elseif ( \is_page() || \is_single() ) {
121
+ // Page/post, skip.
122
+ $base = null;
123
+
124
+ } elseif ( \bbp_is_forum_archive() ) {
125
+ // Forum archive
126
+ $base = \bbp_get_forums_url();
127
+
128
+ } elseif ( \bbp_is_topic_archive() ) {
129
+ // Topic archive
130
+ $base = \bbp_get_topics_url();
131
+ }
132
+
133
+ if ( isset( $base ) )
134
+ $path = \the_seo_framework()->set_url_scheme( $base, 'relative', true );
135
+ endif;
136
+
137
+ return $path;
138
+ }
139
+
140
+ \add_filter( 'the_seo_framework_fetched_description_excerpt', __NAMESPACE__ . '\\_bbpress_filter_excerpt_generation', 10, 4 );
141
+ /**
142
+ * Fixes bbPress excerpts.
143
+ *
144
+ * bbPress has a hard time maintaining WordPress' query after the original query.
145
+ * Reasons unknown.
146
+ * This function fixes the Excerpt part.
147
+ *
148
+ * @since 2.9.0
149
+ * @access private
150
+ *
151
+ * @param string $excerpt The excerpt to use.
152
+ * @param bool $page_id The current page/term ID
153
+ * @param object|mixed $term The current term.
154
+ * @param int $max_char_length Determines the maximum length of excerpt after trimming.
155
+ * @return string The excerpt.
156
+ */
157
+ function _bbpress_filter_excerpt_generation( $excerpt = '', $page_id = 0, $term = '', $max_char_length = 155 ) {
158
+
159
+ if ( \is_bbpress() ) {
160
+
161
+ if ( \bbp_is_topic_tag() ) {
162
+
163
+ $term = \get_queried_object();
164
+
165
+ $description = $term->description ?: '';
166
+
167
+ //* Always overwrite.
168
+ $excerpt = \the_seo_framework()->s_description_raw( $description );
169
+ }
170
+ }
171
+
172
+ return $excerpt;
173
+ }
174
+
175
+ \add_filter( 'the_seo_framework_custom_field_description', __NAMESPACE__ . '\_bbpress_filter_custom_field_description' );
176
+ /**
177
+ * Fixes bbPress custom Description.
178
+ *
179
+ * bbPress has a hard time maintaining WordPress' query after the original query.
180
+ * Reasons unknown.
181
+ * This function fixes the Custom Description part.
182
+ *
183
+ * @since 2.9.0
184
+ * @access private
185
+ *
186
+ * @param string $description The description.
187
+ * @param array $args The description arguments.
188
+ * @return string The custom description.
189
+ */
190
+ function _bbpress_filter_custom_field_description( $description = '', $args = array() ) {
191
+
192
+ if ( \is_bbpress() ) {
193
+
194
+ if ( \bbp_is_topic_tag() ) {
195
+
196
+ $term = \get_queried_object();
197
+ $data = \the_seo_framework()->get_term_data( $term, $term->term_id );
198
+
199
+ if ( ! empty( $data['description'] ) ) {
200
+ $description = $data['description'];
201
+ } else {
202
+ $description = '';
203
+ }
204
+ }
205
+ }
206
+
207
+ return $description;
208
+ }
inc/compat/plugin-wpmudev-dm.php CHANGED
@@ -101,9 +101,16 @@ function _wpmudev_domainmap_get_url( $path, $get_scheme = false ) {
101
  $scheme = \the_seo_framework()->is_ssl() ? '1' : '0';
102
 
103
  if ( '1' === $scheme ) {
 
104
  $scheme_full = 'https://';
105
  $scheme = 'https';
 
 
 
 
 
106
  } else {
 
107
  $scheme_full = 'http://';
108
  $scheme = 'http';
109
  }
101
  $scheme = \the_seo_framework()->is_ssl() ? '1' : '0';
102
 
103
  if ( '1' === $scheme ) {
104
+ //* HTTPS
105
  $scheme_full = 'https://';
106
  $scheme = 'https';
107
+ } elseif ( '2' === $scheme ) {
108
+ //* HTTP/HTTPS, use preferred scheme and build URL expected (https).
109
+ // This will be converted back anyway later if preferred is http.
110
+ $scheme_full = 'https://';
111
+ $scheme = '';
112
  } else {
113
+ //* HTTP
114
  $scheme_full = 'http://';
115
  $scheme = 'http';
116
  }
inc/functions/upgrade.php CHANGED
@@ -60,13 +60,19 @@ function the_seo_framework_do_upgrade() {
60
  if ( get_option( 'the_seo_framework_upgraded_db_version' ) < '2802' )
61
  the_seo_framework_do_upgrade_2802();
62
 
 
 
 
63
  do_action( 'the_seo_framework_upgraded' );
64
  }
65
 
 
66
  add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_to_current' );
67
  /**
68
- * Upgrades the Database version to the latest version if all iterations have been
69
- * executed. This ensure this file will no longer be required.
 
 
70
  * This should run once after every plugin update.
71
  *
72
  * @since 2.7.0
@@ -75,6 +81,42 @@ function the_seo_framework_upgrade_to_current() {
75
  update_option( 'the_seo_framework_upgraded_db_version', THE_SEO_FRAMEWORK_DB_VERSION );
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  /**
79
  * Upgrades term metadata for version 2701.
80
  *
@@ -106,3 +148,27 @@ function the_seo_framework_do_upgrade_2802() {
106
 
107
  update_option( 'the_seo_framework_upgraded_db_version', '2802' );
108
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  if ( get_option( 'the_seo_framework_upgraded_db_version' ) < '2802' )
61
  the_seo_framework_do_upgrade_2802();
62
 
63
+ if ( get_option( 'the_seo_framework_upgraded_db_version' ) < '2900' )
64
+ the_seo_framework_do_upgrade_2900();
65
+
66
  do_action( 'the_seo_framework_upgraded' );
67
  }
68
 
69
+
70
  add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_to_current' );
71
  /**
72
+ * Upgrades the Database version to the latest version.
73
+ *
74
+ * This happens if all iterations have been executed. This ensure this file will
75
+ * no longer be required.
76
  * This should run once after every plugin update.
77
  *
78
  * @since 2.7.0
81
  update_option( 'the_seo_framework_upgraded_db_version', THE_SEO_FRAMEWORK_DB_VERSION );
82
  }
83
 
84
+ /**
85
+ * Lists and returns upgrade notices to be outputted in admin.
86
+ *
87
+ * @since 2.9.0
88
+ * @staticvar array $cache The cached notice strings.
89
+ *
90
+ * @param string $notice The upgrade notice.
91
+ * @param bool $get Whether to return the upgrade notices.
92
+ * @return array|void The notices when $get is true.
93
+ */
94
+ function the_seo_framework_add_upgrade_notice( $notice = '', $get = false ) {
95
+
96
+ static $cache = array();
97
+
98
+ if ( $get )
99
+ return $cache;
100
+
101
+ $cache[] = $notice;
102
+ }
103
+
104
+ add_action( 'admin_notices', 'the_seo_framework_output_upgrade_notices' );
105
+ /**
106
+ * Outputs available upgrade notices.
107
+ *
108
+ * @since 2.9.0
109
+ * @uses the_seo_framework_add_upgrade_notice()
110
+ */
111
+ function the_seo_framework_output_upgrade_notices() {
112
+
113
+ $notices = the_seo_framework_add_upgrade_notice( '', true );
114
+
115
+ foreach ( $notices as $notice ) {
116
+ the_seo_framework()->do_dismissible_notice( $notice, 'updated' );
117
+ }
118
+ }
119
+
120
  /**
121
  * Upgrades term metadata for version 2701.
122
  *
148
 
149
  update_option( 'the_seo_framework_upgraded_db_version', '2802' );
150
  }
151
+
152
+
153
+ /**
154
+ * Updates Twitter 'photo' card option to 'summary_large_image'.
155
+ * Invalidates object cache if changed.
156
+ *
157
+ * @since 2.8.0
158
+ */
159
+ function the_seo_framework_do_upgrade_2900() {
160
+
161
+ $tsf = the_seo_framework();
162
+
163
+ $card_type = trim( esc_attr( $tsf->get_option( 'twitter_card', false ) ) );
164
+
165
+ if ( 'photo' === $card_type ) {
166
+ $tsf->update_option( 'twitter_card', 'summary_large_image' );
167
+ $tsf->delete_object_cache();
168
+ the_seo_framework_add_upgrade_notice(
169
+ esc_html__( 'Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable.', 'autodescription' )
170
+ );
171
+ }
172
+
173
+ update_option( 'the_seo_framework_upgraded_db_version', '2900' );
174
+ }
inc/views/debug/output.php CHANGED
@@ -18,7 +18,7 @@ if ( The_SEO_Framework\Debug::has_debug_output() ) :
18
  $taxonomy = isset( $term->taxonomy ) ? $term->taxonomy : '';
19
 
20
  //* This will return 'Page' on all non-archive types (except the home page)
21
- $type = ! $this->is_archive() && $this->is_front_page( $id ) ? 'Front Page' : $this->get_the_term_name( $term );
22
  $cache_key = $this->generate_cache_key( $this->get_the_real_ID(), $taxonomy );
23
 
24
  if ( $this->is_admin() ) {
18
  $taxonomy = isset( $term->taxonomy ) ? $term->taxonomy : '';
19
 
20
  //* This will return 'Page' on all non-archive types (except the home page)
21
+ $type = ! $this->is_archive() && $this->is_real_front_page() || $this->is_front_page_by_id( $id ) ? 'Front Page' : $this->get_the_term_name( $term );
22
  $cache_key = $this->generate_cache_key( $this->get_the_real_ID(), $taxonomy );
23
 
24
  if ( $this->is_admin() ) {
inc/views/inpost/seo-settings-singular.php ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package The_SEO_Framework\Views\Inpost
4
+ */
5
+
6
+ defined( 'ABSPATH' ) and $_this = the_seo_framework_class() and $this instanceof $_this or die;
7
+
8
+ //* Fetch the required instance within this file.
9
+ $instance = $this->get_view_instance( 'inpost', $instance );
10
+
11
+ //* Setup default vars.
12
+ $post_id = $this->get_the_real_ID();
13
+ $type = isset( $type ) ? $type : '';
14
+ $language = $this->google_language();
15
+
16
+ switch ( $instance ) :
17
+ case 'inpost_main' :
18
+ /**
19
+ * Parse inpost tabs content.
20
+ *
21
+ * @since 2.9.0
22
+ * @see $this->call_function()
23
+ * @see PHP call_user_func_array() For args.
24
+ *
25
+ * @param array $default_tabs { 'id' = The identifier =>
26
+ * array(
27
+ * 'name' => The name
28
+ * 'callback' => The callback function, use array for method calling
29
+ * 'dashicon' => Desired dashicon
30
+ * 'args' => Callback parameters
31
+ * )
32
+ * }
33
+ */
34
+ $default_tabs = array(
35
+ 'general' => array(
36
+ 'name' => __( 'General', 'autodescription' ),
37
+ 'callback' => array( $this, 'singular_inpost_box_general_tab' ),
38
+ 'dashicon' => 'admin-generic',
39
+ 'args' => array( $type ),
40
+ ),
41
+ 'visibility' => array(
42
+ 'name' => __( 'Visibility', 'autodescription' ),
43
+ 'callback' => array( $this, 'singular_inpost_box_visibility_tab' ),
44
+ 'dashicon' => 'visibility',
45
+ 'args' => array( $type ),
46
+ ),
47
+ 'social' => array(
48
+ 'name' => __( 'Social', 'autodescription' ),
49
+ 'callback' => array( $this, 'singular_inpost_box_social_tab' ),
50
+ 'dashicon' => 'share',
51
+ 'args' => array( $type ),
52
+ ),
53
+ );
54
+
55
+ /**
56
+ * Applies filters 'the_seo_framework_inpost_settings_tabs' : array
57
+ *
58
+ * Allows for altering the inpost SEO settings metabox tabs.
59
+ *
60
+ * @since 2.9.0
61
+ *
62
+ * @param array $default_tabs The default tabs.
63
+ * @param array $type The current post type display name, like "Post", "Page", "Product".
64
+ */
65
+ $tabs = (array) apply_filters( 'the_seo_framework_inpost_settings_tabs', $default_tabs, $type );
66
+
67
+ echo '<div class="tsf-flex tsf-flex-inside-wrap">';
68
+ $this->inpost_flex_nav_tab_wrapper( 'inpost', $tabs, '2.6.0' );
69
+ echo '</div>';
70
+ break;
71
+
72
+ case 'inpost_general' :
73
+
74
+ //* Temporarily. TODO refactor.
75
+ $tit_len_parsed = $desc_len_parsed = 0;
76
+ $doctitle_placeholder = $description_placeholder = '';
77
+ $this->_get_inpost_general_tab_vars( $tit_len_parsed, $doctitle_placeholder, $desc_len_parsed, $description_placeholder );
78
+ //= End temporarily.
79
+
80
+ if ( $this->is_option_checked( 'display_seo_bar_metabox' ) ) :
81
+ ?>
82
+ <div class="tsf-flex-setting tsf-flex">
83
+ <div class="tsf-flex-setting-label tsf-flex">
84
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
85
+ <div class="tsf-flex-setting-label-item tsf-flex">
86
+ <div><strong><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></strong></div>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ <div class="tsf-flex-setting-input tsf-flex">
91
+ <div>
92
+ <?php $this->post_status( $post_id, 'inpost', true ); ?>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ <?php
97
+ endif;
98
+
99
+ ?>
100
+ <div class="tsf-flex-setting tsf-flex">
101
+ <div class="tsf-flex-setting-label tsf-flex">
102
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
103
+ <label for="autodescription_title" class="tsf-flex-setting-label-item tsf-flex">
104
+ <div><strong><?php printf( esc_html__( 'Custom %s Title', 'autodescription' ), esc_html( $type ) ); ?></strong></div>
105
+ <div><?php $this->make_info( __( 'Recommended Length: 50 to 55 characters', 'autodescription' ), 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#3' ); ?></div>
106
+ </label>
107
+ <span class="description tsf-counter">
108
+ <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription_title_chars">' . (int) mb_strlen( $tit_len_parsed ) . '</span>' ); ?>
109
+ <span class="hide-if-no-js tsf-ajax"></span>
110
+ </span>
111
+ </div>
112
+ </div>
113
+ <div class="tsf-flex-setting-input tsf-flex">
114
+ <div id="tsf-title-wrap">
115
+ <input class="large-text" type="text" name="autodescription[_genesis_title]" id="autodescription_title" placeholder="<?php echo esc_attr( $doctitle_placeholder ); ?>" value="<?php echo esc_attr( $this->get_custom_field( '_genesis_title' ) ); ?>" />
116
+ <span id="tsf-title-offset" class="hide-if-no-js"></span><span id="tsf-title-placeholder" class="hide-if-no-js"></span>
117
+ </div>
118
+ </div>
119
+ </div>
120
+
121
+
122
+ <div class="tsf-flex-setting tsf-flex">
123
+ <div class="tsf-flex-setting-label tsf-flex">
124
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
125
+ <label for="autodescription_description" class="tsf-flex-setting-label-item tsf-flex">
126
+ <div><strong><?php printf( esc_html__( 'Custom %s Description', 'autodescription' ), esc_html( $type ) ); ?></strong></div>
127
+ <div><?php $this->make_info( __( 'Recommended Length: 145 to 155 characters', 'autodescription' ), 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#1' ); ?></div>
128
+ </label>
129
+ <span class="description tsf-counter">
130
+ <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription_description_chars">' . (int) mb_strlen( $desc_len_parsed ) . '</span>' ); ?>
131
+ <span class="hide-if-no-js tsf-ajax"></span>
132
+ </span>
133
+ </div>
134
+ </div>
135
+ <div class="tsf-flex-setting-input tsf-flex">
136
+ <textarea class="large-text" name="autodescription[_genesis_description]" id="autodescription_description" placeholder="<?php echo esc_attr( $description_placeholder ); ?>" rows="4" cols="4"><?php echo esc_attr( $this->get_custom_field( '_genesis_description' ) ); ?></textarea>
137
+ </div>
138
+ </div>
139
+ <?php
140
+ break;
141
+
142
+ case 'inpost_visibility' :
143
+ //* Fetch Canonical URL.
144
+ $canonical = $this->get_custom_field( '_genesis_canonical_uri' );
145
+ //* Fetch Canonical URL Placeholder.
146
+ $canonical_placeholder = $this->the_url_from_cache( '', $post_id, false, false );
147
+
148
+ ?>
149
+ <div class="tsf-flex-setting tsf-flex">
150
+ <div class="tsf-flex-setting-label tsf-flex">
151
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
152
+ <label for="autodescription_canonical" class="tsf-flex-setting-label-item tsf-flex">
153
+ <div><strong><?php esc_html_e( 'Custom Canonical URL', 'autodescription' ); ?></strong></div>
154
+ <div><?php $this->make_info( sprintf( __( 'Preferred %s URL location', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/139066?hl=' . $language ); ?></div>
155
+ </label>
156
+ </div>
157
+ </div>
158
+ <div class="tsf-flex-setting-input tsf-flex">
159
+ <input class="large-text" type="text" name="autodescription[_genesis_canonical_uri]" id="autodescription_canonical" placeholder="<?php echo esc_url( $canonical_placeholder ); ?>" value="<?php echo esc_url( $this->get_custom_field( '_genesis_canonical_uri' ) ); ?>" />
160
+ </div>
161
+ </div>
162
+
163
+ <div class="tsf-flex-setting tsf-flex">
164
+ <div class="tsf-flex-setting-label tsf-flex">
165
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
166
+ <div class="tsf-flex-setting-label-item tsf-flex">
167
+ <div><strong><?php esc_html_e( 'Robots Meta Settings', 'autodescription' ); ?></strong></div>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ <div class="tsf-flex-setting-input tsf-flex">
172
+ <div class="tsf-checkbox-wrapper">
173
+ <label for="autodescription_noindex">
174
+ <input type="checkbox" name="autodescription[_genesis_noindex]" id="autodescription_noindex" value="1" <?php checked( $this->get_custom_field( '_genesis_noindex' ) ); ?> />
175
+ <?php
176
+ /* translators: 1: Option, 2: Post or Page */
177
+ printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noindex' ), esc_html( $type ) );
178
+ echo ' ';
179
+ $this->make_info( sprintf( __( 'Tell Search Engines not to show this %s in their search results', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/93710?hl=' . $language );
180
+ ?>
181
+ </label>
182
+ </div>
183
+ <div class="tsf-checkbox-wrapper">
184
+ <label for="autodescription_nofollow"><input type="checkbox" name="autodescription[_genesis_nofollow]" id="autodescription_nofollow" value="1" <?php checked( $this->get_custom_field( '_genesis_nofollow' ) ); ?> />
185
+ <?php
186
+ /* translators: 1: Option, 2: Post or Page */
187
+ printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'nofollow' ), esc_html( $type ) );
188
+ echo ' ';
189
+ $this->make_info( sprintf( __( 'Tell Search Engines not to follow links on this %s', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/96569?hl=' . $language );
190
+ ?>
191
+ </label>
192
+ </div>
193
+ <div class="tsf-checkbox-wrapper">
194
+ <label for="autodescription_noarchive"><input type="checkbox" name="autodescription[_genesis_noarchive]" id="autodescription_noarchive" value="1" <?php checked( $this->get_custom_field( '_genesis_noarchive' ) ); ?> />
195
+ <?php
196
+ /* translators: 1: Option, 2: Post or Page */
197
+ printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noarchive' ), esc_html( $type ) );
198
+ echo ' ';
199
+ $this->make_info( sprintf( __( 'Tell Search Engines not to save a cached copy of this %s', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/79812?hl=' . $language );
200
+ ?>
201
+ </label>
202
+ </div>
203
+ </div>
204
+ </div>
205
+
206
+ <div class="tsf-flex-setting tsf-flex">
207
+ <div class="tsf-flex-setting-label tsf-flex">
208
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
209
+ <div class="tsf-flex-setting-label-item tsf-flex">
210
+ <div><strong><?php esc_html_e( 'Local Search Settings', 'autodescription' ); ?></strong></div>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ <div class="tsf-flex-setting-input tsf-flex">
215
+ <div class="tsf-checkbox-wrapper">
216
+ <label for="autodescription_exclude_local_search"><input type="checkbox" name="autodescription[exclude_local_search]" id="autodescription_exclude_local_search" value="1" <?php checked( $this->get_custom_field( 'exclude_local_search' ) ); ?> />
217
+ <?php
218
+ printf( esc_html__( 'Exclude this %s from local search', 'autodescription' ), esc_html( $type ) );
219
+ echo ' ';
220
+ $this->make_info( sprintf( __( 'This excludes this %s from local on-site search results', 'autodescription' ), $type ) );
221
+ ?>
222
+ </label>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <div class="tsf-flex-setting tsf-flex">
228
+ <div class="tsf-flex-setting-label tsf-flex">
229
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
230
+ <label for="autodescription_redirect" class="tsf-flex-setting-label-item tsf-flex">
231
+ <div>
232
+ <strong><?php esc_html_e( 'Custom 301 Redirect URL', 'autodescription' ); ?></strong>
233
+ </div>
234
+ <div>
235
+ <?php
236
+ $this->make_info( __( 'This will force visitors to go to another URL', 'autodescription' ), 'https://support.google.com/webmasters/answer/93633?hl=' . $language );
237
+ ?>
238
+ </div>
239
+ </label>
240
+ </div>
241
+ </div>
242
+ <div class="tsf-flex-setting-input tsf-flex">
243
+ <input class="large-text" type="text" name="autodescription[redirect]" id="autodescription_redirect" value="<?php echo esc_url( $this->get_custom_field( 'redirect' ) ); ?>" />
244
+ </div>
245
+ </div>
246
+ <?php
247
+ break;
248
+
249
+ case 'inpost_social' :
250
+
251
+ //* Fetch image placeholder.
252
+ $image_placeholder = $this->get_social_image( array( 'post_id' => $post_id, 'disallowed' => array( 'postmeta' ), 'escape' => false ) );
253
+
254
+ ?>
255
+ <div class="tsf-flex-setting tsf-flex">
256
+ <div class="tsf-flex-setting-label tsf-flex">
257
+ <div class="tsf-flex-setting-label-inner-wrap tsf-flex">
258
+ <label for="autodescription_socialimage-url" class="tsf-flex-setting-label-item tsf-flex">
259
+ <div><strong><?php esc_html_e( 'Custom Social Image URL', 'autodescription' ); ?></strong></div>
260
+ <div><?php $this->make_info( sprintf( __( 'Preferred %s Social Image URL location', 'autodescription' ), esc_attr( $type ) ), 'https://developers.facebook.com/docs/sharing/best-practices#images' ); ?></div>
261
+ </label>
262
+ </div>
263
+ </div>
264
+ <div class="tsf-flex-setting-input tsf-flex">
265
+ <input class="large-text" type="text" name="autodescription[_social_image_url]" id="autodescription_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_custom_field( '_social_image_url' ) ); ?>" />
266
+ <div class="hide-if-no-js tsf-social-image-buttons">
267
+ <?php
268
+ //* Already escaped.
269
+ echo $this->get_social_image_uploader_form( 'autodescription_socialimage' );
270
+ ?>
271
+ </div>
272
+ <?php
273
+ /**
274
+ * Insert form element only if JS is active. If JS is inactive, then this will cause it to be emptied on $_POST
275
+ * @TODO use disabled and jQuery.removeprop( 'disabled' )?
276
+ */
277
+ ?>
278
+ <script>
279
+ document.getElementById( 'autodescription_socialimage-url' ).insertAdjacentHTML( 'afterend', '<input type="hidden" name="autodescription[_social_image_id]" id="autodescription_socialimage-id" value="<?php echo absint( $this->get_custom_field( '_social_image_id' ) ); ?>" />' );
280
+ </script>
281
+ </div>
282
+ </div>
283
+ <?php
284
+ break;
285
+
286
+ endswitch;
inc/views/inpost/seo-settings-tt.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package The_SEO_Framework\Views\Inpost
4
+ */
5
+
6
+ defined( 'ABSPATH' ) and $_this = the_seo_framework_class() and $this instanceof $_this or die;
7
+
8
+ //* Get the language the Google page should assume.
9
+ $language = $this->google_language();
10
+
11
+ //* Fetch Term ID and taxonomy.
12
+ $term_id = $object->term_id;
13
+ $taxonomy = $object->taxonomy;
14
+ $data = $this->get_term_data( $object, $term_id );
15
+
16
+ $title = isset( $data['doctitle'] ) ? $data['doctitle'] : '';
17
+ $description = isset( $data['description'] ) ? $data['description'] : '';
18
+ $noindex = isset( $data['noindex'] ) ? $data['noindex'] : '';
19
+ $nofollow = isset( $data['nofollow'] ) ? $data['nofollow'] : '';
20
+ $noarchive = isset( $data['noarchive'] ) ? $data['noarchive'] : '';
21
+
22
+ $generated_doctitle_args = array(
23
+ 'term_id' => $term_id,
24
+ 'taxonomy' => $taxonomy,
25
+ 'placeholder' => true,
26
+ 'get_custom_field' => false,
27
+ );
28
+
29
+ $generated_description_args = array(
30
+ 'id' => $term_id,
31
+ 'taxonomy' => $taxonomy,
32
+ 'get_custom_field' => false,
33
+ );
34
+
35
+ //* Generate title and description.
36
+ $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
37
+ $generated_description = $this->generate_description( '', $generated_description_args );
38
+
39
+ $blog_name = $this->get_blogname();
40
+ $add_additions = $this->add_title_additions();
41
+
42
+ /**
43
+ * Separator doesn't matter. Since html_entity_decode is used.
44
+ * Order doesn't matter either. Since it's just used for length calculation.
45
+ *
46
+ * @since 2.3.4
47
+ */
48
+ $doc_pre_rem = $add_additions ? $title . ' | ' . $blog_name : $title;
49
+ $title_len = $title ? $doc_pre_rem : $generated_doctitle;
50
+ $description_len = $description ?: $generated_description;
51
+
52
+ /**
53
+ * Convert to what Google outputs.
54
+ *
55
+ * This will convert e.g. &raquo; to a single length character.
56
+ * @since 2.3.4
57
+ */
58
+ $tit_len_parsed = html_entity_decode( $title_len );
59
+ $desc_len_parsed = html_entity_decode( $description_len );
60
+
61
+ /**
62
+ * Generate static placeholder for when title or description is emptied
63
+ *
64
+ * @since 2.2.4
65
+ */
66
+ $title_placeholder = $generated_doctitle;
67
+ $description_placeholder = $generated_description;
68
+
69
+ ?>
70
+ <h3><?php printf( esc_html__( '%s SEO Settings', 'autodescription' ), esc_html( $type ) ); ?></h3>
71
+
72
+ <table class="form-table">
73
+ <tbody>
74
+ <?php if ( 'above' === $this->inpost_seo_bar || $this->is_option_checked( 'display_seo_bar_metabox' ) ) : ?>
75
+ <tr>
76
+ <th scope="row" valign="top"><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></th>
77
+ <td>
78
+ <?php $this->post_status( $term_id, $taxonomy, true ); ?>
79
+ </td>
80
+ </tr>
81
+ <?php endif; ?>
82
+
83
+ <tr class="form-field">
84
+ <th scope="row" valign="top">
85
+ <label for="autodescription-meta[doctitle]">
86
+ <strong><?php printf( esc_html__( '%s Title', 'autodescription' ), esc_html( $type ) ); ?></strong>
87
+ <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#3' ); ?>" target="_blank" title="<?php esc_attr_e( 'Recommended Length: 50 to 55 characters', 'autodescription' ); ?>">[?]</a>
88
+ </label>
89
+ </th>
90
+ <td>
91
+ <div id="tsf-title-wrap">
92
+ <input name="autodescription-meta[doctitle]" id="autodescription-meta[doctitle]" type="text" placeholder="<?php echo esc_attr( $title_placeholder ) ?>" value="<?php echo esc_attr( $title ); ?>" size="40" />
93
+ <span id="tsf-title-offset" class="hide-if-no-js"></span><span id="tsf-title-placeholder" class="hide-if-no-js"></span>
94
+ </div>
95
+ <p class="description tsf-counter">
96
+ <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription-meta[doctitle]_chars">' . esc_html( mb_strlen( $tit_len_parsed ) ) . '</span>' ); ?>
97
+ <span class="hide-if-no-js tsf-ajax"></span>
98
+ </p>
99
+ </td>
100
+ </tr>
101
+
102
+ <tr class="form-field">
103
+ <th scope="row" valign="top">
104
+ <label for="autodescription-meta[description]">
105
+ <strong><?php printf( esc_html__( '%s Meta Description', 'autodescription' ), esc_html( $type ) ); ?></strong>
106
+ <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#1' ); ?>" target="_blank" title="<?php esc_attr_e( 'Recommended Length: 145 to 155 characters', 'autodescription' ); ?>">[?]</a>
107
+ </label>
108
+ </th>
109
+ <td>
110
+ <textarea name="autodescription-meta[description]" id="autodescription-meta[description]" placeholder="<?php echo esc_attr( $description_placeholder ); ?>" rows="5" cols="50" class="large-text"><?php echo esc_html( $description ); ?></textarea>
111
+ <p class="description tsf-counter">
112
+ <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription-meta[description]_chars">' . esc_html( mb_strlen( $desc_len_parsed ) ) . '</span>' ); ?>
113
+ <span class="hide-if-no-js tsf-ajax"></span>
114
+ </p>
115
+ </td>
116
+ </tr>
117
+
118
+ <tr>
119
+ <th scope="row" valign="top"><?php esc_html_e( 'Robots Meta Settings', 'autodescription' ); ?></th>
120
+ <td>
121
+ <label for="autodescription-meta[noindex]"><input name="autodescription-meta[noindex]" id="autodescription-meta[noindex]" type="checkbox" value="1" <?php checked( $noindex ); ?> />
122
+ <?php printf( esc_html__( 'Apply %s to this term?', 'autodescription' ), $this->code_wrap( 'noindex' ) ); ?>
123
+ <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/93710?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to show this page in their search results', 'autodescription' ) ); ?>">[?]</a>
124
+ </label>
125
+
126
+ <br>
127
+
128
+ <label for="autodescription-meta[nofollow]"><input name="autodescription-meta[nofollow]" id="autodescription-meta[nofollow]" type="checkbox" value="1" <?php checked( $nofollow ); ?> />
129
+ <?php printf( esc_html__( 'Apply %s to this term?', 'autodescription' ), $this->code_wrap( 'nofollow' ) ); ?>
130
+ <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/96569?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to follow links on this page', 'autodescription' ) ); ?>">[?]</a>
131
+ </label>
132
+
133
+ <br>
134
+
135
+ <label for="autodescription-meta[noarchive]"><input name="autodescription-meta[noarchive]" id="autodescription-meta[noarchive]" type="checkbox" value="1" <?php checked( $noarchive ); ?> />
136
+ <?php printf( esc_html__( 'Apply %s to this term?', 'autodescription' ), $this->code_wrap( 'noarchive' ) ); ?>
137
+ <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/79812?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to save a cached copy of this page', 'autodescription' ) ); ?>">[?]</a>
138
+ </label>
139
+
140
+ <?php // Saved flag, if set then it won't fetch for Genesis meta anymore ?>
141
+ <label class="hidden" for="autodescription-meta[saved_flag]">
142
+ <input name="autodescription-meta[saved_flag]" id="autodescription-meta[saved_flag]" type="checkbox" value="1" checked='checked' />
143
+ </label>
144
+ </td>
145
+ </tr>
146
+
147
+ <?php if ( 'below' === $this->inpost_seo_bar ) : ?>
148
+ <tr>
149
+ <th scope="row" valign="top"><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></th>
150
+ <td>
151
+ <?php $this->post_status( $term_id, $taxonomy, true ); ?>
152
+ </td>
153
+ </tr>
154
+ <?php endif; ?>
155
+ </tbody>
156
+ </table>
157
+ <?php
inc/views/inpost/seo-settings.php DELETED
@@ -1,423 +0,0 @@
1
- <?php
2
- /**
3
- * @package The_SEO_Framework\Views\Inpost
4
- */
5
-
6
- defined( 'ABSPATH' ) and $_this = the_seo_framework_class() and $this instanceof $_this or die;
7
-
8
- //* Fetch the required instance within this file.
9
- $instance = $this->get_view_instance( 'the_seo_framework_settings_type', $instance );
10
-
11
- //* Get the language the Google page should assume.
12
- $language = $this->google_language();
13
-
14
- switch ( $instance ) :
15
- case 'the_seo_framework_settings_type_singular' :
16
- $post_id = $this->get_the_real_ID();
17
- $is_static_frontpage = $this->is_static_frontpage( $post_id );
18
-
19
- $title = $this->get_custom_field( '_genesis_title', $post_id );
20
-
21
- /**
22
- * Generate static placeholder
23
- */
24
- if ( $is_static_frontpage ) {
25
- //* Front page.
26
- $generated_doctitle_args = array(
27
- 'page_on_front' => true,
28
- 'placeholder' => true,
29
- 'meta' => true,
30
- 'get_custom_field' => false,
31
- );
32
-
33
- $generated_description_args = array(
34
- 'id' => $post_id,
35
- 'is_home' => true,
36
- 'get_custom_field' => true,
37
- );
38
- } elseif ( $this->is_blog_page( $post_id ) ) {
39
- //* Page for posts.
40
- $generated_doctitle_args = array(
41
- 'placeholder' => true,
42
- 'meta' => true,
43
- 'get_custom_field' => false,
44
- );
45
-
46
- $generated_description_args = array(
47
- 'id' => $post_id,
48
- 'page_for_posts' => true,
49
- );
50
- } else {
51
- $generated_doctitle_args = array(
52
- 'placeholder' => true,
53
- 'meta' => true,
54
- 'get_custom_field' => false,
55
- );
56
-
57
- $generated_description_args = array(
58
- 'id' => $post_id,
59
- );
60
- }
61
- $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
62
- $generated_description = $this->generate_description_from_id( $generated_description_args );
63
-
64
- /**
65
- * Special check for home page.
66
- *
67
- * @since 2.3.4
68
- */
69
- if ( $is_static_frontpage ) {
70
- if ( $this->get_option( 'homepage_tagline' ) ) {
71
- $tit_len_pre = $title ? $title . ' | ' . $this->get_blogdescription() : $generated_doctitle;
72
- } else {
73
- $tit_len_pre = $title ?: $generated_doctitle;
74
- }
75
- } else {
76
- /**
77
- * Separator doesn't matter. Since html_entity_decode is used.
78
- * Order doesn't matter either. Since it's just used for length calculation.
79
- *
80
- * @since 2.3.4
81
- */
82
- if ( $this->add_title_additions() ) {
83
- $tit_len_pre = $title ? $title . ' | ' . $this->get_blogname() : $generated_doctitle;
84
- } else {
85
- $tit_len_pre = $title ?: $generated_doctitle;
86
- }
87
- }
88
-
89
- //* Fetch description from option.
90
- $description = $this->get_custom_field( '_genesis_description' );
91
-
92
- /**
93
- * Calculate current description length
94
- *
95
- * Reworked.
96
- * @since 2.3.4
97
- */
98
- if ( $is_static_frontpage ) {
99
- //* The homepage description takes precedence.
100
- if ( $description ) {
101
- $desc_len_pre = $this->get_option( 'homepage_description' ) ?: $description;
102
- } else {
103
- $desc_len_pre = $this->get_option( 'homepage_description' ) ?: $generated_description;
104
- }
105
- } else {
106
- $desc_len_pre = $description ?: $generated_description;
107
- }
108
-
109
- /**
110
- * Convert to what Google outputs.
111
- *
112
- * This will convert e.g. &raquo; to a single length character.
113
- * @since 2.3.4
114
- */
115
- $tit_len_parsed = html_entity_decode( $tit_len_pre );
116
- $desc_len_parsed = html_entity_decode( $desc_len_pre );
117
-
118
- /**
119
- * Generate static placeholder for when title or description is emptied
120
- *
121
- * Now within aptly named vars.
122
- * @since 2.3.4
123
- */
124
- $doctitle_placeholder = $generated_doctitle;
125
- $description_placeholder = $generated_description;
126
-
127
- //* Fetch Canonical URL.
128
- $canonical = $this->get_custom_field( '_genesis_canonical_uri' );
129
- //* Fetch Canonical URL Placeholder.
130
- $canonical_placeholder = $this->the_url_from_cache( '', $post_id, false, false );
131
-
132
- //* Fetch image placeholder.
133
- $image_placeholder = $this->get_image( $post_id, array( 'disallowed' => array( 'postmeta' ) ), false );
134
-
135
- ?>
136
- <?php if ( 'above' === $this->inpost_seo_bar || $this->is_option_checked( 'display_seo_bar_metabox' ) ) : ?>
137
- <p>
138
- <strong><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></strong>
139
- <div>
140
- <?php $this->post_status( $post_id, 'inpost', true ); ?>
141
- </div>
142
- </p>
143
- <?php endif; ?>
144
-
145
- <p>
146
- <label for="autodescription_title"><strong><?php printf( esc_html__( 'Custom %s Title', 'autodescription' ), esc_html( $type ) ); ?></strong>
147
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#3' ); ?>" target="_blank" title="<?php esc_attr_e( 'Recommended Length: 50 to 55 characters', 'autodescription' ); ?>">[?]</a>
148
- <span class="description tsf-counter">
149
- <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription_title_chars">' . (int) mb_strlen( $tit_len_parsed ) . '</span>' ); ?>
150
- <span class="hide-if-no-js tsf-ajax"></span>
151
- </span>
152
- </label>
153
- </p>
154
- <p>
155
- <div id="tsf-title-wrap">
156
- <input class="large-text" type="text" name="autodescription[_genesis_title]" id="autodescription_title" placeholder="<?php echo esc_attr( $doctitle_placeholder ); ?>" value="<?php echo esc_attr( $this->get_custom_field( '_genesis_title' ) ); ?>" />
157
- <span id="tsf-title-offset" class="hide-if-no-js"></span><span id="tsf-title-placeholder" class="hide-if-no-js"></span>
158
- </div>
159
- </p>
160
-
161
- <p>
162
- <label for="autodescription_description">
163
- <strong><?php printf( esc_html__( 'Custom %s Description', 'autodescription' ), esc_html( $type ) ); ?></strong>
164
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#1' ); ?>" target="_blank" title="<?php esc_attr_e( 'Recommended Length: 145 to 155 characters', 'autodescription' ); ?>">[?]</a>
165
- <span class="description tsf-counter">
166
- <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription_description_chars">' . (int) mb_strlen( $desc_len_parsed ) . '</span>' ); ?>
167
- <span class="hide-if-no-js tsf-ajax"></span>
168
- </span>
169
- </label>
170
- </p>
171
- <p>
172
- <textarea class="large-text" name="autodescription[_genesis_description]" id="autodescription_description" placeholder="<?php echo esc_attr( $description_placeholder ); ?>" rows="4" cols="4"><?php echo esc_attr( $this->get_custom_field( '_genesis_description' ) ); ?></textarea>
173
- </p>
174
-
175
- <p>
176
- <label for="autodescription_socialimage">
177
- <strong><?php esc_html_e( 'Custom Social Image URL', 'autodescription' ); ?></strong>
178
- <a href="<?php echo esc_url( 'https://developers.facebook.com/docs/sharing/best-practices#images' ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Preferred %s Social Image URL location', 'autodescription' ), esc_attr( $type ) ); ?>">[?]</a>
179
- </label>
180
- </p>
181
- <p class="hide-if-no-js">
182
- <?php
183
- //* Already escaped.
184
- echo $this->get_social_image_uploader_form( 'autodescription_socialimage' );
185
- ?>
186
- </p>
187
- <p>
188
- <input class="large-text" type="text" name="autodescription[_social_image_url]" id="autodescription_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_custom_field( '_social_image_url' ) ); ?>" />
189
- <?php
190
- /**
191
- * Insert form element only if JS is active. If JS is inactive, then this will cause it to be emptied on $_POST
192
- * @TODO use disabled and jQuery.removeprop( 'disabled' )?
193
- */
194
- ?>
195
- <script>
196
- document.getElementById( 'autodescription_socialimage-url' ).insertAdjacentHTML( 'afterend', '<input type="hidden" name="autodescription[_social_image_id]" id="autodescription_socialimage-id" value="<?php echo absint( $this->get_custom_field( '_social_image_id' ) ); ?>" />' );
197
- </script>
198
- </p>
199
-
200
- <p>
201
- <label for="autodescription_canonical">
202
- <strong><?php esc_html_e( 'Custom Canonical URL', 'autodescription' ); ?></strong>
203
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/139066?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Preferred %s URL location', 'autodescription' ), esc_attr( $type ) ); ?>">[?]</a>
204
- </label>
205
- </p>
206
- <p>
207
- <input class="large-text" type="text" name="autodescription[_genesis_canonical_uri]" id="autodescription_canonical" placeholder="<?php echo esc_url( $canonical_placeholder ); ?>" value="<?php echo esc_url( $this->get_custom_field( '_genesis_canonical_uri' ) ); ?>" />
208
- </p>
209
-
210
- <p><strong><?php esc_html_e( 'Robots Meta Settings', 'autodescription' ); ?></strong></p>
211
- <p>
212
- <label for="autodescription_noindex"><input type="checkbox" name="autodescription[_genesis_noindex]" id="autodescription_noindex" value="1" <?php checked( $this->get_custom_field( '_genesis_noindex' ) ); ?> />
213
- <?php
214
- /* translators: 1: Option, 2: Post or Page */
215
- printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noindex' ), esc_html( $type ) );
216
- ?>
217
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/93710?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to show this %s in their search results', 'autodescription' ), esc_attr( $type ) ); ?>">[?]</a>
218
- </label>
219
-
220
- <br>
221
-
222
- <label for="autodescription_nofollow"><input type="checkbox" name="autodescription[_genesis_nofollow]" id="autodescription_nofollow" value="1" <?php checked( $this->get_custom_field( '_genesis_nofollow' ) ); ?> />
223
- <?php
224
- /* translators: 1: Option, 2: Post or Page */
225
- printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'nofollow' ), esc_html( $type ) );
226
- ?>
227
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/96569?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to follow links on this %s', 'autodescription' ), esc_attr( $type ) ); ?>">[?]</a>
228
- </label>
229
-
230
- <br>
231
-
232
- <label for="autodescription_noarchive"><input type="checkbox" name="autodescription[_genesis_noarchive]" id="autodescription_noarchive" value="1" <?php checked( $this->get_custom_field( '_genesis_noarchive' ) ); ?> />
233
- <?php
234
- /* translators: 1: Option, 2: Post or Page */
235
- printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noarchive' ), esc_html( $type ) );
236
- ?>
237
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/79812?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to save a cached copy of this %s', 'autodescription' ), esc_attr( $type ) ); ?>">[?]</a>
238
- </label>
239
- </p>
240
-
241
- <p><strong><?php esc_html_e( 'Local Search Settings', 'autodescription' ); ?></strong></p>
242
- <p>
243
- <label for="autodescription_exclude_local_search"><input type="checkbox" name="autodescription[exclude_local_search]" id="autodescription_exclude_local_search" value="1" <?php checked( $this->get_custom_field( 'exclude_local_search' ) ); ?> />
244
- <?php printf( esc_html__( 'Exclude this %s from local search', 'autodescription' ), esc_html( $type ) ); ?>
245
- <span title="<?php printf( esc_attr__( 'This excludes this %s from local on-site search results', 'autodescription' ), esc_attr( $type ) ); ?>">[?]</span>
246
- </label>
247
- </p>
248
-
249
- <p>
250
- <label for="autodescription_redirect">
251
- <strong><?php esc_html_e( 'Custom 301 Redirect URL', 'autodescription' ); ?></strong>
252
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/93633?hl=' . $language ); ?>" target="_blank" title="<?php esc_attr_e( 'This will force visitors to go to another URL', 'autodescription' ); ?>">[?]</a>
253
- </label>
254
- </p>
255
- <p>
256
- <input class="large-text" type="text" name="autodescription[redirect]" id="genesis_redirect" value="<?php echo esc_url( $this->get_custom_field( 'redirect' ) ); ?>" />
257
- </p>
258
-
259
- <?php if ( 'below' === $this->inpost_seo_bar ) : ?>
260
- <p>
261
- <strong><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></strong>
262
- <div>
263
- <?php $this->post_status( $post_id, 'inpost', true ); ?>
264
- </div>
265
- </p>
266
- <?php endif;
267
- break;
268
-
269
- case 'the_seo_framework_settings_type_term' :
270
-
271
- //* Fetch Term ID and taxonomy.
272
- $term_id = $object->term_id;
273
- $taxonomy = $object->taxonomy;
274
-
275
- $data = $this->get_term_data( $object, $term_id );
276
-
277
- $title = isset( $data['doctitle'] ) ? $data['doctitle'] : '';
278
- $description = isset( $data['description'] ) ? $data['description'] : '';
279
- $noindex = isset( $data['noindex'] ) ? $data['noindex'] : '';
280
- $nofollow = isset( $data['nofollow'] ) ? $data['nofollow'] : '';
281
- $noarchive = isset( $data['noarchive'] ) ? $data['noarchive'] : '';
282
-
283
- $generated_doctitle_args = array(
284
- 'term_id' => $term_id,
285
- 'taxonomy' => $taxonomy,
286
- 'placeholder' => true,
287
- 'get_custom_field' => false,
288
- );
289
-
290
- $generated_description_args = array(
291
- 'id' => $term_id,
292
- 'taxonomy' => $taxonomy,
293
- 'get_custom_field' => false,
294
- );
295
-
296
- //* Generate title and description.
297
- $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
298
- $generated_description = $this->generate_description( '', $generated_description_args );
299
-
300
- $blog_name = $this->get_blogname();
301
- $add_additions = $this->add_title_additions();
302
-
303
- /**
304
- * Separator doesn't matter. Since html_entity_decode is used.
305
- * Order doesn't matter either. Since it's just used for length calculation.
306
- *
307
- * @since 2.3.4
308
- */
309
- $doc_pre_rem = $add_additions ? $title . ' | ' . $blog_name : $title;
310
- $title_len = $title ? $doc_pre_rem : $generated_doctitle;
311
- $description_len = $description ?: $generated_description;
312
-
313
- /**
314
- * Convert to what Google outputs.
315
- *
316
- * This will convert e.g. &raquo; to a single length character.
317
- * @since 2.3.4
318
- */
319
- $tit_len_parsed = html_entity_decode( $title_len );
320
- $desc_len_parsed = html_entity_decode( $description_len );
321
-
322
- /**
323
- * Generate static placeholder for when title or description is emptied
324
- *
325
- * @since 2.2.4
326
- */
327
- $title_placeholder = $generated_doctitle;
328
- $description_placeholder = $generated_description;
329
-
330
- ?>
331
- <h3><?php printf( esc_html__( '%s SEO Settings', 'autodescription' ), esc_html( $type ) ); ?></h3>
332
-
333
- <table class="form-table">
334
- <tbody>
335
- <?php if ( 'above' === $this->inpost_seo_bar || $this->is_option_checked( 'display_seo_bar_metabox' ) ) : ?>
336
- <tr>
337
- <th scope="row" valign="top"><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></th>
338
- <td>
339
- <?php $this->post_status( $term_id, $taxonomy, true ); ?>
340
- </td>
341
- </tr>
342
- <?php endif; ?>
343
-
344
- <tr class="form-field">
345
- <th scope="row" valign="top">
346
- <label for="autodescription-meta[doctitle]">
347
- <strong><?php printf( esc_html__( '%s Title', 'autodescription' ), esc_html( $type ) ); ?></strong>
348
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#3' ); ?>" target="_blank" title="<?php esc_attr_e( 'Recommended Length: 50 to 55 characters', 'autodescription' ); ?>">[?]</a>
349
- </label>
350
- </th>
351
- <td>
352
- <div id="tsf-title-wrap">
353
- <input name="autodescription-meta[doctitle]" id="autodescription-meta[doctitle]" type="text" placeholder="<?php echo esc_attr( $title_placeholder ) ?>" value="<?php echo esc_attr( $title ); ?>" size="40" />
354
- <span id="tsf-title-offset" class="hide-if-no-js"></span><span id="tsf-title-placeholder" class="hide-if-no-js"></span>
355
- </div>
356
- <p class="description tsf-counter">
357
- <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription-meta[doctitle]_chars">' . esc_html( mb_strlen( $tit_len_parsed ) ) . '</span>' ); ?>
358
- <span class="hide-if-no-js tsf-ajax"></span>
359
- </p>
360
- </td>
361
- </tr>
362
-
363
- <tr class="form-field">
364
- <th scope="row" valign="top">
365
- <label for="autodescription-meta[description]">
366
- <strong><?php printf( esc_html__( '%s Meta Description', 'autodescription' ), esc_html( $type ) ); ?></strong>
367
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#1' ); ?>" target="_blank" title="<?php esc_attr_e( 'Recommended Length: 145 to 155 characters', 'autodescription' ); ?>">[?]</a>
368
- </label>
369
- </th>
370
- <td>
371
- <textarea name="autodescription-meta[description]" id="autodescription-meta[description]" placeholder="<?php echo esc_attr( $description_placeholder ); ?>" rows="5" cols="50" class="large-text"><?php echo esc_html( $description ); ?></textarea>
372
- <p class="description tsf-counter">
373
- <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription-meta[description]_chars">' . esc_html( mb_strlen( $desc_len_parsed ) ) . '</span>' ); ?>
374
- <span class="hide-if-no-js tsf-ajax"></span>
375
- </p>
376
- </td>
377
- </tr>
378
-
379
- <tr>
380
- <th scope="row" valign="top"><?php esc_html_e( 'Robots Meta Settings', 'autodescription' ); ?></th>
381
- <td>
382
- <label for="autodescription-meta[noindex]"><input name="autodescription-meta[noindex]" id="autodescription-meta[noindex]" type="checkbox" value="1" <?php checked( $noindex ); ?> />
383
- <?php printf( esc_html__( 'Apply %s to this term?', 'autodescription' ), $this->code_wrap( 'noindex' ) ); ?>
384
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/93710?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to show this page in their search results', 'autodescription' ) ); ?>">[?]</a>
385
- </label>
386
-
387
- <br>
388
-
389
- <label for="autodescription-meta[nofollow]"><input name="autodescription-meta[nofollow]" id="autodescription-meta[nofollow]" type="checkbox" value="1" <?php checked( $nofollow ); ?> />
390
- <?php printf( esc_html__( 'Apply %s to this term?', 'autodescription' ), $this->code_wrap( 'nofollow' ) ); ?>
391
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/96569?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to follow links on this page', 'autodescription' ) ); ?>">[?]</a>
392
- </label>
393
-
394
- <br>
395
-
396
- <label for="autodescription-meta[noarchive]"><input name="autodescription-meta[noarchive]" id="autodescription-meta[noarchive]" type="checkbox" value="1" <?php checked( $noarchive ); ?> />
397
- <?php printf( esc_html__( 'Apply %s to this term?', 'autodescription' ), $this->code_wrap( 'noarchive' ) ); ?>
398
- <a href="<?php echo esc_url( 'https://support.google.com/webmasters/answer/79812?hl=' . $language ); ?>" target="_blank" title="<?php printf( esc_attr__( 'Tell Search Engines not to save a cached copy of this page', 'autodescription' ) ); ?>">[?]</a>
399
- </label>
400
-
401
- <?php // Saved flag, if set then it won't fetch for Genesis meta anymore ?>
402
- <label class="hidden" for="autodescription-meta[saved_flag]">
403
- <input name="autodescription-meta[saved_flag]" id="autodescription-meta[saved_flag]" type="checkbox" value="1" checked='checked' />
404
- </label>
405
- </td>
406
- </tr>
407
-
408
- <?php if ( 'below' === $this->inpost_seo_bar ) : ?>
409
- <tr>
410
- <th scope="row" valign="top"><?php esc_html_e( 'Doing it Right', 'autodescription' ); ?></th>
411
- <td>
412
- <?php $this->post_status( $term_id, $taxonomy, true ); ?>
413
- </td>
414
- </tr>
415
- <?php endif; ?>
416
- </tbody>
417
- </table>
418
- <?php
419
- break;
420
-
421
- default :
422
- break;
423
- endswitch;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/views/metaboxes/feed-metabox.php CHANGED
@@ -9,17 +9,17 @@ switch ( $instance ) :
9
  case 'the_seo_framework_feed_metabox_main' :
10
  ?><h4><?php esc_html_e( 'Content Feed Settings', 'autodescription' ); ?></h4><?php
11
  $this->description( __( "Sometimes, your content can get stolen by robots through the WordPress feeds. This can cause duplicate content issues. To prevent this from happening, it's recommended to convert the feed's content into an excerpt.", 'autodescription' ) );
12
- $this->description( __( "Adding a backlink below the feed's content will also let the visitors know where the content came from.", 'autodescription' ) );
13
 
14
  ?>
15
  <hr>
16
 
17
  <h4><?php esc_html_e( 'Change Feed Settings', 'autodescription' ); ?></h4>
18
  <?php
19
- $excerpt_the_feed_label = esc_html__( 'Convert feed content into excerpts?', 'autodescription' );
20
  $excerpt_the_feed_label .= ' ' . $this->make_info( __( 'By default the excerpt will be at most 400 characters long', 'autodescription' ), '', false );
21
 
22
- $source_the_feed_label = esc_html__( 'Add backlinks below the feed content?', 'autodescription' );
23
  $source_the_feed_label .= ' ' . $this->make_info( __( 'This link will not be followed by Search Engines', 'autodescription' ), '', false );
24
 
25
  //* Echo checkboxes.
9
  case 'the_seo_framework_feed_metabox_main' :
10
  ?><h4><?php esc_html_e( 'Content Feed Settings', 'autodescription' ); ?></h4><?php
11
  $this->description( __( "Sometimes, your content can get stolen by robots through the WordPress feeds. This can cause duplicate content issues. To prevent this from happening, it's recommended to convert the feed's content into an excerpt.", 'autodescription' ) );
12
+ $this->description( __( 'Adding a backlink below the feed entries will also let the visitors know where the content came from.', 'autodescription' ) );
13
 
14
  ?>
15
  <hr>
16
 
17
  <h4><?php esc_html_e( 'Change Feed Settings', 'autodescription' ); ?></h4>
18
  <?php
19
+ $excerpt_the_feed_label = esc_html__( 'Convert feed entries into excerpts?', 'autodescription' );
20
  $excerpt_the_feed_label .= ' ' . $this->make_info( __( 'By default the excerpt will be at most 400 characters long', 'autodescription' ), '', false );
21
 
22
+ $source_the_feed_label = esc_html__( 'Add link to source below the feed entry content?', 'autodescription' );
23
  $source_the_feed_label .= ' ' . $this->make_info( __( 'This link will not be followed by Search Engines', 'autodescription' ), '', false );
24
 
25
  //* Echo checkboxes.
inc/views/metaboxes/homepage-metabox.php CHANGED
@@ -43,6 +43,11 @@ switch ( $instance ) :
43
  'callback' => array( $this, 'homepage_metabox_robots_tab' ),
44
  'dashicon' => 'visibility',
45
  ),
 
 
 
 
 
46
  );
47
 
48
  /**
@@ -417,6 +422,65 @@ switch ( $instance ) :
417
  );
418
  break;
419
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  default :
421
  break;
422
  endswitch;
43
  'callback' => array( $this, 'homepage_metabox_robots_tab' ),
44
  'dashicon' => 'visibility',
45
  ),
46
+ 'social' => array(
47
+ 'name' => __( 'Social', 'autodescription' ),
48
+ 'callback' => array( $this, 'homepage_metabox_social_tab' ),
49
+ 'dashicon' => 'share',
50
+ ),
51
  );
52
 
53
  /**
422
  );
423
  break;
424
 
425
+ case 'the_seo_framework_homepage_metabox_social' :
426
+ ?>
427
+ <h4><?php esc_html_e( 'Social Image Settings', 'autodescription' ); ?></h4>
428
+ <?php
429
+ $this->description( __( 'A social image can be displayed when your homepage is shared. It is a great way to grab attention.', 'autodescription' ) );
430
+
431
+ //* Get the front-page ID. It's 0 if front page is blog.
432
+ $page_id = $this->get_the_front_page_ID();
433
+
434
+ if ( $this->has_page_on_front() ) {
435
+ $image_args = array(
436
+ 'post_id' => $page_id,
437
+ 'disallowed' => array(
438
+ 'homemeta',
439
+ ),
440
+ 'escape' => false,
441
+ );
442
+ } else {
443
+ $image_args = array(
444
+ 'post_id' => $page_id,
445
+ 'disallowed' => array(
446
+ 'homemeta',
447
+ 'postmeta',
448
+ 'featured',
449
+ ),
450
+ 'escape' => false,
451
+ );
452
+ }
453
+ $image_placeholder = $this->get_social_image( $image_args );
454
+
455
+ ?>
456
+ <p>
457
+ <label for="tsf_homepage_socialimage-url">
458
+ <strong><?php esc_html_e( 'Custom Home Page Image URL', 'autodescription' ); ?></strong>
459
+ <?php $this->make_info( __( 'Preferred Home Page Social Image URL location', 'autodescription' ), 'https://developers.facebook.com/docs/sharing/best-practices#images' ); ?>
460
+ </label>
461
+ </p>
462
+ <p>
463
+ <input class="large-text" type="text" name="<?php $this->field_name( 'homepage_social_image_url' ); ?>" id="tsf_homepage_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_field_value( 'homepage_social_image_url' ) ); ?>" />
464
+
465
+ </p>
466
+ <p class="hide-if-no-js">
467
+ <?php
468
+ //* Already escaped.
469
+ echo $this->get_social_image_uploader_form( 'tsf_homepage_socialimage' );
470
+ ?>
471
+ </p>
472
+ <?php
473
+ /**
474
+ * Insert form element only if JS is active. If JS is inactive, then this will cause it to be emptied on $_POST
475
+ * @TODO use disabled and jQuery.removeprop( 'disabled' )?
476
+ */
477
+ ?>
478
+ <script>
479
+ document.getElementById( 'tsf_homepage_socialimage-url' ).insertAdjacentHTML( 'afterend', '<input type="hidden" name="<?php $this->field_name( 'homepage_social_image_id' ); ?>" id="tsf_homepage_socialimage-id" value="<?php echo absint( $this->get_field_value( 'homepage_social_image_id' ) ); ?>" />' );
480
+ </script>
481
+ <?php
482
+ break;
483
+
484
  default :
485
  break;
486
  endswitch;
inc/views/metaboxes/sitemaps-metabox.php CHANGED
@@ -134,9 +134,7 @@ switch ( $instance ) :
134
 
135
  case 'the_seo_framework_sitemaps_metabox_robots' :
136
 
137
- $site_url = $this->the_home_url_from_cache( true );
138
- $robots_url = trailingslashit( $site_url ) . 'robots.txt';
139
- $here = '<a href="' . esc_url( $robots_url ) . '" target="_blank" title="' . esc_attr__( 'View robots.txt', 'autodescription' ) . '">' . esc_html_x( 'here', 'The sitemap can be found %s.', 'autodescription' ) . '</a>';
140
 
141
  ?>
142
  <h4><?php esc_html_e( 'Robots.txt Settings', 'autodescription' ); ?></h4>
@@ -164,10 +162,21 @@ switch ( $instance ) :
164
  ), true
165
  );
166
  else :
167
- $this->description( __( 'Another robots.txt sitemap Location addition has been detected.', 'autodescription' ) );
 
 
 
 
 
168
  endif;
169
 
170
- $this->description_noesc( sprintf( esc_html_x( 'The robots.txt file can be found %s.', '%s = here', 'autodescription' ), $here ) );
 
 
 
 
 
 
171
  break;
172
 
173
  case 'the_seo_framework_sitemaps_metabox_timestamps' :
134
 
135
  case 'the_seo_framework_sitemaps_metabox_robots' :
136
 
137
+ $locate_url = true;
 
 
138
 
139
  ?>
140
  <h4><?php esc_html_e( 'Robots.txt Settings', 'autodescription' ); ?></h4>
162
  ), true
163
  );
164
  else :
165
+ if ( $this->is_subdirectory_installation() ) {
166
+ $this->description( __( 'No robots.txt file can be generated on subdirectory installations.', 'autodescription' ) );
167
+ $locate_url = false;
168
+ } else {
169
+ $this->description( __( 'Another robots.txt sitemap location addition has been detected.', 'autodescription' ) );
170
+ }
171
  endif;
172
 
173
+ if ( $locate_url ) {
174
+ $site_url = $this->the_home_url_from_cache( true );
175
+ $robots_url = trailingslashit( $site_url ) . 'robots.txt';
176
+ $here = '<a href="' . esc_url( $robots_url ) . '" target="_blank" title="' . esc_attr__( 'View robots.txt', 'autodescription' ) . '">' . esc_html_x( 'here', 'The sitemap can be found %s.', 'autodescription' ) . '</a>';
177
+
178
+ $this->description_noesc( sprintf( esc_html_x( 'The robots.txt file can be found %s.', '%s = here', 'autodescription' ), $here ) );
179
+ }
180
  break;
181
 
182
  case 'the_seo_framework_sitemaps_metabox_timestamps' :
inc/views/metaboxes/social-metabox.php CHANGED
@@ -47,6 +47,11 @@ switch ( $instance ) :
47
  * Applies filters the_seo_framework_social_settings_tabs : array see $default_tabs
48
  *
49
  * Used to extend Social tabs
 
 
 
 
 
50
  */
51
  $defaults = (array) apply_filters( 'the_seo_framework_social_settings_tabs', $default_tabs, $args );
52
 
@@ -110,41 +115,41 @@ switch ( $instance ) :
110
 
111
  <h4><?php esc_html_e( 'Social Image Settings', 'autodescription' ); ?></h4>
112
  <?php
113
- $this->description( __( 'A social image can be displayed when your website is shared. They are a great way to grab attention.', 'autodescription' ) );
114
 
115
- $image_placeholder = $this->get_image( 0, array( 'disallowed' => array( 'postmeta', 'featured' ) ), false );
116
 
117
  ?>
118
  <p>
119
- <label for="tsf_fb_socialimage">
120
  <strong><?php esc_html_e( 'Social Image Fallback URL', 'autodescription' ); ?></strong>
121
- <a href="<?php echo esc_url( 'https://developers.facebook.com/docs/sharing/best-practices#images' ); ?>" target="_blank" title="<?php echo esc_attr__( 'Preferred Social Image fallback URL location', 'autodescription' ); ?>">[?]</a>
122
  </label>
123
  </p>
 
 
 
124
  <p class="hide-if-no-js">
125
  <?php
126
  //* Already escaped.
127
  echo $this->get_social_image_uploader_form( 'tsf_fb_socialimage' );
128
  ?>
129
  </p>
130
- <p>
131
- <input class="large-text" type="text" name="<?php $this->field_name( 'social_image_fb_url' ); ?>" id="tsf_fb_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_field_value( 'social_image_fb_url' ) ); ?>" />
132
- <?php
133
- /**
134
- * Insert form element only if JS is active. If JS is inactive, then this will cause it to be emptied on $_POST
135
- * @TODO use disabled and jQuery.removeprop( 'disabled' )?
136
- */
137
- ?>
138
- <script>
139
- document.getElementById( 'tsf_fb_socialimage-url' ).insertAdjacentHTML( 'afterend', '<input type="hidden" name="<?php $this->field_name( 'social_image_fb_id' ); ?>" id="tsf_fb_socialimage-id" value="<?php echo absint( $this->get_field_value( 'social_image_fb_id' ) ); ?>" />' );
140
- </script>
141
- </p>
142
 
143
  <hr>
144
 
145
  <h4><?php esc_html_e( 'Site Shortlink Settings', 'autodescription' ); ?></h4>
146
  <?php
147
- $this->description( __( 'The shortlink tag might have some use for 3rd party service discoverability, but it has little to no SEO value whatsoever.', 'autodescription' ) );
148
 
149
  //* Echo checkboxes.
150
  $this->wrap_fields(
47
  * Applies filters the_seo_framework_social_settings_tabs : array see $default_tabs
48
  *
49
  * Used to extend Social tabs
50
+ *
51
+ * @since 2.2.2
52
+ *
53
+ * @param array $default_tabs The default tabs
54
+ * @param array $args The method's input arguments
55
  */
56
  $defaults = (array) apply_filters( 'the_seo_framework_social_settings_tabs', $default_tabs, $args );
57
 
115
 
116
  <h4><?php esc_html_e( 'Social Image Settings', 'autodescription' ); ?></h4>
117
  <?php
118
+ $this->description( __( 'A social image can be displayed when your website is shared. It is a great way to grab attention.', 'autodescription' ) );
119
 
120
+ $image_placeholder = $this->get_social_image( array( 'post_id' => 0, 'disallowed' => array( 'homemeta', 'postmeta', 'featured' ), 'escape' => false ) );
121
 
122
  ?>
123
  <p>
124
+ <label for="tsf_fb_socialimage-url">
125
  <strong><?php esc_html_e( 'Social Image Fallback URL', 'autodescription' ); ?></strong>
126
+ <?php $this->make_info( __( 'Preferred Social Image fallback URL location', 'autodescription' ), 'https://developers.facebook.com/docs/sharing/best-practices#images' ); ?>
127
  </label>
128
  </p>
129
+ <p>
130
+ <input class="large-text" type="text" name="<?php $this->field_name( 'social_image_fb_url' ); ?>" id="tsf_fb_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_field_value( 'social_image_fb_url' ) ); ?>" />
131
+ </p>
132
  <p class="hide-if-no-js">
133
  <?php
134
  //* Already escaped.
135
  echo $this->get_social_image_uploader_form( 'tsf_fb_socialimage' );
136
  ?>
137
  </p>
138
+ <?php
139
+ /**
140
+ * Insert form element only if JS is active. If JS is inactive, then this will cause it to be emptied on $_POST
141
+ * @TODO use disabled and jQuery.removeprop( 'disabled' )?
142
+ */
143
+ ?>
144
+ <script>
145
+ document.getElementById( 'tsf_fb_socialimage-url' ).insertAdjacentHTML( 'afterend', '<input type="hidden" name="<?php $this->field_name( 'social_image_fb_id' ); ?>" id="tsf_fb_socialimage-id" value="<?php echo absint( $this->get_field_value( 'social_image_fb_id' ) ); ?>" />' );
146
+ </script>
 
 
 
147
 
148
  <hr>
149
 
150
  <h4><?php esc_html_e( 'Site Shortlink Settings', 'autodescription' ); ?></h4>
151
  <?php
152
+ $this->description( __( 'The shortlink tag can be manually used for microblogging services like Twitter, but it has no SEO value whatsoever.', 'autodescription' ) );
153
 
154
  //* Echo checkboxes.
155
  $this->wrap_fields(
language/autodescription.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the The SEO Framework package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: The SEO Framework 2.8.2-RC2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/autodescription\n"
7
- "POT-Creation-Date: 2017-01-27 08:25:27+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -12,27 +12,27 @@ msgstr ""
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #: inc/classes/admin-init.class.php:230
16
  msgid "Good"
17
  msgstr ""
18
 
19
- #: inc/classes/admin-init.class.php:231
20
  msgid "Okay"
21
  msgstr ""
22
 
23
- #: inc/classes/admin-init.class.php:232
24
  msgid "Bad"
25
  msgstr ""
26
 
27
- #: inc/classes/admin-init.class.php:233
28
  msgid "Unknown"
29
  msgstr ""
30
 
31
- #: inc/classes/admin-init.class.php:313
32
  msgid "The changes you made will be lost if you navigate away from this page."
33
  msgstr ""
34
 
35
- #: inc/classes/admin-init.class.php:314
36
  msgid "Are you sure you want to reset all SEO settings to their defaults?"
37
  msgstr ""
38
 
@@ -60,8 +60,8 @@ msgstr ""
60
  msgid "New SEO Settings have been updated."
61
  msgstr ""
62
 
63
- #: inc/classes/admin-pages.class.php:102 inc/classes/core.class.php:248
64
- #: inc/classes/site-options.class.php:489
65
  msgid "SEO Settings"
66
  msgstr ""
67
 
@@ -93,8 +93,9 @@ msgstr ""
93
  msgid "Schema Settings"
94
  msgstr ""
95
 
96
- #: inc/classes/admin-pages.class.php:301 inc/views/inpost/seo-settings.php:210
97
- #: inc/views/inpost/seo-settings.php:380
 
98
  msgid "Robots Meta Settings"
99
  msgstr ""
100
 
@@ -110,16 +111,46 @@ msgstr ""
110
  msgid "Feed Settings"
111
  msgstr ""
112
 
113
- #: inc/classes/core.class.php:250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  msgctxt "As in: The Plugin Home Page"
115
  msgid "Plugin Home"
116
  msgstr ""
117
 
118
- #: inc/classes/core.class.php:301
119
  msgid "Dismiss"
120
  msgstr ""
121
 
122
- #: inc/classes/core.class.php:398
123
  msgctxt "e.g. en for English, nl for Dutch, fi for Finish, de for German"
124
  msgid "en"
125
  msgstr ""
@@ -167,249 +198,249 @@ msgstr ""
167
  msgid "No Search"
168
  msgstr ""
169
 
170
- #: inc/classes/doing-it-right.class.php:283
171
  msgid "Refresh to see the SEO Bar status."
172
  msgstr ""
173
 
174
- #: inc/classes/doing-it-right.class.php:367
175
  msgid "Post"
176
  msgstr ""
177
 
178
- #: inc/classes/doing-it-right.class.php:371 inc/classes/inpost.class.php:252
179
- #: inc/classes/term-data.class.php:330
180
  #: inc/views/metaboxes/schema-metabox.php:203
181
  msgid "Page"
182
  msgstr ""
183
 
184
- #: inc/classes/doing-it-right.class.php:415
185
  msgid "Failed to fetch post ID."
186
  msgstr ""
187
 
188
  #. translators: %s = But or And
189
 
190
- #: inc/classes/doing-it-right.class.php:792
191
  msgid "%s the Title contains the Blogname multiple times."
192
  msgstr ""
193
 
194
  #. translators: 1: Word, 2: Occurences
195
 
196
- #: inc/classes/doing-it-right.class.php:963
197
  msgid "%1$s is used %2$d times."
198
  msgstr ""
199
 
200
  #. Translators: %s = Post / Page / Category, etc.
201
 
202
- #: inc/classes/doing-it-right.class.php:1008
203
  msgid "%s is being indexed."
204
  msgstr ""
205
 
206
- #: inc/classes/doing-it-right.class.php:1017
207
  msgid "But you've discouraged indexing for the whole site."
208
  msgstr ""
209
 
210
  #. translators: 1: But or And, 2: Current taxonomy term plural label
211
 
212
- #: inc/classes/doing-it-right.class.php:1041
213
  msgid "%1$s indexing for %2$s have been discouraged."
214
  msgstr ""
215
 
216
  #. translators: 1 = But or And, 1 = Post/Page
217
 
218
- #: inc/classes/doing-it-right.class.php:1054
219
  msgid "%1$s the %2$s is protected from public visibility. This means indexing is discouraged."
220
  msgstr ""
221
 
222
  #. translators: %s = But or And
223
 
224
- #: inc/classes/doing-it-right.class.php:1063
225
  msgid "%s the blog isn't set to public. This means WordPress discourages indexing."
226
  msgstr ""
227
 
228
  #. translators: %s = But or And
229
 
230
- #: inc/classes/doing-it-right.class.php:1077
231
  msgid "%s there are no posts in this term; therefore, indexing has been discouraged."
232
  msgstr ""
233
 
234
- #: inc/classes/doing-it-right.class.php:1161
235
  msgid "%s links aren't being followed."
236
  msgstr ""
237
 
238
- #: inc/classes/doing-it-right.class.php:1167
239
  msgid "%s links are being followed."
240
  msgstr ""
241
 
242
  #. translators: %s = But or And
243
 
244
- #: inc/classes/doing-it-right.class.php:1179
245
  msgid "%s you've discouraged the following of links for the whole site."
246
  msgstr ""
247
 
248
  #. translators: 1: But or And, 2: Current taxonomy term plural label
249
 
250
- #: inc/classes/doing-it-right.class.php:1205
251
  msgid "%1$s following for %2$s have been discouraged."
252
  msgstr ""
253
 
254
  #. translators: %s = But or And
255
 
256
- #: inc/classes/doing-it-right.class.php:1217
257
  msgid "%s the blog isn't set to public. This means WordPress allows the links to be followed regardless."
258
  msgstr ""
259
 
260
- #: inc/classes/doing-it-right.class.php:1269
261
  msgid "Search Engines aren't allowed to archive this %s."
262
  msgstr ""
263
 
264
- #: inc/classes/doing-it-right.class.php:1274
265
  msgid "Search Engines are allowed to archive this %s."
266
  msgstr ""
267
 
268
- #: inc/classes/doing-it-right.class.php:1286
269
  msgid "But you've discouraged archiving for the whole site."
270
  msgstr ""
271
 
272
  #. translators: 1: But or And, 2: Current taxonomy term plural label
273
 
274
- #: inc/classes/doing-it-right.class.php:1312
275
  msgid "%1$s archiving for %2$s have been discouraged."
276
  msgstr ""
277
 
278
  #. translators: %s = But or And
279
 
280
- #: inc/classes/doing-it-right.class.php:1325
281
  msgid "%s the blog isn't set to public. This means WordPress allows the blog to be archived regardless."
282
  msgstr ""
283
 
284
- #: inc/classes/doing-it-right.class.php:1371
285
  msgid "%s isn't being redirected."
286
  msgstr ""
287
 
288
- #: inc/classes/doing-it-right.class.php:1413
289
- #: inc/classes/doing-it-right.class.php:1442
290
  msgid "%s is being redirected. This means no SEO values have to be set."
291
  msgstr ""
292
 
293
- #: inc/classes/doing-it-right.class.php:1416
294
- #: inc/classes/doing-it-right.class.php:1458
295
  msgid "%s is not being indexed. This means no SEO values have to be set."
296
  msgstr ""
297
 
298
- #: inc/classes/doing-it-right.class.php:1572
299
  msgid "Title:"
300
  msgstr ""
301
 
302
- #: inc/classes/doing-it-right.class.php:1573
303
  msgid "Description:"
304
  msgstr ""
305
 
306
- #: inc/classes/doing-it-right.class.php:1574
307
  msgid "Index:"
308
  msgstr ""
309
 
310
- #: inc/classes/doing-it-right.class.php:1575
311
  msgid "Follow:"
312
  msgstr ""
313
 
314
- #: inc/classes/doing-it-right.class.php:1576
315
  msgid "Archive:"
316
  msgstr ""
317
 
318
- #: inc/classes/doing-it-right.class.php:1577
319
  msgid "Redirect:"
320
  msgstr ""
321
 
322
- #: inc/classes/doing-it-right.class.php:1579
323
  msgid "Generated: Automatically generated."
324
  msgstr ""
325
 
326
- #: inc/classes/doing-it-right.class.php:1581
327
  msgctxt "Generated"
328
  msgid "G"
329
  msgstr ""
330
 
331
- #: inc/classes/doing-it-right.class.php:1582
332
  msgctxt "Title"
333
  msgid "T"
334
  msgstr ""
335
 
336
- #: inc/classes/doing-it-right.class.php:1583
337
  msgctxt "Description"
338
  msgid "D"
339
  msgstr ""
340
 
341
- #: inc/classes/doing-it-right.class.php:1584
342
  msgctxt "no-Index"
343
  msgid "I"
344
  msgstr ""
345
 
346
- #: inc/classes/doing-it-right.class.php:1585
347
  msgctxt "no-Follow"
348
  msgid "F"
349
  msgstr ""
350
 
351
- #: inc/classes/doing-it-right.class.php:1586
352
  msgctxt "no-Archive"
353
  msgid "A"
354
  msgstr ""
355
 
356
- #: inc/classes/doing-it-right.class.php:1587
357
  msgctxt "Redirect"
358
  msgid "R"
359
  msgstr ""
360
 
361
- #: inc/classes/doing-it-right.class.php:1589
362
  msgctxt "But there are..."
363
  msgid "But"
364
  msgstr ""
365
 
366
- #: inc/classes/doing-it-right.class.php:1590
367
  msgctxt "And there are..."
368
  msgid "And"
369
  msgstr ""
370
 
371
- #: inc/classes/doing-it-right.class.php:1592
372
  msgid "Length is far too short."
373
  msgstr ""
374
 
375
- #: inc/classes/doing-it-right.class.php:1593
376
  msgid "Length is too short."
377
  msgstr ""
378
 
379
- #: inc/classes/doing-it-right.class.php:1594
380
  msgid "Length is too long."
381
  msgstr ""
382
 
383
- #: inc/classes/doing-it-right.class.php:1595
384
  msgid "Length is far too long."
385
  msgstr ""
386
 
387
- #: inc/classes/doing-it-right.class.php:1596
388
  msgid "Length is good."
389
  msgstr ""
390
 
391
- #: inc/classes/feed.class.php:135
392
  msgctxt "The content source"
393
  msgid "Source"
394
  msgstr ""
395
 
396
  #. translators: 1: Title, 2: Separator, 3: Excerpt
397
 
398
- #: inc/classes/generate-description.class.php:413
399
  msgctxt "1: Title, 2: Separator, 3: Excerpt"
400
  msgid "%1$s %2$s %3$s"
401
  msgstr ""
402
 
403
  #. translators: 1: Title, 2: on, 3: Blogname
404
 
405
- #: inc/classes/generate-description.class.php:620
406
  msgctxt "1: Title, 2: on, 3: Blogname"
407
  msgid "%1$s %2$s %3$s"
408
  msgstr ""
409
 
410
  #. translators: Front-end output.
411
 
412
- #: inc/classes/generate-description.class.php:655
413
  #: inc/views/metaboxes/description-metabox.php:18
414
  msgctxt "Placement. e.g. Post Title \"on\" Blog Name"
415
  msgid "on"
@@ -417,12 +448,14 @@ msgstr ""
417
 
418
  #. translators: Front-end output.
419
 
420
- #: inc/classes/generate-description.class.php:717
421
  msgid "Latest posts:"
422
  msgstr ""
423
 
424
- #: inc/classes/generate-ldjson.class.php:520
425
- #: inc/classes/generate-ldjson.class.php:564
 
 
426
  msgid "Uncategorized"
427
  msgstr ""
428
 
@@ -584,55 +617,27 @@ msgstr ""
584
  msgid "Page %s"
585
  msgstr ""
586
 
587
- #: inc/classes/init.class.php:470
588
- msgid "Start The Seo Framework"
589
  msgstr ""
590
 
591
- #: inc/classes/init.class.php:471
592
- msgid "End The Seo Framework"
593
  msgstr ""
594
 
595
- #: inc/classes/init.class.php:472
596
  msgid "by Sybre Waaijer"
597
  msgstr ""
598
 
599
- #: inc/classes/inpost.class.php:174 inc/views/inpost/seo-settings.php:331
600
  msgid "%s SEO Settings"
601
  msgstr ""
602
 
603
- #: inc/classes/inpost.class.php:312 inc/classes/inpost.class.php:319
604
- msgid "Select social image"
605
- msgstr ""
606
-
607
- #: inc/classes/inpost.class.php:314 inc/classes/inpost.class.php:318
608
- msgid "Select Image"
609
- msgstr ""
610
-
611
- #: inc/classes/inpost.class.php:320
612
- msgid "Change Image"
613
- msgstr ""
614
-
615
- #: inc/classes/inpost.class.php:321
616
- msgid "Remove Image"
617
- msgstr ""
618
-
619
- #: inc/classes/inpost.class.php:322
620
- msgid "Remove selected social image"
621
- msgstr ""
622
-
623
- #: inc/classes/inpost.class.php:323
624
- msgid "Select Social Image"
625
- msgstr ""
626
-
627
- #: inc/classes/inpost.class.php:324
628
- msgid "Use this image"
629
- msgstr ""
630
-
631
- #: inc/classes/site-options.class.php:489
632
  msgid "here"
633
  msgstr ""
634
 
635
- #: inc/classes/site-options.class.php:490
636
  msgctxt "%s = here"
637
  msgid "View the new options %s."
638
  msgstr ""
@@ -645,127 +650,158 @@ msgstr ""
645
  msgid "Sitemap is served from cache"
646
  msgstr ""
647
 
648
- #: inc/classes/sitemaps.class.php:518
649
  msgid "Sitemap is generated on"
650
  msgstr ""
651
 
652
- #: inc/classes/term-data.class.php:332
653
- #: inc/views/metaboxes/social-metabox.php:276
654
  msgid "Pages"
655
  msgstr ""
656
 
657
- #: inc/views/inpost/seo-settings.php:138 inc/views/inpost/seo-settings.php:261
658
- #: inc/views/inpost/seo-settings.php:337 inc/views/inpost/seo-settings.php:410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
  msgid "Doing it Right"
660
  msgstr ""
661
 
662
- #: inc/views/inpost/seo-settings.php:146
663
- #: inc/views/metaboxes/homepage-metabox.php:168
664
  msgid "Custom %s Title"
665
  msgstr ""
666
 
667
- #: inc/views/inpost/seo-settings.php:147 inc/views/inpost/seo-settings.php:348
668
- #: inc/views/metaboxes/homepage-metabox.php:169
 
669
  msgid "Recommended Length: 50 to 55 characters"
670
  msgstr ""
671
 
672
- #: inc/views/inpost/seo-settings.php:149 inc/views/inpost/seo-settings.php:166
673
- #: inc/views/inpost/seo-settings.php:357 inc/views/inpost/seo-settings.php:373
674
- #: inc/views/metaboxes/homepage-metabox.php:171
675
- #: inc/views/metaboxes/homepage-metabox.php:222
 
 
676
  msgid "Characters Used: %s"
677
  msgstr ""
678
 
679
- #: inc/views/inpost/seo-settings.php:163
680
- #: inc/views/metaboxes/homepage-metabox.php:219
681
  msgid "Custom %s Description"
682
  msgstr ""
683
 
684
- #: inc/views/inpost/seo-settings.php:164 inc/views/inpost/seo-settings.php:367
685
- #: inc/views/metaboxes/homepage-metabox.php:220
 
686
  msgid "Recommended Length: 145 to 155 characters"
687
  msgstr ""
688
 
689
- #: inc/views/inpost/seo-settings.php:177
690
- msgid "Custom Social Image URL"
691
- msgstr ""
692
-
693
- #: inc/views/inpost/seo-settings.php:178
694
- msgid "Preferred %s Social Image URL location"
695
- msgstr ""
696
-
697
- #: inc/views/inpost/seo-settings.php:202
698
  msgid "Custom Canonical URL"
699
  msgstr ""
700
 
701
- #: inc/views/inpost/seo-settings.php:203
702
  msgid "Preferred %s URL location"
703
  msgstr ""
704
 
705
  #. translators: 1: Option, 2: Post or Page
706
 
707
- #: inc/views/inpost/seo-settings.php:215 inc/views/inpost/seo-settings.php:225
708
- #: inc/views/inpost/seo-settings.php:235
 
709
  msgid "Apply %1$s to this %2$s"
710
  msgstr ""
711
 
712
- #: inc/views/inpost/seo-settings.php:217
713
  msgid "Tell Search Engines not to show this %s in their search results"
714
  msgstr ""
715
 
716
- #: inc/views/inpost/seo-settings.php:227
717
  msgid "Tell Search Engines not to follow links on this %s"
718
  msgstr ""
719
 
720
- #: inc/views/inpost/seo-settings.php:237
721
  msgid "Tell Search Engines not to save a cached copy of this %s"
722
  msgstr ""
723
 
724
- #: inc/views/inpost/seo-settings.php:241
725
  msgid "Local Search Settings"
726
  msgstr ""
727
 
728
- #: inc/views/inpost/seo-settings.php:244
729
  msgid "Exclude this %s from local search"
730
  msgstr ""
731
 
732
- #: inc/views/inpost/seo-settings.php:245
733
  msgid "This excludes this %s from local on-site search results"
734
  msgstr ""
735
 
736
- #: inc/views/inpost/seo-settings.php:251
737
  msgid "Custom 301 Redirect URL"
738
  msgstr ""
739
 
740
- #: inc/views/inpost/seo-settings.php:252
741
  msgid "This will force visitors to go to another URL"
742
  msgstr ""
743
 
744
- #: inc/views/inpost/seo-settings.php:347
 
 
 
 
 
 
 
 
745
  msgid "%s Title"
746
  msgstr ""
747
 
748
- #: inc/views/inpost/seo-settings.php:366
749
  msgid "%s Meta Description"
750
  msgstr ""
751
 
752
- #: inc/views/inpost/seo-settings.php:383 inc/views/inpost/seo-settings.php:390
753
- #: inc/views/inpost/seo-settings.php:397
 
754
  msgid "Apply %s to this term?"
755
  msgstr ""
756
 
757
- #: inc/views/inpost/seo-settings.php:384
758
- #: inc/views/metaboxes/homepage-metabox.php:345
759
  msgid "Tell Search Engines not to show this page in their search results"
760
  msgstr ""
761
 
762
- #: inc/views/inpost/seo-settings.php:391
763
- #: inc/views/metaboxes/homepage-metabox.php:355
764
  msgid "Tell Search Engines not to follow links on this page"
765
  msgstr ""
766
 
767
- #: inc/views/inpost/seo-settings.php:398
768
- #: inc/views/metaboxes/homepage-metabox.php:365
769
  msgid "Tell Search Engines not to save a cached copy of this page"
770
  msgstr ""
771
 
@@ -782,7 +818,7 @@ msgid "Automated Description Settings"
782
  msgstr ""
783
 
784
  #: inc/views/metaboxes/description-metabox.php:42
785
- #: inc/views/metaboxes/homepage-metabox.php:231
786
  msgid "The meta description can be used to determine the text used under the title on Search Engine results pages."
787
  msgstr ""
788
 
@@ -790,16 +826,6 @@ msgstr ""
790
  msgid "Example Automated Description Output"
791
  msgstr ""
792
 
793
- #: inc/views/metaboxes/description-metabox.php:67
794
- #: inc/views/metaboxes/homepage-metabox.php:32
795
- #: inc/views/metaboxes/robots-metabox.php:57
796
- #: inc/views/metaboxes/schema-metabox.php:37
797
- #: inc/views/metaboxes/sitemaps-metabox.php:38
798
- #: inc/views/metaboxes/social-metabox.php:25
799
- #: inc/views/metaboxes/title-metabox.php:61
800
- msgid "General"
801
- msgstr ""
802
-
803
  #: inc/views/metaboxes/description-metabox.php:72
804
  #: inc/views/metaboxes/homepage-metabox.php:37
805
  #: inc/views/metaboxes/title-metabox.php:66
@@ -855,7 +881,7 @@ msgid "Sometimes, your content can get stolen by robots through the WordPress fe
855
  msgstr ""
856
 
857
  #: inc/views/metaboxes/feed-metabox.php:12
858
- msgid "Adding a backlink below the feed's content will also let the visitors know where the content came from."
859
  msgstr ""
860
 
861
  #: inc/views/metaboxes/feed-metabox.php:17
@@ -863,7 +889,7 @@ msgid "Change Feed Settings"
863
  msgstr ""
864
 
865
  #: inc/views/metaboxes/feed-metabox.php:19
866
- msgid "Convert feed content into excerpts?"
867
  msgstr ""
868
 
869
  #: inc/views/metaboxes/feed-metabox.php:20
@@ -871,7 +897,7 @@ msgid "By default the excerpt will be at most 400 characters long"
871
  msgstr ""
872
 
873
  #: inc/views/metaboxes/feed-metabox.php:22
874
- msgid "Add backlinks below the feed content?"
875
  msgstr ""
876
 
877
  #: inc/views/metaboxes/feed-metabox.php:23
@@ -1064,111 +1090,128 @@ msgstr ""
1064
  msgid "Robots"
1065
  msgstr ""
1066
 
1067
- #: inc/views/metaboxes/homepage-metabox.php:66
1068
  msgid "Title"
1069
  msgstr ""
1070
 
1071
- #: inc/views/metaboxes/homepage-metabox.php:67
1072
  msgid "Description"
1073
  msgstr ""
1074
 
1075
- #: inc/views/metaboxes/homepage-metabox.php:68
1076
- #: inc/views/metaboxes/homepage-metabox.php:267
1077
- #: inc/views/metaboxes/homepage-metabox.php:312
1078
- #: inc/views/metaboxes/social-metabox.php:278
1079
- #: inc/views/metaboxes/social-metabox.php:309
1080
  msgid "Home Page"
1081
  msgstr ""
1082
 
1083
- #: inc/views/metaboxes/homepage-metabox.php:138
1084
- #: inc/views/metaboxes/homepage-metabox.php:191
1085
  msgid "Page SEO Settings"
1086
  msgstr ""
1087
 
1088
  #. translators: 1: Option, 2: Page SEO Settings, 3: Home Page
1089
 
1090
- #: inc/views/metaboxes/homepage-metabox.php:140
1091
- #: inc/views/metaboxes/homepage-metabox.php:189
1092
  msgid "Note: The %1$s is fetched from the %2$s on the %3$s."
1093
  msgstr ""
1094
 
1095
- #: inc/views/metaboxes/homepage-metabox.php:157
1096
  msgid "Custom %s Title Tagline"
1097
  msgstr ""
1098
 
1099
  #. translators: %s = Home page URL markdown
1100
 
1101
- #: inc/views/metaboxes/homepage-metabox.php:207
1102
- #: inc/views/metaboxes/homepage-metabox.php:247
1103
  msgid "A plugin has been detected that suggests to maintain this option on the [Home Page](%s)."
1104
  msgstr ""
1105
 
1106
- #: inc/views/metaboxes/homepage-metabox.php:271
1107
  #: inc/views/metaboxes/title-metabox.php:132
1108
  msgid "Document Title Additions Location"
1109
  msgstr ""
1110
 
1111
- #: inc/views/metaboxes/homepage-metabox.php:272
1112
  #: inc/views/metaboxes/title-metabox.php:134
1113
  msgid "Determines which side the added title text will go on."
1114
  msgstr ""
1115
 
1116
- #: inc/views/metaboxes/homepage-metabox.php:278
1117
  #: inc/views/metaboxes/title-metabox.php:140
1118
  msgid "Left:"
1119
  msgstr ""
1120
 
1121
- #: inc/views/metaboxes/homepage-metabox.php:288
1122
  #: inc/views/metaboxes/title-metabox.php:147
1123
  msgid "Right:"
1124
  msgstr ""
1125
 
1126
- #: inc/views/metaboxes/homepage-metabox.php:299
1127
  msgid "%s Tagline"
1128
  msgstr ""
1129
 
1130
- #: inc/views/metaboxes/homepage-metabox.php:303
1131
  msgid "Add site description (tagline) to the Title on the %s?"
1132
  msgstr ""
1133
 
1134
- #: inc/views/metaboxes/homepage-metabox.php:329
1135
  msgid "View Home Page Settings"
1136
  msgstr ""
1137
 
1138
- #: inc/views/metaboxes/homepage-metabox.php:329
1139
  msgid "Checked in Page"
1140
  msgstr ""
1141
 
1142
- #: inc/views/metaboxes/homepage-metabox.php:333
1143
  msgid "Home Page Robots Meta Settings"
1144
  msgstr ""
1145
 
1146
  #. translators: 1: Option, 2: Location
1147
 
1148
- #: inc/views/metaboxes/homepage-metabox.php:342
1149
- #: inc/views/metaboxes/homepage-metabox.php:352
1150
- #: inc/views/metaboxes/homepage-metabox.php:362
1151
  msgid "Apply %1$s to the %2$s?"
1152
  msgstr ""
1153
 
1154
- #: inc/views/metaboxes/homepage-metabox.php:397
1155
  msgid "Note: If any of these options are unchecked, but are checked on the Home Page, they will be outputted regardless."
1156
  msgstr ""
1157
 
1158
- #: inc/views/metaboxes/homepage-metabox.php:403
1159
  msgid "Home Page Pagination Robots Settings"
1160
  msgstr ""
1161
 
1162
- #: inc/views/metaboxes/homepage-metabox.php:404
1163
  msgid "If your Home Page is paginated and outputs content that's also found elsewhere on the website, enabling this option might prevent duplicate content."
1164
  msgstr ""
1165
 
1166
  #. translators: 1: Option, 2: Location
1167
 
1168
- #: inc/views/metaboxes/homepage-metabox.php:412
1169
  msgid "Apply %1$s to every second or later page on the %2$s?"
1170
  msgstr ""
1171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1172
  #: inc/views/metaboxes/robots-metabox.php:13
1173
  #: inc/views/metaboxes/title-metabox.php:192
1174
  msgid "Category"
@@ -1463,7 +1506,7 @@ msgstr ""
1463
 
1464
  #: inc/views/metaboxes/sitemaps-metabox.php:14
1465
  #: inc/views/metaboxes/sitemaps-metabox.php:130
1466
- #: inc/views/metaboxes/sitemaps-metabox.php:139
1467
  msgctxt "The sitemap can be found %s."
1468
  msgid "here"
1469
  msgstr ""
@@ -1531,140 +1574,144 @@ msgctxt "%s = here"
1531
  msgid "The sitemap can be found %s."
1532
  msgstr ""
1533
 
1534
- #: inc/views/metaboxes/sitemaps-metabox.php:139
1535
- msgid "View robots.txt"
1536
- msgstr ""
1537
-
1538
- #: inc/views/metaboxes/sitemaps-metabox.php:142
1539
  msgid "Robots.txt Settings"
1540
  msgstr ""
1541
 
1542
- #: inc/views/metaboxes/sitemaps-metabox.php:146
1543
  msgid "A robots.txt file has been detected in the root folder of your website; therefore no settings are able to alter its output."
1544
  msgstr ""
1545
 
1546
- #: inc/views/metaboxes/sitemaps-metabox.php:148
1547
  msgid "The robots.txt file is the first thing Search Engines look for. If you add the sitemap location in the robots.txt file, then Search Engines will look for and index the sitemap."
1548
  msgstr ""
1549
 
1550
- #: inc/views/metaboxes/sitemaps-metabox.php:149
1551
  msgid "If you do not add the sitemap location to the robots.txt file, you will need to notify Search Engines manually through the Webmaster Console provided by the Search Engines."
1552
  msgstr ""
1553
 
1554
- #: inc/views/metaboxes/sitemaps-metabox.php:154
1555
  msgid "Add sitemap location in robots.txt"
1556
  msgstr ""
1557
 
1558
- #: inc/views/metaboxes/sitemaps-metabox.php:161
1559
  msgid "Add sitemap location in robots?"
1560
  msgstr ""
1561
 
1562
- #: inc/views/metaboxes/sitemaps-metabox.php:161
1563
  msgid "This only has effect if the sitemap is active"
1564
  msgstr ""
1565
 
1566
- #: inc/views/metaboxes/sitemaps-metabox.php:167
1567
- msgid "Another robots.txt sitemap Location addition has been detected."
 
 
 
 
1568
  msgstr ""
1569
 
1570
- #: inc/views/metaboxes/sitemaps-metabox.php:170
 
 
 
 
1571
  msgctxt "%s = here"
1572
  msgid "The robots.txt file can be found %s."
1573
  msgstr ""
1574
 
1575
- #: inc/views/metaboxes/sitemaps-metabox.php:189
1576
  msgid "Timestamps Settings"
1577
  msgstr ""
1578
 
1579
- #: inc/views/metaboxes/sitemaps-metabox.php:190
1580
  msgid "The modified time suggests to Search Engines where to look for content changes. It has no impact on the SEO value unless you drastically change pages or posts. It then depends on how well your content is constructed."
1581
  msgstr ""
1582
 
1583
- #: inc/views/metaboxes/sitemaps-metabox.php:191
1584
  msgid "By default, the sitemap only outputs the modified date if you've enabled them within the Social Metabox. This setting overrides those settings for the Sitemap."
1585
  msgstr ""
1586
 
1587
- #: inc/views/metaboxes/sitemaps-metabox.php:196
1588
  msgid "Output Modified Date"
1589
  msgstr ""
1590
 
1591
- #: inc/views/metaboxes/sitemaps-metabox.php:203
1592
  msgid "Add %s to the sitemap?"
1593
  msgstr ""
1594
 
1595
- #: inc/views/metaboxes/sitemaps-metabox.php:213
1596
  msgid "Timestamp Format Settings"
1597
  msgstr ""
1598
 
1599
- #: inc/views/metaboxes/sitemaps-metabox.php:214
1600
  msgid "Determines how specific the modification timestamp is."
1601
  msgstr ""
1602
 
1603
- #: inc/views/metaboxes/sitemaps-metabox.php:220
1604
  msgid "Complete date"
1605
  msgstr ""
1606
 
1607
- #: inc/views/metaboxes/sitemaps-metabox.php:226
1608
  msgid "Complete date plus hours, minutes and timezone"
1609
  msgstr ""
1610
 
1611
- #: inc/views/metaboxes/sitemaps-metabox.php:236
1612
  msgid "Ping Settings"
1613
  msgstr ""
1614
 
1615
- #: inc/views/metaboxes/sitemaps-metabox.php:237
1616
  msgid "Notifying Search Engines of a sitemap change is helpful to get your content indexed as soon as possible."
1617
  msgstr ""
1618
 
1619
- #: inc/views/metaboxes/sitemaps-metabox.php:238
1620
  msgid "By default this will happen at most once an hour."
1621
  msgstr ""
1622
 
1623
- #: inc/views/metaboxes/sitemaps-metabox.php:243
1624
  msgid "Notify Search Engines"
1625
  msgstr ""
1626
 
1627
- #: inc/views/metaboxes/sitemaps-metabox.php:255
1628
  msgid "Notify %s about sitemap changes?"
1629
  msgstr ""
1630
 
1631
- #: inc/views/metaboxes/sitemaps-metabox.php:266
1632
  msgid "Sitemap Styling Settings"
1633
  msgstr ""
1634
 
1635
- #: inc/views/metaboxes/sitemaps-metabox.php:269
1636
  msgid "You can style the sitemap to give it a more personal look. Styling the sitemap has no SEO value whatsoever."
1637
  msgstr ""
1638
 
1639
- #: inc/views/metaboxes/sitemaps-metabox.php:274
1640
  msgid "Enable styling"
1641
  msgstr ""
1642
 
1643
- #: inc/views/metaboxes/sitemaps-metabox.php:281
1644
  msgid "Style Sitemap?"
1645
  msgstr ""
1646
 
1647
- #: inc/views/metaboxes/sitemaps-metabox.php:281
1648
  msgid "This makes the sitemap more readable for humans"
1649
  msgstr ""
1650
 
1651
- #: inc/views/metaboxes/sitemaps-metabox.php:290
1652
  msgid "Style configuration"
1653
  msgstr ""
1654
 
1655
- #: inc/views/metaboxes/sitemaps-metabox.php:298
1656
  msgid "Add site logo?"
1657
  msgstr ""
1658
 
1659
- #: inc/views/metaboxes/sitemaps-metabox.php:298
1660
  msgid "The logo is set in Customizer"
1661
  msgstr ""
1662
 
1663
- #: inc/views/metaboxes/sitemaps-metabox.php:311
1664
  msgid "Sitemap header background color"
1665
  msgstr ""
1666
 
1667
- #: inc/views/metaboxes/sitemaps-metabox.php:320
1668
  msgid "Sitemap title and lines color"
1669
  msgstr ""
1670
 
@@ -1672,192 +1719,188 @@ msgstr ""
1672
  msgid "Post Dates"
1673
  msgstr ""
1674
 
1675
- #: inc/views/metaboxes/social-metabox.php:61
1676
  msgid "Social Meta Tags Settings"
1677
  msgstr ""
1678
 
1679
- #: inc/views/metaboxes/social-metabox.php:63
1680
  msgid "Output various meta tags for social site integration, among other 3rd party services."
1681
  msgstr ""
1682
 
1683
- #: inc/views/metaboxes/social-metabox.php:73
1684
  msgid "Output Open Graph meta tags?"
1685
  msgstr ""
1686
 
1687
- #: inc/views/metaboxes/social-metabox.php:74
1688
  msgid "Facebook, Twitter, Pinterest and many other social sites make use of these tags."
1689
  msgstr ""
1690
 
1691
- #: inc/views/metaboxes/social-metabox.php:81
1692
  msgid "Note: Another Open Graph plugin has been detected."
1693
  msgstr ""
1694
 
1695
- #: inc/views/metaboxes/social-metabox.php:87
1696
  msgid "Output Facebook meta tags?"
1697
  msgstr ""
1698
 
1699
- #: inc/views/metaboxes/social-metabox.php:88
1700
- #: inc/views/metaboxes/social-metabox.php:99
1701
  msgid "Output various tags targetted at %s."
1702
  msgstr ""
1703
 
1704
- #: inc/views/metaboxes/social-metabox.php:98
1705
  msgid "Output Twitter meta tags?"
1706
  msgstr ""
1707
 
1708
- #: inc/views/metaboxes/social-metabox.php:106
1709
- msgid "Note: Another Twitter Card plugin has been detected."
1710
- msgstr ""
1711
-
1712
  #: inc/views/metaboxes/social-metabox.php:111
1713
- msgid "Social Image Settings"
1714
  msgstr ""
1715
 
1716
- #: inc/views/metaboxes/social-metabox.php:113
1717
- msgid "A social image can be displayed when your website is shared. They are a great way to grab attention."
1718
  msgstr ""
1719
 
1720
- #: inc/views/metaboxes/social-metabox.php:120
1721
  msgid "Social Image Fallback URL"
1722
  msgstr ""
1723
 
1724
- #: inc/views/metaboxes/social-metabox.php:121
1725
  msgid "Preferred Social Image fallback URL location"
1726
  msgstr ""
1727
 
1728
- #: inc/views/metaboxes/social-metabox.php:145
1729
  msgid "Site Shortlink Settings"
1730
  msgstr ""
1731
 
1732
- #: inc/views/metaboxes/social-metabox.php:147
1733
- msgid "The shortlink tag might have some use for 3rd party service discoverability, but it has little to no SEO value whatsoever."
1734
  msgstr ""
1735
 
1736
- #: inc/views/metaboxes/social-metabox.php:153
1737
  msgid "Output shortlink tag?"
1738
  msgstr ""
1739
 
1740
- #: inc/views/metaboxes/social-metabox.php:164
1741
  msgctxt "Example Facebook Personal URL"
1742
  msgid "http://www.facebook.com/YourPersonalProfile"
1743
  msgstr ""
1744
 
1745
- #: inc/views/metaboxes/social-metabox.php:167
1746
  msgctxt "Example Verified Facebook Business URL"
1747
  msgid "http://www.facebook.com/YourVerifiedBusinessProfile"
1748
  msgstr ""
1749
 
1750
- #: inc/views/metaboxes/social-metabox.php:172
1751
  msgid "Default Facebook Integration Settings"
1752
  msgstr ""
1753
 
1754
- #: inc/views/metaboxes/social-metabox.php:173
1755
  msgid "Facebook post sharing works mostly through Open Graph. However, you can also link your Business and Personal Facebook pages, among various other options."
1756
  msgstr ""
1757
 
1758
- #: inc/views/metaboxes/social-metabox.php:174
1759
  msgid "When these options are filled in, Facebook might link your Facebook profile to be followed and liked when your post or page is shared."
1760
  msgstr ""
1761
 
1762
- #: inc/views/metaboxes/social-metabox.php:181
1763
  msgid "Article Author Facebook URL"
1764
  msgstr ""
1765
 
1766
- #: inc/views/metaboxes/social-metabox.php:182
1767
  msgid "Your Facebook Profile"
1768
  msgstr ""
1769
 
1770
- #: inc/views/metaboxes/social-metabox.php:191
1771
  msgid "Article Publisher Facebook URL"
1772
  msgstr ""
1773
 
1774
- #: inc/views/metaboxes/social-metabox.php:192
1775
  msgid "To use this, you need to be a verified business"
1776
  msgstr ""
1777
 
1778
- #: inc/views/metaboxes/social-metabox.php:201
1779
  msgid "Facebook App ID"
1780
  msgstr ""
1781
 
1782
- #: inc/views/metaboxes/social-metabox.php:202
1783
  msgid "Get Facebook App ID"
1784
  msgstr ""
1785
 
1786
- #: inc/views/metaboxes/social-metabox.php:214
1787
  msgctxt "Twitter @username"
1788
  msgid "@your-site-username"
1789
  msgstr ""
1790
 
1791
- #: inc/views/metaboxes/social-metabox.php:217
1792
  msgctxt "Twitter @username"
1793
  msgid "@your-personal-username"
1794
  msgstr ""
1795
 
1796
- #: inc/views/metaboxes/social-metabox.php:221
1797
  msgid "Default Twitter Integration Settings"
1798
  msgstr ""
1799
 
1800
- #: inc/views/metaboxes/social-metabox.php:222
1801
  msgid "Twitter post sharing works mostly through Open Graph. However, you can also link your Business and Personal Twitter pages, among various other options."
1802
  msgstr ""
1803
 
1804
- #: inc/views/metaboxes/social-metabox.php:228
1805
  msgid "Twitter Card Type"
1806
  msgstr ""
1807
 
1808
- #: inc/views/metaboxes/social-metabox.php:229
1809
  msgid "What kind of Twitter card would you like to use? It will default to %s if no image is found."
1810
  msgstr ""
1811
 
1812
- #: inc/views/metaboxes/social-metabox.php:239
1813
  msgid "Example"
1814
  msgstr ""
1815
 
1816
- #: inc/views/metaboxes/social-metabox.php:250
1817
  msgid "When the following options are filled in, Twitter might link your Twitter Site or Personal Profile when your post or page is shared."
1818
  msgstr ""
1819
 
1820
- #: inc/views/metaboxes/social-metabox.php:254
1821
  msgid "Your Website's Twitter Profile"
1822
  msgstr ""
1823
 
1824
- #: inc/views/metaboxes/social-metabox.php:255
1825
- #: inc/views/metaboxes/social-metabox.php:265
1826
  msgid "Find your @username"
1827
  msgstr ""
1828
 
1829
- #: inc/views/metaboxes/social-metabox.php:264
1830
  msgid "Your Personal Twitter Profile"
1831
  msgstr ""
1832
 
1833
- #: inc/views/metaboxes/social-metabox.php:277
1834
  msgid "Posts"
1835
  msgstr ""
1836
 
1837
- #: inc/views/metaboxes/social-metabox.php:280
1838
  msgid "Post Date Settings"
1839
  msgstr ""
1840
 
1841
- #: inc/views/metaboxes/social-metabox.php:281
1842
  msgid "Some Search Engines output the publishing date and modified date next to the search results. These help Search Engines find new content and could impact the SEO value."
1843
  msgstr ""
1844
 
1845
- #: inc/views/metaboxes/social-metabox.php:282
1846
  msgid "It's recommended on posts, but it's not recommended on pages unless you modify or create new pages frequently."
1847
  msgstr ""
1848
 
1849
  #. translators: 1: Option, 2: Post Type
1850
 
1851
- #: inc/views/metaboxes/social-metabox.php:285
1852
- #: inc/views/metaboxes/social-metabox.php:289
1853
- #: inc/views/metaboxes/social-metabox.php:296
1854
- #: inc/views/metaboxes/social-metabox.php:300
1855
- #: inc/views/metaboxes/social-metabox.php:314
1856
- #: inc/views/metaboxes/social-metabox.php:318
1857
  msgid "Add %1$s to %2$s?"
1858
  msgstr ""
1859
 
1860
- #: inc/views/metaboxes/social-metabox.php:311
1861
  msgid "Because you only publish the Home Page once, Search Engines might think your website is outdated. This can be prevented by disabling the following options."
1862
  msgstr ""
1863
 
2
  # This file is distributed under the same license as the The SEO Framework package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: The SEO Framework 2.9.0-RC-1-2017.03.25.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/autodescription\n"
7
+ "POT-Creation-Date: 2017-03-25 04:37:16+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #: inc/classes/admin-init.class.php:231
16
  msgid "Good"
17
  msgstr ""
18
 
19
+ #: inc/classes/admin-init.class.php:232
20
  msgid "Okay"
21
  msgstr ""
22
 
23
+ #: inc/classes/admin-init.class.php:233
24
  msgid "Bad"
25
  msgstr ""
26
 
27
+ #: inc/classes/admin-init.class.php:234
28
  msgid "Unknown"
29
  msgstr ""
30
 
31
+ #: inc/classes/admin-init.class.php:325
32
  msgid "The changes you made will be lost if you navigate away from this page."
33
  msgstr ""
34
 
35
+ #: inc/classes/admin-init.class.php:326
36
  msgid "Are you sure you want to reset all SEO settings to their defaults?"
37
  msgstr ""
38
 
60
  msgid "New SEO Settings have been updated."
61
  msgstr ""
62
 
63
+ #: inc/classes/admin-pages.class.php:102 inc/classes/core.class.php:251
64
+ #: inc/classes/site-options.class.php:429
65
  msgid "SEO Settings"
66
  msgstr ""
67
 
93
  msgid "Schema Settings"
94
  msgstr ""
95
 
96
+ #: inc/classes/admin-pages.class.php:301
97
+ #: inc/views/inpost/seo-settings-singular.php:167
98
+ #: inc/views/inpost/seo-settings-tt.php:119
99
  msgid "Robots Meta Settings"
100
  msgstr ""
101
 
111
  msgid "Feed Settings"
112
  msgstr ""
113
 
114
+ #: inc/classes/admin-pages.class.php:838 inc/classes/admin-pages.class.php:845
115
+ msgctxt "Button hover"
116
+ msgid "Select social image"
117
+ msgstr ""
118
+
119
+ #: inc/classes/admin-pages.class.php:840 inc/classes/admin-pages.class.php:844
120
+ msgid "Select Image"
121
+ msgstr ""
122
+
123
+ #: inc/classes/admin-pages.class.php:846
124
+ msgid "Change Image"
125
+ msgstr ""
126
+
127
+ #: inc/classes/admin-pages.class.php:847
128
+ msgid "Remove Image"
129
+ msgstr ""
130
+
131
+ #: inc/classes/admin-pages.class.php:848
132
+ msgid "Remove selected social image"
133
+ msgstr ""
134
+
135
+ #: inc/classes/admin-pages.class.php:849
136
+ msgctxt "Frame title"
137
+ msgid "Select Social Image"
138
+ msgstr ""
139
+
140
+ #: inc/classes/admin-pages.class.php:850
141
+ msgid "Use this image"
142
+ msgstr ""
143
+
144
+ #: inc/classes/core.class.php:253
145
  msgctxt "As in: The Plugin Home Page"
146
  msgid "Plugin Home"
147
  msgstr ""
148
 
149
+ #: inc/classes/core.class.php:304
150
  msgid "Dismiss"
151
  msgstr ""
152
 
153
+ #: inc/classes/core.class.php:401
154
  msgctxt "e.g. en for English, nl for Dutch, fi for Finish, de for German"
155
  msgid "en"
156
  msgstr ""
198
  msgid "No Search"
199
  msgstr ""
200
 
201
+ #: inc/classes/doing-it-right.class.php:293
202
  msgid "Refresh to see the SEO Bar status."
203
  msgstr ""
204
 
205
+ #: inc/classes/doing-it-right.class.php:377
206
  msgid "Post"
207
  msgstr ""
208
 
209
+ #: inc/classes/doing-it-right.class.php:381 inc/classes/inpost.class.php:379
210
+ #: inc/classes/term-data.class.php:332
211
  #: inc/views/metaboxes/schema-metabox.php:203
212
  msgid "Page"
213
  msgstr ""
214
 
215
+ #: inc/classes/doing-it-right.class.php:425
216
  msgid "Failed to fetch post ID."
217
  msgstr ""
218
 
219
  #. translators: %s = But or And
220
 
221
+ #: inc/classes/doing-it-right.class.php:813
222
  msgid "%s the Title contains the Blogname multiple times."
223
  msgstr ""
224
 
225
  #. translators: 1: Word, 2: Occurences
226
 
227
+ #: inc/classes/doing-it-right.class.php:984
228
  msgid "%1$s is used %2$d times."
229
  msgstr ""
230
 
231
  #. Translators: %s = Post / Page / Category, etc.
232
 
233
+ #: inc/classes/doing-it-right.class.php:1029
234
  msgid "%s is being indexed."
235
  msgstr ""
236
 
237
+ #: inc/classes/doing-it-right.class.php:1038
238
  msgid "But you've discouraged indexing for the whole site."
239
  msgstr ""
240
 
241
  #. translators: 1: But or And, 2: Current taxonomy term plural label
242
 
243
+ #: inc/classes/doing-it-right.class.php:1062
244
  msgid "%1$s indexing for %2$s have been discouraged."
245
  msgstr ""
246
 
247
  #. translators: 1 = But or And, 1 = Post/Page
248
 
249
+ #: inc/classes/doing-it-right.class.php:1075
250
  msgid "%1$s the %2$s is protected from public visibility. This means indexing is discouraged."
251
  msgstr ""
252
 
253
  #. translators: %s = But or And
254
 
255
+ #: inc/classes/doing-it-right.class.php:1084
256
  msgid "%s the blog isn't set to public. This means WordPress discourages indexing."
257
  msgstr ""
258
 
259
  #. translators: %s = But or And
260
 
261
+ #: inc/classes/doing-it-right.class.php:1098
262
  msgid "%s there are no posts in this term; therefore, indexing has been discouraged."
263
  msgstr ""
264
 
265
+ #: inc/classes/doing-it-right.class.php:1182
266
  msgid "%s links aren't being followed."
267
  msgstr ""
268
 
269
+ #: inc/classes/doing-it-right.class.php:1188
270
  msgid "%s links are being followed."
271
  msgstr ""
272
 
273
  #. translators: %s = But or And
274
 
275
+ #: inc/classes/doing-it-right.class.php:1200
276
  msgid "%s you've discouraged the following of links for the whole site."
277
  msgstr ""
278
 
279
  #. translators: 1: But or And, 2: Current taxonomy term plural label
280
 
281
+ #: inc/classes/doing-it-right.class.php:1226
282
  msgid "%1$s following for %2$s have been discouraged."
283
  msgstr ""
284
 
285
  #. translators: %s = But or And
286
 
287
+ #: inc/classes/doing-it-right.class.php:1238
288
  msgid "%s the blog isn't set to public. This means WordPress allows the links to be followed regardless."
289
  msgstr ""
290
 
291
+ #: inc/classes/doing-it-right.class.php:1290
292
  msgid "Search Engines aren't allowed to archive this %s."
293
  msgstr ""
294
 
295
+ #: inc/classes/doing-it-right.class.php:1295
296
  msgid "Search Engines are allowed to archive this %s."
297
  msgstr ""
298
 
299
+ #: inc/classes/doing-it-right.class.php:1307
300
  msgid "But you've discouraged archiving for the whole site."
301
  msgstr ""
302
 
303
  #. translators: 1: But or And, 2: Current taxonomy term plural label
304
 
305
+ #: inc/classes/doing-it-right.class.php:1333
306
  msgid "%1$s archiving for %2$s have been discouraged."
307
  msgstr ""
308
 
309
  #. translators: %s = But or And
310
 
311
+ #: inc/classes/doing-it-right.class.php:1346
312
  msgid "%s the blog isn't set to public. This means WordPress allows the blog to be archived regardless."
313
  msgstr ""
314
 
315
+ #: inc/classes/doing-it-right.class.php:1392
316
  msgid "%s isn't being redirected."
317
  msgstr ""
318
 
319
+ #: inc/classes/doing-it-right.class.php:1434
320
+ #: inc/classes/doing-it-right.class.php:1463
321
  msgid "%s is being redirected. This means no SEO values have to be set."
322
  msgstr ""
323
 
324
+ #: inc/classes/doing-it-right.class.php:1437
325
+ #: inc/classes/doing-it-right.class.php:1479
326
  msgid "%s is not being indexed. This means no SEO values have to be set."
327
  msgstr ""
328
 
329
+ #: inc/classes/doing-it-right.class.php:1593
330
  msgid "Title:"
331
  msgstr ""
332
 
333
+ #: inc/classes/doing-it-right.class.php:1594
334
  msgid "Description:"
335
  msgstr ""
336
 
337
+ #: inc/classes/doing-it-right.class.php:1595
338
  msgid "Index:"
339
  msgstr ""
340
 
341
+ #: inc/classes/doing-it-right.class.php:1596
342
  msgid "Follow:"
343
  msgstr ""
344
 
345
+ #: inc/classes/doing-it-right.class.php:1597
346
  msgid "Archive:"
347
  msgstr ""
348
 
349
+ #: inc/classes/doing-it-right.class.php:1598
350
  msgid "Redirect:"
351
  msgstr ""
352
 
353
+ #: inc/classes/doing-it-right.class.php:1600
354
  msgid "Generated: Automatically generated."
355
  msgstr ""
356
 
357
+ #: inc/classes/doing-it-right.class.php:1602
358
  msgctxt "Generated"
359
  msgid "G"
360
  msgstr ""
361
 
362
+ #: inc/classes/doing-it-right.class.php:1603
363
  msgctxt "Title"
364
  msgid "T"
365
  msgstr ""
366
 
367
+ #: inc/classes/doing-it-right.class.php:1604
368
  msgctxt "Description"
369
  msgid "D"
370
  msgstr ""
371
 
372
+ #: inc/classes/doing-it-right.class.php:1605
373
  msgctxt "no-Index"
374
  msgid "I"
375
  msgstr ""
376
 
377
+ #: inc/classes/doing-it-right.class.php:1606
378
  msgctxt "no-Follow"
379
  msgid "F"
380
  msgstr ""
381
 
382
+ #: inc/classes/doing-it-right.class.php:1607
383
  msgctxt "no-Archive"
384
  msgid "A"
385
  msgstr ""
386
 
387
+ #: inc/classes/doing-it-right.class.php:1608
388
  msgctxt "Redirect"
389
  msgid "R"
390
  msgstr ""
391
 
392
+ #: inc/classes/doing-it-right.class.php:1610
393
  msgctxt "But there are..."
394
  msgid "But"
395
  msgstr ""
396
 
397
+ #: inc/classes/doing-it-right.class.php:1611
398
  msgctxt "And there are..."
399
  msgid "And"
400
  msgstr ""
401
 
402
+ #: inc/classes/doing-it-right.class.php:1613
403
  msgid "Length is far too short."
404
  msgstr ""
405
 
406
+ #: inc/classes/doing-it-right.class.php:1614
407
  msgid "Length is too short."
408
  msgstr ""
409
 
410
+ #: inc/classes/doing-it-right.class.php:1615
411
  msgid "Length is too long."
412
  msgstr ""
413
 
414
+ #: inc/classes/doing-it-right.class.php:1616
415
  msgid "Length is far too long."
416
  msgstr ""
417
 
418
+ #: inc/classes/doing-it-right.class.php:1617
419
  msgid "Length is good."
420
  msgstr ""
421
 
422
+ #: inc/classes/feed.class.php:178
423
  msgctxt "The content source"
424
  msgid "Source"
425
  msgstr ""
426
 
427
  #. translators: 1: Title, 2: Separator, 3: Excerpt
428
 
429
+ #: inc/classes/generate-description.class.php:440
430
  msgctxt "1: Title, 2: Separator, 3: Excerpt"
431
  msgid "%1$s %2$s %3$s"
432
  msgstr ""
433
 
434
  #. translators: 1: Title, 2: on, 3: Blogname
435
 
436
+ #: inc/classes/generate-description.class.php:647
437
  msgctxt "1: Title, 2: on, 3: Blogname"
438
  msgid "%1$s %2$s %3$s"
439
  msgstr ""
440
 
441
  #. translators: Front-end output.
442
 
443
+ #: inc/classes/generate-description.class.php:683
444
  #: inc/views/metaboxes/description-metabox.php:18
445
  msgctxt "Placement. e.g. Post Title \"on\" Blog Name"
446
  msgid "on"
448
 
449
  #. translators: Front-end output.
450
 
451
+ #: inc/classes/generate-description.class.php:745
452
  msgid "Latest posts:"
453
  msgstr ""
454
 
455
+ #: inc/classes/generate-ldjson.class.php:538
456
+ #: inc/classes/generate-ldjson.class.php:541
457
+ #: inc/classes/generate-ldjson.class.php:581
458
+ #: inc/classes/generate-ldjson.class.php:584
459
  msgid "Uncategorized"
460
  msgstr ""
461
 
617
  msgid "Page %s"
618
  msgstr ""
619
 
620
+ #: inc/classes/init.class.php:472
621
+ msgid "Start The SEO Framework"
622
  msgstr ""
623
 
624
+ #: inc/classes/init.class.php:473
625
+ msgid "End The SEO Framework"
626
  msgstr ""
627
 
628
+ #: inc/classes/init.class.php:474
629
  msgid "by Sybre Waaijer"
630
  msgstr ""
631
 
632
+ #: inc/classes/inpost.class.php:302 inc/views/inpost/seo-settings-tt.php:70
633
  msgid "%s SEO Settings"
634
  msgstr ""
635
 
636
+ #: inc/classes/site-options.class.php:429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
  msgid "here"
638
  msgstr ""
639
 
640
+ #: inc/classes/site-options.class.php:430
641
  msgctxt "%s = here"
642
  msgid "View the new options %s."
643
  msgstr ""
650
  msgid "Sitemap is served from cache"
651
  msgstr ""
652
 
653
+ #: inc/classes/sitemaps.class.php:520
654
  msgid "Sitemap is generated on"
655
  msgstr ""
656
 
657
+ #: inc/classes/term-data.class.php:334
658
+ #: inc/views/metaboxes/social-metabox.php:281
659
  msgid "Pages"
660
  msgstr ""
661
 
662
+ #: inc/functions/upgrade.php:169
663
+ msgid "Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable."
664
+ msgstr ""
665
+
666
+ #: inc/views/inpost/seo-settings-singular.php:36
667
+ #: inc/views/metaboxes/description-metabox.php:67
668
+ #: inc/views/metaboxes/homepage-metabox.php:32
669
+ #: inc/views/metaboxes/robots-metabox.php:57
670
+ #: inc/views/metaboxes/schema-metabox.php:37
671
+ #: inc/views/metaboxes/sitemaps-metabox.php:38
672
+ #: inc/views/metaboxes/social-metabox.php:25
673
+ #: inc/views/metaboxes/title-metabox.php:61
674
+ msgid "General"
675
+ msgstr ""
676
+
677
+ #: inc/views/inpost/seo-settings-singular.php:42
678
+ msgid "Visibility"
679
+ msgstr ""
680
+
681
+ #: inc/views/inpost/seo-settings-singular.php:48
682
+ #: inc/views/metaboxes/homepage-metabox.php:47
683
+ msgid "Social"
684
+ msgstr ""
685
+
686
+ #: inc/views/inpost/seo-settings-singular.php:86
687
+ #: inc/views/inpost/seo-settings-tt.php:76
688
+ #: inc/views/inpost/seo-settings-tt.php:149
689
  msgid "Doing it Right"
690
  msgstr ""
691
 
692
+ #: inc/views/inpost/seo-settings-singular.php:104
693
+ #: inc/views/metaboxes/homepage-metabox.php:173
694
  msgid "Custom %s Title"
695
  msgstr ""
696
 
697
+ #: inc/views/inpost/seo-settings-singular.php:105
698
+ #: inc/views/inpost/seo-settings-tt.php:87
699
+ #: inc/views/metaboxes/homepage-metabox.php:174
700
  msgid "Recommended Length: 50 to 55 characters"
701
  msgstr ""
702
 
703
+ #: inc/views/inpost/seo-settings-singular.php:108
704
+ #: inc/views/inpost/seo-settings-singular.php:130
705
+ #: inc/views/inpost/seo-settings-tt.php:96
706
+ #: inc/views/inpost/seo-settings-tt.php:112
707
+ #: inc/views/metaboxes/homepage-metabox.php:176
708
+ #: inc/views/metaboxes/homepage-metabox.php:227
709
  msgid "Characters Used: %s"
710
  msgstr ""
711
 
712
+ #: inc/views/inpost/seo-settings-singular.php:126
713
+ #: inc/views/metaboxes/homepage-metabox.php:224
714
  msgid "Custom %s Description"
715
  msgstr ""
716
 
717
+ #: inc/views/inpost/seo-settings-singular.php:127
718
+ #: inc/views/inpost/seo-settings-tt.php:106
719
+ #: inc/views/metaboxes/homepage-metabox.php:225
720
  msgid "Recommended Length: 145 to 155 characters"
721
  msgstr ""
722
 
723
+ #: inc/views/inpost/seo-settings-singular.php:153
 
 
 
 
 
 
 
 
724
  msgid "Custom Canonical URL"
725
  msgstr ""
726
 
727
+ #: inc/views/inpost/seo-settings-singular.php:154
728
  msgid "Preferred %s URL location"
729
  msgstr ""
730
 
731
  #. translators: 1: Option, 2: Post or Page
732
 
733
+ #: inc/views/inpost/seo-settings-singular.php:177
734
+ #: inc/views/inpost/seo-settings-singular.php:187
735
+ #: inc/views/inpost/seo-settings-singular.php:197
736
  msgid "Apply %1$s to this %2$s"
737
  msgstr ""
738
 
739
+ #: inc/views/inpost/seo-settings-singular.php:179
740
  msgid "Tell Search Engines not to show this %s in their search results"
741
  msgstr ""
742
 
743
+ #: inc/views/inpost/seo-settings-singular.php:189
744
  msgid "Tell Search Engines not to follow links on this %s"
745
  msgstr ""
746
 
747
+ #: inc/views/inpost/seo-settings-singular.php:199
748
  msgid "Tell Search Engines not to save a cached copy of this %s"
749
  msgstr ""
750
 
751
+ #: inc/views/inpost/seo-settings-singular.php:210
752
  msgid "Local Search Settings"
753
  msgstr ""
754
 
755
+ #: inc/views/inpost/seo-settings-singular.php:218
756
  msgid "Exclude this %s from local search"
757
  msgstr ""
758
 
759
+ #: inc/views/inpost/seo-settings-singular.php:220
760
  msgid "This excludes this %s from local on-site search results"
761
  msgstr ""
762
 
763
+ #: inc/views/inpost/seo-settings-singular.php:232
764
  msgid "Custom 301 Redirect URL"
765
  msgstr ""
766
 
767
+ #: inc/views/inpost/seo-settings-singular.php:236
768
  msgid "This will force visitors to go to another URL"
769
  msgstr ""
770
 
771
+ #: inc/views/inpost/seo-settings-singular.php:259
772
+ msgid "Custom Social Image URL"
773
+ msgstr ""
774
+
775
+ #: inc/views/inpost/seo-settings-singular.php:260
776
+ msgid "Preferred %s Social Image URL location"
777
+ msgstr ""
778
+
779
+ #: inc/views/inpost/seo-settings-tt.php:86
780
  msgid "%s Title"
781
  msgstr ""
782
 
783
+ #: inc/views/inpost/seo-settings-tt.php:105
784
  msgid "%s Meta Description"
785
  msgstr ""
786
 
787
+ #: inc/views/inpost/seo-settings-tt.php:122
788
+ #: inc/views/inpost/seo-settings-tt.php:129
789
+ #: inc/views/inpost/seo-settings-tt.php:136
790
  msgid "Apply %s to this term?"
791
  msgstr ""
792
 
793
+ #: inc/views/inpost/seo-settings-tt.php:123
794
+ #: inc/views/metaboxes/homepage-metabox.php:350
795
  msgid "Tell Search Engines not to show this page in their search results"
796
  msgstr ""
797
 
798
+ #: inc/views/inpost/seo-settings-tt.php:130
799
+ #: inc/views/metaboxes/homepage-metabox.php:360
800
  msgid "Tell Search Engines not to follow links on this page"
801
  msgstr ""
802
 
803
+ #: inc/views/inpost/seo-settings-tt.php:137
804
+ #: inc/views/metaboxes/homepage-metabox.php:370
805
  msgid "Tell Search Engines not to save a cached copy of this page"
806
  msgstr ""
807
 
818
  msgstr ""
819
 
820
  #: inc/views/metaboxes/description-metabox.php:42
821
+ #: inc/views/metaboxes/homepage-metabox.php:236
822
  msgid "The meta description can be used to determine the text used under the title on Search Engine results pages."
823
  msgstr ""
824
 
826
  msgid "Example Automated Description Output"
827
  msgstr ""
828
 
 
 
 
 
 
 
 
 
 
 
829
  #: inc/views/metaboxes/description-metabox.php:72
830
  #: inc/views/metaboxes/homepage-metabox.php:37
831
  #: inc/views/metaboxes/title-metabox.php:66
881
  msgstr ""
882
 
883
  #: inc/views/metaboxes/feed-metabox.php:12
884
+ msgid "Adding a backlink below the feed entries will also let the visitors know where the content came from."
885
  msgstr ""
886
 
887
  #: inc/views/metaboxes/feed-metabox.php:17
889
  msgstr ""
890
 
891
  #: inc/views/metaboxes/feed-metabox.php:19
892
+ msgid "Convert feed entries into excerpts?"
893
  msgstr ""
894
 
895
  #: inc/views/metaboxes/feed-metabox.php:20
897
  msgstr ""
898
 
899
  #: inc/views/metaboxes/feed-metabox.php:22
900
+ msgid "Add link to source below the feed entry content?"
901
  msgstr ""
902
 
903
  #: inc/views/metaboxes/feed-metabox.php:23
1090
  msgid "Robots"
1091
  msgstr ""
1092
 
1093
+ #: inc/views/metaboxes/homepage-metabox.php:71
1094
  msgid "Title"
1095
  msgstr ""
1096
 
1097
+ #: inc/views/metaboxes/homepage-metabox.php:72
1098
  msgid "Description"
1099
  msgstr ""
1100
 
1101
+ #: inc/views/metaboxes/homepage-metabox.php:73
1102
+ #: inc/views/metaboxes/homepage-metabox.php:272
1103
+ #: inc/views/metaboxes/homepage-metabox.php:317
1104
+ #: inc/views/metaboxes/social-metabox.php:283
1105
+ #: inc/views/metaboxes/social-metabox.php:314
1106
  msgid "Home Page"
1107
  msgstr ""
1108
 
1109
+ #: inc/views/metaboxes/homepage-metabox.php:143
1110
+ #: inc/views/metaboxes/homepage-metabox.php:196
1111
  msgid "Page SEO Settings"
1112
  msgstr ""
1113
 
1114
  #. translators: 1: Option, 2: Page SEO Settings, 3: Home Page
1115
 
1116
+ #: inc/views/metaboxes/homepage-metabox.php:145
1117
+ #: inc/views/metaboxes/homepage-metabox.php:194
1118
  msgid "Note: The %1$s is fetched from the %2$s on the %3$s."
1119
  msgstr ""
1120
 
1121
+ #: inc/views/metaboxes/homepage-metabox.php:162
1122
  msgid "Custom %s Title Tagline"
1123
  msgstr ""
1124
 
1125
  #. translators: %s = Home page URL markdown
1126
 
1127
+ #: inc/views/metaboxes/homepage-metabox.php:212
1128
+ #: inc/views/metaboxes/homepage-metabox.php:252
1129
  msgid "A plugin has been detected that suggests to maintain this option on the [Home Page](%s)."
1130
  msgstr ""
1131
 
1132
+ #: inc/views/metaboxes/homepage-metabox.php:276
1133
  #: inc/views/metaboxes/title-metabox.php:132
1134
  msgid "Document Title Additions Location"
1135
  msgstr ""
1136
 
1137
+ #: inc/views/metaboxes/homepage-metabox.php:277
1138
  #: inc/views/metaboxes/title-metabox.php:134
1139
  msgid "Determines which side the added title text will go on."
1140
  msgstr ""
1141
 
1142
+ #: inc/views/metaboxes/homepage-metabox.php:283
1143
  #: inc/views/metaboxes/title-metabox.php:140
1144
  msgid "Left:"
1145
  msgstr ""
1146
 
1147
+ #: inc/views/metaboxes/homepage-metabox.php:293
1148
  #: inc/views/metaboxes/title-metabox.php:147
1149
  msgid "Right:"
1150
  msgstr ""
1151
 
1152
+ #: inc/views/metaboxes/homepage-metabox.php:304
1153
  msgid "%s Tagline"
1154
  msgstr ""
1155
 
1156
+ #: inc/views/metaboxes/homepage-metabox.php:308
1157
  msgid "Add site description (tagline) to the Title on the %s?"
1158
  msgstr ""
1159
 
1160
+ #: inc/views/metaboxes/homepage-metabox.php:334
1161
  msgid "View Home Page Settings"
1162
  msgstr ""
1163
 
1164
+ #: inc/views/metaboxes/homepage-metabox.php:334
1165
  msgid "Checked in Page"
1166
  msgstr ""
1167
 
1168
+ #: inc/views/metaboxes/homepage-metabox.php:338
1169
  msgid "Home Page Robots Meta Settings"
1170
  msgstr ""
1171
 
1172
  #. translators: 1: Option, 2: Location
1173
 
1174
+ #: inc/views/metaboxes/homepage-metabox.php:347
1175
+ #: inc/views/metaboxes/homepage-metabox.php:357
1176
+ #: inc/views/metaboxes/homepage-metabox.php:367
1177
  msgid "Apply %1$s to the %2$s?"
1178
  msgstr ""
1179
 
1180
+ #: inc/views/metaboxes/homepage-metabox.php:402
1181
  msgid "Note: If any of these options are unchecked, but are checked on the Home Page, they will be outputted regardless."
1182
  msgstr ""
1183
 
1184
+ #: inc/views/metaboxes/homepage-metabox.php:408
1185
  msgid "Home Page Pagination Robots Settings"
1186
  msgstr ""
1187
 
1188
+ #: inc/views/metaboxes/homepage-metabox.php:409
1189
  msgid "If your Home Page is paginated and outputs content that's also found elsewhere on the website, enabling this option might prevent duplicate content."
1190
  msgstr ""
1191
 
1192
  #. translators: 1: Option, 2: Location
1193
 
1194
+ #: inc/views/metaboxes/homepage-metabox.php:417
1195
  msgid "Apply %1$s to every second or later page on the %2$s?"
1196
  msgstr ""
1197
 
1198
+ #: inc/views/metaboxes/homepage-metabox.php:427
1199
+ #: inc/views/metaboxes/social-metabox.php:116
1200
+ msgid "Social Image Settings"
1201
+ msgstr ""
1202
+
1203
+ #: inc/views/metaboxes/homepage-metabox.php:429
1204
+ msgid "A social image can be displayed when your homepage is shared. It is a great way to grab attention."
1205
+ msgstr ""
1206
+
1207
+ #: inc/views/metaboxes/homepage-metabox.php:458
1208
+ msgid "Custom Home Page Image URL"
1209
+ msgstr ""
1210
+
1211
+ #: inc/views/metaboxes/homepage-metabox.php:459
1212
+ msgid "Preferred Home Page Social Image URL location"
1213
+ msgstr ""
1214
+
1215
  #: inc/views/metaboxes/robots-metabox.php:13
1216
  #: inc/views/metaboxes/title-metabox.php:192
1217
  msgid "Category"
1506
 
1507
  #: inc/views/metaboxes/sitemaps-metabox.php:14
1508
  #: inc/views/metaboxes/sitemaps-metabox.php:130
1509
+ #: inc/views/metaboxes/sitemaps-metabox.php:176
1510
  msgctxt "The sitemap can be found %s."
1511
  msgid "here"
1512
  msgstr ""
1574
  msgid "The sitemap can be found %s."
1575
  msgstr ""
1576
 
1577
+ #: inc/views/metaboxes/sitemaps-metabox.php:140
 
 
 
 
1578
  msgid "Robots.txt Settings"
1579
  msgstr ""
1580
 
1581
+ #: inc/views/metaboxes/sitemaps-metabox.php:144
1582
  msgid "A robots.txt file has been detected in the root folder of your website; therefore no settings are able to alter its output."
1583
  msgstr ""
1584
 
1585
+ #: inc/views/metaboxes/sitemaps-metabox.php:146
1586
  msgid "The robots.txt file is the first thing Search Engines look for. If you add the sitemap location in the robots.txt file, then Search Engines will look for and index the sitemap."
1587
  msgstr ""
1588
 
1589
+ #: inc/views/metaboxes/sitemaps-metabox.php:147
1590
  msgid "If you do not add the sitemap location to the robots.txt file, you will need to notify Search Engines manually through the Webmaster Console provided by the Search Engines."
1591
  msgstr ""
1592
 
1593
+ #: inc/views/metaboxes/sitemaps-metabox.php:152
1594
  msgid "Add sitemap location in robots.txt"
1595
  msgstr ""
1596
 
1597
+ #: inc/views/metaboxes/sitemaps-metabox.php:159
1598
  msgid "Add sitemap location in robots?"
1599
  msgstr ""
1600
 
1601
+ #: inc/views/metaboxes/sitemaps-metabox.php:159
1602
  msgid "This only has effect if the sitemap is active"
1603
  msgstr ""
1604
 
1605
+ #: inc/views/metaboxes/sitemaps-metabox.php:166
1606
+ msgid "No robots.txt file can be generated on subdirectory installations."
1607
+ msgstr ""
1608
+
1609
+ #: inc/views/metaboxes/sitemaps-metabox.php:169
1610
+ msgid "Another robots.txt sitemap location addition has been detected."
1611
  msgstr ""
1612
 
1613
+ #: inc/views/metaboxes/sitemaps-metabox.php:176
1614
+ msgid "View robots.txt"
1615
+ msgstr ""
1616
+
1617
+ #: inc/views/metaboxes/sitemaps-metabox.php:178
1618
  msgctxt "%s = here"
1619
  msgid "The robots.txt file can be found %s."
1620
  msgstr ""
1621
 
1622
+ #: inc/views/metaboxes/sitemaps-metabox.php:198
1623
  msgid "Timestamps Settings"
1624
  msgstr ""
1625
 
1626
+ #: inc/views/metaboxes/sitemaps-metabox.php:199
1627
  msgid "The modified time suggests to Search Engines where to look for content changes. It has no impact on the SEO value unless you drastically change pages or posts. It then depends on how well your content is constructed."
1628
  msgstr ""
1629
 
1630
+ #: inc/views/metaboxes/sitemaps-metabox.php:200
1631
  msgid "By default, the sitemap only outputs the modified date if you've enabled them within the Social Metabox. This setting overrides those settings for the Sitemap."
1632
  msgstr ""
1633
 
1634
+ #: inc/views/metaboxes/sitemaps-metabox.php:205
1635
  msgid "Output Modified Date"
1636
  msgstr ""
1637
 
1638
+ #: inc/views/metaboxes/sitemaps-metabox.php:212
1639
  msgid "Add %s to the sitemap?"
1640
  msgstr ""
1641
 
1642
+ #: inc/views/metaboxes/sitemaps-metabox.php:222
1643
  msgid "Timestamp Format Settings"
1644
  msgstr ""
1645
 
1646
+ #: inc/views/metaboxes/sitemaps-metabox.php:223
1647
  msgid "Determines how specific the modification timestamp is."
1648
  msgstr ""
1649
 
1650
+ #: inc/views/metaboxes/sitemaps-metabox.php:229
1651
  msgid "Complete date"
1652
  msgstr ""
1653
 
1654
+ #: inc/views/metaboxes/sitemaps-metabox.php:235
1655
  msgid "Complete date plus hours, minutes and timezone"
1656
  msgstr ""
1657
 
1658
+ #: inc/views/metaboxes/sitemaps-metabox.php:245
1659
  msgid "Ping Settings"
1660
  msgstr ""
1661
 
1662
+ #: inc/views/metaboxes/sitemaps-metabox.php:246
1663
  msgid "Notifying Search Engines of a sitemap change is helpful to get your content indexed as soon as possible."
1664
  msgstr ""
1665
 
1666
+ #: inc/views/metaboxes/sitemaps-metabox.php:247
1667
  msgid "By default this will happen at most once an hour."
1668
  msgstr ""
1669
 
1670
+ #: inc/views/metaboxes/sitemaps-metabox.php:252
1671
  msgid "Notify Search Engines"
1672
  msgstr ""
1673
 
1674
+ #: inc/views/metaboxes/sitemaps-metabox.php:264
1675
  msgid "Notify %s about sitemap changes?"
1676
  msgstr ""
1677
 
1678
+ #: inc/views/metaboxes/sitemaps-metabox.php:275
1679
  msgid "Sitemap Styling Settings"
1680
  msgstr ""
1681
 
1682
+ #: inc/views/metaboxes/sitemaps-metabox.php:278
1683
  msgid "You can style the sitemap to give it a more personal look. Styling the sitemap has no SEO value whatsoever."
1684
  msgstr ""
1685
 
1686
+ #: inc/views/metaboxes/sitemaps-metabox.php:283
1687
  msgid "Enable styling"
1688
  msgstr ""
1689
 
1690
+ #: inc/views/metaboxes/sitemaps-metabox.php:290
1691
  msgid "Style Sitemap?"
1692
  msgstr ""
1693
 
1694
+ #: inc/views/metaboxes/sitemaps-metabox.php:290
1695
  msgid "This makes the sitemap more readable for humans"
1696
  msgstr ""
1697
 
1698
+ #: inc/views/metaboxes/sitemaps-metabox.php:299
1699
  msgid "Style configuration"
1700
  msgstr ""
1701
 
1702
+ #: inc/views/metaboxes/sitemaps-metabox.php:307
1703
  msgid "Add site logo?"
1704
  msgstr ""
1705
 
1706
+ #: inc/views/metaboxes/sitemaps-metabox.php:307
1707
  msgid "The logo is set in Customizer"
1708
  msgstr ""
1709
 
1710
+ #: inc/views/metaboxes/sitemaps-metabox.php:320
1711
  msgid "Sitemap header background color"
1712
  msgstr ""
1713
 
1714
+ #: inc/views/metaboxes/sitemaps-metabox.php:329
1715
  msgid "Sitemap title and lines color"
1716
  msgstr ""
1717
 
1719
  msgid "Post Dates"
1720
  msgstr ""
1721
 
1722
+ #: inc/views/metaboxes/social-metabox.php:66
1723
  msgid "Social Meta Tags Settings"
1724
  msgstr ""
1725
 
1726
+ #: inc/views/metaboxes/social-metabox.php:68
1727
  msgid "Output various meta tags for social site integration, among other 3rd party services."
1728
  msgstr ""
1729
 
1730
+ #: inc/views/metaboxes/social-metabox.php:78
1731
  msgid "Output Open Graph meta tags?"
1732
  msgstr ""
1733
 
1734
+ #: inc/views/metaboxes/social-metabox.php:79
1735
  msgid "Facebook, Twitter, Pinterest and many other social sites make use of these tags."
1736
  msgstr ""
1737
 
1738
+ #: inc/views/metaboxes/social-metabox.php:86
1739
  msgid "Note: Another Open Graph plugin has been detected."
1740
  msgstr ""
1741
 
1742
+ #: inc/views/metaboxes/social-metabox.php:92
1743
  msgid "Output Facebook meta tags?"
1744
  msgstr ""
1745
 
1746
+ #: inc/views/metaboxes/social-metabox.php:93
1747
+ #: inc/views/metaboxes/social-metabox.php:104
1748
  msgid "Output various tags targetted at %s."
1749
  msgstr ""
1750
 
1751
+ #: inc/views/metaboxes/social-metabox.php:103
1752
  msgid "Output Twitter meta tags?"
1753
  msgstr ""
1754
 
 
 
 
 
1755
  #: inc/views/metaboxes/social-metabox.php:111
1756
+ msgid "Note: Another Twitter Card plugin has been detected."
1757
  msgstr ""
1758
 
1759
+ #: inc/views/metaboxes/social-metabox.php:118
1760
+ msgid "A social image can be displayed when your website is shared. It is a great way to grab attention."
1761
  msgstr ""
1762
 
1763
+ #: inc/views/metaboxes/social-metabox.php:125
1764
  msgid "Social Image Fallback URL"
1765
  msgstr ""
1766
 
1767
+ #: inc/views/metaboxes/social-metabox.php:126
1768
  msgid "Preferred Social Image fallback URL location"
1769
  msgstr ""
1770
 
1771
+ #: inc/views/metaboxes/social-metabox.php:150
1772
  msgid "Site Shortlink Settings"
1773
  msgstr ""
1774
 
1775
+ #: inc/views/metaboxes/social-metabox.php:152
1776
+ msgid "The shortlink tag can be manually used for microblogging services like Twitter, but it has no SEO value whatsoever."
1777
  msgstr ""
1778
 
1779
+ #: inc/views/metaboxes/social-metabox.php:158
1780
  msgid "Output shortlink tag?"
1781
  msgstr ""
1782
 
1783
+ #: inc/views/metaboxes/social-metabox.php:169
1784
  msgctxt "Example Facebook Personal URL"
1785
  msgid "http://www.facebook.com/YourPersonalProfile"
1786
  msgstr ""
1787
 
1788
+ #: inc/views/metaboxes/social-metabox.php:172
1789
  msgctxt "Example Verified Facebook Business URL"
1790
  msgid "http://www.facebook.com/YourVerifiedBusinessProfile"
1791
  msgstr ""
1792
 
1793
+ #: inc/views/metaboxes/social-metabox.php:177
1794
  msgid "Default Facebook Integration Settings"
1795
  msgstr ""
1796
 
1797
+ #: inc/views/metaboxes/social-metabox.php:178
1798
  msgid "Facebook post sharing works mostly through Open Graph. However, you can also link your Business and Personal Facebook pages, among various other options."
1799
  msgstr ""
1800
 
1801
+ #: inc/views/metaboxes/social-metabox.php:179
1802
  msgid "When these options are filled in, Facebook might link your Facebook profile to be followed and liked when your post or page is shared."
1803
  msgstr ""
1804
 
1805
+ #: inc/views/metaboxes/social-metabox.php:186
1806
  msgid "Article Author Facebook URL"
1807
  msgstr ""
1808
 
1809
+ #: inc/views/metaboxes/social-metabox.php:187
1810
  msgid "Your Facebook Profile"
1811
  msgstr ""
1812
 
1813
+ #: inc/views/metaboxes/social-metabox.php:196
1814
  msgid "Article Publisher Facebook URL"
1815
  msgstr ""
1816
 
1817
+ #: inc/views/metaboxes/social-metabox.php:197
1818
  msgid "To use this, you need to be a verified business"
1819
  msgstr ""
1820
 
1821
+ #: inc/views/metaboxes/social-metabox.php:206
1822
  msgid "Facebook App ID"
1823
  msgstr ""
1824
 
1825
+ #: inc/views/metaboxes/social-metabox.php:207
1826
  msgid "Get Facebook App ID"
1827
  msgstr ""
1828
 
1829
+ #: inc/views/metaboxes/social-metabox.php:219
1830
  msgctxt "Twitter @username"
1831
  msgid "@your-site-username"
1832
  msgstr ""
1833
 
1834
+ #: inc/views/metaboxes/social-metabox.php:222
1835
  msgctxt "Twitter @username"
1836
  msgid "@your-personal-username"
1837
  msgstr ""
1838
 
1839
+ #: inc/views/metaboxes/social-metabox.php:226
1840
  msgid "Default Twitter Integration Settings"
1841
  msgstr ""
1842
 
1843
+ #: inc/views/metaboxes/social-metabox.php:227
1844
  msgid "Twitter post sharing works mostly through Open Graph. However, you can also link your Business and Personal Twitter pages, among various other options."
1845
  msgstr ""
1846
 
1847
+ #: inc/views/metaboxes/social-metabox.php:233
1848
  msgid "Twitter Card Type"
1849
  msgstr ""
1850
 
1851
+ #: inc/views/metaboxes/social-metabox.php:234
1852
  msgid "What kind of Twitter card would you like to use? It will default to %s if no image is found."
1853
  msgstr ""
1854
 
1855
+ #: inc/views/metaboxes/social-metabox.php:244
1856
  msgid "Example"
1857
  msgstr ""
1858
 
1859
+ #: inc/views/metaboxes/social-metabox.php:255
1860
  msgid "When the following options are filled in, Twitter might link your Twitter Site or Personal Profile when your post or page is shared."
1861
  msgstr ""
1862
 
1863
+ #: inc/views/metaboxes/social-metabox.php:259
1864
  msgid "Your Website's Twitter Profile"
1865
  msgstr ""
1866
 
1867
+ #: inc/views/metaboxes/social-metabox.php:260
1868
+ #: inc/views/metaboxes/social-metabox.php:270
1869
  msgid "Find your @username"
1870
  msgstr ""
1871
 
1872
+ #: inc/views/metaboxes/social-metabox.php:269
1873
  msgid "Your Personal Twitter Profile"
1874
  msgstr ""
1875
 
1876
+ #: inc/views/metaboxes/social-metabox.php:282
1877
  msgid "Posts"
1878
  msgstr ""
1879
 
1880
+ #: inc/views/metaboxes/social-metabox.php:285
1881
  msgid "Post Date Settings"
1882
  msgstr ""
1883
 
1884
+ #: inc/views/metaboxes/social-metabox.php:286
1885
  msgid "Some Search Engines output the publishing date and modified date next to the search results. These help Search Engines find new content and could impact the SEO value."
1886
  msgstr ""
1887
 
1888
+ #: inc/views/metaboxes/social-metabox.php:287
1889
  msgid "It's recommended on posts, but it's not recommended on pages unless you modify or create new pages frequently."
1890
  msgstr ""
1891
 
1892
  #. translators: 1: Option, 2: Post Type
1893
 
1894
+ #: inc/views/metaboxes/social-metabox.php:290
1895
+ #: inc/views/metaboxes/social-metabox.php:294
1896
+ #: inc/views/metaboxes/social-metabox.php:301
1897
+ #: inc/views/metaboxes/social-metabox.php:305
1898
+ #: inc/views/metaboxes/social-metabox.php:319
1899
+ #: inc/views/metaboxes/social-metabox.php:323
1900
  msgid "Add %1$s to %2$s?"
1901
  msgstr ""
1902
 
1903
+ #: inc/views/metaboxes/social-metabox.php:316
1904
  msgid "Because you only publish the Home Page once, Search Engines might think your website is outdated. This can be prevented by disabling the following options."
1905
  msgstr ""
1906
 
lib/css/tsf-rtl.css CHANGED
@@ -117,9 +117,9 @@ th.column-tsf-seo-bar-wrap ~ th {
117
  user-select: none;
118
  box-sizing: content-box;
119
  top: 0;
120
- left: 0;
121
  overflow: hidden;
122
- white-space: nowrap;
123
  text-overflow: ellipsis;
124
  }
125
 
@@ -200,7 +200,6 @@ span.tsf-seo-bar-inner-wrap {
200
  position: relative;
201
  }
202
 
203
-
204
  span.tsf-seo-bar-section-wrap {
205
  display: table-cell;
206
  border-collapse: collapse;
@@ -276,7 +275,7 @@ span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap a {
276
  width: 12.5%;
277
  }
278
 
279
- .ad-11 {
280
  width: 11.333%;
281
  }
282
 
@@ -315,6 +314,7 @@ span.tsf-seo-bar .tsf-explanation-desc {
315
  left: 0;
316
  right: 0;
317
  text-align: left;
 
318
  }
319
 
320
  span.tsf-seo-bar .tsf-explanation-desc span {
@@ -537,6 +537,250 @@ body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content {
537
  * End tabs.
538
  */
539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  .tsf-metaboxes .tsf-default-selected {
541
  border-color: #1c9d38;
542
  }
@@ -574,6 +818,17 @@ body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content {
574
  margin: 1em 0;
575
  }
576
 
 
 
 
 
 
 
 
 
 
 
 
577
  .tsf-counter .tsf-ajax {
578
  margin-right: 3px;
579
  }
@@ -616,24 +871,24 @@ a.tsf-set-social-image.button {
616
  #tsf-inpost-box textarea::-webkit-input-placeholder,
617
  .tsf-metaboxes input[type="text"]::-webkit-input-placeholder,
618
  .tsf-metaboxes textarea::-webkit-input-placeholder {
619
- -webkit-transition: all 0.33s ease-in;
620
- -o-transition: all 0.33s ease-in;
621
- transition: all 0.33s ease-in;
622
  }
623
 
624
  #tsf-inpost-box input[type="text"]::-moz-placeholder,
625
  #tsf-inpost-box textarea::-moz-placeholder,
626
  .tsf-metaboxes input[type="text"]::-moz-placeholder,
627
  .tsf-metaboxes textarea::-moz-placeholder {
628
- -moz-transition: all 0.33s ease-in;
629
- transition: all 0.33s ease-in;
630
  }
631
 
632
  #tsf-inpost-box input[type="text"]:-ms-input-placeholder,
633
  #tsf-inpost-box textarea:-ms-input-placeholder,
634
  .tsf-metaboxes input[type="text"]:-ms-input-placeholder,
635
  .tsf-metaboxes textarea:-ms-input-placeholder {
636
- transition: all 0.33s ease-in;
637
  }
638
 
639
  #tsf-inpost-box input[type="text"]:focus::-webkit-input-placeholder,
@@ -681,7 +936,7 @@ a.tsf-set-social-image.button {
681
  @media screen and (max-width: 782px) {
682
  .tsf-metaboxes p.tsf-fields,
683
  .tsf-inpost-box p.tsf-fields {
684
- line-height: 2.8
685
  }
686
 
687
  .tsf-metaboxes #tsf-title-location label span,
@@ -716,7 +971,7 @@ a.tsf-set-social-image.button {
716
  @media only screen and ( min-width: 768px ) {
717
  /**
718
  * https://bugzilla.mozilla.org/show_bug.cgi?id=587438
719
- * Only fix when title is second element and there are more than 6 elemnents in the table.
720
  */
721
  .widefat tr th.column-title:nth-child(2):nth-last-child(n+6),
722
  .widefat tr td.column-title:nth-child(2):nth-last-child(n+6),
@@ -741,3 +996,19 @@ a.tsf-set-social-image.button {
741
  margin: 2px 0;
742
  }
743
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  user-select: none;
118
  box-sizing: content-box;
119
  top: 0;
120
+ right: 0;
121
  overflow: hidden;
122
+ white-space: pre;
123
  text-overflow: ellipsis;
124
  }
125
 
200
  position: relative;
201
  }
202
 
 
203
  span.tsf-seo-bar-section-wrap {
204
  display: table-cell;
205
  border-collapse: collapse;
275
  width: 12.5%;
276
  }
277
 
278
+ .tsf-11 {
279
  width: 11.333%;
280
  }
281
 
314
  left: 0;
315
  right: 0;
316
  text-align: left;
317
+ pointer-events: none;
318
  }
319
 
320
  span.tsf-seo-bar .tsf-explanation-desc span {
537
  * End tabs.
538
  */
539
 
540
+ /**
541
+ * Start Inpost.
542
+ */
543
+
544
+ .tsf-flex,
545
+ #tsf-inpost-box .inside {
546
+ box-sizing: border-box;
547
+ display: -webkit-box;
548
+ display: -webkit-flex;
549
+ display: -ms-flexbox;
550
+ display: flex;
551
+ -webkit-flex: 1 1 auto;
552
+ flex: 1 1 auto;
553
+ -webkit-flex-wrap: wrap;
554
+ -ms-flex-wrap: wrap;
555
+ flex-wrap: wrap;
556
+ -webkit-flex-direction: column;
557
+ flex-direction: column;
558
+ -webkit-justify-content: flex-start;
559
+ justify-content: flex-start;
560
+ }
561
+
562
+ #tsf-inpost-box .inside {
563
+ margin: 0;
564
+ padding: 0;
565
+ -webkit-flex: 1 0 100%;
566
+ flex: 1 0 100%;
567
+ -webkit-flex-wrap: nowrap;
568
+ -ms-flex-wrap: nowrap;
569
+ flex-wrap: nowrap;
570
+ }
571
+
572
+ #tsf-inpost-box.closed .inside {
573
+ display: none;
574
+ }
575
+
576
+ .tsf-flex-inside-wrap {
577
+ /* IE11 wrapper fix */
578
+ -webkit-flex-direction: row;
579
+ flex-direction: row;
580
+ -webkit-flex: 1 1 auto;
581
+ flex: 1 1 auto;
582
+ }
583
+
584
+ .tsf-flex-setting {
585
+ width: 100%;
586
+ -webkit-flex-direction: row;
587
+ flex-direction: row;
588
+ }
589
+
590
+ .tsf-flex-setting-label,
591
+ .tsf-flex-setting-input {
592
+ background-color: #fff;
593
+ padding: 15px 12px;
594
+ -webkit-flex: 10 1 350px;
595
+ flex: 10 1 350px;
596
+ box-shadow: 0 0 0 1px #e9e9e9;
597
+ }
598
+
599
+ .tsf-flex-setting-label {
600
+ background-color: #f9f9f9;
601
+ -webkit-flex: 1 1 200px;
602
+ flex: 1 1 200px;
603
+ }
604
+
605
+ .tsf-flex-setting-input {
606
+ -webkit-justify-content: center;
607
+ justify-content: center;
608
+ }
609
+
610
+ .tsf-flex-setting-label-item {
611
+ -webkit-flex-wrap: nowrap;
612
+ -ms-flex-wrap: nowrap;
613
+ flex-wrap: nowrap;
614
+ -webkit-flex-direction: row;
615
+ flex-direction: row;
616
+ -webkit-justify-content: space-between;
617
+ justify-content: space-between;
618
+ -webkit-flex-grow: 0;
619
+ flex-grow: 0;
620
+ }
621
+
622
+ .tsf-flex-setting-label-inner-wrap {
623
+ -webkit-justify-content: center;
624
+ justify-content: center;
625
+ }
626
+
627
+ .tsf-flex-setting-label-item > * {
628
+ margin-right: 4px;
629
+ }
630
+
631
+ .tsf-flex-setting-label-item > *:last-child {
632
+ margin-right: 0;
633
+ }
634
+
635
+ .tsf-flex-setting-label .tsf-counter {
636
+ font-weight: 400;
637
+ color: #666;
638
+ margin-top: 15px;
639
+ }
640
+
641
+ .tsf-social-image-buttons {
642
+ margin-top: 15px;
643
+ margin-left: 1px;
644
+ }
645
+
646
+ .tsf-flex-setting-input textarea {
647
+ max-height: 250px;
648
+ }
649
+
650
+ /* Start inpost tabs */
651
+ input[type="radio"].tsf-flex-nav-tab-radio {
652
+ display: none;
653
+ width: 0;
654
+ height: 0;
655
+ margin: 0;
656
+ padding: 0;
657
+ position: absolute;
658
+ left: -9001px;
659
+ }
660
+
661
+ .tsf-flex-nav-tab-wrapper {
662
+ background-color: #fcfcfc;
663
+ border-bottom: 2px solid #dadada;
664
+ -webkit-align-items: baseline;
665
+ align-items: baseline;
666
+ -webkit-flex-direction: row;
667
+ flex-direction: row;
668
+ /* IE11 fix */
669
+ -webkit-flex: 1 1 100%;
670
+ flex: 1 1 100%;
671
+ /* Firefox fix, don't use overflow:hidden because that could cause more issues. */
672
+ -webkit-flex-wrap: nowrap;
673
+ -ms-flex-wrap: nowrap;
674
+ flex-wrap: nowrap;
675
+ max-width: 100%;
676
+ }
677
+
678
+ .tsf-flex-nav-tab-inner {
679
+ -webkit-flex-direction: row;
680
+ flex-direction: row;
681
+ -webkit-flex-wrap: nowrap;
682
+ -ms-flex-wrap: nowrap;
683
+ flex-wrap: nowrap;
684
+ /* IE11 reverse fix for newer browsers */
685
+ -webkit-flex: 1 0 auto;
686
+ flex: 1 0 auto;
687
+ }
688
+
689
+ .tsf-flex-nav-tab {
690
+ -webkit-flex-direction: row;
691
+ flex-direction: row;
692
+ /* Edge bug */
693
+ -webkit-flex: 0 1 125px;
694
+ flex: 0 1 125px;
695
+ /* IE11 bug */
696
+ -webkit-flex: 1 1 100%;
697
+ flex: 1 1 100%;
698
+ /* Edge/IE11 fix */
699
+ -webkit-flex: 1 1 auto;
700
+ flex: 1 1 auto;
701
+ max-width: 125px; /* I wanted this to be flex-basis */
702
+ }
703
+
704
+ .tsf-flex-nav-tab-label {
705
+ padding: 12px;
706
+ text-align: center;
707
+ -webkit-flex-direction: row;
708
+ flex-direction: row;
709
+ box-shadow: 0 0 0 0 transparent inset;
710
+ -webkit-transition: box-shadow 0.15s ease-out;
711
+ -o-transition: box-shadow 0.15s ease-out;
712
+ transition: box-shadow 0.15s ease-out;
713
+ -webkit-align-items: center;
714
+ align-items: center;
715
+ -webkit-align-content: space-between;
716
+ align-content: space-between;
717
+ }
718
+
719
+ .tsf-flex-nav-dashicon,
720
+ .tsf-flex-nav-name {
721
+ -webkit-align-items: center;
722
+ align-items: center;
723
+ -webkit-justify-content: center;
724
+ justify-content: center;
725
+ }
726
+
727
+ .tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked + .tsf-flex-nav-tab-label {
728
+ box-shadow: 0 -2px 0 0 #007bd2 inset;
729
+ -webkit-transition: box-shadow 0.25s ease-in;
730
+ -o-transition: box-shadow 0.25s ease-in;
731
+ transition: box-shadow 0.25s ease-in;
732
+ }
733
+
734
+ .tsf-flex-tab-content {
735
+ -webkit-flex: 1 0 100%;
736
+ flex: 1 0 100%;
737
+ -webkit-flex-wrap: nowrap;
738
+ -ms-flex-wrap: nowrap;
739
+ flex-wrap: nowrap;
740
+ }
741
+
742
+ body.js .tsf-flex-tab-content {
743
+ display: none;
744
+ }
745
+
746
+ body.js .tsf-flex-tab-content.tsf-flex-tab-content-active {
747
+ display: -webkit-box;
748
+ display: -webkit-flex;
749
+ display: -ms-flexbox;
750
+ display: flex;
751
+ }
752
+
753
+ .tsf-flex-tabs-content-no-js {
754
+ background-color: #f3f3f3;
755
+ border-bottom: 1px solid #dadada;
756
+ box-shadow: 0 2px 0 0 #dadada inset;
757
+ }
758
+
759
+ .tsf-flex-tab-no-js {
760
+ -webkit-align-items: baseline;
761
+ align-items: baseline;
762
+ -webkit-flex-direction: row;
763
+ flex-direction: row;
764
+ flex: 1 1 100%;
765
+ }
766
+
767
+ .tsf-flex-tab-no-js .tsf-flex-nav-tab {
768
+ padding: 12px;
769
+ min-width: 125px;
770
+ box-shadow: 0 -2px 0 0 #007bd2 inset;
771
+ -webkit-flex-direction: row;
772
+ flex-direction: row;
773
+ -webkit-flex: 0 1 auto;
774
+ flex: 0 1 auto;
775
+ }
776
+
777
+ /**
778
+ * End inpost.
779
+ */
780
+
781
+ /**
782
+ * General fields.
783
+ */
784
  .tsf-metaboxes .tsf-default-selected {
785
  border-color: #1c9d38;
786
  }
818
  margin: 1em 0;
819
  }
820
 
821
+ .tsf-checkbox-wrapper {
822
+ margin-top: 15px;
823
+ }
824
+
825
+ .tsf-checkbox-wrapper:first-child {
826
+ margin-top: 0;
827
+ }
828
+
829
+ /**
830
+ * Start AJAX
831
+ */
832
  .tsf-counter .tsf-ajax {
833
  margin-right: 3px;
834
  }
871
  #tsf-inpost-box textarea::-webkit-input-placeholder,
872
  .tsf-metaboxes input[type="text"]::-webkit-input-placeholder,
873
  .tsf-metaboxes textarea::-webkit-input-placeholder {
874
+ -webkit-transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
875
+ -o-transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
876
+ transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
877
  }
878
 
879
  #tsf-inpost-box input[type="text"]::-moz-placeholder,
880
  #tsf-inpost-box textarea::-moz-placeholder,
881
  .tsf-metaboxes input[type="text"]::-moz-placeholder,
882
  .tsf-metaboxes textarea::-moz-placeholder {
883
+ -moz-transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
884
+ transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
885
  }
886
 
887
  #tsf-inpost-box input[type="text"]:-ms-input-placeholder,
888
  #tsf-inpost-box textarea:-ms-input-placeholder,
889
  .tsf-metaboxes input[type="text"]:-ms-input-placeholder,
890
  .tsf-metaboxes textarea:-ms-input-placeholder {
891
+ transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
892
  }
893
 
894
  #tsf-inpost-box input[type="text"]:focus::-webkit-input-placeholder,
936
  @media screen and (max-width: 782px) {
937
  .tsf-metaboxes p.tsf-fields,
938
  .tsf-inpost-box p.tsf-fields {
939
+ line-height: 2.8;
940
  }
941
 
942
  .tsf-metaboxes #tsf-title-location label span,
971
  @media only screen and ( min-width: 768px ) {
972
  /**
973
  * https://bugzilla.mozilla.org/show_bug.cgi?id=587438
974
+ * Only fix when title is second element and there are more than 6 elements in the table.
975
  */
976
  .widefat tr th.column-title:nth-child(2):nth-last-child(n+6),
977
  .widefat tr td.column-title:nth-child(2):nth-last-child(n+6),
996
  margin: 2px 0;
997
  }
998
  }
999
+
1000
+ /**
1001
+ * Start override
1002
+ */
1003
+
1004
+ body.js .tsf-flex-hide-if-js,
1005
+ .tsf-flex-hide-if-no-js {
1006
+ display: none;
1007
+ }
1008
+
1009
+ body.js .tsf-flex-hide-if-no-js {
1010
+ display: -webkit-box;
1011
+ display: -webkit-flex;
1012
+ display: -ms-flexbox;
1013
+ display: flex;
1014
+ }
lib/css/tsf-rtl.min.css CHANGED
@@ -1 +1 @@
1
- .tsf-metaboxes .tsf-top-buttons,.tsf-metaboxes .tsf-top-wrap>h1,.tsf-metaboxes .tsf-top-wrap>h2{float:left}.tsf-notice{position:relative;clear:both}.tsf-notice.tsf-show-icon p:before{content:'';margin-left:12px;background:0 0;display:inline-block;font:400 14px/16px dashicons;speak:none;height:16px;text-align:center;vertical-align:middle;width:16px;line-height:14px;-webkit-font-smoothing:antialiased}.error.tsf-notice.tsf-show-icon p:before{color:#dd3811;content:"\f534"}.notice-warning.tsf-notice.tsf-show-icon p:before{color:#ffa01b;content:"\f227"}.updated.tsf-notice.tsf-show-icon p:before{color:#0cc34b;font-size:16px;content:"\f147"}a.tsf-dismiss{position:absolute;top:0;left:1px;border:none;margin:0;padding:9px;background:0 0;color:#b4b9be;cursor:pointer;text-decoration:none}a.tsf-dismiss:before{background:0 0;content:"\f153";display:block;font:400 16px/20px dashicons;speak:none;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a.tsf-dismiss:hover{color:#c00}table.wp-list-table .column-name{width:15%}table.wp-list-table .column-icl_translations,table.wp-list-table .column-is_in_stock,table.wp-list-table .column-price,table.wp-list-table .column-sku,th.column-tsf-seo-bar-wrap~th{width:8%}.tsf-seo-bar a{text-decoration:none;font-size:13px}#tsf-title-wrap{position:relative;display:block;padding:0;height:auto;width:auto;overflow:hidden}#tsf-title-offset{visibility:hidden;height:0;display:inline-block;position:absolute;right:0;color:transparent;white-space:pre}#tsf-title-placeholder{position:absolute;color:#777;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;top:0;left:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.tsf-counter{font-weight:600;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}span.tsf-count-bad{color:#dd3811}span.tsf-count-okay{color:#ffa700}span.tsf-count-good{color:#0cc34b}span.tsf-counter-one{color:#fff;border-radius:4em;padding:0 .5em;min-width:2em;display:inline-block;text-align:center;vertical-align:baseline}span.tsf-counter-one.tsf-count-bad{background-color:#dd3811}span.tsf-counter-one.tsf-count-okay{background-color:#ffa700}span.tsf-counter-one.tsf-count-good{background-color:#0cc34b}#tsf-seo-bar-wrap{width:18%}th:last-of-type#tsf-seo-bar-wrap{width:160px}span.tsf-seo-bar{display:block;width:95%;max-width:220px;border-radius:0;padding:3px;text-shadow:0 0 3px rgba(0,0,0,.3)}span.tsf-seo-bar.tsf-100{width:100%}span.tsf-seo-bar-inner-wrap{display:table;width:100%;border-radius:0;margin:0 auto;border-collapse:separate;border-spacing:0;vertical-align:middle;position:relative}span.tsf-seo-bar-section-wrap{display:table-cell;border-collapse:collapse}.tsf-seo-bar-inner-wrap a{display:table;width:100%;color:#fff;text-align:center;cursor:help;height:100%;min-width:12px;vertical-align:top;line-height:1.625em;box-shadow:2px 0 0 -1px rgba(0,0,0,.1) inset,-2px 0 0 -1px rgba(0,0,0,.1) inset}span.tsf-seo-bar.pill,span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap{border-radius:30px}span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap a{box-shadow:2px 6px 3px -2px rgba(255,255,255,.2) inset,-2px -6px 3px -2px rgba(41,41,41,.2) inset,0 0 1px rgba(41,41,41,.6)}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type a{border-top-left-radius:30px;border-bottom-left-radius:30px}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type a{border-top-right-radius:30px;border-bottom-right-radius:30px}.tsf-100{width:100%}.tsf-60{width:60%}.tsf-50{width:50%}.tsf-40{width:40%}.tsf-33{width:33.333%}.tsf-25{width:25%}.tsf-20{width:20%}.tsf-16{width:16.666%}.tsf-12-5{width:12.5%}.ad-11{width:11.333%}.tsf-10{width:10%}.tsf-seo-bar-bad{background-color:#dd3811}.tsf-seo-bar-okay{background-color:#ffa700}.tsf-seo-bar-good{background-color:#0cc34b}.tsf-seo-bar-unknown{background-color:#007bd2}span.tsf-seo-bar .tsf-explanation-desc{position:absolute;width:auto;min-width:90%;max-width:220px;font-weight:600;background:#007bd2;padding:8px 12px;color:#fdfdfd;border-radius:0;z-index:900142;box-shadow:0 0 2px rgba(0,0,0,.6);left:0;right:0;text-align:left}span.tsf-seo-bar .tsf-explanation-desc span{text-decoration:underline}span.tsf-seo-bar .tsf-explanation-desc div{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid #007bd2;position:absolute;bottom:-8px;z-index:9999999;left:0}.tsf-seo-bar-wrap.column-tsf-seo-bar-temp{overflow:initial!important;min-width:160px}#col-container,#col-right{overflow:initial}.tsf-metaboxes{box-sizing:border-box;max-width:690px;padding-bottom:20px}.tsf-metaboxes .tsf-top-wrap{width:100%;display:inline-block;vertical-align:top}.tsf-metaboxes .metabox-holder{clear:both}.tsf-metaboxes .tsf-bottom-buttons{text-align:left}.tsf-metaboxes .tsf-bottom-buttons input,.tsf-metaboxes .tsf-top-buttons input{margin-left:10px}.tsf-metaboxes #tsf-description-separator,.tsf-metaboxes #tsf-title-separator{display:table;width:100%;border-collapse:collapse;border-spacing:0}.tsf-metaboxes #tsf-description-separator input,.tsf-metaboxes #tsf-title-separator input{display:none;float:left;width:0;min-width:0;opacity:0}.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{display:inline-block;width:auto;min-width:28px;min-height:28px;margin:3px;-moz-margin-end:1.5px;-moz-margin-start:1.5px;padding:0 4px;border:1px solid #ccc;line-height:28px;text-align:center;cursor:pointer;box-shadow:-1px -1px 1px #aaa inset;font-size:16px}.tsf-metaboxes #tsf-description-separator label.tsf-recommended,.tsf-metaboxes #tsf-title-separator label.tsf-recommended{border:1px solid #0cc34b;box-shadow:-1px -1px 1px #0cc34b inset}.tsf-metaboxes #tsf-description-separator input:hover+label,.tsf-metaboxes #tsf-description-separator label:hover,.tsf-metaboxes #tsf-title-separator input:hover+label,.tsf-metaboxes #tsf-title-separator label:hover{box-shadow:1px 1px 1px #aaa inset;background-color:#fff}.tsf-metaboxes #tsf-description-separator input:checked+label,.tsf-metaboxes #tsf-title-separator input:checked+label{box-shadow:1px 1px 1px #333 inset;background-color:#fff}.tsf-metaboxes #tsf-home-title-location,.tsf-metaboxes #tsf-title-location{display:block}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span,.tsf-metaboxes #tsf-twitter-cards label span{display:inline-block;min-width:60px;vertical-align:baseline}.tsf-metaboxes #tsf-twitter-cards label span{min-width:150px}.tsf-metaboxes #tsf-home-title-location label .tsf-sep-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-blogname-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-tagline-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-title-js,.tsf-metaboxes #tsf-title-location label .tsf-sep-js{display:inline;min-width:0;white-space:pre}.tsf-metaboxes .tsf-nav-tab-wrapper,.tsf-metaboxes .tsf-tab-no-js{position:relative;clear:both;width:100%;display:inline-block;border-bottom:1px solid #ccc;line-height:inherit;padding:8px 12px 0;margin:-4px -12px}.tsf-metaboxes .tsf-nav-tab{float:right;border:1px solid #ccc;margin-right:.5em;margin-bottom:-1px;padding:5px 14px;font-size:12px;line-height:16px;background:#f1f1f1;color:#555;font-weight:600}.tsf-metaboxes .tsf-dashicons-tabs{font-size:initial;display:inline;vertical-align:text-bottom}.tsf-metaboxes .tsf-tabs-radio{display:none;width:0;height:0;position:absolute;left:-9001px}.tsf-metaboxes .tsf-active-tab,.tsf-metaboxes .tsf-tabs-radio:checked+label{background-color:inherit;border-bottom-color:#fff;color:#000}.tsf-metaboxes .tsf-tabs-content{margin:1.33em auto 0}.tsf-metaboxes .tsf-content-no-js{margin:1.33em auto}body.js .tsf-metaboxes .tsf-tabs-content{display:none}body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content{display:block}.tsf-metaboxes .tsf-default-selected{border-color:#1c9d38}.tsf-metaboxes .tsf-default-selected:checked:before{color:#1c9d38}.tsf-metaboxes .tsf-warning-selected{border-color:#dd3811}.tsf-metaboxes .tsf-warning-selected:checked:before{color:#dd3811}.tsf-fields{font-size:13px;line-height:1.5;margin:1em 0}.tsf-fields .tsf-toblock{display:block;width:100%;margin-bottom:4px}.tsf-fields p.description{margin:7px 0 5px;color:#666}.tsf-option-spacer{margin:1em 0}.tsf-counter .tsf-ajax{margin-right:3px}.tsf-ajax:before{display:inline-block;line-height:1;font-family:dashicons;font-style:normal;font-weight:400;font-size:1.225em;vertical-align:middle;content:""}.tsf-ajax.tsf-loading:before{content:"\f463";color:#007bd2;-webkit-animation:tsf-spin 1.5s linear infinite;-moz-animation:tsf-spin 1.5s linear infinite;-o-animation:tsf-spin 1.5s linear infinite;animation:tsf-spin 1.5s linear infinite}.tsf-ajax.tsf-error:before{content:"\f158";color:#dd3811}.tsf-ajax.tsf-success:before{content:"\f147";color:#0cc34b}a.tsf-set-social-image.button{margin-left:7px}#tsf-inpost-box input[type=text]::-webkit-input-placeholder,#tsf-inpost-box textarea::-webkit-input-placeholder,.tsf-metaboxes input[type=text]::-webkit-input-placeholder,.tsf-metaboxes textarea::-webkit-input-placeholder{-webkit-transition:all .33s ease-in;-o-transition:all .33s ease-in;transition:all .33s ease-in}#tsf-inpost-box input[type=text]::-moz-placeholder,#tsf-inpost-box textarea::-moz-placeholder,.tsf-metaboxes input[type=text]::-moz-placeholder,.tsf-metaboxes textarea::-moz-placeholder{-moz-transition:all .33s ease-in;transition:all .33s ease-in}#tsf-inpost-box input[type=text]:-ms-input-placeholder,#tsf-inpost-box textarea:-ms-input-placeholder,.tsf-metaboxes input[type=text]:-ms-input-placeholder,.tsf-metaboxes textarea:-ms-input-placeholder{transition:all .33s ease-in}#tsf-inpost-box input[type=text]:focus::-webkit-input-placeholder,#tsf-inpost-box textarea:focus::-webkit-input-placeholder,.tsf-metaboxes input[type=text]:focus::-webkit-input-placeholder,.tsf-metaboxes textarea:focus::-webkit-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus::-moz-placeholder,#tsf-inpost-box textarea:focus::-moz-placeholder,.tsf-metaboxe textarea:focus::-moz-placeholder,.tsf-metaboxes input[type=text]:focus::-moz-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus:-ms-input-placeholder,#tsf-inpost-box textarea:focus:-ms-input-placeholder,.tsf-metaboxes input[type=text]:focus:-ms-input-placeholder,.tsf-metaboxes textarea:focus:-ms-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}@-webkit-keyframes tsf-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}@keyframes tsf-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@media screen and (max-width:782px){.tsf-inpost-box p.tsf-fields,.tsf-metaboxes p.tsf-fields{line-height:2.8}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span{min-width:40px}.wp-list-table .is-expanded td.tsf-seo-bar-wrap:not(.hidden){overflow:initial!important}}@media screen and (max-width:642px){.tsf-metaboxes span.tsf-nav-desktop{display:none}}@media screen and (max-width:510px){span.tsf-seo-bar.tsf-100{width:inherit}}@-moz-document url-prefix(){.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{margin:3px 1px}@media only screen and (min-width:768px){.widefat tr td.column-title:nth-child(2):nth-last-child(n+6),.widefat tr td.title:nth-child(2):nth-last-child(n+6),.widefat tr th.column-title:nth-child(2):nth-last-child(n+6),.widefat tr th.title:nth-child(2):nth-last-child(n+6){min-width:1em;width:25%;max-width:100%;white-space:unset}}.tsf-metaboxes .tsf-default-selected{box-shadow:0 0 2px 0 #1c9d38}.tsf-metaboxes .tsf-warning-selected{box-shadow:0 0 2px 0 #dd3811}.tsf-metaboxes legend h4{margin:2px 0}}
1
+ #tsf-title-offset,#tsf-title-placeholder{right:0;white-space:pre;position:absolute}.tsf-metaboxes .tsf-top-buttons,.tsf-metaboxes .tsf-top-wrap>h1,.tsf-metaboxes .tsf-top-wrap>h2{float:left}.tsf-notice{position:relative;clear:both}.tsf-notice.tsf-show-icon p:before{content:'';margin-left:12px;background:0 0;display:inline-block;font:400 14px/16px dashicons;speak:none;height:16px;text-align:center;vertical-align:middle;width:16px;line-height:14px;-webkit-font-smoothing:antialiased}.error.tsf-notice.tsf-show-icon p:before{color:#dd3811;content:"\f534"}.notice-warning.tsf-notice.tsf-show-icon p:before{color:#ffa01b;content:"\f227"}.updated.tsf-notice.tsf-show-icon p:before{color:#0cc34b;font-size:16px;content:"\f147"}a.tsf-dismiss{position:absolute;top:0;left:1px;border:none;margin:0;padding:9px;background:0 0;color:#b4b9be;cursor:pointer;text-decoration:none}a.tsf-dismiss:before{background:0 0;content:"\f153";display:block;font:400 16px/20px dashicons;speak:none;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a.tsf-dismiss:hover{color:#c00}table.wp-list-table .column-name{width:15%}table.wp-list-table .column-icl_translations,table.wp-list-table .column-is_in_stock,table.wp-list-table .column-price,table.wp-list-table .column-sku,th.column-tsf-seo-bar-wrap~th{width:8%}.tsf-seo-bar a{text-decoration:none;font-size:13px}#tsf-title-wrap{position:relative;display:block;padding:0;height:auto;width:auto;overflow:hidden}#tsf-title-offset{visibility:hidden;height:0;display:inline-block;color:transparent}#tsf-title-placeholder{color:#777;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;top:0;overflow:hidden;text-overflow:ellipsis}.tsf-counter{font-weight:600;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}span.tsf-count-bad{color:#dd3811}span.tsf-count-okay{color:#ffa700}span.tsf-count-good{color:#0cc34b}span.tsf-counter-one{color:#fff;border-radius:4em;padding:0 .5em;min-width:2em;display:inline-block;text-align:center;vertical-align:baseline}span.tsf-counter-one.tsf-count-bad{background-color:#dd3811}span.tsf-counter-one.tsf-count-okay{background-color:#ffa700}span.tsf-counter-one.tsf-count-good{background-color:#0cc34b}#tsf-seo-bar-wrap{width:18%}th:last-of-type#tsf-seo-bar-wrap{width:160px}span.tsf-seo-bar{display:block;width:95%;max-width:220px;border-radius:0;padding:3px;text-shadow:0 0 3px rgba(0,0,0,.3)}span.tsf-seo-bar.tsf-100{width:100%}span.tsf-seo-bar-inner-wrap{display:table;width:100%;border-radius:0;margin:0 auto;border-collapse:separate;border-spacing:0;vertical-align:middle;position:relative}span.tsf-seo-bar-section-wrap{display:table-cell;border-collapse:collapse}.tsf-seo-bar-inner-wrap a{display:table;width:100%;color:#fff;text-align:center;cursor:help;height:100%;min-width:12px;vertical-align:top;line-height:1.625em;box-shadow:2px 0 0 -1px rgba(0,0,0,.1) inset,-2px 0 0 -1px rgba(0,0,0,.1) inset}span.tsf-seo-bar.pill,span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap{border-radius:30px}span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap a{box-shadow:2px 6px 3px -2px rgba(255,255,255,.2) inset,-2px -6px 3px -2px rgba(41,41,41,.2) inset,0 0 1px rgba(41,41,41,.6)}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type a{border-top-left-radius:30px;border-bottom-left-radius:30px}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type a{border-top-right-radius:30px;border-bottom-right-radius:30px}.tsf-100{width:100%}.tsf-60{width:60%}.tsf-50{width:50%}.tsf-40{width:40%}.tsf-33{width:33.333%}.tsf-25{width:25%}.tsf-20{width:20%}.tsf-16{width:16.666%}.tsf-12-5{width:12.5%}.tsf-11{width:11.333%}.tsf-10{width:10%}.tsf-seo-bar-bad{background-color:#dd3811}.tsf-seo-bar-okay{background-color:#ffa700}.tsf-seo-bar-good{background-color:#0cc34b}.tsf-seo-bar-unknown{background-color:#007bd2}span.tsf-seo-bar .tsf-explanation-desc{position:absolute;width:auto;min-width:90%;max-width:220px;font-weight:600;background:#007bd2;padding:8px 12px;color:#fdfdfd;border-radius:0;z-index:900142;box-shadow:0 0 2px rgba(0,0,0,.6);left:0;right:0;text-align:left;pointer-events:none}span.tsf-seo-bar .tsf-explanation-desc span{text-decoration:underline}span.tsf-seo-bar .tsf-explanation-desc div{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid #007bd2;position:absolute;bottom:-8px;z-index:9999999;left:0}.tsf-seo-bar-wrap.column-tsf-seo-bar-temp{overflow:initial!important;min-width:160px}#col-container,#col-right{overflow:initial}.tsf-metaboxes{box-sizing:border-box;max-width:690px;padding-bottom:20px}.tsf-metaboxes .tsf-top-wrap{width:100%;display:inline-block;vertical-align:top}.tsf-metaboxes .metabox-holder{clear:both}.tsf-metaboxes .tsf-bottom-buttons{text-align:left}.tsf-metaboxes .tsf-bottom-buttons input,.tsf-metaboxes .tsf-top-buttons input{margin-left:10px}.tsf-metaboxes #tsf-description-separator,.tsf-metaboxes #tsf-title-separator{display:table;width:100%;border-collapse:collapse;border-spacing:0}.tsf-metaboxes #tsf-description-separator input,.tsf-metaboxes #tsf-title-separator input{display:none;float:left;width:0;min-width:0;opacity:0}.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{display:inline-block;width:auto;min-width:28px;min-height:28px;margin:3px;-moz-margin-end:1.5px;-moz-margin-start:1.5px;padding:0 4px;border:1px solid #ccc;line-height:28px;text-align:center;cursor:pointer;box-shadow:-1px -1px 1px #aaa inset;font-size:16px}.tsf-metaboxes #tsf-description-separator label.tsf-recommended,.tsf-metaboxes #tsf-title-separator label.tsf-recommended{border:1px solid #0cc34b;box-shadow:-1px -1px 1px #0cc34b inset}.tsf-metaboxes #tsf-description-separator input:hover+label,.tsf-metaboxes #tsf-description-separator label:hover,.tsf-metaboxes #tsf-title-separator input:hover+label,.tsf-metaboxes #tsf-title-separator label:hover{box-shadow:1px 1px 1px #aaa inset;background-color:#fff}.tsf-metaboxes #tsf-description-separator input:checked+label,.tsf-metaboxes #tsf-title-separator input:checked+label{box-shadow:1px 1px 1px #333 inset;background-color:#fff}.tsf-metaboxes #tsf-home-title-location,.tsf-metaboxes #tsf-title-location{display:block}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span,.tsf-metaboxes #tsf-twitter-cards label span{display:inline-block;min-width:60px;vertical-align:baseline}.tsf-metaboxes #tsf-twitter-cards label span{min-width:150px}.tsf-metaboxes #tsf-home-title-location label .tsf-sep-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-blogname-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-tagline-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-title-js,.tsf-metaboxes #tsf-title-location label .tsf-sep-js{display:inline;min-width:0;white-space:pre}.tsf-metaboxes .tsf-nav-tab-wrapper,.tsf-metaboxes .tsf-tab-no-js{position:relative;clear:both;width:100%;display:inline-block;border-bottom:1px solid #ccc;line-height:inherit;padding:8px 12px 0;margin:-4px -12px}.tsf-metaboxes .tsf-nav-tab{float:right;border:1px solid #ccc;margin-right:.5em;margin-bottom:-1px;padding:5px 14px;font-size:12px;line-height:16px;background:#f1f1f1;color:#555;font-weight:600}.tsf-metaboxes .tsf-dashicons-tabs{font-size:initial;display:inline;vertical-align:text-bottom}.tsf-metaboxes .tsf-tabs-radio{display:none;width:0;height:0;position:absolute;left:-9001px}.tsf-metaboxes .tsf-active-tab,.tsf-metaboxes .tsf-tabs-radio:checked+label{background-color:inherit;border-bottom-color:#fff;color:#000}.tsf-metaboxes .tsf-tabs-content{margin:1.33em auto 0}.tsf-metaboxes .tsf-content-no-js{margin:1.33em auto}body.js .tsf-metaboxes .tsf-tabs-content{display:none}body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content{display:block}#tsf-inpost-box .inside,.tsf-flex{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 1 auto;flex:1 1 auto;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:flex-start;justify-content:flex-start}#tsf-inpost-box.closed .inside,body.js .tsf-flex-tab-content{display:none}#tsf-inpost-box .inside{margin:0;padding:0;-webkit-flex:1 0 100%;flex:1 0 100%;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.tsf-flex-inside-wrap{-webkit-flex-direction:row;flex-direction:row;-webkit-flex:1 1 auto;flex:1 1 auto}.tsf-flex-setting{width:100%;-webkit-flex-direction:row;flex-direction:row}.tsf-flex-setting-input,.tsf-flex-setting-label{background-color:#fff;padding:15px 12px;-webkit-flex:10 1 350px;flex:10 1 350px;box-shadow:0 0 0 1px #e9e9e9}.tsf-flex-setting-label{background-color:#f9f9f9;-webkit-flex:1 1 200px;flex:1 1 200px}.tsf-flex-setting-input{-webkit-justify-content:center;justify-content:center}.tsf-flex-setting-label-item{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between;-webkit-flex-grow:0;flex-grow:0}.tsf-flex-setting-label-inner-wrap{-webkit-justify-content:center;justify-content:center}.tsf-flex-setting-label-item>*{margin-right:4px}.tsf-flex-setting-label-item>:last-child{margin-right:0}.tsf-flex-setting-label .tsf-counter{font-weight:400;color:#666;margin-top:15px}.tsf-social-image-buttons{margin-top:15px;margin-left:1px}.tsf-flex-setting-input textarea{max-height:250px}input[type=radio].tsf-flex-nav-tab-radio{display:none;width:0;height:0;margin:0;padding:0;position:absolute;left:-9001px}.tsf-flex-nav-tab-wrapper{background-color:#fcfcfc;border-bottom:2px solid #dadada;-webkit-align-items:baseline;align-items:baseline;-webkit-flex-direction:row;flex-direction:row;-webkit-flex:1 1 100%;flex:1 1 100%;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-width:100%}.tsf-flex-nav-tab-inner{-webkit-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex:1 0 auto;flex:1 0 auto}.tsf-flex-nav-tab{-webkit-flex-direction:row;flex-direction:row;-webkit-flex:1 1 auto;flex:1 1 auto;max-width:125px}.tsf-flex-nav-tab-label{padding:12px;text-align:center;-webkit-flex-direction:row;flex-direction:row;box-shadow:0 0 0 0 transparent inset;-webkit-transition:box-shadow .15s ease-out;-o-transition:box-shadow .15s ease-out;transition:box-shadow .15s ease-out;-webkit-align-items:center;align-items:center;-webkit-align-content:space-between;align-content:space-between}.tsf-flex-nav-dashicon,.tsf-flex-nav-name{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked+.tsf-flex-nav-tab-label{box-shadow:0 -2px 0 0 #007bd2 inset;-webkit-transition:box-shadow .25s ease-in;-o-transition:box-shadow .25s ease-in;transition:box-shadow .25s ease-in}.tsf-flex-tab-content{-webkit-flex:1 0 100%;flex:1 0 100%;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}body.js .tsf-flex-tab-content.tsf-flex-tab-content-active{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tsf-flex-tabs-content-no-js{background-color:#f3f3f3;border-bottom:1px solid #dadada;box-shadow:0 2px 0 0 #dadada inset}.tsf-flex-tab-no-js{-webkit-align-items:baseline;align-items:baseline;-webkit-flex-direction:row;flex-direction:row;flex:1 1 100%}.tsf-flex-tab-no-js .tsf-flex-nav-tab{padding:12px;min-width:125px;box-shadow:0 -2px 0 0 #007bd2 inset;-webkit-flex-direction:row;flex-direction:row;-webkit-flex:0 1 auto;flex:0 1 auto}.tsf-metaboxes .tsf-default-selected{border-color:#1c9d38}.tsf-metaboxes .tsf-default-selected:checked:before{color:#1c9d38}.tsf-metaboxes .tsf-warning-selected{border-color:#dd3811}.tsf-metaboxes .tsf-warning-selected:checked:before{color:#dd3811}.tsf-fields{font-size:13px;line-height:1.5;margin:1em 0}.tsf-fields .tsf-toblock{display:block;width:100%;margin-bottom:4px}.tsf-fields p.description{margin:7px 0 5px;color:#666}.tsf-option-spacer{margin:1em 0}.tsf-checkbox-wrapper{margin-top:15px}.tsf-checkbox-wrapper:first-child{margin-top:0}.tsf-counter .tsf-ajax{margin-right:3px}.tsf-ajax:before{display:inline-block;line-height:1;font-family:dashicons;font-style:normal;font-weight:400;font-size:1.225em;vertical-align:middle;content:""}.tsf-ajax.tsf-loading:before{content:"\f463";color:#007bd2;-webkit-animation:tsf-spin 1.5s linear infinite;-moz-animation:tsf-spin 1.5s linear infinite;-o-animation:tsf-spin 1.5s linear infinite;animation:tsf-spin 1.5s linear infinite}.tsf-ajax.tsf-error:before{content:"\f158";color:#dd3811}.tsf-ajax.tsf-success:before{content:"\f147";color:#0cc34b}a.tsf-set-social-image.button{margin-left:7px}#tsf-inpost-box input[type=text]::-webkit-input-placeholder,#tsf-inpost-box textarea::-webkit-input-placeholder,.tsf-metaboxes input[type=text]::-webkit-input-placeholder,.tsf-metaboxes textarea::-webkit-input-placeholder{-webkit-transition:color .33s ease-in,text-shadow .33s ease-in;-o-transition:color .33s ease-in,text-shadow .33s ease-in;transition:color .33s ease-in,text-shadow .33s ease-in}#tsf-inpost-box input[type=text]::-moz-placeholder,#tsf-inpost-box textarea::-moz-placeholder,.tsf-metaboxes input[type=text]::-moz-placeholder,.tsf-metaboxes textarea::-moz-placeholder{-moz-transition:color .33s ease-in,text-shadow .33s ease-in;transition:color .33s ease-in,text-shadow .33s ease-in}#tsf-inpost-box input[type=text]:-ms-input-placeholder,#tsf-inpost-box textarea:-ms-input-placeholder,.tsf-metaboxes input[type=text]:-ms-input-placeholder,.tsf-metaboxes textarea:-ms-input-placeholder{transition:color .33s ease-in,text-shadow .33s ease-in}#tsf-inpost-box input[type=text]:focus::-webkit-input-placeholder,#tsf-inpost-box textarea:focus::-webkit-input-placeholder,.tsf-metaboxes input[type=text]:focus::-webkit-input-placeholder,.tsf-metaboxes textarea:focus::-webkit-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus::-moz-placeholder,#tsf-inpost-box textarea:focus::-moz-placeholder,.tsf-metaboxe textarea:focus::-moz-placeholder,.tsf-metaboxes input[type=text]:focus::-moz-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus:-ms-input-placeholder,#tsf-inpost-box textarea:focus:-ms-input-placeholder,.tsf-metaboxes input[type=text]:focus:-ms-input-placeholder,.tsf-metaboxes textarea:focus:-ms-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}@-webkit-keyframes tsf-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}@keyframes tsf-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@media screen and (max-width:782px){.tsf-inpost-box p.tsf-fields,.tsf-metaboxes p.tsf-fields{line-height:2.8}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span{min-width:40px}.wp-list-table .is-expanded td.tsf-seo-bar-wrap:not(.hidden){overflow:initial!important}}@media screen and (max-width:642px){.tsf-metaboxes span.tsf-nav-desktop{display:none}}@media screen and (max-width:510px){span.tsf-seo-bar.tsf-100{width:inherit}}@-moz-document url-prefix(){.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{margin:3px 1px}@media only screen and (min-width:768px){.widefat tr td.column-title:nth-child(2):nth-last-child(n+6),.widefat tr td.title:nth-child(2):nth-last-child(n+6),.widefat tr th.column-title:nth-child(2):nth-last-child(n+6),.widefat tr th.title:nth-child(2):nth-last-child(n+6){min-width:1em;width:25%;max-width:100%;white-space:unset}}.tsf-metaboxes .tsf-default-selected{box-shadow:0 0 2px 0 #1c9d38}.tsf-metaboxes .tsf-warning-selected{box-shadow:0 0 2px 0 #dd3811}.tsf-metaboxes legend h4{margin:2px 0}}.tsf-flex-hide-if-no-js,body.js .tsf-flex-hide-if-js{display:none}body.js .tsf-flex-hide-if-no-js{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}
lib/css/tsf.css CHANGED
@@ -124,7 +124,7 @@ th.column-tsf-seo-bar-wrap ~ th {
124
  top: 0;
125
  left: 0;
126
  overflow: hidden;
127
- white-space: nowrap;
128
  text-overflow: ellipsis;
129
  }
130
 
@@ -280,7 +280,7 @@ span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap a {
280
  width: 12.5%;
281
  }
282
 
283
- .ad-11 {
284
  width: 11.333%;
285
  }
286
 
@@ -319,6 +319,7 @@ span.tsf-seo-bar .tsf-explanation-desc {
319
  left: 0;
320
  right: 0;
321
  text-align: left;
 
322
  }
323
 
324
  span.tsf-seo-bar .tsf-explanation-desc span {
@@ -541,6 +542,250 @@ body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content {
541
  * End tabs.
542
  */
543
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
  .tsf-metaboxes .tsf-default-selected {
545
  border-color: #1c9d38;
546
  }
@@ -578,6 +823,17 @@ body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content {
578
  margin: 1em 0;
579
  }
580
 
 
 
 
 
 
 
 
 
 
 
 
581
  .tsf-counter .tsf-ajax {
582
  margin-left: 3px;
583
  }
@@ -620,24 +876,24 @@ a.tsf-set-social-image.button {
620
  #tsf-inpost-box textarea::-webkit-input-placeholder,
621
  .tsf-metaboxes input[type="text"]::-webkit-input-placeholder,
622
  .tsf-metaboxes textarea::-webkit-input-placeholder {
623
- -webkit-transition: all 0.33s ease-in;
624
- -o-transition: all 0.33s ease-in;
625
- transition: all 0.33s ease-in;
626
  }
627
 
628
  #tsf-inpost-box input[type="text"]::-moz-placeholder,
629
  #tsf-inpost-box textarea::-moz-placeholder,
630
  .tsf-metaboxes input[type="text"]::-moz-placeholder,
631
  .tsf-metaboxes textarea::-moz-placeholder {
632
- -moz-transition: all 0.33s ease-in;
633
- transition: all 0.33s ease-in;
634
  }
635
 
636
  #tsf-inpost-box input[type="text"]:-ms-input-placeholder,
637
  #tsf-inpost-box textarea:-ms-input-placeholder,
638
  .tsf-metaboxes input[type="text"]:-ms-input-placeholder,
639
  .tsf-metaboxes textarea:-ms-input-placeholder {
640
- transition: all 0.33s ease-in;
641
  }
642
 
643
  #tsf-inpost-box input[type="text"]:focus::-webkit-input-placeholder,
@@ -745,3 +1001,19 @@ a.tsf-set-social-image.button {
745
  margin: 2px 0;
746
  }
747
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  top: 0;
125
  left: 0;
126
  overflow: hidden;
127
+ white-space: pre;
128
  text-overflow: ellipsis;
129
  }
130
 
280
  width: 12.5%;
281
  }
282
 
283
+ .tsf-11 {
284
  width: 11.333%;
285
  }
286
 
319
  left: 0;
320
  right: 0;
321
  text-align: left;
322
+ pointer-events: none;
323
  }
324
 
325
  span.tsf-seo-bar .tsf-explanation-desc span {
542
  * End tabs.
543
  */
544
 
545
+ /**
546
+ * Start Inpost.
547
+ */
548
+
549
+ .tsf-flex,
550
+ #tsf-inpost-box .inside {
551
+ box-sizing: border-box;
552
+ display: -webkit-box;
553
+ display: -webkit-flex;
554
+ display: -ms-flexbox;
555
+ display: flex;
556
+ -webkit-flex: 1 1 auto;
557
+ flex: 1 1 auto;
558
+ -webkit-flex-wrap: wrap;
559
+ -ms-flex-wrap: wrap;
560
+ flex-wrap: wrap;
561
+ -webkit-flex-direction: column;
562
+ flex-direction: column;
563
+ -webkit-justify-content: flex-start;
564
+ justify-content: flex-start;
565
+ }
566
+
567
+ #tsf-inpost-box .inside {
568
+ margin: 0;
569
+ padding: 0;
570
+ -webkit-flex: 1 0 100%;
571
+ flex: 1 0 100%;
572
+ -webkit-flex-wrap: nowrap;
573
+ -ms-flex-wrap: nowrap;
574
+ flex-wrap: nowrap;
575
+ }
576
+
577
+ #tsf-inpost-box.closed .inside {
578
+ display: none;
579
+ }
580
+
581
+ .tsf-flex-inside-wrap {
582
+ /* IE11 wrapper fix */
583
+ -webkit-flex-direction: row;
584
+ flex-direction: row;
585
+ -webkit-flex: 1 1 auto;
586
+ flex: 1 1 auto;
587
+ }
588
+
589
+ .tsf-flex-setting {
590
+ width: 100%;
591
+ -webkit-flex-direction: row;
592
+ flex-direction: row;
593
+ }
594
+
595
+ .tsf-flex-setting-label,
596
+ .tsf-flex-setting-input {
597
+ background-color: #fff;
598
+ padding: 15px 12px;
599
+ -webkit-flex: 10 1 350px;
600
+ flex: 10 1 350px;
601
+ box-shadow: 0 0 0 1px #e9e9e9;
602
+ }
603
+
604
+ .tsf-flex-setting-label {
605
+ background-color: #f9f9f9;
606
+ -webkit-flex: 1 1 200px;
607
+ flex: 1 1 200px;
608
+ }
609
+
610
+ .tsf-flex-setting-input {
611
+ -webkit-justify-content: center;
612
+ justify-content: center;
613
+ }
614
+
615
+ .tsf-flex-setting-label-item {
616
+ -webkit-flex-wrap: nowrap;
617
+ -ms-flex-wrap: nowrap;
618
+ flex-wrap: nowrap;
619
+ -webkit-flex-direction: row;
620
+ flex-direction: row;
621
+ -webkit-justify-content: space-between;
622
+ justify-content: space-between;
623
+ -webkit-flex-grow: 0;
624
+ flex-grow: 0;
625
+ }
626
+
627
+ .tsf-flex-setting-label-inner-wrap {
628
+ -webkit-justify-content: center;
629
+ justify-content: center;
630
+ }
631
+
632
+ .tsf-flex-setting-label-item > * {
633
+ margin-right: 4px;
634
+ }
635
+
636
+ .tsf-flex-setting-label-item > *:last-child {
637
+ margin-right: 0;
638
+ }
639
+
640
+ .tsf-flex-setting-label .tsf-counter {
641
+ font-weight: 400;
642
+ color: #666;
643
+ margin-top: 15px;
644
+ }
645
+
646
+ .tsf-social-image-buttons {
647
+ margin-top: 15px;
648
+ margin-left: 1px;
649
+ }
650
+
651
+ .tsf-flex-setting-input textarea {
652
+ max-height: 250px;
653
+ }
654
+
655
+ /* Start inpost tabs */
656
+ input[type="radio"].tsf-flex-nav-tab-radio {
657
+ display: none;
658
+ width: 0;
659
+ height: 0;
660
+ margin: 0;
661
+ padding: 0;
662
+ position: absolute;
663
+ left: -9001px;
664
+ }
665
+
666
+ .tsf-flex-nav-tab-wrapper {
667
+ background-color: #fcfcfc;
668
+ border-bottom: 2px solid #dadada;
669
+ -webkit-align-items: baseline;
670
+ align-items: baseline;
671
+ -webkit-flex-direction: row;
672
+ flex-direction: row;
673
+ /* IE11 fix */
674
+ -webkit-flex: 1 1 100%;
675
+ flex: 1 1 100%;
676
+ /* Firefox fix, don't use overflow:hidden because that could cause more issues. */
677
+ -webkit-flex-wrap: nowrap;
678
+ -ms-flex-wrap: nowrap;
679
+ flex-wrap: nowrap;
680
+ max-width: 100%;
681
+ }
682
+
683
+ .tsf-flex-nav-tab-inner {
684
+ -webkit-flex-direction: row;
685
+ flex-direction: row;
686
+ -webkit-flex-wrap: nowrap;
687
+ -ms-flex-wrap: nowrap;
688
+ flex-wrap: nowrap;
689
+ /* IE11 reverse fix for newer browsers */
690
+ -webkit-flex: 1 0 auto;
691
+ flex: 1 0 auto;
692
+ }
693
+
694
+ .tsf-flex-nav-tab {
695
+ -webkit-flex-direction: row;
696
+ flex-direction: row;
697
+ /* Edge bug */
698
+ -webkit-flex: 0 1 125px;
699
+ flex: 0 1 125px;
700
+ /* IE11 bug */
701
+ -webkit-flex: 1 1 100%;
702
+ flex: 1 1 100%;
703
+ /* Edge/IE11 fix */
704
+ -webkit-flex: 1 1 auto;
705
+ flex: 1 1 auto;
706
+ max-width: 125px; /* I wanted this to be flex-basis */
707
+ }
708
+
709
+ .tsf-flex-nav-tab-label {
710
+ padding: 12px;
711
+ text-align: center;
712
+ -webkit-flex-direction: row;
713
+ flex-direction: row;
714
+ box-shadow: 0 0 0 0 transparent inset;
715
+ -webkit-transition: box-shadow 0.15s ease-out;
716
+ -o-transition: box-shadow 0.15s ease-out;
717
+ transition: box-shadow 0.15s ease-out;
718
+ -webkit-align-items: center;
719
+ align-items: center;
720
+ -webkit-align-content: space-between;
721
+ align-content: space-between;
722
+ }
723
+
724
+ .tsf-flex-nav-dashicon,
725
+ .tsf-flex-nav-name {
726
+ -webkit-align-items: center;
727
+ align-items: center;
728
+ -webkit-justify-content: center;
729
+ justify-content: center;
730
+ }
731
+
732
+ .tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked + .tsf-flex-nav-tab-label {
733
+ box-shadow: 0 -2px 0 0 #007bd2 inset;
734
+ -webkit-transition: box-shadow 0.25s ease-in;
735
+ -o-transition: box-shadow 0.25s ease-in;
736
+ transition: box-shadow 0.25s ease-in;
737
+ }
738
+
739
+ .tsf-flex-tab-content {
740
+ -webkit-flex: 1 0 100%;
741
+ flex: 1 0 100%;
742
+ -webkit-flex-wrap: nowrap;
743
+ -ms-flex-wrap: nowrap;
744
+ flex-wrap: nowrap;
745
+ }
746
+
747
+ body.js .tsf-flex-tab-content {
748
+ display: none;
749
+ }
750
+
751
+ body.js .tsf-flex-tab-content.tsf-flex-tab-content-active {
752
+ display: -webkit-box;
753
+ display: -webkit-flex;
754
+ display: -ms-flexbox;
755
+ display: flex;
756
+ }
757
+
758
+ .tsf-flex-tabs-content-no-js {
759
+ background-color: #f3f3f3;
760
+ border-bottom: 1px solid #dadada;
761
+ box-shadow: 0 2px 0 0 #dadada inset;
762
+ }
763
+
764
+ .tsf-flex-tab-no-js {
765
+ -webkit-align-items: baseline;
766
+ align-items: baseline;
767
+ -webkit-flex-direction: row;
768
+ flex-direction: row;
769
+ flex: 1 1 100%;
770
+ }
771
+
772
+ .tsf-flex-tab-no-js .tsf-flex-nav-tab {
773
+ padding: 12px;
774
+ min-width: 125px;
775
+ box-shadow: 0 -2px 0 0 #007bd2 inset;
776
+ -webkit-flex-direction: row;
777
+ flex-direction: row;
778
+ -webkit-flex: 0 1 auto;
779
+ flex: 0 1 auto;
780
+ }
781
+
782
+ /**
783
+ * End inpost.
784
+ */
785
+
786
+ /**
787
+ * General fields.
788
+ */
789
  .tsf-metaboxes .tsf-default-selected {
790
  border-color: #1c9d38;
791
  }
823
  margin: 1em 0;
824
  }
825
 
826
+ .tsf-checkbox-wrapper {
827
+ margin-top: 15px;
828
+ }
829
+
830
+ .tsf-checkbox-wrapper:first-child {
831
+ margin-top: 0;
832
+ }
833
+
834
+ /**
835
+ * Start AJAX
836
+ */
837
  .tsf-counter .tsf-ajax {
838
  margin-left: 3px;
839
  }
876
  #tsf-inpost-box textarea::-webkit-input-placeholder,
877
  .tsf-metaboxes input[type="text"]::-webkit-input-placeholder,
878
  .tsf-metaboxes textarea::-webkit-input-placeholder {
879
+ -webkit-transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
880
+ -o-transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
881
+ transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
882
  }
883
 
884
  #tsf-inpost-box input[type="text"]::-moz-placeholder,
885
  #tsf-inpost-box textarea::-moz-placeholder,
886
  .tsf-metaboxes input[type="text"]::-moz-placeholder,
887
  .tsf-metaboxes textarea::-moz-placeholder {
888
+ -moz-transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
889
+ transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
890
  }
891
 
892
  #tsf-inpost-box input[type="text"]:-ms-input-placeholder,
893
  #tsf-inpost-box textarea:-ms-input-placeholder,
894
  .tsf-metaboxes input[type="text"]:-ms-input-placeholder,
895
  .tsf-metaboxes textarea:-ms-input-placeholder {
896
+ transition: color 0.33s ease-in, text-shadow 0.33s ease-in;
897
  }
898
 
899
  #tsf-inpost-box input[type="text"]:focus::-webkit-input-placeholder,
1001
  margin: 2px 0;
1002
  }
1003
  }
1004
+
1005
+ /**
1006
+ * Start override
1007
+ */
1008
+
1009
+ body.js .tsf-flex-hide-if-js,
1010
+ .tsf-flex-hide-if-no-js {
1011
+ display: none;
1012
+ }
1013
+
1014
+ body.js .tsf-flex-hide-if-no-js {
1015
+ display: -webkit-box;
1016
+ display: -webkit-flex;
1017
+ display: -ms-flexbox;
1018
+ display: flex;
1019
+ }
lib/css/tsf.min.css CHANGED
@@ -1 +1 @@
1
- .tsf-notice{position:relative;clear:both}.tsf-notice.tsf-show-icon p:before{content:'';margin-right:12px;background:0 0;display:inline-block;font:400 14px/16px dashicons;speak:none;height:16px;text-align:center;vertical-align:middle;width:16px;line-height:14px;-webkit-font-smoothing:antialiased}.error.tsf-notice.tsf-show-icon p:before{color:#dd3811;content:"\f534"}.notice-warning.tsf-notice.tsf-show-icon p:before{color:#ffa01b;content:"\f227"}.updated.tsf-notice.tsf-show-icon p:before{color:#0cc34b;font-size:16px;content:"\f147"}a.tsf-dismiss{position:absolute;top:0;right:1px;border:none;margin:0;padding:9px;background:0 0;color:#b4b9be;cursor:pointer;text-decoration:none}a.tsf-dismiss:before{background:0 0;content:"\f153";display:block;font:400 16px/20px dashicons;speak:none;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a.tsf-dismiss:hover{color:#c00}table.wp-list-table .column-name{width:15%}table.wp-list-table .column-icl_translations,table.wp-list-table .column-is_in_stock,table.wp-list-table .column-price,table.wp-list-table .column-sku,th.column-tsf-seo-bar-wrap~th{width:8%}.tsf-seo-bar a{text-decoration:none;font-size:13px}#tsf-title-wrap{position:relative;display:block;padding:0;height:auto;width:auto;overflow:hidden}#tsf-title-offset{visibility:hidden;height:0;display:inline-block;position:absolute;left:0;color:transparent;white-space:pre}#tsf-title-placeholder{position:absolute;color:#777;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;top:0;left:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.tsf-counter{font-weight:600;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}span.tsf-count-bad{color:#dd3811}span.tsf-count-okay{color:#ffa700}span.tsf-count-good{color:#0cc34b}span.tsf-counter-one{color:#fff;border-radius:4em;padding:0 .5em;min-width:2em;display:inline-block;text-align:center;vertical-align:baseline}span.tsf-counter-one.tsf-count-bad{background-color:#dd3811}span.tsf-counter-one.tsf-count-okay{background-color:#ffa700}span.tsf-counter-one.tsf-count-good{background-color:#0cc34b}#tsf-seo-bar-wrap{width:18%}th:last-of-type#tsf-seo-bar-wrap{width:160px}span.tsf-seo-bar{display:block;width:95%;max-width:220px;border-radius:0;padding:3px;text-shadow:0 0 3px rgba(0,0,0,.3)}span.tsf-seo-bar.tsf-100{width:100%}span.tsf-seo-bar-inner-wrap{display:table;width:100%;border-radius:0;margin:0 auto;border-collapse:separate;border-spacing:0;vertical-align:middle;position:relative}span.tsf-seo-bar-section-wrap{display:table-cell;border-collapse:collapse}.tsf-seo-bar-inner-wrap a{display:table;width:100%;color:#fff;text-align:center;cursor:help;height:100%;min-width:12px;vertical-align:top;line-height:1.625em;box-shadow:2px 0 0 -1px rgba(0,0,0,.1) inset,-2px 0 0 -1px rgba(0,0,0,.1) inset}span.tsf-seo-bar.pill,span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap{border-radius:30px}span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap a{box-shadow:2px 6px 3px -2px rgba(255,255,255,.2) inset,-2px -6px 3px -2px rgba(41,41,41,.2) inset,0 0 1px rgba(41,41,41,.6)}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type a{border-top-left-radius:30px;border-bottom-left-radius:30px}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type a{border-top-right-radius:30px;border-bottom-right-radius:30px}.tsf-100{width:100%}.tsf-60{width:60%}.tsf-50{width:50%}.tsf-40{width:40%}.tsf-33{width:33.333%}.tsf-25{width:25%}.tsf-20{width:20%}.tsf-16{width:16.666%}.tsf-12-5{width:12.5%}.ad-11{width:11.333%}.tsf-10{width:10%}.tsf-seo-bar-bad{background-color:#dd3811}.tsf-seo-bar-okay{background-color:#ffa700}.tsf-seo-bar-good{background-color:#0cc34b}.tsf-seo-bar-unknown{background-color:#007bd2}span.tsf-seo-bar .tsf-explanation-desc{position:absolute;width:auto;min-width:90%;max-width:220px;font-weight:600;background:#007bd2;padding:8px 12px;color:#fdfdfd;border-radius:0;z-index:900142;box-shadow:0 0 2px rgba(0,0,0,.6);left:0;right:0;text-align:left}span.tsf-seo-bar .tsf-explanation-desc span{text-decoration:underline}span.tsf-seo-bar .tsf-explanation-desc div{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid #007bd2;position:absolute;bottom:-8px;z-index:9999999;left:0}.tsf-seo-bar-wrap.column-tsf-seo-bar-temp{overflow:initial!important;min-width:160px}#col-container,#col-right{overflow:initial}.tsf-metaboxes{box-sizing:border-box;max-width:690px;padding-bottom:20px}.tsf-metaboxes .tsf-top-wrap{width:100%;display:inline-block;vertical-align:top}.tsf-metaboxes .tsf-top-wrap>h1,.tsf-metaboxes .tsf-top-wrap>h2{float:left}.tsf-metaboxes .metabox-holder{clear:both}.tsf-metaboxes .tsf-top-buttons{float:right}.tsf-metaboxes .tsf-bottom-buttons{text-align:right}.tsf-metaboxes .tsf-bottom-buttons input,.tsf-metaboxes .tsf-top-buttons input{margin-left:10px}.tsf-metaboxes #tsf-description-separator,.tsf-metaboxes #tsf-title-separator{display:table;width:100%;border-collapse:collapse;border-spacing:0}.tsf-metaboxes #tsf-description-separator input,.tsf-metaboxes #tsf-title-separator input{display:none;float:left;width:0;min-width:0;opacity:0}.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{display:inline-block;width:auto;min-width:28px;min-height:28px;margin:3px;-moz-margin-end:1.5px;-moz-margin-start:1.5px;padding:0 4px;border:1px solid #ccc;line-height:28px;text-align:center;cursor:pointer;box-shadow:-1px -1px 1px #aaa inset;font-size:16px}.tsf-metaboxes #tsf-description-separator label.tsf-recommended,.tsf-metaboxes #tsf-title-separator label.tsf-recommended{border:1px solid #0cc34b;box-shadow:-1px -1px 1px #0cc34b inset}.tsf-metaboxes #tsf-description-separator input:hover+label,.tsf-metaboxes #tsf-description-separator label:hover,.tsf-metaboxes #tsf-title-separator input:hover+label,.tsf-metaboxes #tsf-title-separator label:hover{box-shadow:1px 1px 1px #aaa inset;background-color:#fff}.tsf-metaboxes #tsf-description-separator input:checked+label,.tsf-metaboxes #tsf-title-separator input:checked+label{box-shadow:1px 1px 1px #333 inset;background-color:#fff}.tsf-metaboxes #tsf-home-title-location,.tsf-metaboxes #tsf-title-location{display:block}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span,.tsf-metaboxes #tsf-twitter-cards label span{display:inline-block;min-width:60px;vertical-align:baseline}.tsf-metaboxes #tsf-twitter-cards label span{min-width:150px}.tsf-metaboxes #tsf-home-title-location label .tsf-sep-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-blogname-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-tagline-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-title-js,.tsf-metaboxes #tsf-title-location label .tsf-sep-js{display:inline;min-width:0;white-space:pre}.tsf-metaboxes .tsf-nav-tab-wrapper,.tsf-metaboxes .tsf-tab-no-js{position:relative;clear:both;width:100%;display:inline-block;border-bottom:1px solid #ccc;line-height:inherit;padding:8px 12px 0;margin:-4px -12px}.tsf-metaboxes .tsf-nav-tab{float:left;border:1px solid #ccc;margin-left:.5em;margin-bottom:-1px;padding:5px 14px;font-size:12px;line-height:16px;background:#f1f1f1;color:#555;font-weight:600}.tsf-metaboxes .tsf-dashicons-tabs{font-size:initial;display:inline;vertical-align:text-bottom}.tsf-metaboxes .tsf-tabs-radio{display:none;width:0;height:0;position:absolute;left:-9001px}.tsf-metaboxes .tsf-active-tab,.tsf-metaboxes .tsf-tabs-radio:checked+label{background-color:inherit;border-bottom-color:#fff;color:#000}.tsf-metaboxes .tsf-tabs-content{margin:1.33em auto 0}.tsf-metaboxes .tsf-content-no-js{margin:1.33em auto}body.js .tsf-metaboxes .tsf-tabs-content{display:none}body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content{display:block}.tsf-metaboxes .tsf-default-selected{border-color:#1c9d38}.tsf-metaboxes .tsf-default-selected:checked:before{color:#1c9d38}.tsf-metaboxes .tsf-warning-selected{border-color:#dd3811}.tsf-metaboxes .tsf-warning-selected:checked:before{color:#dd3811}.tsf-fields{font-size:13px;line-height:1.5;margin:1em 0}.tsf-fields .tsf-toblock{display:block;width:100%;margin-bottom:4px}.tsf-fields p.description{margin:7px 0 5px;color:#666}.tsf-option-spacer{margin:1em 0}.tsf-counter .tsf-ajax{margin-left:3px}.tsf-ajax:before{display:inline-block;line-height:1;font-family:dashicons;font-style:normal;font-weight:400;font-size:1.225em;vertical-align:middle;content:""}.tsf-ajax.tsf-loading:before{content:"\f463";color:#007bd2;-webkit-animation:tsf-spin 1.5s linear infinite;-moz-animation:tsf-spin 1.5s linear infinite;-o-animation:tsf-spin 1.5s linear infinite;animation:tsf-spin 1.5s linear infinite}.tsf-ajax.tsf-error:before{content:"\f158";color:#dd3811}.tsf-ajax.tsf-success:before{content:"\f147";color:#0cc34b}a.tsf-set-social-image.button{margin-right:7px}#tsf-inpost-box input[type=text]::-webkit-input-placeholder,#tsf-inpost-box textarea::-webkit-input-placeholder,.tsf-metaboxes input[type=text]::-webkit-input-placeholder,.tsf-metaboxes textarea::-webkit-input-placeholder{-webkit-transition:all .33s ease-in;-o-transition:all .33s ease-in;transition:all .33s ease-in}#tsf-inpost-box input[type=text]::-moz-placeholder,#tsf-inpost-box textarea::-moz-placeholder,.tsf-metaboxes input[type=text]::-moz-placeholder,.tsf-metaboxes textarea::-moz-placeholder{-moz-transition:all .33s ease-in;transition:all .33s ease-in}#tsf-inpost-box input[type=text]:-ms-input-placeholder,#tsf-inpost-box textarea:-ms-input-placeholder,.tsf-metaboxes input[type=text]:-ms-input-placeholder,.tsf-metaboxes textarea:-ms-input-placeholder{transition:all .33s ease-in}#tsf-inpost-box input[type=text]:focus::-webkit-input-placeholder,#tsf-inpost-box textarea:focus::-webkit-input-placeholder,.tsf-metaboxes input[type=text]:focus::-webkit-input-placeholder,.tsf-metaboxes textarea:focus::-webkit-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus::-moz-placeholder,#tsf-inpost-box textarea:focus::-moz-placeholder,.tsf-metaboxe textarea:focus::-moz-placeholder,.tsf-metaboxes input[type=text]:focus::-moz-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus:-ms-input-placeholder,#tsf-inpost-box textarea:focus:-ms-input-placeholder,.tsf-metaboxes input[type=text]:focus:-ms-input-placeholder,.tsf-metaboxes textarea:focus:-ms-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}@-webkit-keyframes tsf-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}@keyframes tsf-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@media screen and (max-width:782px){.tsf-inpost-box p.tsf-fields,.tsf-metaboxes p.tsf-fields{line-height:2.8}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span{min-width:40px}.wp-list-table .is-expanded td.tsf-seo-bar-wrap:not(.hidden){overflow:initial!important}}@media screen and (max-width:642px){.tsf-metaboxes span.tsf-nav-desktop{display:none}}@media screen and (max-width:510px){span.tsf-seo-bar.tsf-100{width:inherit}}@-moz-document url-prefix(){.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{margin:3px 1px}@media only screen and (min-width:768px){.widefat tr td.column-title:nth-child(2):nth-last-child(n+6),.widefat tr td.title:nth-child(2):nth-last-child(n+6),.widefat tr th.column-title:nth-child(2):nth-last-child(n+6),.widefat tr th.title:nth-child(2):nth-last-child(n+6){min-width:1em;width:25%;max-width:100%;white-space:unset}}.tsf-metaboxes .tsf-default-selected{box-shadow:0 0 2px 0 #1c9d38}.tsf-metaboxes .tsf-warning-selected{box-shadow:0 0 2px 0 #dd3811}.tsf-metaboxes legend h4{margin:2px 0}}
1
+ .tsf-notice{position:relative;clear:both}.tsf-notice.tsf-show-icon p:before{content:'';margin-right:12px;background:0 0;display:inline-block;font:400 14px/16px dashicons;speak:none;height:16px;text-align:center;vertical-align:middle;width:16px;line-height:14px;-webkit-font-smoothing:antialiased}.error.tsf-notice.tsf-show-icon p:before{color:#dd3811;content:"\f534"}.notice-warning.tsf-notice.tsf-show-icon p:before{color:#ffa01b;content:"\f227"}.updated.tsf-notice.tsf-show-icon p:before{color:#0cc34b;font-size:16px;content:"\f147"}a.tsf-dismiss{position:absolute;top:0;right:1px;border:none;margin:0;padding:9px;background:0 0;color:#b4b9be;cursor:pointer;text-decoration:none}a.tsf-dismiss:before{background:0 0;content:"\f153";display:block;font:400 16px/20px dashicons;speak:none;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a.tsf-dismiss:hover{color:#c00}table.wp-list-table .column-name{width:15%}table.wp-list-table .column-icl_translations,table.wp-list-table .column-is_in_stock,table.wp-list-table .column-price,table.wp-list-table .column-sku,th.column-tsf-seo-bar-wrap~th{width:8%}.tsf-seo-bar a{text-decoration:none;font-size:13px}#tsf-title-wrap{position:relative;display:block;padding:0;height:auto;width:auto;overflow:hidden}#tsf-title-offset{visibility:hidden;height:0;display:inline-block;position:absolute;left:0;color:transparent;white-space:pre}#tsf-title-placeholder{position:absolute;color:#777;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;top:0;left:0;overflow:hidden;white-space:pre;text-overflow:ellipsis}.tsf-counter{font-weight:600;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}span.tsf-count-bad{color:#dd3811}span.tsf-count-okay{color:#ffa700}span.tsf-count-good{color:#0cc34b}span.tsf-counter-one{color:#fff;border-radius:4em;padding:0 .5em;min-width:2em;display:inline-block;text-align:center;vertical-align:baseline}span.tsf-counter-one.tsf-count-bad{background-color:#dd3811}span.tsf-counter-one.tsf-count-okay{background-color:#ffa700}span.tsf-counter-one.tsf-count-good{background-color:#0cc34b}#tsf-seo-bar-wrap{width:18%}th:last-of-type#tsf-seo-bar-wrap{width:160px}span.tsf-seo-bar{display:block;width:95%;max-width:220px;border-radius:0;padding:3px;text-shadow:0 0 3px rgba(0,0,0,.3)}span.tsf-seo-bar.tsf-100{width:100%}span.tsf-seo-bar-inner-wrap{display:table;width:100%;border-radius:0;margin:0 auto;border-collapse:separate;border-spacing:0;vertical-align:middle;position:relative}span.tsf-seo-bar-section-wrap{display:table-cell;border-collapse:collapse}.tsf-seo-bar-inner-wrap a{display:table;width:100%;color:#fff;text-align:center;cursor:help;height:100%;min-width:12px;vertical-align:top;line-height:1.625em;box-shadow:2px 0 0 -1px rgba(0,0,0,.1) inset,-2px 0 0 -1px rgba(0,0,0,.1) inset}span.tsf-seo-bar.pill,span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap{border-radius:30px}span.tsf-seo-bar.pill span.tsf-seo-bar-inner-wrap a{box-shadow:2px 6px 3px -2px rgba(255,255,255,.2) inset,-2px -6px 3px -2px rgba(41,41,41,.2) inset,0 0 1px rgba(41,41,41,.6)}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:first-of-type a{border-top-left-radius:30px;border-bottom-left-radius:30px}.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type,.tsf-seo-bar.pill .tsf-seo-bar-inner-wrap span.tsf-seo-bar-section-wrap:last-of-type a{border-top-right-radius:30px;border-bottom-right-radius:30px}.tsf-100{width:100%}.tsf-60{width:60%}.tsf-50{width:50%}.tsf-40{width:40%}.tsf-33{width:33.333%}.tsf-25{width:25%}.tsf-20{width:20%}.tsf-16{width:16.666%}.tsf-12-5{width:12.5%}.tsf-11{width:11.333%}.tsf-10{width:10%}.tsf-seo-bar-bad{background-color:#dd3811}.tsf-seo-bar-okay{background-color:#ffa700}.tsf-seo-bar-good{background-color:#0cc34b}.tsf-seo-bar-unknown{background-color:#007bd2}span.tsf-seo-bar .tsf-explanation-desc{position:absolute;width:auto;min-width:90%;max-width:220px;font-weight:600;background:#007bd2;padding:8px 12px;color:#fdfdfd;border-radius:0;z-index:900142;box-shadow:0 0 2px rgba(0,0,0,.6);left:0;right:0;text-align:left;pointer-events:none}span.tsf-seo-bar .tsf-explanation-desc span{text-decoration:underline}span.tsf-seo-bar .tsf-explanation-desc div{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid #007bd2;position:absolute;bottom:-8px;z-index:9999999;left:0}.tsf-seo-bar-wrap.column-tsf-seo-bar-temp{overflow:initial!important;min-width:160px}#col-container,#col-right{overflow:initial}.tsf-metaboxes{box-sizing:border-box;max-width:690px;padding-bottom:20px}.tsf-metaboxes .tsf-top-wrap{width:100%;display:inline-block;vertical-align:top}.tsf-metaboxes .tsf-top-wrap>h1,.tsf-metaboxes .tsf-top-wrap>h2{float:left}.tsf-metaboxes .metabox-holder{clear:both}.tsf-metaboxes .tsf-top-buttons{float:right}.tsf-metaboxes .tsf-bottom-buttons{text-align:right}.tsf-metaboxes .tsf-bottom-buttons input,.tsf-metaboxes .tsf-top-buttons input{margin-left:10px}.tsf-metaboxes #tsf-description-separator,.tsf-metaboxes #tsf-title-separator{display:table;width:100%;border-collapse:collapse;border-spacing:0}.tsf-metaboxes #tsf-description-separator input,.tsf-metaboxes #tsf-title-separator input{display:none;float:left;width:0;min-width:0;opacity:0}.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{display:inline-block;width:auto;min-width:28px;min-height:28px;margin:3px;-moz-margin-end:1.5px;-moz-margin-start:1.5px;padding:0 4px;border:1px solid #ccc;line-height:28px;text-align:center;cursor:pointer;box-shadow:-1px -1px 1px #aaa inset;font-size:16px}.tsf-metaboxes #tsf-description-separator label.tsf-recommended,.tsf-metaboxes #tsf-title-separator label.tsf-recommended{border:1px solid #0cc34b;box-shadow:-1px -1px 1px #0cc34b inset}.tsf-metaboxes #tsf-description-separator input:hover+label,.tsf-metaboxes #tsf-description-separator label:hover,.tsf-metaboxes #tsf-title-separator input:hover+label,.tsf-metaboxes #tsf-title-separator label:hover{box-shadow:1px 1px 1px #aaa inset;background-color:#fff}.tsf-metaboxes #tsf-description-separator input:checked+label,.tsf-metaboxes #tsf-title-separator input:checked+label{box-shadow:1px 1px 1px #333 inset;background-color:#fff}.tsf-metaboxes #tsf-home-title-location,.tsf-metaboxes #tsf-title-location{display:block}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span,.tsf-metaboxes #tsf-twitter-cards label span{display:inline-block;min-width:60px;vertical-align:baseline}.tsf-metaboxes #tsf-twitter-cards label span{min-width:150px}.tsf-metaboxes #tsf-home-title-location label .tsf-sep-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-blogname-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-tagline-js,.tsf-metaboxes #tsf-home-title-location label span.tsf-custom-title-js,.tsf-metaboxes #tsf-title-location label .tsf-sep-js{display:inline;min-width:0;white-space:pre}.tsf-metaboxes .tsf-nav-tab-wrapper,.tsf-metaboxes .tsf-tab-no-js{position:relative;clear:both;width:100%;display:inline-block;border-bottom:1px solid #ccc;line-height:inherit;padding:8px 12px 0;margin:-4px -12px}.tsf-metaboxes .tsf-nav-tab{float:left;border:1px solid #ccc;margin-left:.5em;margin-bottom:-1px;padding:5px 14px;font-size:12px;line-height:16px;background:#f1f1f1;color:#555;font-weight:600}.tsf-metaboxes .tsf-dashicons-tabs{font-size:initial;display:inline;vertical-align:text-bottom}.tsf-metaboxes .tsf-tabs-radio{display:none;width:0;height:0;position:absolute;left:-9001px}.tsf-metaboxes .tsf-active-tab,.tsf-metaboxes .tsf-tabs-radio:checked+label{background-color:inherit;border-bottom-color:#fff;color:#000}.tsf-metaboxes .tsf-tabs-content{margin:1.33em auto 0}.tsf-metaboxes .tsf-content-no-js{margin:1.33em auto}body.js .tsf-metaboxes .tsf-tabs-content{display:none}body.js .tsf-metaboxes .tsf-tabs-content.tsf-active-tab-content{display:block}#tsf-inpost-box .inside,.tsf-flex{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 1 auto;flex:1 1 auto;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:flex-start;justify-content:flex-start}#tsf-inpost-box.closed .inside,body.js .tsf-flex-tab-content{display:none}#tsf-inpost-box .inside{margin:0;padding:0;-webkit-flex:1 0 100%;flex:1 0 100%;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.tsf-flex-inside-wrap{-webkit-flex-direction:row;flex-direction:row;-webkit-flex:1 1 auto;flex:1 1 auto}.tsf-flex-setting{width:100%;-webkit-flex-direction:row;flex-direction:row}.tsf-flex-setting-input,.tsf-flex-setting-label{background-color:#fff;padding:15px 12px;-webkit-flex:10 1 350px;flex:10 1 350px;box-shadow:0 0 0 1px #e9e9e9}.tsf-flex-setting-label{background-color:#f9f9f9;-webkit-flex:1 1 200px;flex:1 1 200px}.tsf-flex-setting-input{-webkit-justify-content:center;justify-content:center}.tsf-flex-setting-label-item{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between;-webkit-flex-grow:0;flex-grow:0}.tsf-flex-setting-label-inner-wrap{-webkit-justify-content:center;justify-content:center}.tsf-flex-setting-label-item>*{margin-right:4px}.tsf-flex-setting-label-item>:last-child{margin-right:0}.tsf-flex-setting-label .tsf-counter{font-weight:400;color:#666;margin-top:15px}.tsf-social-image-buttons{margin-top:15px;margin-left:1px}.tsf-flex-setting-input textarea{max-height:250px}input[type=radio].tsf-flex-nav-tab-radio{display:none;width:0;height:0;margin:0;padding:0;position:absolute;left:-9001px}.tsf-flex-nav-tab-wrapper{background-color:#fcfcfc;border-bottom:2px solid #dadada;-webkit-align-items:baseline;align-items:baseline;-webkit-flex-direction:row;flex-direction:row;-webkit-flex:1 1 100%;flex:1 1 100%;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-width:100%}.tsf-flex-nav-tab-inner{-webkit-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex:1 0 auto;flex:1 0 auto}.tsf-flex-nav-tab{-webkit-flex-direction:row;flex-direction:row;-webkit-flex:1 1 auto;flex:1 1 auto;max-width:125px}.tsf-flex-nav-tab-label{padding:12px;text-align:center;-webkit-flex-direction:row;flex-direction:row;box-shadow:0 0 0 0 transparent inset;-webkit-transition:box-shadow .15s ease-out;-o-transition:box-shadow .15s ease-out;transition:box-shadow .15s ease-out;-webkit-align-items:center;align-items:center;-webkit-align-content:space-between;align-content:space-between}.tsf-flex-nav-dashicon,.tsf-flex-nav-name{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked+.tsf-flex-nav-tab-label{box-shadow:0 -2px 0 0 #007bd2 inset;-webkit-transition:box-shadow .25s ease-in;-o-transition:box-shadow .25s ease-in;transition:box-shadow .25s ease-in}.tsf-flex-tab-content{-webkit-flex:1 0 100%;flex:1 0 100%;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}body.js .tsf-flex-tab-content.tsf-flex-tab-content-active{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tsf-flex-tabs-content-no-js{background-color:#f3f3f3;border-bottom:1px solid #dadada;box-shadow:0 2px 0 0 #dadada inset}.tsf-flex-tab-no-js{-webkit-align-items:baseline;align-items:baseline;-webkit-flex-direction:row;flex-direction:row;flex:1 1 100%}.tsf-flex-tab-no-js .tsf-flex-nav-tab{padding:12px;min-width:125px;box-shadow:0 -2px 0 0 #007bd2 inset;-webkit-flex-direction:row;flex-direction:row;-webkit-flex:0 1 auto;flex:0 1 auto}.tsf-metaboxes .tsf-default-selected{border-color:#1c9d38}.tsf-metaboxes .tsf-default-selected:checked:before{color:#1c9d38}.tsf-metaboxes .tsf-warning-selected{border-color:#dd3811}.tsf-metaboxes .tsf-warning-selected:checked:before{color:#dd3811}.tsf-fields{font-size:13px;line-height:1.5;margin:1em 0}.tsf-fields .tsf-toblock{display:block;width:100%;margin-bottom:4px}.tsf-fields p.description{margin:7px 0 5px;color:#666}.tsf-option-spacer{margin:1em 0}.tsf-checkbox-wrapper{margin-top:15px}.tsf-checkbox-wrapper:first-child{margin-top:0}.tsf-counter .tsf-ajax{margin-left:3px}.tsf-ajax:before{display:inline-block;line-height:1;font-family:dashicons;font-style:normal;font-weight:400;font-size:1.225em;vertical-align:middle;content:""}.tsf-ajax.tsf-loading:before{content:"\f463";color:#007bd2;-webkit-animation:tsf-spin 1.5s linear infinite;-moz-animation:tsf-spin 1.5s linear infinite;-o-animation:tsf-spin 1.5s linear infinite;animation:tsf-spin 1.5s linear infinite}.tsf-ajax.tsf-error:before{content:"\f158";color:#dd3811}.tsf-ajax.tsf-success:before{content:"\f147";color:#0cc34b}a.tsf-set-social-image.button{margin-right:7px}#tsf-inpost-box input[type=text]::-webkit-input-placeholder,#tsf-inpost-box textarea::-webkit-input-placeholder,.tsf-metaboxes input[type=text]::-webkit-input-placeholder,.tsf-metaboxes textarea::-webkit-input-placeholder{-webkit-transition:color .33s ease-in,text-shadow .33s ease-in;-o-transition:color .33s ease-in,text-shadow .33s ease-in;transition:color .33s ease-in,text-shadow .33s ease-in}#tsf-inpost-box input[type=text]::-moz-placeholder,#tsf-inpost-box textarea::-moz-placeholder,.tsf-metaboxes input[type=text]::-moz-placeholder,.tsf-metaboxes textarea::-moz-placeholder{-moz-transition:color .33s ease-in,text-shadow .33s ease-in;transition:color .33s ease-in,text-shadow .33s ease-in}#tsf-inpost-box input[type=text]:-ms-input-placeholder,#tsf-inpost-box textarea:-ms-input-placeholder,.tsf-metaboxes input[type=text]:-ms-input-placeholder,.tsf-metaboxes textarea:-ms-input-placeholder{transition:color .33s ease-in,text-shadow .33s ease-in}#tsf-inpost-box input[type=text]:focus::-webkit-input-placeholder,#tsf-inpost-box textarea:focus::-webkit-input-placeholder,.tsf-metaboxes input[type=text]:focus::-webkit-input-placeholder,.tsf-metaboxes textarea:focus::-webkit-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus::-moz-placeholder,#tsf-inpost-box textarea:focus::-moz-placeholder,.tsf-metaboxe textarea:focus::-moz-placeholder,.tsf-metaboxes input[type=text]:focus::-moz-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}#tsf-inpost-box input[type=text]:focus:-ms-input-placeholder,#tsf-inpost-box textarea:focus:-ms-input-placeholder,.tsf-metaboxes input[type=text]:focus:-ms-input-placeholder,.tsf-metaboxes textarea:focus:-ms-input-placeholder{color:transparent;text-shadow:0 0 1px rgba(114,119,124,.75)}@-webkit-keyframes tsf-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}@keyframes tsf-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@media screen and (max-width:782px){.tsf-inpost-box p.tsf-fields,.tsf-metaboxes p.tsf-fields{line-height:2.8}.tsf-metaboxes #tsf-home-title-location label span,.tsf-metaboxes #tsf-title-location label span{min-width:40px}.wp-list-table .is-expanded td.tsf-seo-bar-wrap:not(.hidden){overflow:initial!important}}@media screen and (max-width:642px){.tsf-metaboxes span.tsf-nav-desktop{display:none}}@media screen and (max-width:510px){span.tsf-seo-bar.tsf-100{width:inherit}}@-moz-document url-prefix(){.tsf-metaboxes #tsf-description-separator label,.tsf-metaboxes #tsf-title-separator label{margin:3px 1px}@media only screen and (min-width:768px){.widefat tr td.column-title:nth-child(2):nth-last-child(n+6),.widefat tr td.title:nth-child(2):nth-last-child(n+6),.widefat tr th.column-title:nth-child(2):nth-last-child(n+6),.widefat tr th.title:nth-child(2):nth-last-child(n+6){min-width:1em;width:25%;max-width:100%;white-space:unset}}.tsf-metaboxes .tsf-default-selected{box-shadow:0 0 2px 0 #1c9d38}.tsf-metaboxes .tsf-warning-selected{box-shadow:0 0 2px 0 #dd3811}.tsf-metaboxes legend h4{margin:2px 0}}.tsf-flex-hide-if-no-js,body.js .tsf-flex-hide-if-js{display:none}body.js .tsf-flex-hide-if-no-js{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}
lib/js/tsf.externs.js CHANGED
@@ -45,6 +45,11 @@ function tsf() {};
45
  */
46
  tsf.nonce;
47
 
 
 
 
 
 
48
  /**
49
  * @const {Object<string, string>}
50
  */
45
  */
46
  tsf.nonce;
47
 
48
+ /**
49
+ * @type {Object<string, string>}
50
+ */
51
+ tsf.nonces;
52
+
53
  /**
54
  * @const {Object<string, string>}
55
  */
lib/js/tsf.externs.protected.js CHANGED
@@ -280,12 +280,6 @@ tsf.prototype.dynamicPlaceholder = function( event ) {};
280
  */
281
  tsf.prototype.selectTitleInput = function() {};
282
 
283
- /**
284
- * @protected
285
- * @return {undefined}
286
- */
287
- tsf.prototype.dynamicPlaceholderOnLoad = function() {};
288
-
289
  /**
290
  * @protected
291
  * @return {undefined}
280
  */
281
  tsf.prototype.selectTitleInput = function() {};
282
 
 
 
 
 
 
 
283
  /**
284
  * @protected
285
  * @return {undefined}
lib/js/tsf.js CHANGED
@@ -45,11 +45,21 @@ window.tsf = {
45
  * AJAX Nonce string.
46
  *
47
  * @since 2.7.0
 
48
  *
49
  * @type {String} nonce The AJAX nonce
50
  */
51
  nonce : tsfL10n.nonce,
52
 
 
 
 
 
 
 
 
 
 
53
  /**
54
  * i18n object.
55
  *
@@ -166,6 +176,8 @@ window.tsf = {
166
  * Cached doctitle function.
167
  *
168
  * @since 2.3.3
 
 
169
  *
170
  * @function
171
  * @return {!jQuery} The jQuery doctitle ID's
@@ -173,7 +185,16 @@ window.tsf = {
173
  docTitles: function() {
174
  'use strict';
175
 
176
- var $doctitles = jQuery( "#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]" );
 
 
 
 
 
 
 
 
 
177
 
178
  return $doctitles;
179
  },
@@ -182,6 +203,7 @@ window.tsf = {
182
  * Cached description function.
183
  *
184
  * @since 2.5.0
 
185
  *
186
  * @function
187
  * @return {!jQuery} The jQuery description ID's
@@ -189,7 +211,16 @@ window.tsf = {
189
  docDescriptions: function() {
190
  'use strict';
191
 
192
- var $descriptions = jQuery( "#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]" );
 
 
 
 
 
 
 
 
 
193
 
194
  return $descriptions;
195
  },
@@ -248,6 +279,7 @@ window.tsf = {
248
  if ( tsf.additionsClass )
249
  counterClass += ' ' + tsf.additionsClass;
250
 
 
251
  if ( ! tsf.counterType || 1 == tsf.counterType ) {
252
  output = calcLength.toString();
253
  } else if ( 2 == tsf.counterType ) {
@@ -381,7 +413,8 @@ window.tsf = {
381
  separatorSwitchTitle: function( event ) {
382
  'use strict';
383
 
384
- var $sep = jQuery( ".tsf-sep-js" ),
 
385
  val = jQuery( event.target ).val();
386
 
387
  //* Update cache.
@@ -408,7 +441,8 @@ window.tsf = {
408
  separatorSwitchDesc: function( event ) {
409
  'use strict';
410
 
411
- var $sep = jQuery( "#autodescription-descsep-js" ),
 
412
  val = jQuery( event.target ).val();
413
 
414
  if ( 'pipe' === val ) {
@@ -431,7 +465,8 @@ window.tsf = {
431
  statusBarHover: function() {
432
  'use strict';
433
 
434
- var $wrap = jQuery( '.tsf-seo-bar-inner-wrap' ).find( 'a' );
 
435
 
436
  $wrap.on( 'mouseenter', tsf.statusBarHoverEnter );
437
  $wrap.on( 'mousemove', tsf.statusBarHoverMove );
@@ -450,13 +485,14 @@ window.tsf = {
450
  statusBarHoverEnter: function( event ) {
451
  'use strict';
452
 
453
- var $this = jQuery( event.target ),
 
454
  desc = $this.data( 'desc' );
455
 
456
  if ( desc !== undefined && 0 === $this.find( 'div' ).length ) {
457
  $this.append( '<div class="tsf-explanation-desc">' + desc + '<div></div></div>' );
458
 
459
- var height = $this.find( 'div.tsf-explanation-desc' ).height() + 28;
460
 
461
  $this.find( 'div.tsf-explanation-desc' ).css( 'top', ( $this.position().top - height ) + 'px' );
462
  }
@@ -476,14 +512,14 @@ window.tsf = {
476
 
477
  var $this = jQuery( event.target ),
478
  pagex = event.pageX,
479
- mousex = pagex - jQuery( '.tsf-seo-bar-inner-wrap' ).offset().left - 11, // 22px width of arrow / 2 = 11 middle
480
  $balloon = $this.find( '.tsf-explanation-desc' ),
481
  $arrow = $balloon.find( 'div' );
482
 
483
  if ( mousex < 1 ) {
484
  $arrow.css( 'left', 0 + "px" );
485
  } else if ( $balloon.offset() !== undefined ) {
486
- var width = $balloon.width(),
487
  maxOffset = $balloon.offset().left + width + 11;
488
 
489
  if ( pagex > maxOffset ) {
@@ -520,7 +556,8 @@ window.tsf = {
520
  removeDesc: function() {
521
  'use strict';
522
 
523
- var $target = jQuery( document.body.target ),
 
524
  $desc = jQuery( '.tsf-seo-bar-inner-wrap a' );
525
 
526
  if ( ! $target.closest( $desc ).length )
@@ -528,30 +565,143 @@ window.tsf = {
528
  },
529
 
530
  /**
531
- * Refines Styling for the navigation tabs on the settings pages
532
  *
533
  * @since 2.2.2
534
- *
535
- * Rewritten
536
- * @since 2.6.0
537
  *
538
  * @function
539
  * @param {!jQuery.Event} event
540
- * @return {undefined}
541
  */
542
  tabToggle: function( event ) {
543
  'use strict';
544
 
545
- var target = jQuery( event.target ).prop( 'id' ),
546
- name = jQuery( event.target ).prop( 'name' );
547
 
548
- if ( typeof target !== 'undefined' ) {
549
- var $content = jQuery( '#' + target + '-content' ),
550
- $other = jQuery( '.' + name + '-content' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
 
552
- if ( typeof $content !== 'undefined' ) {
553
- $other.removeClass( 'tsf-active-tab-content' );
554
- $content.addClass( 'tsf-active-tab-content' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  }
556
  }
557
  },
@@ -568,7 +718,8 @@ window.tsf = {
568
  taglineToggleTitle: function( event ) {
569
  'use strict';
570
 
571
- var $this = jQuery( event.target ),
 
572
  $tag = jQuery( '.tsf-custom-blogname-js' );
573
 
574
  if ( $this.is( ':checked' ) ) {
@@ -594,7 +745,8 @@ window.tsf = {
594
  taglineToggleDesc: function( event ) {
595
  'use strict';
596
 
597
- var $this = jQuery( event.target ),
 
598
  $tagDesc = jQuery( '#tsf-on-blogname-js' );
599
 
600
  if ( $this.is(':checked') ) {
@@ -616,7 +768,8 @@ window.tsf = {
616
  titleLocationToggle: function( event ) {
617
  'use strict';
618
 
619
- var val = jQuery( event.target ).val(),
 
620
  $titleExampleLeft = jQuery( '.tsf-title-additions-example-left' ),
621
  $titleExampleRight = jQuery( '.tsf-title-additions-example-right' );
622
 
@@ -641,7 +794,8 @@ window.tsf = {
641
  titlePrefixToggle: function( event ) {
642
  'use strict';
643
 
644
- var $this = jQuery( event.target ),
 
645
  $prefix = jQuery( '.tsf-title-prefix-example' );
646
 
647
  if ( $this.is(':checked') ) {
@@ -663,7 +817,8 @@ window.tsf = {
663
  additionsToggleDesc: function( event ) {
664
  'use strict';
665
 
666
- var $this = jQuery( event.target ),
 
667
  $tagDesc = jQuery( '#tsf-description-additions-js' );
668
 
669
  if ( $this.is(':checked') ) {
@@ -688,7 +843,8 @@ window.tsf = {
688
  if ( ! tsf.hasInput )
689
  return;
690
 
691
- var $tagTitle = jQuery( '#tsf-title-tagline-toggle :input' ),
 
692
  $title = jQuery( '.tsf-custom-blogname-js' ),
693
  $tagDescAdditions = jQuery( '#tsf-description-additions-toggle :input' ),
694
  $descAdditions = jQuery( '#tsf-description-additions-js' ),
@@ -739,7 +895,7 @@ window.tsf = {
739
  $title = jQuery( '.tsf-custom-title-js' );
740
 
741
  if ( val.length === 0 ) {
742
- $title.text( tsf.i18n['siteTitle'] );
743
  } else {
744
  $title.text( val );
745
  }
@@ -778,7 +934,6 @@ window.tsf = {
778
  } else {
779
  placeholder = description + ' ' + sep + ' ' + title;
780
  }
781
-
782
  }
783
 
784
  $floatTag.text( description );
@@ -789,7 +944,7 @@ window.tsf = {
789
  },
790
 
791
  /**
792
- * Trigger Change on Left/Right selection of Home Page Title
793
  *
794
  * @since 2.5.0
795
  *
@@ -799,7 +954,58 @@ window.tsf = {
799
  taglinePropTrigger: function() {
800
  'use strict';
801
 
802
- jQuery( "#autodescription-site-settings\\[homepage_title_tagline\\]" ).trigger( 'input', tsf.taglineProp );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
  },
804
 
805
  /**
@@ -813,7 +1019,8 @@ window.tsf = {
813
  titleToggle: function() {
814
  'use strict';
815
 
816
- var $this = jQuery( event.target ),
 
817
  $tagDesc = jQuery( '.tsf-title-additions-js' );
818
 
819
  if ( $this.is( ':checked' ) ) {
@@ -837,12 +1044,12 @@ window.tsf = {
837
  if ( ! tsf.hasInput )
838
  return;
839
 
840
- jQuery( '.tsf-metaboxes :input, #tsf-inpost-box .inside :input' ).not( '.tsf-tab :input' ).change( function() {
841
  tsf.registerChange();
842
  } );
843
 
844
  jQuery( '.tsf-metaboxes input[type=text], .tsf-metaboxes textarea, #tsf-inpost-box .inside input[type=text], #tsf-inpost-box .inside textarea' ).not(
845
- '.tsf-nav-tab-wrapper :input' ).on( 'input', function() {
846
  tsf.registerChange();
847
  } );
848
 
@@ -897,19 +1104,19 @@ window.tsf = {
897
  dynamicPlaceholder: function( event ) {
898
  'use strict';
899
 
900
- var hasAdditions = tsf.params['titleAdditions'].length,
 
901
  $placeholder = jQuery( '#tsf-title-placeholder' );
902
 
903
- // If check is defined, we're on SEO settings page.
904
- if ( 0 === hasAdditions ) {
905
- var $this = jQuery( event.target );
906
-
907
  // Empty the placeholder as we can't execute.
908
- $this.css( 'text-indent', "initial" );
909
  return $placeholder.empty();
910
  }
911
 
912
- var after = false,
 
913
  check = jQuery( '#tsf-home-title-location input:checked' ).val(),
914
  rtl = tsf.states['isRTL'],
915
  additions = '';
@@ -917,7 +1124,7 @@ window.tsf = {
917
  if ( typeof check !== 'undefined' && check.length !== 0 ) {
918
  //* We're in SEO Settings page.
919
 
920
- if ( '1' === rtl ) {
921
  if ( 'right' === check ) {
922
  after = true;
923
  }
@@ -929,14 +1136,12 @@ window.tsf = {
929
  } else {
930
  //* We're in post/page edit screen.
931
 
932
- var isHome = tsf.states['isHome'],
933
- titleLocation = tsf.params['titleLocation'],
934
- tagline = tsf.titleTagline;
935
 
936
  // We're on post/page screen.
937
- if ( isHome ) {
938
  // Static Front page, switch check.
939
- if ( tagline ) {
940
  if ( rtl ) {
941
  if ( 'right' === titleLocation ) {
942
  after = true;
@@ -956,21 +1161,25 @@ window.tsf = {
956
  }
957
  }
958
 
959
- var $tagbox = jQuery( '#tsf-title-tagline-toggle :input' );
960
 
961
  if ( typeof $tagbox !== "undefined" && $tagbox.length > 0 && ! $tagbox.is( ':checked' ) ) {
962
  //* We're on SEO Settings Page now, and tagline has been disabled.
963
- var $this = jQuery( event.target );
 
964
 
965
  $this.css( 'text-indent', "initial" );
966
- $placeholder.css( 'display', 'none' );
967
  } else {
968
  var $this = jQuery( event.target ),
969
  inputVal = $this.val(),
970
- $offsetTest = jQuery( "#tsf-title-offset" ),
971
- offsetWidth = 0,
 
 
 
972
  heightPad = ( $this.outerHeight( true ) - $this.height() ) / 2,
973
- horPad = ( $this.outerWidth() - $this.width() ) / 2,
974
  leftOffset = ( $this.outerWidth( true ) - $this.width() ) / 2,
975
  taglineVal = jQuery( "#autodescription-site-settings\\[homepage_title_tagline\\]" ).val(),
976
  pos = 'left',
@@ -985,20 +1194,20 @@ window.tsf = {
985
  }
986
 
987
  if ( after ) {
988
- additions = separator + " " + tsf.params['titleAdditions'];
989
 
990
  // Exchange the placeholder value of the custom Tagline in the HomePage Metabox
991
  if ( typeof taglineVal !== "undefined" && taglineVal.length > 0 ) {
992
- additions = separator + " " + taglineVal;
993
  }
994
 
995
  $this.css( 'text-indent', "initial" );
996
  } else {
997
- additions = tsf.params['titleAdditions'] + " " + separator;
998
 
999
  // Exchange the placeholder value of the custom Tagline in the HomePage Metabox
1000
  if ( typeof taglineVal !== "undefined" && taglineVal.length > 0 ) {
1001
- additions = taglineVal + " " + separator;
1002
  }
1003
  }
1004
 
@@ -1012,7 +1221,7 @@ window.tsf = {
1012
  });
1013
  offsetWidth = $offsetTest.width();
1014
 
1015
- var maxWidth = $this.width() - horPad - offsetWidth;
1016
 
1017
  if ( maxWidth < 0 )
1018
  maxWidth = 0;
@@ -1040,12 +1249,13 @@ window.tsf = {
1040
  } else {
1041
  $placeholder.text( additions );
1042
 
1043
- // Don't calculate when empty.
1044
- if ( $this.outerWidth() > leftOffset ) {
1045
  if ( after ) {
1046
  $placeholder.css( pos, horPad + leftOffset + $offsetTest.width() + "px" );
1047
  } else {
1048
- var indent = horPad + $placeholder.width();
 
1049
 
1050
  if ( indent < 0 )
1051
  indent = 0;
@@ -1069,13 +1279,15 @@ window.tsf = {
1069
  selectTitleInput: function() {
1070
  'use strict';
1071
 
1072
- var $input = tsf.docTitles();
 
1073
 
1074
  $input.focus();
1075
 
1076
  if ( $input.setSelectionRange ) {
1077
  // Go to end times 2 if setSelectionRange exists.
1078
- var length = $input.val().length * 2;
 
1079
  $input.setSelectionRange( length, length );
1080
  } else {
1081
  // Replace value with itself.
@@ -1083,31 +1295,6 @@ window.tsf = {
1083
  }
1084
  },
1085
 
1086
- /**
1087
- * Adds dynamic placeholder to Title input based on site settings on Load.
1088
- *
1089
- * @since 2.5.0
1090
- *
1091
- * @function
1092
- * @return {undefined}
1093
- */
1094
- dynamicPlaceholderOnLoad: function() {
1095
- 'use strict';
1096
-
1097
- if ( ! tsf.hasInput )
1098
- return;
1099
-
1100
- var $input = tsf.docTitles();
1101
-
1102
- if ( typeof $input.val() !== "undefined" ) {
1103
- if ( $input.val().length > 0 ) {
1104
- $input.trigger( 'input', tsf.dynamicPlaceholder );
1105
- } else {
1106
- $input.trigger( 'input', tsf.updateCharacterCountTitle );
1107
- }
1108
- }
1109
- },
1110
-
1111
  /**
1112
  * Triggers keyup on description input so the counter can colorize.
1113
  *
@@ -1122,12 +1309,12 @@ window.tsf = {
1122
  if ( ! tsf.hasInput )
1123
  return;
1124
 
1125
- var $input = tsf.docDescriptions();
 
1126
 
1127
  $input.trigger( 'input', tsf.updateCharacterCountDescription );
1128
  },
1129
 
1130
-
1131
  /**
1132
  * Triggers keyup on title input so the counter can colorize.
1133
  *
@@ -1142,7 +1329,8 @@ window.tsf = {
1142
  if ( ! tsf.hasInput )
1143
  return;
1144
 
1145
- var $input = tsf.docTitles();
 
1146
 
1147
  $input.trigger( 'input', tsf.updateCharacterCountTitle );
1148
  },
@@ -1174,7 +1362,8 @@ window.tsf = {
1174
  dismissNotice: function( event ) {
1175
  'use strict';
1176
 
1177
- var $this = jQuery( event.target );
 
1178
 
1179
  $this.parents( '.tsf-notice' ).slideUp( 200, function() {
1180
  $this.remove();
@@ -1209,7 +1398,8 @@ window.tsf = {
1209
  unsetAjaxLoader: function( target, success ) {
1210
  'use strict';
1211
 
1212
- var newclass = 'tsf-success',
 
1213
  fade = 2500;
1214
 
1215
  if ( ! success ) {
@@ -1256,7 +1446,7 @@ window.tsf = {
1256
  //* Update counters locally.
1257
  tsf.additionsClassInit();
1258
 
1259
- var target = '.tsf-counter .tsf-ajax',
1260
  status = 0;
1261
 
1262
  //* Reset ajax loader
@@ -1266,13 +1456,13 @@ window.tsf = {
1266
  tsf.setAjaxLoader( target );
1267
 
1268
  //* Setup external update.
1269
- var settings = {
1270
  method: 'POST',
1271
  url: ajaxurl,
1272
  datatype: 'json',
1273
  data: {
1274
  'action' : 'the_seo_framework_update_counter',
1275
- 'nonce' : tsf.nonce,
1276
  'val' : tsf.counterType,
1277
  },
1278
  async: true,
@@ -1332,8 +1522,9 @@ window.tsf = {
1332
  if ( ! tsf.hasInput )
1333
  return;
1334
 
1335
- var counterType = tsf.counterType,
1336
- cache = tsf.settingsChanged;
 
1337
 
1338
  if ( 1 == counterType ) {
1339
  tsf.additionsClass = 'tsf-counter-one';
@@ -1352,7 +1543,7 @@ window.tsf = {
1352
  tsf.updateCounters();
1353
 
1354
  // Reset settingsChanged to previous value.
1355
- tsf.settingsChanged = cache;
1356
  },
1357
 
1358
  /**
@@ -1389,6 +1580,7 @@ window.tsf = {
1389
  * Returns converted HTML title/description separator.
1390
  *
1391
  * @since 2.7.0
 
1392
  *
1393
  * @function
1394
  * @param {String} type
@@ -1397,27 +1589,53 @@ window.tsf = {
1397
  getSep: function( type ) {
1398
  'use strict';
1399
 
 
 
 
 
1400
  if ( 'title' === type ) {
1401
- var sep = tsf.titleSeparator;
1402
  } else {
1403
- var sep = tsf.descriptionSeparator;
1404
  }
1405
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1406
  if ( 'pipe' === sep || '|' === sep ) {
1407
- sep = ( "|" );
1408
  } else if ( 'dash' === sep || '-' === sep ) {
1409
- sep = ( "-" );
1410
  } else if ( sep.charCodeAt(0) < 123 ) {
1411
  //* Checked for UTF-8 conversion.
1412
  // Create a memory div to store the html in, convert to text to append in $placeholder
1413
- sep = jQuery.trim( sep );
1414
  if ( '&' === sep.charAt(0) && ';' === sep.slice(-1) )
1415
  sep = sep.substr(1).slice(0, -1);
1416
 
1417
- sep = jQuery( '<div/>' ).html( "&" + sep + ";" ).text();
1418
  }
1419
 
1420
- return sep;
 
 
 
 
 
1421
  },
1422
 
1423
  /**
@@ -1481,7 +1699,8 @@ window.tsf = {
1481
 
1482
  frame.on( 'cropped', function( croppedImage ) {
1483
 
1484
- var url = croppedImage.url,
 
1485
  attachmentId = croppedImage.id,
1486
  w = croppedImage.width,
1487
  h = croppedImage.height;
@@ -1493,7 +1712,8 @@ window.tsf = {
1493
 
1494
  frame.on( 'skippedcrop', function( selection ) {
1495
 
1496
- var url = selection.get( 'url' ),
 
1497
  attachmentId = selection.get( 'id' ),
1498
  w = selection.get( 'width' ),
1499
  h = selection.get( 'height' );
@@ -1529,6 +1749,7 @@ window.tsf = {
1529
  * @return {(undefined|null)}
1530
  */
1531
  appendRemoveButton: function( target, inputID, animate ) {
 
1532
 
1533
  if ( target && inputID ) {
1534
  if ( ! jQuery( '#' + inputID + '-remove' ).length ) {
@@ -1562,6 +1783,7 @@ window.tsf = {
1562
  * @return {(undefined|null)}
1563
  */
1564
  removeEditorImage: function( event ) {
 
1565
 
1566
  var $target = jQuery( event.target ),
1567
  inputID = $target.data( 'inputid' );
@@ -1612,8 +1834,9 @@ window.tsf = {
1612
  * @augments wp.media.controller.State
1613
  * @augments Backbone.Model
1614
  */
1615
- var Controller = wp.media.controller,
1616
- TSFCropper;
 
1617
 
1618
  TSFCropper = Controller.Cropper.extend( {
1619
  doCrop: function( attachment ) {
@@ -1654,8 +1877,8 @@ window.tsf = {
1654
  cropDetails.dst_height = 0;
1655
  }
1656
 
1657
- return wp.ajax.post( 'crop-image', {
1658
- 'nonce' : attachment.get( 'nonces' ).edit,
1659
  'id' : attachment.get( 'id' ),
1660
  'context' : 'tsf-image',
1661
  'cropDetails' : cropDetails
@@ -1691,17 +1914,23 @@ window.tsf = {
1691
  calculateImageSelectOptions: function( attachment, controller ) {
1692
  'use strict';
1693
 
1694
- var control = tsf.cropper.control,
1695
- flexWidth = !! parseInt( control.params.flex_width, 10 ),
 
 
1696
  flexHeight = !! parseInt( control.params.flex_height, 10 ),
1697
- realWidth = attachment.get( 'width' ),
1698
- realHeight = attachment.get( 'height' ),
1699
  xInit = parseInt( control.params.width, 10 ),
1700
- yInit = parseInt( control.params.height, 10 ),
 
 
 
 
1701
  ratio = xInit / yInit,
1702
  xImg = xInit,
1703
  yImg = yInit,
1704
- x1, y1, imgSelectOptions;
 
 
1705
 
1706
  controller.set( 'control', control.params );
1707
  controller.set( 'canSkipCrop', ! tsf.mustBeCropped( control.params.flex_width, control.params.flex_height, realWidth, realHeight ) );
@@ -1766,9 +1995,8 @@ window.tsf = {
1766
  mustBeCropped: function( dstW, dstH, imgW, imgH ) {
1767
  'use strict';
1768
 
1769
- if ( imgW <= dstW && imgH <= dstH ) {
1770
  return false;
1771
- }
1772
 
1773
  return true;
1774
  },
@@ -1782,6 +2010,8 @@ window.tsf = {
1782
  * @return {(undefined|null)}
1783
  */
1784
  resetImageEditorActions: function() {
 
 
1785
  jQuery( '.tsf-remove-social-image' ).on( 'click', tsf.removeEditorImage );
1786
  },
1787
 
@@ -1794,6 +2024,8 @@ window.tsf = {
1794
  * @return {(undefined|null)}
1795
  */
1796
  setupImageEditorActions: function() {
 
 
1797
  jQuery( '.tsf-set-social-image' ).on( 'click', tsf.openImageEditor );
1798
  jQuery( '.tsf-remove-social-image' ).on( 'click', tsf.removeEditorImage );
1799
  },
@@ -1807,11 +2039,13 @@ window.tsf = {
1807
  * @return {(undefined|null)}
1808
  */
1809
  checkImageEditorInput: function() {
 
1810
 
1811
- var $buttons = jQuery( '.tsf-set-social-image' );
 
1812
 
1813
  if ( $buttons.length ) {
1814
- var inputID = '',
1815
  $valID = '';
1816
 
1817
  jQuery.each( $buttons, function( index, value ) {
@@ -1839,12 +2073,15 @@ window.tsf = {
1839
  * @return {(undefined|null)}
1840
  */
1841
  setColorOnload: function() {
 
1842
 
1843
- var $selectors = jQuery( '.tsf-color-picker' );
 
1844
 
1845
  if ( $selectors.length ) {
1846
  jQuery.each( $selectors, function( index, value ) {
1847
- var $input = jQuery( value ),
 
1848
  currentColor = '',
1849
  defaultColor = $input.data( 'tsf-default-color' );
1850
 
@@ -1882,6 +2119,7 @@ window.tsf = {
1882
  * @return {(undefined|null)}
1883
  */
1884
  setupVars: function() {
 
1885
 
1886
  //The current title separator.
1887
  tsf.titleSeparator = tsf.params['titleSeparator'];
@@ -1892,13 +2130,203 @@ window.tsf = {
1892
  // The current title tagline.
1893
  tsf.titleTagline = tsf.states['titleTagline'];
1894
 
1895
- // Mixed string and int (i10n is string, JS is int).
1896
- tsf.counterType = tsf.states['counterType'];
1897
 
1898
  // Determines if the current page has input boxes for The SEO Framework.
1899
  tsf.hasInput = tsf.states['hasInput'];
1900
  },
1901
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1902
  /**
1903
  * Initialises all aspects of the scripts.
1904
  *
@@ -1910,6 +2338,9 @@ window.tsf = {
1910
  * @since 2.2.4
1911
  * @since 2.7.0 jQuery object is now passed.
1912
  *
 
 
 
1913
  * @function
1914
  * @param {!jQuery} jQ jQuery
1915
  * @return {undefined}
@@ -1923,28 +2354,28 @@ window.tsf = {
1923
  // Move the page updates notices below the tsf-top-wrap.
1924
  jQ( 'div.updated, div.error, div.notice-warning' ).insertAfter( 'div.tsf-top-wrap' );
1925
 
 
 
 
 
 
 
1926
  // Set up additions classes.
1927
  jQ( document.body ).ready( tsf.additionsClassInit );
1928
 
1929
- // Toggle Dynamic Title Placeholder onLoad, also toggles doing it right colors.
1930
- jQ( document.body ).ready( tsf.dynamicPlaceholderOnLoad );
1931
-
1932
  // Check if the Title Tagline or Description Additions should be removed when page is loaded.
1933
  jQ( document.body ).ready( tsf.taglineToggleOnload );
1934
 
1935
  // Initialize the status bar hover balloon.
1936
  jQ( document.body ).ready( tsf.statusBarHover );
1937
 
1938
- // Initialize status bar removal hover for touch screens.
1939
- jQ( document.body ).on( 'click touchstart MSPointerDown', tsf.removeDesc );
1940
-
1941
  // Initialize image uploader button cache.
1942
  jQ( document.body ).ready( tsf.setupImageEditorActions );
1943
 
1944
  // Determine image editor button input states.
1945
  jQ( document.body ).ready( tsf.checkImageEditorInput );
1946
 
1947
- // Color picker
1948
  jQ( document.body ).ready( tsf.setColorOnload );
1949
 
1950
  // #== End Before Change listener
@@ -1955,8 +2386,17 @@ window.tsf = {
1955
  // Deregister changes.
1956
  jQ( document.body ).ready( tsf.onLoadUnregisterChange );
1957
 
 
 
 
1958
  // #== Start After Change listener
1959
 
 
 
 
 
 
 
1960
  // Bind character counters.
1961
  tsf.docDescriptions().on( 'input', tsf.updateCharacterCountDescription );
1962
  tsf.docTitles().on( 'input', tsf.updateCharacterCountTitle );
@@ -1970,36 +2410,15 @@ window.tsf = {
1970
  jQ( '.tsf-js-confirm-reset' ).on( 'click', tsf.confirmedReset );
1971
 
1972
  // Toggle Tabs in the SEO settings page.
1973
- jQ( '.tsf-tab' ).on( 'click', tsf.tabToggle );
1974
 
1975
- // Toggle Title tagline aditions removal.
1976
- jQ( '#tsf-title-tagline-toggle :input' ).on( 'click', tsf.taglineToggleTitle );
1977
- // Toggle Title additions location.
1978
- jQ( '#tsf-title-location input' ).on( 'click', tsf.titleLocationToggle );
1979
- // Toggle Title prefixes display.
1980
- jQ( '#title-prefixes-toggle :input' ).on( 'click', tsf.titlePrefixToggle );
1981
 
1982
  // Toggle Description additions removal.
1983
  jQ( '#tsf-description-onblogname-toggle :input' ).on( 'click', tsf.taglineToggleDesc );
1984
  jQ( '#tsf-description-additions-toggle :input' ).on( 'click', tsf.additionsToggleDesc );
1985
 
1986
- // Change Home Page Title Example prop on input changes.
1987
- jQ( '#autodescription-site-settings\\[homepage_title\\]' ).on( 'input', tsf.titleProp );
1988
- jQ( '#tsf-home-title-location :input, #tsf-title-tagline-toggle :input, #tsf-title-separator input' ).on( 'click', tsf.taglinePropTrigger );
1989
- jQ( '#autodescription-site-settings\\[homepage_title_tagline\\]' ).on( 'input', tsf.taglineProp );
1990
-
1991
- // Make sure the titleProp is correctly rendered when revealed after being hidden.
1992
- jQ( '#homepage-tab-general' ).on( 'change', tsf.taglinePropTrigger );
1993
-
1994
- // Change Global Title Example prop on input changes.
1995
- jQ( '#autodescription-site-settings\\[title_rem_additions\\]' ).on( 'click', tsf.titleToggle );
1996
-
1997
- // Dynamic Placeholder, acts on keydown for a11y, although more cpu intensive. Acts on keyup for perfect output.
1998
- tsf.docTitles().on( 'input', tsf.dynamicPlaceholder );
1999
-
2000
- // Move click on dynamic additions to focus input behind.
2001
- jQ( '#tsf-title-placeholder' ).on( 'click', tsf.selectTitleInput );
2002
-
2003
  // Dismiss notices.
2004
  jQ( '.tsf-dismiss' ).on( 'click', tsf.dismissNotice );
2005
 
45
  * AJAX Nonce string.
46
  *
47
  * @since 2.7.0
48
+ * @todo deprecate
49
  *
50
  * @type {String} nonce The AJAX nonce
51
  */
52
  nonce : tsfL10n.nonce,
53
 
54
+ /**
55
+ * AJAX Nonces object.
56
+ *
57
+ * @since 2.9.0
58
+ *
59
+ * @type {Object<string, string>} nonces The AJAX nonces
60
+ */
61
+ nonces : tsfL10n.nonces,
62
+
63
  /**
64
  * i18n object.
65
  *
176
  * Cached doctitle function.
177
  *
178
  * @since 2.3.3
179
+ * @todo Convert to class var instead of function call. It's much faster.
180
+ * i.e. setDocTitles() == docTitles : {}
181
  *
182
  * @function
183
  * @return {!jQuery} The jQuery doctitle ID's
185
  docTitles: function() {
186
  'use strict';
187
 
188
+ /** Concept:
189
+ if ( this.docTitles.cache )
190
+ return this.docTitles.cache;
191
+
192
+ // converted to var in compiler.
193
+ let $doctitles = this.docTitles.cache = jQuery( "#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]" );
194
+ */
195
+
196
+ // converted to var in compiler.
197
+ let $doctitles = jQuery( "#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]" );
198
 
199
  return $doctitles;
200
  },
203
  * Cached description function.
204
  *
205
  * @since 2.5.0
206
+ * @todo Convert to class var instead of function call. It's much faster.
207
  *
208
  * @function
209
  * @return {!jQuery} The jQuery description ID's
211
  docDescriptions: function() {
212
  'use strict';
213
 
214
+ /** Concept:
215
+ if ( this.docDescriptions.cache )
216
+ return this.docDescriptions.cache;
217
+
218
+ // converted to var in compiler.
219
+ let $descriptions = this.docDescriptions.cache = jQuery( "#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]" );
220
+ */
221
+
222
+ // converted to var in compiler.
223
+ let $descriptions = jQuery( "#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]" );
224
 
225
  return $descriptions;
226
  },
279
  if ( tsf.additionsClass )
280
  counterClass += ' ' + tsf.additionsClass;
281
 
282
+ //* Not strict by design.
283
  if ( ! tsf.counterType || 1 == tsf.counterType ) {
284
  output = calcLength.toString();
285
  } else if ( 2 == tsf.counterType ) {
413
  separatorSwitchTitle: function( event ) {
414
  'use strict';
415
 
416
+ // converted to var in compiler.
417
+ let $sep = jQuery( ".tsf-sep-js" ),
418
  val = jQuery( event.target ).val();
419
 
420
  //* Update cache.
441
  separatorSwitchDesc: function( event ) {
442
  'use strict';
443
 
444
+ // converted to var in compiler.
445
+ let $sep = jQuery( "#autodescription-descsep-js" ),
446
  val = jQuery( event.target ).val();
447
 
448
  if ( 'pipe' === val ) {
465
  statusBarHover: function() {
466
  'use strict';
467
 
468
+ // converted to var in compiler.
469
+ let $wrap = jQuery( '.tsf-seo-bar-inner-wrap' ).find( 'a' );
470
 
471
  $wrap.on( 'mouseenter', tsf.statusBarHoverEnter );
472
  $wrap.on( 'mousemove', tsf.statusBarHoverMove );
485
  statusBarHoverEnter: function( event ) {
486
  'use strict';
487
 
488
+ // converted to var in compiler.
489
+ let $this = jQuery( event.target ),
490
  desc = $this.data( 'desc' );
491
 
492
  if ( desc !== undefined && 0 === $this.find( 'div' ).length ) {
493
  $this.append( '<div class="tsf-explanation-desc">' + desc + '<div></div></div>' );
494
 
495
+ let height = $this.find( 'div.tsf-explanation-desc' ).height() + 28;
496
 
497
  $this.find( 'div.tsf-explanation-desc' ).css( 'top', ( $this.position().top - height ) + 'px' );
498
  }
512
 
513
  var $this = jQuery( event.target ),
514
  pagex = event.pageX,
515
+ mousex = pagex - $this.closest( '.tsf-seo-bar-inner-wrap' ).offset().left - 11, // 22px width of arrow / 2 = 11 middle
516
  $balloon = $this.find( '.tsf-explanation-desc' ),
517
  $arrow = $balloon.find( 'div' );
518
 
519
  if ( mousex < 1 ) {
520
  $arrow.css( 'left', 0 + "px" );
521
  } else if ( $balloon.offset() !== undefined ) {
522
+ let width = $balloon.width(),
523
  maxOffset = $balloon.offset().left + width + 11;
524
 
525
  if ( pagex > maxOffset ) {
556
  removeDesc: function() {
557
  'use strict';
558
 
559
+ // converted to var in compiler.
560
+ let $target = jQuery( document.body.target ),
561
  $desc = jQuery( '.tsf-seo-bar-inner-wrap a' );
562
 
563
  if ( ! $target.closest( $desc ).length )
565
  },
566
 
567
  /**
568
+ * Sets correct tab content and classes on toggle.
569
  *
570
  * @since 2.2.2
571
+ * @since 2.6.0 Improved.
572
+ * @since 2.9.0 Now always expects radio button input.
573
+ * @see tsf.setTabsOnload
574
  *
575
  * @function
576
  * @param {!jQuery.Event} event
577
+ * @return {(undefined|null)}
578
  */
579
  tabToggle: function( event ) {
580
  'use strict';
581
 
582
+ let $this = jQuery( event.target );
 
583
 
584
+ if ( ! $this.is( ':checked' ) )
585
+ return;
586
+
587
+ // converted to var in compiler.
588
+ let target = $this.prop( 'id' ),
589
+ name = $this.prop( 'name' );
590
+
591
+ if ( typeof name !== 'undefined' ) {
592
+ // converted to var in compiler.
593
+ let activeClass = 'tsf-active-tab-content',
594
+ $newContent = jQuery( '#' + target + '-content' ),
595
+ $previousContent = jQuery( '.' + activeClass );
596
+
597
+ //* Only parse if old content isn't the new.
598
+ if ( ! $newContent.is( $previousContent ) && typeof $newContent !== 'undefined' ) {
599
+ // converted to var in compiler.
600
+ let $allContent = jQuery( '.' + name + '-content' );
601
 
602
+ $allContent.fadeOut( 150, function() {
603
+ jQuery( this ).removeClass( activeClass );
604
+ } );
605
+ setTimeout( function() {
606
+ $newContent.addClass( activeClass ).fadeIn( 250 );
607
+ }, 150 );
608
+ setTimeout( function() {
609
+ jQuery( '#' + target ).trigger( 'tsf-tab-toggled' );
610
+ }, 175 );
611
+ }
612
+ }
613
+ },
614
+
615
+ /**
616
+ * Refines Styling for the navigation tabs on the settings pages
617
+ *
618
+ * @since 2.9.0
619
+ * @todo merge with tabTobble or a collective method?
620
+ *
621
+ * @function
622
+ * @param {!jQuery.Event} event
623
+ * @return {(undefined|null)}
624
+ */
625
+ flexTabToggle : function( event ){
626
+ 'use strict';
627
+
628
+ let $this = jQuery( event.target );
629
+
630
+ if ( ! $this.is( ':checked' ) )
631
+ return;
632
+
633
+ // converted to var in compiler.
634
+ let target = $this.prop( 'id' ),
635
+ name = $this.prop( 'name' );
636
+
637
+ if ( typeof name !== 'undefined' ) {
638
+ // converted to var in compiler.
639
+ let activeClass = 'tsf-flex-tab-content-active',
640
+ $newContent = jQuery( '#' + target + '-content' ),
641
+ $previousContent = jQuery( '.' + activeClass );
642
+
643
+ //* Only parse if old content isn't the new.
644
+ if ( ! $newContent.is( $previousContent ) && typeof $newContent !== 'undefined' ) {
645
+ // converted to var in compiler.
646
+ let $allContent = jQuery( '.' + name + '-content' );
647
+
648
+ $allContent.fadeOut( 150, function() {
649
+ jQuery( this ).removeClass( activeClass );
650
+ } );
651
+ setTimeout( function() {
652
+ $newContent.addClass( activeClass ).fadeIn( 250 );
653
+ }, 150 );
654
+ setTimeout( function() {
655
+ jQuery( '#' + target ).trigger( 'tsf-flex-tab-toggled' );
656
+ }, 175 );
657
+ }
658
+ }
659
+ },
660
+
661
+ /**
662
+ * Sets the navigation tabs content equal to the buttons.
663
+ *
664
+ * @since 2.9.0
665
+ * @see tsf.tabToggle
666
+ *
667
+ * @function
668
+ * @return {(undefined|null)}
669
+ */
670
+ setTabsOnload: function() {
671
+
672
+ if ( tsf.hasInput ) {
673
+ if ( tsf.states['isSettingsPage'] ) {
674
+ // converted to var in compiler.
675
+ let $buttons = jQuery( '.tsf-nav-tab-wrapper .tsf-tab:nth-of-type(n+2) input:checked' );
676
+
677
+ // Select all second or later tabs that have attribute checked.
678
+ if ( $buttons.length ) {
679
+ $buttons.each( function( i ) {
680
+ // converted to var in compiler.
681
+ let $this = jQuery( this ),
682
+ target = $this.prop( 'id' ),
683
+ name = $this.prop( 'name' );
684
+
685
+ if ( typeof name !== 'undefined' ) {
686
+ // converted to var in compiler.
687
+ let activeClass = 'tsf-active-tab-content',
688
+ $newContent = jQuery( '#' + target + '-content' );
689
+
690
+ //* Only parse if old content isn't the new.
691
+ if ( typeof $newContent !== 'undefined' ) {
692
+ let $allContent = jQuery( '.' + name + '-content' );
693
+
694
+ $allContent.removeClass( activeClass );
695
+ $newContent.addClass( activeClass );
696
+ setTimeout( function() {
697
+ jQuery( '#' + target ).trigger( 'tsf-tab-toggled' );
698
+ }, 20 );
699
+ }
700
+ }
701
+ } );
702
+ }
703
+ } else {
704
+ // WordPress resets radio buttons on inpost settings. Leave this open for "when".
705
  }
706
  }
707
  },
718
  taglineToggleTitle: function( event ) {
719
  'use strict';
720
 
721
+ // converted to var in compiler.
722
+ let $this = jQuery( event.target ),
723
  $tag = jQuery( '.tsf-custom-blogname-js' );
724
 
725
  if ( $this.is( ':checked' ) ) {
745
  taglineToggleDesc: function( event ) {
746
  'use strict';
747
 
748
+ // converted to var in compiler.
749
+ let $this = jQuery( event.target ),
750
  $tagDesc = jQuery( '#tsf-on-blogname-js' );
751
 
752
  if ( $this.is(':checked') ) {
768
  titleLocationToggle: function( event ) {
769
  'use strict';
770
 
771
+ // converted to var in compiler.
772
+ let val = jQuery( event.target ).val(),
773
  $titleExampleLeft = jQuery( '.tsf-title-additions-example-left' ),
774
  $titleExampleRight = jQuery( '.tsf-title-additions-example-right' );
775
 
794
  titlePrefixToggle: function( event ) {
795
  'use strict';
796
 
797
+ // converted to var in compiler.
798
+ let $this = jQuery( event.target ),
799
  $prefix = jQuery( '.tsf-title-prefix-example' );
800
 
801
  if ( $this.is(':checked') ) {
817
  additionsToggleDesc: function( event ) {
818
  'use strict';
819
 
820
+ // converted to var in compiler.
821
+ let $this = jQuery( event.target ),
822
  $tagDesc = jQuery( '#tsf-description-additions-js' );
823
 
824
  if ( $this.is(':checked') ) {
843
  if ( ! tsf.hasInput )
844
  return;
845
 
846
+ // converted to var in compiler.
847
+ let $tagTitle = jQuery( '#tsf-title-tagline-toggle :input' ),
848
  $title = jQuery( '.tsf-custom-blogname-js' ),
849
  $tagDescAdditions = jQuery( '#tsf-description-additions-toggle :input' ),
850
  $descAdditions = jQuery( '#tsf-description-additions-js' ),
895
  $title = jQuery( '.tsf-custom-title-js' );
896
 
897
  if ( val.length === 0 ) {
898
+ $title.text( tsf.params['siteTitle'] );
899
  } else {
900
  $title.text( val );
901
  }
934
  } else {
935
  placeholder = description + ' ' + sep + ' ' + title;
936
  }
 
937
  }
938
 
939
  $floatTag.text( description );
944
  },
945
 
946
  /**
947
+ * Trigger input event for page titles.
948
  *
949
  * @since 2.5.0
950
  *
954
  taglinePropTrigger: function() {
955
  'use strict';
956
 
957
+ // converted to var in compiler.
958
+ let settingsChangedCache = tsf.settingsChanged;
959
+
960
+ if ( tsf.states['isSettingsPage'] ) {
961
+ jQuery( "#autodescription-site-settings\\[homepage_title_tagline\\]" ).trigger( 'input', tsf.taglineProp );
962
+ } else {
963
+ jQuery( "#autodescription_title" ).trigger( 'input', tsf.taglineProp );
964
+ }
965
+
966
+ // Reset settingsChanged to previous value.
967
+ tsf.settingsChanged = settingsChangedCache;
968
+ },
969
+
970
+ /**
971
+ * Triggers input event for titles in set intervals on window resize.
972
+ *
973
+ * This only happens if boundaries are surpassed to reduce CPU usage.
974
+ * This boundary is 782 pixels, because that forces input fields to change.
975
+ * in WordPress.
976
+ *
977
+ * @since 2.9.0
978
+ *
979
+ * @function
980
+ * @return {undefined}
981
+ */
982
+ taglinePropTriggerResize: function() {
983
+ 'use strict';
984
+
985
+ let resizeTimeout = 0,
986
+ prevWidth = 0;
987
+
988
+ jQuery( window ).resize( function() {
989
+
990
+ clearTimeout( resizeTimeout );
991
+
992
+ resizeTimeout = setTimeout( function() {
993
+
994
+ let width = jQuery( window ).width();
995
+
996
+ if ( prevWidth < width ) {
997
+ if ( prevWidth <= 782 && width >= 782 ) {
998
+ tsf.taglinePropTrigger();
999
+ }
1000
+ } else {
1001
+ if ( prevWidth >= 782 && width <= 782 ) {
1002
+ tsf.taglinePropTrigger();
1003
+ }
1004
+ }
1005
+
1006
+ prevWidth = width;
1007
+ }, 250 );
1008
+ } );
1009
  },
1010
 
1011
  /**
1019
  titleToggle: function() {
1020
  'use strict';
1021
 
1022
+ // converted to var in compiler.
1023
+ let $this = jQuery( event.target ),
1024
  $tagDesc = jQuery( '.tsf-title-additions-js' );
1025
 
1026
  if ( $this.is( ':checked' ) ) {
1044
  if ( ! tsf.hasInput )
1045
  return;
1046
 
1047
+ jQuery( '.tsf-metaboxes :input, #tsf-inpost-box .inside :input' ).not( '.tsf-tab :input, .tsf-flex-nav-tab :input' ).change( function() {
1048
  tsf.registerChange();
1049
  } );
1050
 
1051
  jQuery( '.tsf-metaboxes input[type=text], .tsf-metaboxes textarea, #tsf-inpost-box .inside input[type=text], #tsf-inpost-box .inside textarea' ).not(
1052
+ '.tsf-nav-tab-wrapper input, .tsf-flex-nav-tab-wrapper input' ).on( 'input', function() {
1053
  tsf.registerChange();
1054
  } );
1055
 
1104
  dynamicPlaceholder: function( event ) {
1105
  'use strict';
1106
 
1107
+ // converted to var in compiler.
1108
+ let hasAdditions = tsf.params['titleAdditions'].length,
1109
  $placeholder = jQuery( '#tsf-title-placeholder' );
1110
 
1111
+ // If hasAdditions is empty, there's nothing to do.
1112
+ if ( ! hasAdditions ) {
 
 
1113
  // Empty the placeholder as we can't execute.
1114
+ jQuery( event.target ).css( 'text-indent', "initial" );
1115
  return $placeholder.empty();
1116
  }
1117
 
1118
+ // converted to var in compiler.
1119
+ let after = false,
1120
  check = jQuery( '#tsf-home-title-location input:checked' ).val(),
1121
  rtl = tsf.states['isRTL'],
1122
  additions = '';
1124
  if ( typeof check !== 'undefined' && check.length !== 0 ) {
1125
  //* We're in SEO Settings page.
1126
 
1127
+ if ( rtl ) {
1128
  if ( 'right' === check ) {
1129
  after = true;
1130
  }
1136
  } else {
1137
  //* We're in post/page edit screen.
1138
 
1139
+ let titleLocation = tsf.params['titleLocation'];
 
 
1140
 
1141
  // We're on post/page screen.
1142
+ if ( tsf.states['isHome'] ) {
1143
  // Static Front page, switch check.
1144
+ if ( tsf.titleTagline ) {
1145
  if ( rtl ) {
1146
  if ( 'right' === titleLocation ) {
1147
  after = true;
1161
  }
1162
  }
1163
 
1164
+ let $tagbox = jQuery( '#tsf-title-tagline-toggle :input' );
1165
 
1166
  if ( typeof $tagbox !== "undefined" && $tagbox.length > 0 && ! $tagbox.is( ':checked' ) ) {
1167
  //* We're on SEO Settings Page now, and tagline has been disabled.
1168
+ // converted to var in compiler.
1169
+ let $this = jQuery( event.target );
1170
 
1171
  $this.css( 'text-indent', "initial" );
1172
+ $placeholder.css( 'display', "none" );
1173
  } else {
1174
  var $this = jQuery( event.target ),
1175
  inputVal = $this.val(),
1176
+ $offsetTest = jQuery( "#tsf-title-offset" );
1177
+
1178
+ // converted to var in compiler.
1179
+ let offsetWidth = 0,
1180
+ outerWidth = $this.outerWidth(),
1181
  heightPad = ( $this.outerHeight( true ) - $this.height() ) / 2,
1182
+ horPad = ( outerWidth - $this.innerWidth() ) / 2,
1183
  leftOffset = ( $this.outerWidth( true ) - $this.width() ) / 2,
1184
  taglineVal = jQuery( "#autodescription-site-settings\\[homepage_title_tagline\\]" ).val(),
1185
  pos = 'left',
1194
  }
1195
 
1196
  if ( after ) {
1197
+ additions = " " + separator + " " + tsf.params['titleAdditions'];
1198
 
1199
  // Exchange the placeholder value of the custom Tagline in the HomePage Metabox
1200
  if ( typeof taglineVal !== "undefined" && taglineVal.length > 0 ) {
1201
+ additions = " " + separator + " " + taglineVal;
1202
  }
1203
 
1204
  $this.css( 'text-indent', "initial" );
1205
  } else {
1206
+ additions = tsf.params['titleAdditions'] + " " + separator + " ";
1207
 
1208
  // Exchange the placeholder value of the custom Tagline in the HomePage Metabox
1209
  if ( typeof taglineVal !== "undefined" && taglineVal.length > 0 ) {
1210
+ additions = taglineVal + " " + separator + " ";
1211
  }
1212
  }
1213
 
1221
  });
1222
  offsetWidth = $offsetTest.width();
1223
 
1224
+ let maxWidth = $this.width() - horPad - offsetWidth;
1225
 
1226
  if ( maxWidth < 0 )
1227
  maxWidth = 0;
1249
  } else {
1250
  $placeholder.text( additions );
1251
 
1252
+ // Only calculate when context is present.
1253
+ if ( outerWidth > leftOffset ) {
1254
  if ( after ) {
1255
  $placeholder.css( pos, horPad + leftOffset + $offsetTest.width() + "px" );
1256
  } else {
1257
+ // converted to var in compiler.
1258
+ let indent = horPad + $placeholder.width();
1259
 
1260
  if ( indent < 0 )
1261
  indent = 0;
1279
  selectTitleInput: function() {
1280
  'use strict';
1281
 
1282
+ // converted to var in compiler.
1283
+ let $input = tsf.docTitles();
1284
 
1285
  $input.focus();
1286
 
1287
  if ( $input.setSelectionRange ) {
1288
  // Go to end times 2 if setSelectionRange exists.
1289
+ // converted to var in compiler.
1290
+ let length = $input.val().length * 2;
1291
  $input.setSelectionRange( length, length );
1292
  } else {
1293
  // Replace value with itself.
1295
  }
1296
  },
1297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1298
  /**
1299
  * Triggers keyup on description input so the counter can colorize.
1300
  *
1309
  if ( ! tsf.hasInput )
1310
  return;
1311
 
1312
+ // converted to var in compiler.
1313
+ let $input = tsf.docDescriptions();
1314
 
1315
  $input.trigger( 'input', tsf.updateCharacterCountDescription );
1316
  },
1317
 
 
1318
  /**
1319
  * Triggers keyup on title input so the counter can colorize.
1320
  *
1329
  if ( ! tsf.hasInput )
1330
  return;
1331
 
1332
+ // converted to var in compiler.
1333
+ let $input = tsf.docTitles();
1334
 
1335
  $input.trigger( 'input', tsf.updateCharacterCountTitle );
1336
  },
1362
  dismissNotice: function( event ) {
1363
  'use strict';
1364
 
1365
+ // converted to var in compiler.
1366
+ let $this = jQuery( event.target );
1367
 
1368
  $this.parents( '.tsf-notice' ).slideUp( 200, function() {
1369
  $this.remove();
1398
  unsetAjaxLoader: function( target, success ) {
1399
  'use strict';
1400
 
1401
+ // converted to var in compiler.
1402
+ let newclass = 'tsf-success',
1403
  fade = 2500;
1404
 
1405
  if ( ! success ) {
1446
  //* Update counters locally.
1447
  tsf.additionsClassInit();
1448
 
1449
+ let target = '.tsf-counter .tsf-ajax',
1450
  status = 0;
1451
 
1452
  //* Reset ajax loader
1456
  tsf.setAjaxLoader( target );
1457
 
1458
  //* Setup external update.
1459
+ let settings = {
1460
  method: 'POST',
1461
  url: ajaxurl,
1462
  datatype: 'json',
1463
  data: {
1464
  'action' : 'the_seo_framework_update_counter',
1465
+ 'nonce' : tsf.nonces['edit_posts'],
1466
  'val' : tsf.counterType,
1467
  },
1468
  async: true,
1522
  if ( ! tsf.hasInput )
1523
  return;
1524
 
1525
+ // converted to var in compiler.
1526
+ let counterType = tsf.counterType,
1527
+ settingsChangedCache = tsf.settingsChanged;
1528
 
1529
  if ( 1 == counterType ) {
1530
  tsf.additionsClass = 'tsf-counter-one';
1543
  tsf.updateCounters();
1544
 
1545
  // Reset settingsChanged to previous value.
1546
+ tsf.settingsChanged = settingsChangedCache;
1547
  },
1548
 
1549
  /**
1580
  * Returns converted HTML title/description separator.
1581
  *
1582
  * @since 2.7.0
1583
+ * @since 2.9.0 Added caching.
1584
  *
1585
  * @function
1586
  * @param {String} type
1589
  getSep: function( type ) {
1590
  'use strict';
1591
 
1592
+ // converted to var in compiler.
1593
+ let sep = '',
1594
+ retVal = '';
1595
+
1596
  if ( 'title' === type ) {
1597
+ sep = tsf.titleSeparator;
1598
  } else {
1599
+ sep = tsf.descriptionSeparator;
1600
  }
1601
 
1602
+ /** Concept:
1603
+ if ( this.getSep.cachedSep && this.getSep.cachedSep.hasOwnProperty( type ) && sep === this.getSep.cachedSep[ type ]['sep'] ) {
1604
+ return this.getSep.cachedSep[ type ]['retVal'];
1605
+ } else {
1606
+ //* Setup main cache container.
1607
+ if ( ! this.getSep.cachedSep )
1608
+ this.getSep.cachedSep = {};
1609
+
1610
+ //* Set up secondary cache container.
1611
+ if ( ! this.getSep.cachedSep[ type ] )
1612
+ this.getSep.cachedSep[ type ] = {};
1613
+
1614
+ //* Setup cache listener.
1615
+ this.getSep.cachedSep[ type ]['sep'] = sep;
1616
+ }
1617
+ */
1618
+
1619
  if ( 'pipe' === sep || '|' === sep ) {
1620
+ retVal = ( "|" );
1621
  } else if ( 'dash' === sep || '-' === sep ) {
1622
+ retVal = ( "-" );
1623
  } else if ( sep.charCodeAt(0) < 123 ) {
1624
  //* Checked for UTF-8 conversion.
1625
  // Create a memory div to store the html in, convert to text to append in $placeholder
1626
+ retVal = jQuery.trim( sep );
1627
  if ( '&' === sep.charAt(0) && ';' === sep.slice(-1) )
1628
  sep = sep.substr(1).slice(0, -1);
1629
 
1630
+ retVal = jQuery( '<div/>' ).html( "&" + sep + ";" ).text();
1631
  }
1632
 
1633
+ /** Concept:
1634
+ return this.getSep.cachedSep[ type ]['retVal'] = retVal;
1635
+ */
1636
+
1637
+ //* Setup cache listener and return val.
1638
+ return retVal;
1639
  },
1640
 
1641
  /**
1699
 
1700
  frame.on( 'cropped', function( croppedImage ) {
1701
 
1702
+ // converted to var in compiler.
1703
+ let url = croppedImage.url,
1704
  attachmentId = croppedImage.id,
1705
  w = croppedImage.width,
1706
  h = croppedImage.height;
1712
 
1713
  frame.on( 'skippedcrop', function( selection ) {
1714
 
1715
+ // converted to var in compiler.
1716
+ let url = selection.get( 'url' ),
1717
  attachmentId = selection.get( 'id' ),
1718
  w = selection.get( 'width' ),
1719
  h = selection.get( 'height' );
1749
  * @return {(undefined|null)}
1750
  */
1751
  appendRemoveButton: function( target, inputID, animate ) {
1752
+ 'use strict';
1753
 
1754
  if ( target && inputID ) {
1755
  if ( ! jQuery( '#' + inputID + '-remove' ).length ) {
1783
  * @return {(undefined|null)}
1784
  */
1785
  removeEditorImage: function( event ) {
1786
+ 'use strict';
1787
 
1788
  var $target = jQuery( event.target ),
1789
  inputID = $target.data( 'inputid' );
1834
  * @augments wp.media.controller.State
1835
  * @augments Backbone.Model
1836
  */
1837
+ var TSFCropper;
1838
+ // converted to var in compiler.
1839
+ let Controller = wp.media.controller;
1840
 
1841
  TSFCropper = Controller.Cropper.extend( {
1842
  doCrop: function( attachment ) {
1877
  cropDetails.dst_height = 0;
1878
  }
1879
 
1880
+ return wp.ajax.post( 'tsf-crop-image', {
1881
+ 'nonce' : tsf.nonces['upload_files'],
1882
  'id' : attachment.get( 'id' ),
1883
  'context' : 'tsf-image',
1884
  'cropDetails' : cropDetails
1914
  calculateImageSelectOptions: function( attachment, controller ) {
1915
  'use strict';
1916
 
1917
+ // converted to var in compiler.
1918
+ let control = tsf.cropper.control;
1919
+
1920
+ var flexWidth = !! parseInt( control.params.flex_width, 10 ),
1921
  flexHeight = !! parseInt( control.params.flex_height, 10 ),
 
 
1922
  xInit = parseInt( control.params.width, 10 ),
1923
+ yInit = parseInt( control.params.height, 10 );
1924
+
1925
+ // converted to var in compiler.
1926
+ let realWidth = attachment.get( 'width' ),
1927
+ realHeight = attachment.get( 'height' ),
1928
  ratio = xInit / yInit,
1929
  xImg = xInit,
1930
  yImg = yInit,
1931
+ x1,
1932
+ y1,
1933
+ imgSelectOptions;
1934
 
1935
  controller.set( 'control', control.params );
1936
  controller.set( 'canSkipCrop', ! tsf.mustBeCropped( control.params.flex_width, control.params.flex_height, realWidth, realHeight ) );
1995
  mustBeCropped: function( dstW, dstH, imgW, imgH ) {
1996
  'use strict';
1997
 
1998
+ if ( imgW <= dstW && imgH <= dstH )
1999
  return false;
 
2000
 
2001
  return true;
2002
  },
2010
  * @return {(undefined|null)}
2011
  */
2012
  resetImageEditorActions: function() {
2013
+ 'use strict';
2014
+
2015
  jQuery( '.tsf-remove-social-image' ).on( 'click', tsf.removeEditorImage );
2016
  },
2017
 
2024
  * @return {(undefined|null)}
2025
  */
2026
  setupImageEditorActions: function() {
2027
+ 'use strict';
2028
+
2029
  jQuery( '.tsf-set-social-image' ).on( 'click', tsf.openImageEditor );
2030
  jQuery( '.tsf-remove-social-image' ).on( 'click', tsf.removeEditorImage );
2031
  },
2039
  * @return {(undefined|null)}
2040
  */
2041
  checkImageEditorInput: function() {
2042
+ 'use strict';
2043
 
2044
+ // converted to var in compiler.
2045
+ let $buttons = jQuery( '.tsf-set-social-image' );
2046
 
2047
  if ( $buttons.length ) {
2048
+ let inputID = '',
2049
  $valID = '';
2050
 
2051
  jQuery.each( $buttons, function( index, value ) {
2073
  * @return {(undefined|null)}
2074
  */
2075
  setColorOnload: function() {
2076
+ 'use strict';
2077
 
2078
+ // converted to var in compiler.
2079
+ let $selectors = jQuery( '.tsf-color-picker' );
2080
 
2081
  if ( $selectors.length ) {
2082
  jQuery.each( $selectors, function( index, value ) {
2083
+ // converted to var in compiler.
2084
+ let $input = jQuery( value ),
2085
  currentColor = '',
2086
  defaultColor = $input.data( 'tsf-default-color' );
2087
 
2119
  * @return {(undefined|null)}
2120
  */
2121
  setupVars: function() {
2122
+ 'use strict';
2123
 
2124
  //The current title separator.
2125
  tsf.titleSeparator = tsf.params['titleSeparator'];
2130
  // The current title tagline.
2131
  tsf.titleTagline = tsf.states['titleTagline'];
2132
 
2133
+ // The counter type. Mixed string and int (i10n is string, JS is int).
2134
+ tsf.counterType = parseInt( tsf.states['counterType'] );
2135
 
2136
  // Determines if the current page has input boxes for The SEO Framework.
2137
  tsf.hasInput = tsf.states['hasInput'];
2138
  },
2139
 
2140
+ /**
2141
+ * Registers title prop listeners.
2142
+ *
2143
+ * @since 2.9.0
2144
+ *
2145
+ * @function
2146
+ * @return {(undefined|null)}
2147
+ */
2148
+ _initTitlepropListener: function() {
2149
+ 'use strict';
2150
+
2151
+ if ( tsf.hasInput ) {
2152
+ let jQ = jQuery;
2153
+
2154
+ //* Trigger directly on call load.
2155
+ //tsf.taglinePropTrigger();
2156
+
2157
+ // Toggle Title tagline aditions removal.
2158
+ jQ( '#tsf-title-tagline-toggle :input' ).on( 'click', tsf.taglineToggleTitle );
2159
+ // Toggle Title additions location.
2160
+ jQ( '#tsf-title-location input' ).on( 'click', tsf.titleLocationToggle );
2161
+ // Toggle Title prefixes display.
2162
+ jQ( '#title-prefixes-toggle :input' ).on( 'click', tsf.titlePrefixToggle );
2163
+
2164
+ // Change Home Page Title Example prop on input changes.
2165
+ jQ( '#autodescription-site-settings\\[homepage_title\\]' ).on( 'input', tsf.titleProp );
2166
+ jQ( '#tsf-home-title-location :input, #tsf-title-tagline-toggle :input, #tsf-title-separator input' ).on( 'click', tsf.taglinePropTrigger );
2167
+ jQ( '#autodescription-site-settings\\[homepage_title_tagline\\]' ).on( 'input', tsf.taglineProp );
2168
+
2169
+ // Make sure the titleProp is correctly rendered when revealed after being hidden.
2170
+ jQ( '#homepage-tab-general' ).on( 'tsf-tab-toggled', tsf.taglinePropTrigger );
2171
+ jQ( '#autodescription-homepage-settings > button' ).on( 'click', tsf.taglinePropTrigger );
2172
+ jQ( '#tsf-inpost-box > button' ).on( 'click', tsf.taglinePropTrigger );
2173
+
2174
+ // Change Global Title Example prop on input changes.
2175
+ jQ( '#autodescription-site-settings\\[title_rem_additions\\]' ).on( 'click', tsf.titleToggle );
2176
+
2177
+ // Dynamic Placeholder, acts on keydown for a11y, although more cpu intensive. Acts on keyup for perfect output.
2178
+ tsf.docTitles().on( 'input', tsf.dynamicPlaceholder );
2179
+
2180
+ // Move click on dynamic additions to focus input behind.
2181
+ jQ( '#tsf-title-placeholder' ).on( 'click', tsf.selectTitleInput );
2182
+
2183
+ jQ( window ).resize( tsf.taglinePropTriggerResize );
2184
+ }
2185
+ },
2186
+
2187
+ /**
2188
+ * Registers on resize/orientationchange listeners and debounces to only run
2189
+ * at intervals.
2190
+ *
2191
+ * For Flexbox implementation.
2192
+ *
2193
+ * @since 2.9.0
2194
+ *
2195
+ * @function
2196
+ * @return {(undefined|null)}
2197
+ */
2198
+ _doFlexResizeListener: function() {
2199
+ 'use strict';
2200
+
2201
+ if ( ! jQuery( '.tsf-flex' ).length )
2202
+ return;
2203
+
2204
+ //* Set event listeners.
2205
+ tsf._setResizeListeners();
2206
+
2207
+ var resizeTimeout = 0,
2208
+ $lastWidth = {},
2209
+ timeOut = 0;
2210
+
2211
+ // Warning: Only checks for the first item existence.
2212
+ var $tabWrapper = jQuery( '.tsf-flex-nav-tab-wrapper' );
2213
+
2214
+ jQuery( window ).on( 'tsf-flex-resize', function() {
2215
+
2216
+ clearTimeout( resizeTimeout );
2217
+
2218
+ // Onload delays are 0, after than it's 10, 20 and 30 respectively.
2219
+ let _delay = 0,
2220
+ __delay = 0,
2221
+ ___delay = 0;
2222
+
2223
+ resizeTimeout = setTimeout( function() {
2224
+ if ( $tabWrapper.length ) {
2225
+ // Flex Tab Wrapper.
2226
+ let $innerWrap = jQuery( '.tsf-flex-nav-tab-inner' ),
2227
+ outerWrapWidth = $tabWrapper.width(),
2228
+ innerWrapWidth = $innerWrap.width(),
2229
+ $navName = jQuery( '.tsf-flex-nav-name' );
2230
+
2231
+ if ( ! $lastWidth.tabWrapper ) {
2232
+ $lastWidth.tabWrapper = {};
2233
+ $lastWidth.tabWrapper.outer = 0;
2234
+ $lastWidth.tabWrapper.inner = 0;
2235
+ $lastWidth.tabWrapper.shown = 1;
2236
+ }
2237
+
2238
+ // First run, revealed, or testing for new width. Either way, fadeIn.
2239
+ if ( ! $lastWidth.tabWrapper.shown && $lastWidth.tabWrapper.outer < outerWrapWidth ) {
2240
+ /**
2241
+ * If ANYONE can find a way that doesn't make it flicker
2242
+ * without using clones with stripped IDs/names, let me know.
2243
+ * https://github.com/sybrew/the-seo-framework/issues/new
2244
+ * https://github.com/sybrew/the-seo-framework/compare
2245
+ */
2246
+ $navName.fadeIn( 250 );
2247
+
2248
+ // Wait for 10 ms for slow browsers.
2249
+ setTimeout( function() {
2250
+ // Recalulate inner width (outer didn't change):
2251
+ innerWrapWidth = $innerWrap.width();
2252
+ }, _delay );
2253
+ }
2254
+
2255
+ // Wait for an additional 10 ms for slow browsers.
2256
+ setTimeout( function() {
2257
+ if ( innerWrapWidth > outerWrapWidth ) {
2258
+ // Overflow (can be first run).
2259
+ $navName.hide();
2260
+ $lastWidth.tabWrapper.shown = 0;
2261
+ } else if ( $lastWidth.tabWrapper.outer < outerWrapWidth ) {
2262
+ // Grown or first run.
2263
+ $navName.fadeIn( 250 );
2264
+ $lastWidth.tabWrapper.shown = 1;
2265
+ }
2266
+ }, __delay );
2267
+
2268
+ // Wait for an additional 10 ms for slow browsers.
2269
+ setTimeout( function() {
2270
+ $lastWidth.tabWrapper.outer = outerWrapWidth;
2271
+ $lastWidth.tabWrapper.inner = innerWrapWidth;
2272
+ }, ___delay );
2273
+ }
2274
+ }, timeOut );
2275
+
2276
+ // Update future timeouts.
2277
+ _delay = 10;
2278
+ __delay = 20;
2279
+ ___delay = 30;
2280
+ timeOut = 75;
2281
+ } );
2282
+
2283
+ //* Trigger after setup.
2284
+ jQuery( window ).trigger( 'tsf-flex-resize' );
2285
+ },
2286
+
2287
+ /**
2288
+ * Sets flex resize listeners.
2289
+ *
2290
+ * @since 2.9.0
2291
+ *
2292
+ * @function
2293
+ * @return {(undefined|null)}
2294
+ */
2295
+ _setResizeListeners: function() {
2296
+ jQuery( window ).on( 'resize orientationchange', tsf._triggerResize );
2297
+ jQuery( '#collapse-menu' ).click( tsf._triggerResize );
2298
+ jQuery( '.columns-prefs :input[type=radio]' ).change( tsf._triggerResize );
2299
+ jQuery( '.meta-box-sortables' ).on( 'sortupdate', tsf._triggerResize );
2300
+ },
2301
+
2302
+ /**
2303
+ * Triggers resize on event.
2304
+ *
2305
+ * @since 2.9.0
2306
+ *
2307
+ * @function
2308
+ * @return {(undefined|null)}
2309
+ */
2310
+ _triggerResize: function() {
2311
+ jQuery( window ).trigger( 'tsf-flex-resize' );
2312
+ },
2313
+
2314
+ /**
2315
+ * Sets tsf.ready action.
2316
+ *
2317
+ * Example: jQuery( document.body ).on( 'tsf-ready', myFunc );
2318
+ *
2319
+ * @since 2.9.0
2320
+ * @access private
2321
+ *
2322
+ * @function
2323
+ */
2324
+ _triggerReady: function() {
2325
+ 'use strict';
2326
+
2327
+ jQuery( document.body ).trigger( 'tsf-ready' );
2328
+ },
2329
+
2330
  /**
2331
  * Initialises all aspects of the scripts.
2332
  *
2338
  * @since 2.2.4
2339
  * @since 2.7.0 jQuery object is now passed.
2340
  *
2341
+ * @todo setup ready action list and action callers. Now it's ravioli that's
2342
+ * dependent on eachother.
2343
+ *
2344
  * @function
2345
  * @param {!jQuery} jQ jQuery
2346
  * @return {undefined}
2354
  // Move the page updates notices below the tsf-top-wrap.
2355
  jQ( 'div.updated, div.error, div.notice-warning' ).insertAfter( 'div.tsf-top-wrap' );
2356
 
2357
+ // Add title prop listeners. Must load before setTabsOnload to work.
2358
+ jQ( document.body ).ready( tsf._initTitlepropListener );
2359
+
2360
+ // Sets tabs to correct radio button on load.
2361
+ jQ( document.body ).ready( tsf.setTabsOnload );
2362
+
2363
  // Set up additions classes.
2364
  jQ( document.body ).ready( tsf.additionsClassInit );
2365
 
 
 
 
2366
  // Check if the Title Tagline or Description Additions should be removed when page is loaded.
2367
  jQ( document.body ).ready( tsf.taglineToggleOnload );
2368
 
2369
  // Initialize the status bar hover balloon.
2370
  jQ( document.body ).ready( tsf.statusBarHover );
2371
 
 
 
 
2372
  // Initialize image uploader button cache.
2373
  jQ( document.body ).ready( tsf.setupImageEditorActions );
2374
 
2375
  // Determine image editor button input states.
2376
  jQ( document.body ).ready( tsf.checkImageEditorInput );
2377
 
2378
+ // Correct Color Picker input
2379
  jQ( document.body ).ready( tsf.setColorOnload );
2380
 
2381
  // #== End Before Change listener
2386
  // Deregister changes.
2387
  jQ( document.body ).ready( tsf.onLoadUnregisterChange );
2388
 
2389
+ // Trigger tsf-ready event.
2390
+ jQ( document.body ).ready( tsf._triggerReady );
2391
+
2392
  // #== Start After Change listener
2393
 
2394
+ // Do flex resize functionality.
2395
+ jQ( document.body ).ready( tsf._doFlexResizeListener );
2396
+
2397
+ // Initialize status bar removal hover for touch screens.
2398
+ jQ( document.body ).on( 'click touchstart MSPointerDown', tsf.removeDesc );
2399
+
2400
  // Bind character counters.
2401
  tsf.docDescriptions().on( 'input', tsf.updateCharacterCountDescription );
2402
  tsf.docTitles().on( 'input', tsf.updateCharacterCountTitle );
2410
  jQ( '.tsf-js-confirm-reset' ).on( 'click', tsf.confirmedReset );
2411
 
2412
  // Toggle Tabs in the SEO settings page.
2413
+ jQ( '.tsf-tabs-radio' ).on( 'change', tsf.tabToggle );
2414
 
2415
+ // Toggle Tabs for the inpost Flex settings.
2416
+ jQ( '.tsf-flex-nav-tab-radio' ).on( 'change', tsf.flexTabToggle );
 
 
 
 
2417
 
2418
  // Toggle Description additions removal.
2419
  jQ( '#tsf-description-onblogname-toggle :input' ).on( 'click', tsf.taglineToggleDesc );
2420
  jQ( '#tsf-description-additions-toggle :input' ).on( 'click', tsf.additionsToggleDesc );
2421
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2422
  // Dismiss notices.
2423
  jQ( '.tsf-dismiss' ).on( 'click', tsf.dismissNotice );
2424
 
lib/js/tsf.min.js CHANGED
@@ -1,32 +1,37 @@
1
- window.tsf={nonce:tsfL10n.nonce,i18n:tsfL10n.i18n,states:tsfL10n.states,params:tsfL10n.params,other:tsfL10n.other,i:!1,j:!1,m:"",u:"",a:0,f:!1,b:"",cropper:{},c:function(){return jQuery("#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]")},v:function(){return jQuery("#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]")},confirm:function(a){return confirm(a)},I:function(a){var b=
2
- jQuery(a.target),d=b.val().length;a=jQuery("#"+tsf.A(a.target.id)+"_chars");var c,e="";0===d&&(d=b.prop("placeholder").length);100>d||175<=d?(b="tsf-count-bad",c=tsf.g("bad")):137>d||155<d&&175>d?(b="tsf-count-okay",c=tsf.g("okay")):(b="tsf-count-good",c=tsf.g("good"));tsf.b&&(b+=" "+tsf.b);tsf.a&&1!=tsf.a?2==tsf.a?e=c:3==tsf.a&&(e=d.toString()+" - "+c):e=d.toString();a.html(e).removeClass().addClass(b)},l:function(a){var b=jQuery(a.target),d=tsf.params.titleAdditions.length,c=tsf.params.blogDescription.length,
3
- e=tsf.params.siteTitle.length,f=b.val().length,m=b.prop("placeholder").length,h=jQuery("#autodescription-site-settings\\[homepage_title_tagline\\]").val(),g=3;a=jQuery("#"+tsf.A(a.target.id)+"_chars");var k=0,b=tsf.b,l=tsf.a,n="";tsf.j||(g=d=0);0===f&&(0!==e?f=e:k=m);0!==f&&(0!==d&&"undefined"!==typeof h&&(d=h.length,d=0!==d?d:c),k=0===d?f:f+g+d);25>k||75<=k?(c="tsf-count-bad",f=tsf.g("bad")):42>k||55<k&&75>k?(c="tsf-count-okay",f=tsf.g("okay")):(c="tsf-count-good",f=tsf.g("good"));b&&(c+=" "+b);
4
- l&&1!=l?2==l?n=f:3==l&&(n=k.toString()+" - "+f):n=k.toString();a.html(n).removeClass().addClass(c)},A:function(a){return a?a.replace(/([\[\]\/])/g,"\\$1"):a},aa:function(a){var b=jQuery(".tsf-sep-js");a=jQuery(a.target).val();tsf.m=a;"pipe"===a?b.text(" | "):"dash"===a?b.text(" - "):b.html(" &"+a+"; ")},Z:function(a){var b=jQuery("#autodescription-descsep-js");a=jQuery(a.target).val();"pipe"===a?b.text(" | "):"dash"===a?b.text(" - "):b.html(" &"+a+"; ")},statusBarHover:function(){var a=jQuery(".tsf-seo-bar-inner-wrap").find("a");
5
- a.on("mouseenter",tsf.fa);a.on("mousemove",tsf.ha);a.on("mouseleave",tsf.ga)},fa:function(a){a=jQuery(a.target);var b=a.data("desc");void 0!==b&&0===a.find("div").length&&(a.append('<div class="tsf-explanation-desc">'+b+"<div></div></div>"),b=a.find("div.tsf-explanation-desc").height()+28,a.find("div.tsf-explanation-desc").css("top",a.position().top-b+"px"))},ha:function(a){var b=jQuery(a.target);a=a.pageX;var d=a-jQuery(".tsf-seo-bar-inner-wrap").offset().left-11,c=b.find(".tsf-explanation-desc"),
6
- b=c.find("div");if(1>d)b.css("left","0px");else if(void 0!==c.offset()){var e=c.width(),c=c.offset().left+e+11;a>c?b.css("left",e+"px"):b.css("left",d+"px")}},ga:function(a){jQuery(a.target).find("div.tsf-explanation-desc").remove()},W:function(){var a=jQuery(document.body.target),b=jQuery(".tsf-seo-bar-inner-wrap a");a.closest(b).length||b.find("div.tsf-explanation-desc").remove()},ia:function(a){var b=jQuery(a.target).prop("id");a=jQuery(a.target).prop("name");"undefined"!==typeof b&&(b=jQuery("#"+
7
- b+"-content"),a=jQuery("."+a+"-content"),"undefined"!==typeof b&&(a.removeClass("tsf-active-tab-content"),b.addClass("tsf-active-tab-content")))},la:function(a){a=jQuery(a.target);var b=jQuery(".tsf-custom-blogname-js");a.is(":checked")?(b.css("display","inline"),tsf.j=!0):(b.css("display","none"),tsf.j=!1);tsf.c().trigger("keyup",tsf.l)},ja:function(a){a=jQuery(a.target);var b=jQuery("#tsf-on-blogname-js");a.is(":checked")?b.css("display","inline"):b.css("display","none")},ma:function(a){a=jQuery(a.target).val();
8
- var b=jQuery(".tsf-title-additions-example-left"),d=jQuery(".tsf-title-additions-example-right");"right"===a?(b.css("display","none"),d.css("display","inline")):(b.css("display","inline"),d.css("display","none"))},na:function(a){a=jQuery(a.target);var b=jQuery(".tsf-title-prefix-example");a.is(":checked")?b.css("display","none"):b.css("display","inline")},J:function(a){a=jQuery(a.target);var b=jQuery("#tsf-description-additions-js");a.is(":checked")?b.css("display","inline"):b.css("display","none")},
9
- ka:function(){if(tsf.f){var a=jQuery("#tsf-title-tagline-toggle :input"),b=jQuery(".tsf-custom-blogname-js"),d=jQuery("#tsf-description-additions-toggle :input"),c=jQuery("#tsf-description-additions-js"),e=jQuery("#tsf-description-onblogname-toggle :input"),f=jQuery("#tsf-on-blogname-js"),m=jQuery("#tsf-title-additions-toggle :input"),h=jQuery(".tsf-title-additions-js");a.is(":checked")?b.css("display","inline"):b.css("display","none");d.is(":checked")?c.css("display","inline"):c.css("display","none");
10
- e.is(":checked")?f.css("display","inline"):f.css("display","none");m.is(":checked")?h.css("display","none"):h.css("display","inline")}},oa:function(a){a=jQuery(a.target).val();var b=jQuery(".tsf-custom-title-js");0===a.length?b.text(tsf.i18n.siteTitle):b.text(a)},F:function(a){a=jQuery(a.target).val();var b=jQuery(".tsf-custom-tagline-js"),d=jQuery("#autodescription-site-settings\\[homepage_title\\]"),c=jQuery("#tsf-home-title-location input:checked").val(),e=jQuery("#autodescription-site-settings\\[homepage_tagline\\]"),
11
- f=tsf.params.siteTitle,m=f,h=tsf.params.blogDescription,g=tsf.B("title");e.is(":checked")&&(0!==a.length&&(h=a),m=0!==c.length&&"left"===c?f+" "+g+" "+h:h+" "+g+" "+f);b.text(h);d.prop("placeholder",m);tsf.c().trigger("input",tsf.l)},G:function(){jQuery("#autodescription-site-settings\\[homepage_title_tagline\\]").trigger("input",tsf.F)},pa:function(){var a=jQuery(event.target),b=jQuery(".tsf-title-additions-js");a.is(":checked")?b.css("display","none"):b.css("display","inline")},K:function(){tsf.f&&
12
- (jQuery(".tsf-metaboxes :input, #tsf-inpost-box .inside :input").not(".tsf-tab :input").change(function(){tsf.h()}),jQuery(".tsf-metaboxes input[type=text], .tsf-metaboxes textarea, #tsf-inpost-box .inside input[type=text], #tsf-inpost-box .inside textarea").not(".tsf-nav-tab-wrapper :input").on("input",function(){tsf.h()}),window.onbeforeunload=function(){if(tsf.i)return tsf.i18n.saveAlert},jQuery('.tsf-metaboxes input[type="submit"], #publishing-action input[type="submit"], #save-action input[type="submit"], a.submitdelete').click(function(){window.onbeforeunload=
13
- null}))},h:function(){tsf.i=!0},M:function(){return confirm(tsf.i18n.confirmReset)},w:function(a){var b=tsf.params.titleAdditions.length,d=jQuery("#tsf-title-placeholder");if(0===b)return a=jQuery(a.target),a.css("text-indent","initial"),d.empty();var b=!1,c=jQuery("#tsf-home-title-location input:checked").val(),e=tsf.states.isRTL;if("undefined"!==typeof c&&0!==c.length)"1"===e?"right"===c&&(b=!0):"left"===c&&(b=!0);else{var c=tsf.params.titleLocation,f=tsf.j;tsf.states.isHome?f&&(e?"right"===c&&
14
- (b=!0):"left"===c&&(b=!0)):e?"left"===c&&(b=!0):"right"===c&&(b=!0)}c=jQuery("#tsf-title-tagline-toggle :input");if("undefined"!==typeof c&&0<c.length&&!c.is(":checked"))a=jQuery(a.target),a.css("text-indent","initial"),d.css("display","none");else{a=jQuery(a.target);var m=a.val(),h=jQuery("#tsf-title-offset"),g,k=(a.outerHeight(!0)-a.height())/2,l=(a.outerWidth()-a.width())/2,c=(a.outerWidth(!0)-a.width())/2;g=jQuery("#autodescription-site-settings\\[homepage_title_tagline\\]").val();var f="left",
15
- n=tsf.B("title");e&&(f="right");"undefined"!==typeof g&&0===g.length&&(g=tsf.params.blogDescription);b?(e=n+" "+tsf.params.titleAdditions,"undefined"!==typeof g&&0<g.length&&(e=n+" "+g),a.css("text-indent","initial")):(e=tsf.params.titleAdditions+" "+n,"undefined"!==typeof g&&0<g.length&&(e=g+" "+n));h.text(m);h.css({fontFamily:a.css("fontFamily"),fontWeight:a.css("fontWeight"),letterSpacing:a.css("letterSpacing"),fontSize:a.css("fontSize")});g=h.width();g=a.width()-l-g;0>g&&(g=0);d.css({display:a.css("display"),
16
- lineHeight:a.css("lineHeight"),paddingTop:k+"px",paddingBottom:k+"px",fontFamily:a.css("fontFamily"),fontWeight:a.css("fontWeight"),fontSize:a.css("fontSize"),letterSpacing:a.css("letterSpacing"),maxWidth:g+"px"});"undefined"===typeof m||1>m.length?(b||a.css("text-indent","initial"),d.empty()):(d.text(e),a.outerWidth()>c&&(b?d.css(f,l+c+h.width()+"px"):(b=l+d.width(),0>b&&(b=0),d.css(f,c+"px"),a.css("text-indent",b+"px"))))}},Y:function(){var a=tsf.c();a.focus();if(a.setSelectionRange){var b=2*a.val().length;
17
- a.setSelectionRange(b,b)}else a.val(a.val()).focus()},R:function(){if(tsf.f){var a=tsf.c();"undefined"!==typeof a.val()&&(0<a.val().length?a.trigger("input",tsf.w):a.trigger("input",tsf.l))}},qa:function(){tsf.f&&tsf.v().trigger("input",tsf.I)},ra:function(){tsf.f&&tsf.c().trigger("input",tsf.l)},U:function(){tsf.i=!1},P:function(a){var b=jQuery(a.target);b.parents(".tsf-notice").slideUp(200,function(){b.remove()})},ba:function(a){jQuery(a).toggleClass("tsf-loading")},H:function(a,b){var d="tsf-success",
18
- c=2500;b||(d="tsf-error",c=5E3);jQuery(a).removeClass("tsf-loading").addClass(d).fadeOut(c)},D:function(a){jQuery(a).stop().empty().prop("class","tsf-ajax").css("opacity","1").removeProp("style")},N:function(){tsf.a+=1;3<tsf.a&&(tsf.a=0);tsf.o();var a=0;tsf.D(".tsf-counter .tsf-ajax");tsf.ba(".tsf-counter .tsf-ajax");jQuery.ajax({method:"POST",url:ajaxurl,ua:"json",data:{action:"the_seo_framework_update_counter",nonce:tsf.nonce,val:tsf.a},async:!0,success:function(b){b=jQuery.parseJSON(b);"success"===
19
- b.type&&(a=1);tsf.O(".tsf-counter .tsf-ajax",a)}})},O:function(a,b){switch(b){case 0:tsf.H(a,!1);break;case 1:tsf.H(a,!0);break;default:tsf.D(a)}},o:function(){if(tsf.f){var a=tsf.a,b=tsf.i;1==a?(tsf.b="tsf-counter-one",tsf.a=1):2==a?(tsf.b="tsf-counter-two",tsf.a=2):3==a?(tsf.b="tsf-counter-three",tsf.a=3):(tsf.b="tsf-counter-zero",tsf.a=0);tsf.sa();tsf.i=b}},sa:function(){tsf.ra();tsf.qa()},g:function(a){return tsf.i18n[a]},B:function(a){a="title"===a?tsf.m:tsf.u;"pipe"===a||"|"===a?a="|":"dash"===
20
- a||"-"===a?a="-":123>a.charCodeAt(0)&&(a=jQuery.trim(a),"&"===a.charAt(0)&&";"===a.slice(-1)&&(a=a.substr(1).slice(0,-1)),a=jQuery("<div/>").html("&"+a+";").text());return a},V:function(a){if(jQuery(a.target).prop("disabled")||"undefined"===typeof wp.media)a.preventDefault(),a.stopPropagation();else{var b=jQuery(a.target),d=b.data("inputid"),c;c||(a.preventDefault(),a.stopPropagation(),tsf.S(),c=wp.media({button:{text:tsf.other[d].frame_button,close:!1},states:[new wp.media.controller.Library({title:tsf.other[d].frame_title,
21
- library:wp.media.query({type:"image"}),multiple:!1,date:!1,priority:20,suggestedWidth:1200,suggestedHeight:630}),new tsf.cropper({imgSelectOptions:tsf.calculateImageSelectOptions})]}),c.on("select",function(){c.setState("cropper")}),c.on("cropped",function(a){var b=a.url;a=a.id;jQuery("#"+d+"-url").val(b);jQuery("#"+d+"-id").val(a)}),c.on("skippedcrop",function(a){var b=a.get("url"),c=a.get("id");a.get("width");a.get("height");jQuery("#"+d+"-url").val(b);jQuery("#"+d+"-id").val(c)}),c.on("skippedcrop cropped",
22
- function(){jQuery("#"+d+"-select").text(tsf.other[d].change);jQuery("#"+d+"-url").prop("readonly",!0).css("opacity",0).animate({opacity:1},{queue:!0,duration:1E3},"swing");tsf.s(b,d,!0);tsf.h()}));c.open()}},s:function(a,b,d){a&&b&&!jQuery("#"+b+"-remove").length&&(a.after('<a href="javascript:void(0)" id="'+b+'-remove" class="tsf-remove-social-image button button-small" data-inputid="'+b+'" title="'+tsf.other[b].remove_title+'">'+tsf.other[b].remove+"</a>"),d&&jQuery("#"+b+"-remove").css("opacity",
23
- 0).animate({opacity:1},{queue:!0,duration:1E3},"swing"));tsf.X()},C:function(a){var b=jQuery(a.target).data("inputid");jQuery("#"+b+"-select").prop("disabled")||(jQuery("#"+b+"-select").addClass("disabled").prop("disabled",!0),jQuery("#"+b+"-remove").addClass("disabled").prop("disabled",!0).fadeOut(500,function(){jQuery(this).remove();jQuery("#"+b+"-select").text(tsf.other[b].select).removeClass("disabled").removeProp("disabled")}),jQuery("#"+b+"-url").val("").removeProp("readonly").css("opacity",
24
- 0).animate({opacity:1},{queue:!0,duration:500},"swing"),jQuery("#"+b+"-id").val(""),tsf.h())},S:function(){if("undefined"===typeof tsf.cropper.control){var a;a=wp.media.controller.Cropper.extend({doCrop:function(a){var b=a.get("cropDetails"),c=tsf.cropper.control;if(c.params.flex_width&&c.params.flex_height)if(b.width===b.height)b.width>c.params.flex_width&&(b.dst_width=b.dst_height=c.params.flex_width);else if(b.width>c.params.flex_width||b.height>c.params.flex_height)if(b.width>b.height){var e=
25
- b.width/c.params.flex_width;b.dst_width=c.params.flex_width;b.dst_height=Math.round(b.height/e)}else e=b.height/c.params.flex_height,b.dst_height=c.params.flex_height,b.dst_width=Math.round(b.width/e);"undefined"===typeof b.dst_width&&(b.dst_width=0,b.dst_height=0);return wp.ajax.post("crop-image",{nonce:a.get("nonces").edit,id:a.get("id"),context:"tsf-image",cropDetails:b})}});a.prototype.control={};a.control={params:{flex_width:1500,flex_height:1500,width:1200,height:630}};tsf.cropper=a}},calculateImageSelectOptions:function(a,
26
- b){var d=tsf.cropper.control,c=!!parseInt(d.params.flex_width,10),e=!!parseInt(d.params.flex_height,10),f=a.get("width"),m=a.get("height"),h=parseInt(d.params.width,10),g=parseInt(d.params.height,10),k=h/g,l=h,n=g;b.set("control",d.params);b.set("canSkipCrop",!tsf.T(d.params.flex_width,d.params.flex_height,f,m));f/m>k?(g=m,h=g*k):(h=f,g=h/k);d=(f-h)/2;k=(m-g)/2;l={handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:f,imageHeight:m,minWidth:l>h?h:l,minHeight:n>g?g:n,x1:d,y1:k,x2:h+d,y2:g+k};!1===
27
- e&&!1===c&&(l.ta=h+":"+g);!0===e&&(l.minHeight=200,l.maxWidth=f);!0===c&&(l.minWidth=200,l.maxHeight=m);return l},T:function(a,b,d,c){return d<=a&&c<=b?!1:!0},X:function(){jQuery(".tsf-remove-social-image").on("click",tsf.C)},da:function(){jQuery(".tsf-set-social-image").on("click",tsf.V);jQuery(".tsf-remove-social-image").on("click",tsf.C)},L:function(){var a=jQuery(".tsf-set-social-image");if(a.length){var b="",d="";jQuery.each(a,function(a,e){b=jQuery(e).data("inputid");d=jQuery("#"+b+"-id");d.length&&
28
- 0<d.val()&&(jQuery("#"+b+"-url").prop("readonly",!0),tsf.s(jQuery(e),b,!1));jQuery("#"+b+"-url").val()&&jQuery("#"+b+"-select").text(tsf.other[b].change)})}},ca:function(){var a=jQuery(".tsf-color-picker");a.length&&jQuery.each(a,function(a,d){var b=jQuery(d),e="",f=b.data("tsf-default-color");b.wpColorPicker({defaultColor:f,width:238,change:function(){e=b.wpColorPicker("color");""===e&&(e=f);b.val(e);tsf.h()},clear:function(){b.parent().siblings(".wp-color-result").css("backgroundColor",f);tsf.h()},
29
- palettes:!1})})},ea:function(){tsf.m=tsf.params.titleSeparator;tsf.u=tsf.params.descriptionSeparator;tsf.j=tsf.states.titleTagline;tsf.a=tsf.states.counterType;tsf.f=tsf.states.hasInput},ready:function(a){tsf.ea();a("div.updated, div.error, div.notice-warning").insertAfter("div.tsf-top-wrap");a(document.body).ready(tsf.o);a(document.body).ready(tsf.R);a(document.body).ready(tsf.ka);a(document.body).ready(tsf.statusBarHover);a(document.body).on("click touchstart MSPointerDown",tsf.W);a(document.body).ready(tsf.da);
30
- a(document.body).ready(tsf.L);a(document.body).ready(tsf.ca);a(document.body).ready(tsf.K);a(document.body).ready(tsf.U);tsf.v().on("input",tsf.I);tsf.c().on("input",tsf.l);a("#tsf-title-separator input").on("click",tsf.aa);a("#tsf-description-separator input").on("click",tsf.Z);a(".tsf-js-confirm-reset").on("click",tsf.M);a(".tsf-tab").on("click",tsf.ia);a("#tsf-title-tagline-toggle :input").on("click",tsf.la);a("#tsf-title-location input").on("click",tsf.ma);a("#title-prefixes-toggle :input").on("click",
31
- tsf.na);a("#tsf-description-onblogname-toggle :input").on("click",tsf.ja);a("#tsf-description-additions-toggle :input").on("click",tsf.J);a("#autodescription-site-settings\\[homepage_title\\]").on("input",tsf.oa);a("#tsf-home-title-location :input, #tsf-title-tagline-toggle :input, #tsf-title-separator input").on("click",tsf.G);a("#autodescription-site-settings\\[homepage_title_tagline\\]").on("input",tsf.F);a("#homepage-tab-general").on("change",tsf.G);a("#autodescription-site-settings\\[title_rem_additions\\]").on("click",
32
- tsf.pa);tsf.c().on("input",tsf.w);a("#tsf-title-placeholder").on("click",tsf.Y);a(".tsf-dismiss").on("click",tsf.P);a(".tsf-counter").on("click",tsf.N)}};jQuery(tsf.ready);
 
 
 
 
 
1
+ window.tsf={nonce:tsfL10n.nonce,nonces:tsfL10n.nonces,i18n:tsfL10n.i18n,states:tsfL10n.states,params:tsfL10n.params,other:tsfL10n.other,g:!1,m:!1,A:"",D:"",a:0,c:!1,f:"",cropper:{},h:function(){return jQuery("#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]")},F:function(){return jQuery("#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]")},confirm:function(a){return confirm(a)},
2
+ L:function(a){var b=jQuery(a.target),c=b.val().length;a=jQuery("#"+tsf.G(a.target.id)+"_chars");var d,e="";0===c&&(c=b.prop("placeholder").length);100>c||175<=c?(b="tsf-count-bad",d=tsf.i("bad")):137>c||155<c&&175>c?(b="tsf-count-okay",d=tsf.i("okay")):(b="tsf-count-good",d=tsf.i("good"));tsf.f&&(b+=" "+tsf.f);tsf.a&&1!=tsf.a?2==tsf.a?e=d:3==tsf.a&&(e=c.toString()+" - "+d):e=c.toString();a.html(e).removeClass().addClass(b)},s:function(a){var b=jQuery(a.target),c=tsf.params.titleAdditions.length,d=
3
+ tsf.params.blogDescription.length,e=tsf.params.siteTitle.length,f=b.val().length,h=b.prop("placeholder").length,g=jQuery("#autodescription-site-settings\\[homepage_title_tagline\\]").val(),m=3;a=jQuery("#"+tsf.G(a.target.id)+"_chars");var k=0,b=tsf.f,l=tsf.a,n="";tsf.m||(m=c=0);0===f&&(0!==e?f=e:k=h);0!==f&&(0!==c&&"undefined"!==typeof g&&(c=g.length,c=0!==c?c:d),k=0===c?f:f+m+c);25>k||75<=k?(d="tsf-count-bad",f=tsf.i("bad")):42>k||55<k&&75>k?(d="tsf-count-okay",f=tsf.i("okay")):(d="tsf-count-good",
4
+ f=tsf.i("good"));b&&(d+=" "+b);l&&1!=l?2==l?n=f:3==l&&(n=k.toString()+" - "+f):n=k.toString();a.html(n).removeClass().addClass(d)},G:function(a){return a?a.replace(/([\[\]\/])/g,"\\$1"):a},ja:function(a){var b=jQuery(".tsf-sep-js");a=jQuery(a.target).val();tsf.A=a;"pipe"===a?b.text(" | "):"dash"===a?b.text(" - "):b.html(" &"+a+"; ")},ia:function(a){var b=jQuery("#autodescription-descsep-js");a=jQuery(a.target).val();"pipe"===a?b.text(" | "):"dash"===a?b.text(" - "):b.html(" &"+a+"; ")},statusBarHover:function(){var a=
5
+ jQuery(".tsf-seo-bar-inner-wrap").find("a");a.on("mouseenter",tsf.pa);a.on("mousemove",tsf.ra);a.on("mouseleave",tsf.qa)},pa:function(a){a=jQuery(a.target);var b=a.data("desc");void 0!==b&&0===a.find("div").length&&(a.append('<div class="tsf-explanation-desc">'+b+"<div></div></div>"),b=a.find("div.tsf-explanation-desc").height()+28,a.find("div.tsf-explanation-desc").css("top",a.position().top-b+"px"))},ra:function(a){var b=jQuery(a.target);a=a.pageX;var c=a-b.closest(".tsf-seo-bar-inner-wrap").offset().left-
6
+ 11,d=b.find(".tsf-explanation-desc"),b=d.find("div");if(1>c)b.css("left","0px");else if(void 0!==d.offset()){var e=d.width(),d=d.offset().left+e+11;a>d?b.css("left",e+"px"):b.css("left",c+"px")}},qa:function(a){jQuery(a.target).find("div.tsf-explanation-desc").remove()},fa:function(){var a=jQuery(document.body.target),b=jQuery(".tsf-seo-bar-inner-wrap a");a.closest(b).length||b.find("div.tsf-explanation-desc").remove()},sa:function(a){a=jQuery(a.target);if(a.is(":checked")){var b=a.prop("id");a=a.prop("name");
7
+ if("undefined"!==typeof a){var c=jQuery("#"+b+"-content"),d=jQuery(".tsf-active-tab-content");c.is(d)||"undefined"===typeof c||(jQuery("."+a+"-content").fadeOut(150,function(){jQuery(this).removeClass("tsf-active-tab-content")}),setTimeout(function(){c.addClass("tsf-active-tab-content").fadeIn(250)},150),setTimeout(function(){jQuery("#"+b).trigger("tsf-tab-toggled")},175))}}},aa:function(a){a=jQuery(a.target);if(a.is(":checked")){var b=a.prop("id");a=a.prop("name");if("undefined"!==typeof a){var c=
8
+ jQuery("#"+b+"-content"),d=jQuery(".tsf-flex-tab-content-active");c.is(d)||"undefined"===typeof c||(jQuery("."+a+"-content").fadeOut(150,function(){jQuery(this).removeClass("tsf-flex-tab-content-active")}),setTimeout(function(){c.addClass("tsf-flex-tab-content-active").fadeIn(250)},150),setTimeout(function(){jQuery("#"+b).trigger("tsf-flex-tab-toggled")},175))}}},ma:function(){if(tsf.c&&tsf.states.isSettingsPage){var a=jQuery(".tsf-nav-tab-wrapper .tsf-tab:nth-of-type(n+2) input:checked");a.length&&
9
+ a.each(function(){var a=jQuery(this),c=a.prop("id"),a=a.prop("name");if("undefined"!==typeof a){var d=jQuery("#"+c+"-content");"undefined"!==typeof d&&(jQuery("."+a+"-content").removeClass("tsf-active-tab-content"),d.addClass("tsf-active-tab-content"),setTimeout(function(){jQuery("#"+c).trigger("tsf-tab-toggled")},20))}})}},wa:function(a){a=jQuery(a.target);var b=jQuery(".tsf-custom-blogname-js");a.is(":checked")?(b.css("display","inline"),tsf.m=!0):(b.css("display","none"),tsf.m=!1);tsf.h().trigger("keyup",
10
+ tsf.s)},ua:function(a){a=jQuery(a.target);var b=jQuery("#tsf-on-blogname-js");a.is(":checked")?b.css("display","inline"):b.css("display","none")},xa:function(a){a=jQuery(a.target).val();var b=jQuery(".tsf-title-additions-example-left"),c=jQuery(".tsf-title-additions-example-right");"right"===a?(b.css("display","none"),c.css("display","inline")):(b.css("display","inline"),c.css("display","none"))},ya:function(a){a=jQuery(a.target);var b=jQuery(".tsf-title-prefix-example");a.is(":checked")?b.css("display",
11
+ "none"):b.css("display","inline")},R:function(a){a=jQuery(a.target);var b=jQuery("#tsf-description-additions-js");a.is(":checked")?b.css("display","inline"):b.css("display","none")},va:function(){if(tsf.c){var a=jQuery("#tsf-title-tagline-toggle :input"),b=jQuery(".tsf-custom-blogname-js"),c=jQuery("#tsf-description-additions-toggle :input"),d=jQuery("#tsf-description-additions-js"),e=jQuery("#tsf-description-onblogname-toggle :input"),f=jQuery("#tsf-on-blogname-js"),h=jQuery("#tsf-title-additions-toggle :input"),
12
+ g=jQuery(".tsf-title-additions-js");a.is(":checked")?b.css("display","inline"):b.css("display","none");c.is(":checked")?d.css("display","inline"):d.css("display","none");e.is(":checked")?f.css("display","inline"):f.css("display","none");h.is(":checked")?g.css("display","none"):g.css("display","inline")}},za:function(a){a=jQuery(a.target).val();var b=jQuery(".tsf-custom-title-js");0===a.length?b.text(tsf.params.siteTitle):b.text(a)},w:function(a){a=jQuery(a.target).val();var b=jQuery(".tsf-custom-tagline-js"),
13
+ c=jQuery("#autodescription-site-settings\\[homepage_title\\]"),d=jQuery("#tsf-home-title-location input:checked").val(),e=jQuery("#autodescription-site-settings\\[homepage_tagline\\]"),f=tsf.params.siteTitle,h=f,g=tsf.params.blogDescription,m=tsf.H("title");e.is(":checked")&&(0!==a.length&&(g=a),h=0!==d.length&&"left"===d?f+" "+m+" "+g:g+" "+m+" "+f);b.text(g);c.prop("placeholder",h);tsf.h().trigger("input",tsf.s)},l:function(){var a=tsf.g;tsf.states.isSettingsPage?jQuery("#autodescription-site-settings\\[homepage_title_tagline\\]").trigger("input",
14
+ tsf.w):jQuery("#autodescription_title").trigger("input",tsf.w);tsf.g=a},ta:function(){var a=0,b=0;jQuery(window).resize(function(){clearTimeout(a);a=setTimeout(function(){var a=jQuery(window).width();b<a?782>=b&&782<=a&&tsf.l():782<=b&&782>=a&&tsf.l();b=a},250)})},Aa:function(){var a=jQuery(event.target),b=jQuery(".tsf-title-additions-js");a.is(":checked")?b.css("display","none"):b.css("display","inline")},S:function(){tsf.c&&(jQuery(".tsf-metaboxes :input, #tsf-inpost-box .inside :input").not(".tsf-tab :input, .tsf-flex-nav-tab :input").change(function(){tsf.j()}),
15
+ jQuery(".tsf-metaboxes input[type=text], .tsf-metaboxes textarea, #tsf-inpost-box .inside input[type=text], #tsf-inpost-box .inside textarea").not(".tsf-nav-tab-wrapper input, .tsf-flex-nav-tab-wrapper input").on("input",function(){tsf.j()}),window.onbeforeunload=function(){if(tsf.g)return tsf.i18n.saveAlert},jQuery('.tsf-metaboxes input[type="submit"], #publishing-action input[type="submit"], #save-action input[type="submit"], a.submitdelete').click(function(){window.onbeforeunload=null}))},j:function(){tsf.g=
16
+ !0},U:function(){return confirm(tsf.i18n.confirmReset)},Y:function(a){var b=tsf.params.titleAdditions.length,c=jQuery("#tsf-title-placeholder");if(!b)return jQuery(a.target).css("text-indent","initial"),c.empty();var b=!1,d=jQuery("#tsf-home-title-location input:checked").val(),e=tsf.states.isRTL;"undefined"!==typeof d&&0!==d.length?e?"right"===d&&(b=!0):"left"===d&&(b=!0):(d=tsf.params.titleLocation,tsf.states.isHome?tsf.m&&(e?"right"===d&&(b=!0):"left"===d&&(b=!0)):e?"left"===d&&(b=!0):"right"===
17
+ d&&(b=!0));d=jQuery("#tsf-title-tagline-toggle :input");if("undefined"!==typeof d&&0<d.length&&!d.is(":checked"))jQuery(a.target).css("text-indent","initial"),c.css("display","none");else{a=jQuery(a.target);var f=a.val(),h=jQuery("#tsf-title-offset"),g,m=a.outerWidth(),k=(a.outerHeight(!0)-a.height())/2,l=(m-a.innerWidth())/2,d=(a.outerWidth(!0)-a.width())/2;g=jQuery("#autodescription-site-settings\\[homepage_title_tagline\\]").val();var n="left",p=tsf.H("title");e&&(n="right");"undefined"!==typeof g&&
18
+ 0===g.length&&(g=tsf.params.blogDescription);b?(e=" "+p+" "+tsf.params.titleAdditions,"undefined"!==typeof g&&0<g.length&&(e=" "+p+" "+g),a.css("text-indent","initial")):(e=tsf.params.titleAdditions+" "+p+" ","undefined"!==typeof g&&0<g.length&&(e=g+" "+p+" "));h.text(f);h.css({fontFamily:a.css("fontFamily"),fontWeight:a.css("fontWeight"),letterSpacing:a.css("letterSpacing"),fontSize:a.css("fontSize")});g=h.width();g=a.width()-l-g;0>g&&(g=0);c.css({display:a.css("display"),lineHeight:a.css("lineHeight"),
19
+ paddingTop:k+"px",paddingBottom:k+"px",fontFamily:a.css("fontFamily"),fontWeight:a.css("fontWeight"),fontSize:a.css("fontSize"),letterSpacing:a.css("letterSpacing"),maxWidth:g+"px"});"undefined"===typeof f||1>f.length?(b||a.css("text-indent","initial"),c.empty()):(c.text(e),m>d&&(b?c.css(n,l+d+h.width()+"px"):(b=l+c.width(),0>b&&(b=0),c.css(n,d+"px"),a.css("text-indent",b+"px"))))}},ha:function(){var a=tsf.h();a.focus();if(a.setSelectionRange){var b=2*a.val().length;a.setSelectionRange(b,b)}else a.val(a.val()).focus()},
20
+ Ba:function(){tsf.c&&tsf.F().trigger("input",tsf.L)},Ca:function(){tsf.c&&tsf.h().trigger("input",tsf.s)},da:function(){tsf.g=!1},X:function(a){var b=jQuery(a.target);b.parents(".tsf-notice").slideUp(200,function(){b.remove()})},ka:function(a){jQuery(a).toggleClass("tsf-loading")},K:function(a,b){var c="tsf-success",d=2500;b||(c="tsf-error",d=5E3);jQuery(a).removeClass("tsf-loading").addClass(c).fadeOut(d)},J:function(a){jQuery(a).stop().empty().prop("class","tsf-ajax").css("opacity","1").removeProp("style")},
21
+ V:function(){tsf.a+=1;3<tsf.a&&(tsf.a=0);tsf.B();var a=0;tsf.J(".tsf-counter .tsf-ajax");tsf.ka(".tsf-counter .tsf-ajax");jQuery.ajax({method:"POST",url:ajaxurl,Fa:"json",data:{action:"the_seo_framework_update_counter",nonce:tsf.nonces.edit_posts,val:tsf.a},async:!0,success:function(b){b=jQuery.parseJSON(b);"success"===b.type&&(a=1);tsf.W(".tsf-counter .tsf-ajax",a)}})},W:function(a,b){switch(b){case 0:tsf.K(a,!1);break;case 1:tsf.K(a,!0);break;default:tsf.J(a)}},B:function(){if(tsf.c){var a=tsf.a,
22
+ b=tsf.g;1==a?(tsf.f="tsf-counter-one",tsf.a=1):2==a?(tsf.f="tsf-counter-two",tsf.a=2):3==a?(tsf.f="tsf-counter-three",tsf.a=3):(tsf.f="tsf-counter-zero",tsf.a=0);tsf.Da();tsf.g=b}},Da:function(){tsf.Ca();tsf.Ba()},i:function(a){return tsf.i18n[a]},H:function(a){var b="";a="title"===a?tsf.A:tsf.D;"pipe"===a||"|"===a?b="|":"dash"===a||"-"===a?b="-":123>a.charCodeAt(0)&&("&"===a.charAt(0)&&";"===a.slice(-1)&&(a=a.substr(1).slice(0,-1)),b=jQuery("<div/>").html("&"+a+";").text());return b},ea:function(a){if(jQuery(a.target).prop("disabled")||
23
+ "undefined"===typeof wp.media)a.preventDefault(),a.stopPropagation();else{var b=jQuery(a.target),c=b.data("inputid"),d;d||(a.preventDefault(),a.stopPropagation(),tsf.Z(),d=wp.media({button:{text:tsf.other[c].frame_button,close:!1},states:[new wp.media.controller.Library({title:tsf.other[c].frame_title,library:wp.media.query({type:"image"}),multiple:!1,date:!1,priority:20,suggestedWidth:1200,suggestedHeight:630}),new tsf.cropper({imgSelectOptions:tsf.calculateImageSelectOptions})]}),d.on("select",
24
+ function(){d.setState("cropper")}),d.on("cropped",function(a){var b=a.url;a=a.id;jQuery("#"+c+"-url").val(b);jQuery("#"+c+"-id").val(a)}),d.on("skippedcrop",function(a){var b=a.get("url"),d=a.get("id");a.get("width");a.get("height");jQuery("#"+c+"-url").val(b);jQuery("#"+c+"-id").val(d)}),d.on("skippedcrop cropped",function(){jQuery("#"+c+"-select").text(tsf.other[c].change);jQuery("#"+c+"-url").prop("readonly",!0).css("opacity",0).animate({opacity:1},{queue:!0,duration:1E3},"swing");tsf.C(b,c,!0);
25
+ tsf.j()}));d.open()}},C:function(a,b,c){a&&b&&!jQuery("#"+b+"-remove").length&&(a.after('<a href="javascript:void(0)" id="'+b+'-remove" class="tsf-remove-social-image button button-small" data-inputid="'+b+'" title="'+tsf.other[b].remove_title+'">'+tsf.other[b].remove+"</a>"),c&&jQuery("#"+b+"-remove").css("opacity",0).animate({opacity:1},{queue:!0,duration:1E3},"swing"));tsf.ga()},I:function(a){var b=jQuery(a.target).data("inputid");jQuery("#"+b+"-select").prop("disabled")||(jQuery("#"+b+"-select").addClass("disabled").prop("disabled",
26
+ !0),jQuery("#"+b+"-remove").addClass("disabled").prop("disabled",!0).fadeOut(500,function(){jQuery(this).remove();jQuery("#"+b+"-select").text(tsf.other[b].select).removeClass("disabled").removeProp("disabled")}),jQuery("#"+b+"-url").val("").removeProp("readonly").css("opacity",0).animate({opacity:1},{queue:!0,duration:500},"swing"),jQuery("#"+b+"-id").val(""),tsf.j())},Z:function(){if("undefined"===typeof tsf.cropper.control){var a;a=wp.media.controller.Cropper.extend({doCrop:function(a){var b=a.get("cropDetails"),
27
+ d=tsf.cropper.control;if(d.params.flex_width&&d.params.flex_height)if(b.width===b.height)b.width>d.params.flex_width&&(b.dst_width=b.dst_height=d.params.flex_width);else if(b.width>d.params.flex_width||b.height>d.params.flex_height)if(b.width>b.height){var e=b.width/d.params.flex_width;b.dst_width=d.params.flex_width;b.dst_height=Math.round(b.height/e)}else e=b.height/d.params.flex_height,b.dst_height=d.params.flex_height,b.dst_width=Math.round(b.width/e);"undefined"===typeof b.dst_width&&(b.dst_width=
28
+ 0,b.dst_height=0);return wp.ajax.post("tsf-crop-image",{nonce:tsf.nonces.upload_files,id:a.get("id"),context:"tsf-image",cropDetails:b})}});a.prototype.control={};a.control={params:{flex_width:1500,flex_height:1500,width:1200,height:630}};tsf.cropper=a}},calculateImageSelectOptions:function(a,b){var c=tsf.cropper.control,d=!!parseInt(c.params.flex_width,10),e=!!parseInt(c.params.flex_height,10),f=parseInt(c.params.width,10),h=parseInt(c.params.height,10),g=a.get("width"),m=a.get("height"),k=f/h,l=
29
+ f,n=h;b.set("control",c.params);b.set("canSkipCrop",!tsf.ca(c.params.flex_width,c.params.flex_height,g,m));g/m>k?(h=m,f=h*k):(f=g,h=f/k);c=(g-f)/2;k=(m-h)/2;l={handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:g,imageHeight:m,minWidth:l>f?f:l,minHeight:n>h?h:n,x1:c,y1:k,x2:f+c,y2:h+k};!1===e&&!1===d&&(l.Ea=f+":"+h);!0===e&&(l.minHeight=200,l.maxWidth=g);!0===d&&(l.minWidth=200,l.maxHeight=m);return l},ca:function(a,b,c,d){return c<=a&&d<=b?!1:!0},ga:function(){jQuery(".tsf-remove-social-image").on("click",
30
+ tsf.I)},na:function(){jQuery(".tsf-set-social-image").on("click",tsf.ea);jQuery(".tsf-remove-social-image").on("click",tsf.I)},T:function(){var a=jQuery(".tsf-set-social-image");if(a.length){var b="",c="";jQuery.each(a,function(a,e){b=jQuery(e).data("inputid");c=jQuery("#"+b+"-id");c.length&&0<c.val()&&(jQuery("#"+b+"-url").prop("readonly",!0),tsf.C(jQuery(e),b,!1));jQuery("#"+b+"-url").val()&&jQuery("#"+b+"-select").text(tsf.other[b].change)})}},la:function(){var a=jQuery(".tsf-color-picker");a.length&&
31
+ jQuery.each(a,function(a,c){var b=jQuery(c),e="",f=b.data("tsf-default-color");b.wpColorPicker({defaultColor:f,width:238,change:function(){e=b.wpColorPicker("color");""===e&&(e=f);b.val(e);tsf.j()},clear:function(){b.parent().siblings(".wp-color-result").css("backgroundColor",f);tsf.j()},palettes:!1})})},oa:function(){tsf.A=tsf.params.titleSeparator;tsf.D=tsf.params.descriptionSeparator;tsf.m=tsf.states.titleTagline;tsf.a=parseInt(tsf.states.counterType);tsf.c=tsf.states.hasInput},N:function(){if(tsf.c){var a=
32
+ jQuery;a("#tsf-title-tagline-toggle :input").on("click",tsf.wa);a("#tsf-title-location input").on("click",tsf.xa);a("#title-prefixes-toggle :input").on("click",tsf.ya);a("#autodescription-site-settings\\[homepage_title\\]").on("input",tsf.za);a("#tsf-home-title-location :input, #tsf-title-tagline-toggle :input, #tsf-title-separator input").on("click",tsf.l);a("#autodescription-site-settings\\[homepage_title_tagline\\]").on("input",tsf.w);a("#homepage-tab-general").on("tsf-tab-toggled",tsf.l);a("#autodescription-homepage-settings > button").on("click",
33
+ tsf.l);a("#tsf-inpost-box > button").on("click",tsf.l);a("#autodescription-site-settings\\[title_rem_additions\\]").on("click",tsf.Aa);tsf.h().on("input",tsf.Y);a("#tsf-title-placeholder").on("click",tsf.ha);a(window).resize(tsf.ta)}},M:function(){if(jQuery(".tsf-flex").length){tsf.O();var a=0,b={},c=0,d=jQuery(".tsf-flex-nav-tab-wrapper");jQuery(window).on("tsf-flex-resize",function(){clearTimeout(a);var e=0,f=0,h=0;a=setTimeout(function(){if(d.length){var a=jQuery(".tsf-flex-nav-tab-inner"),c=d.width(),
34
+ k=a.width(),l=jQuery(".tsf-flex-nav-name");b.b||(b.b={},b.b.u=0,b.b.ba=0,b.b.v=1);!b.b.v&&b.b.u<c&&(l.fadeIn(250),setTimeout(function(){k=a.width()},e));setTimeout(function(){k>c?(l.hide(),b.b.v=0):b.b.u<c&&(l.fadeIn(250),b.b.v=1)},f);setTimeout(function(){b.b.u=c;b.b.ba=k},h)}},c);e=10;f=20;h=30;c=75});jQuery(window).trigger("tsf-flex-resize")}},O:function(){jQuery(window).on("resize orientationchange",tsf.o);jQuery("#collapse-menu").click(tsf.o);jQuery(".columns-prefs :input[type=radio]").change(tsf.o);
35
+ jQuery(".meta-box-sortables").on("sortupdate",tsf.o)},o:function(){jQuery(window).trigger("tsf-flex-resize")},P:function(){jQuery(document.body).trigger("tsf-ready")},ready:function(a){tsf.oa();a("div.updated, div.error, div.notice-warning").insertAfter("div.tsf-top-wrap");a(document.body).ready(tsf.N);a(document.body).ready(tsf.ma);a(document.body).ready(tsf.B);a(document.body).ready(tsf.va);a(document.body).ready(tsf.statusBarHover);a(document.body).ready(tsf.na);a(document.body).ready(tsf.T);a(document.body).ready(tsf.la);
36
+ a(document.body).ready(tsf.S);a(document.body).ready(tsf.da);a(document.body).ready(tsf.P);a(document.body).ready(tsf.M);a(document.body).on("click touchstart MSPointerDown",tsf.fa);tsf.F().on("input",tsf.L);tsf.h().on("input",tsf.s);a("#tsf-title-separator input").on("click",tsf.ja);a("#tsf-description-separator input").on("click",tsf.ia);a(".tsf-js-confirm-reset").on("click",tsf.U);a(".tsf-tabs-radio").on("change",tsf.sa);a(".tsf-flex-nav-tab-radio").on("change",tsf.aa);a("#tsf-description-onblogname-toggle :input").on("click",
37
+ tsf.ua);a("#tsf-description-additions-toggle :input").on("click",tsf.R);a(".tsf-dismiss").on("click",tsf.X);a(".tsf-counter").on("click",tsf.V)}};jQuery(tsf.ready);
load.php CHANGED
@@ -53,17 +53,17 @@ function _init() {
53
  return $tsf;
54
  }
55
 
56
- add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_locale', 10 );
57
  /**
58
  * Plugin locale 'autodescription'
59
  * File located in plugin folder autodescription/language/
60
  * @since 1.0.0
61
  */
62
  function _init_locale() {
63
- load_plugin_textdomain( 'autodescription', false, basename( dirname( __FILE__ ) ) . '/language/' );
64
  }
65
 
66
- add_action( 'admin_init', __NAMESPACE__ . '\\_init_upgrade', 5 );
67
  /**
68
  * Determines whether the plugin needs an option upgrade.
69
  *
53
  return $tsf;
54
  }
55
 
56
+ \add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_locale', 10 );
57
  /**
58
  * Plugin locale 'autodescription'
59
  * File located in plugin folder autodescription/language/
60
  * @since 1.0.0
61
  */
62
  function _init_locale() {
63
+ \load_plugin_textdomain( 'autodescription', false, basename( dirname( __FILE__ ) ) . '/language/' );
64
  }
65
 
66
+ \add_action( 'admin_init', __NAMESPACE__ . '\\_init_upgrade', 5 );
67
  /**
68
  * Determines whether the plugin needs an option upgrade.
69
  *
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://theseoframework.com/donate/
4
  Tags: google, bing, open graph, seo, xml sitemap, breadcrumbs, meta, search engine, pagerank, serp, facebook, twitter
5
  Requires at least: 4.4.0
6
  Tested up to: 4.8.0
7
- Stable tag: 2.8.2
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -16,6 +16,8 @@ The SEO Framework plugin provides an automated and advanced SEO solution for you
16
 
17
  An accessible, unbranded and extremely fast SEO solution for any WordPress website.
18
 
 
 
19
  > <strong>This plugin strongly helps you create better SEO value for your content.</strong><br>
20
  > But at the end of the day, it all depends on how entertaining or well-constructed your content or product is.
21
  >
@@ -51,7 +53,7 @@ Nobody has to know about the tools you've used to create your or someone else's
51
 
52
  * Title, with super-fast 'wrong themes' support.
53
  * Description, with anti-spam techniques.
54
- * A canonical URL, with full WPMUdev Domain Mapping, subdomain and HTTPS support to prevent duplicated content.
55
  * Various Open Graph, Facebook and Twitter tags.
56
  * Special Open Graph description, which organically integrates with the Facebook and Twitter snippets.
57
  * Extended Open Graph Images support, including automated image manipulation.
@@ -60,7 +62,7 @@ Nobody has to know about the tools you've used to create your or someone else's
60
  * Advanced Schema.org JSON-LD script for Breadcrumbs (just like the visual one) which extends page relation support in Google Search.
61
  * Schema.org JSON-LD script to show the correct site name in Google Breadcrumbs.
62
  * Publishing and editing dates, accurate to the day.
63
- * Link relationships, with full WPMUdev Domain Mapping and HTTPS support.
64
  * Simple Sitemap with Pages, Posts and Custom Post Types (CPT), which listens to the in-post settings.
65
  * Feed excerpts and backlinks to prevent content scraping.
66
 
@@ -108,12 +110,14 @@ A caching plugin isn't even needed for this plugin as you won't notice a differe
108
 
109
  = Compatibility =
110
 
 
 
111
  * Full internationalization support through WordPress.org.
112
  * Extended Multibyte support (CJK).
113
  * Full Right to Left (RTL) language support.
114
  * Extended Color vision deficiency accessibility.
115
  * Screen reader accessibility.
116
- * MultiSite, this plugin is in fact built upon one.
117
  * Detection of robots.txt and sitemap.xml files.
118
  * Detection of theme Title output "doing it right" (or wrong).
119
  * Automatic detection of various other popular SEO tools.
@@ -136,13 +140,15 @@ The Breadcrumb script generated by this plugin on Posts will also make sure Goog
136
  1. That's it!
137
  1. Let the plugin automatically work or fine-tune each page with the metaboxes beneath the content or on the taxonomy pages.
138
  1. Adjust the SEO settings through the SEO settings page if desired. Red checkboxes are rather left unchecked. Green checkboxes are default enabled.
 
139
 
140
  == Screenshots ==
141
 
142
- 1. This plugin shows you what you can improve, at a glance. With full color vision deficiency support.
143
- 2. Hover over any of the SEO Bar's items to see how you can improve the page's SEO. Red is bad, orange is okay, green is good. Blue is situational.
144
- 3. The dynamic Post/Page SEO settings Metabox. This box is also neatly implemented in Categories and Tags.
145
- 4. The SEO Settings Page. With over 90 settings, you are in full control. Using the Default Settings and filling in the Knowledge Graph Settings and Social Meta Settings is recommended to do.
 
146
 
147
  == Frequently Asked Questions ==
148
 
@@ -150,6 +156,14 @@ The Breadcrumb script generated by this plugin on Posts will also make sure Goog
150
 
151
  Absolutely! It will stay free as well, without ads or nags!
152
 
 
 
 
 
 
 
 
 
153
  = I have a feature request, I've found a bug, a plugin is incompatible... =
154
 
155
  Please visit [the support forums](https://wordpress.org/support/plugin/autodescription) and kindly tell me about it. I try to get back to you within 48 hours. :)
@@ -163,12 +177,12 @@ Extensions built for this plugin might just as well work as a standalone. The SE
163
  = I am a developer; how can I help? =
164
 
165
  The SEO Framework is currently a one-man project. However, any input is greatly appreciated and everything will be considered.
166
- Please leave feature requests in the Support Forums and I will talk you through the process of implementing it if necessary.
167
 
168
  = I want to remove or change stuff, but I can't find an option! =
169
 
170
  The SEO Framework is very pluggable on many fields. Please refer to the [Other Notes](https://wordpress.org/plugins/autodescription/other_notes/).
171
- Please note that a free plugin is underway which will allow you to change all filters from the dashboard. No ETA yet.
172
 
173
  = The sitemap doesn't contain categories, images, news, etc. is this OK? =
174
 
@@ -177,7 +191,9 @@ If a visitor can't find a page, then why would a Search Engine? Don't rely on yo
177
 
178
  = What's does the application/ld+json script do? =
179
 
180
- The JSON-LD scripts are Search Engine helpers which tell Search Engines how to connect and index the site. They can tell the Search Engine if your site contains an internal search engine, what sites you're socially connected to and what page structure you're using.
 
 
181
 
182
  = The meta data is not being updated, and I'm using a caching plugin. =
183
 
@@ -190,168 +206,60 @@ Transporting Terms and Taxonomies SEO data isn't supported.
190
 
191
  == Changelog ==
192
 
193
- = 2.8.2 - Immaculated Perception =
194
-
195
- **Release date:**
196
-
197
- * January 28th 2017
198
-
199
- *If you haven't read the [2.8.0 upgrade notes](https://theseoframework.com/?p=1792) yet, please do.*
200
-
201
- **Summarized:**
202
-
203
- * The 2.8.0 release didn't contain everything I wanted. So, two new features in a minor release? Certainly!
204
- * First, there's now a fallback Social Image uploader.
205
- * Second, when scheduled posts are published they now trigger a sitemap cache flush and Search Engine pinging.
206
- * Moreover, this update fixes a few bugs: namely ones that caused character encoding issues in the admin area.
207
-
208
- **Detailed log:**
209
-
210
- ***I don't believe in luck, but I do believe in assigning [value to things](https://theseoframework.com/?p=1832#detailed).***
211
 
212
- = 2.8.1 - Integral Adroitness =
213
 
214
  **Release date:**
215
 
216
- * January 23rd 2017
217
-
218
- *This update fixes a corner case bug with mbstring compatibility. If you haven't read the [2.8.0 upgrade notes](https://theseoframework.com/?p=1792) yet, please do.*
219
-
220
- **Detailed log:**
221
-
222
- ***What truly is [logic](https://theseoframework.com/?p=1812)?***
223
-
224
- = 2.8.0 - Ventricular Perspicacity =
225
-
226
- *In a dream it's typical not to be rational. - John Forbes Nash, Jr.*
227
-
228
- **Release date:**
229
-
230
- * January 22nd 2017
231
-
232
- **Upgrade Notes:**
233
-
234
- ***WordPress recommends using PHP 7.0+***
235
-
236
- ***1: PHP 5.2 support has been dropped. Here's why:***
237
-
238
- * PHP 5.2 hasn't received updates for [over 6 years](http://php.net/eol.php) and using it is a major security risk.
239
- * **This major release completely drops support for PHP 5.2**. So, if you're using PHP 5.2, from this version on you can no longer run The SEO Framework.
240
- * PHP 5.2 is a practicality and convenience hindrance for developers and is also source for bugs. Sometimes, we have to split otherwise simple code over multiple lines just to support it.
241
- * Inform your host to keep updated! Read more about informing your host [here](https://wordpress.org/about/requirements/). If they decline, I'd urge you to switch hosts for your website's sake.
242
-
243
- ***2: The minimum required WordPress version is now 4.4. Here's why:***
244
-
245
- * The SEO Framework uses lots of functionality given by WordPress. All this functionality will be maintained internally by WordPress.
246
- * If we require functionality of WordPress that hasn't been included yet, we need to check for its existence or copy its functionality within this plugin.
247
- * This not only slows down the plugin, but it also makes the plugin much more complex and prone to annoying bugs.
248
- * The WordPress Core team constantly provides updates to give you the best blogging and CMS experience, and The SEO Framework follows their footsteps.
249
- * If we constantly require to do multiple version testing, then this slows down the progression we wish to make.
250
-
251
- *If, for whatever reason, you still wish to use PHP 5.2 and/or WordPress 4.3, The SEO Framework 2.7.3 still supports them.*
252
 
253
  **Summarized:**
254
 
255
- * This major release not only fixes various bugs, but also introduces new options for you to fiddle with.
256
- * You're now able to adjust General Settings easily! These settings include options to adjust the cache, (re)move the SEO Bar, and set a Canonical Scheme.
257
- * Google's Knowledge Graph has been transformed into something much bigger last year, so the related settings now fall under a new name: "Authorized Presence".
258
- * You can now select your website's social images. With this much asked for feature, you're now really in control.
259
- * You can now also control the style of your sitemap. The sitemap title will link back to your homepage when clicked upon.
260
-
261
- **Survey:**
262
-
263
- * After updating, please fill in our [Update Survey](https://theseoframework.com/?p=1781): tell us what can be done better.
264
-
265
- **Love this plugin?**
266
-
267
- * Please consider [making a donation](https://theseoframework.com/donate/). Or, even better: [get yourself an Early Bird premium license](https://premium.theseoframework.com/shop/).
268
-
269
- **New plugin logo!**
270
-
271
- * Thank you so much [Terence](https://profiles.wordpress.org/pubdirltd/) for making this!
272
-
273
- **Feature highlights:**
274
 
275
- * **Added:**
276
- * Canonical SEO settings
277
- * Sitemap styling settings
278
- * Performance settings
279
- * Layout settings
280
- * Social image upload
281
- * Site logo detection
282
- * **Improved:**
283
- * Cache validation
284
- * Compatibility stability
285
- * Security and sanitation
286
- * Post status detection
287
- * Detection of placeholders
288
 
289
- **New development technology overview:**
 
 
290
 
291
- * Markdown conversion
292
- * RGB luminance detection and conversion
293
- * JavaScript compilation prototyping
294
- * Namespaces
295
- * Magic methods
296
- * Class autoloader
297
- * Debug autoloader
298
- * Object interfaces
299
- * Crop ratio conversion
300
- * Plugin/Server compatibility autoloading
301
-
302
- **For everyone - About Canonical SEO:**
303
-
304
- * A new setting has been added that allows you to adjust the preferred URL scheme of your website.
305
- * This new setting influences which pages Search Engines might index. The default setting is Detect Automatically.
306
- * This new setting doesn't affect scheme redirection of pages and posts, which should be done using `.htaccess`, when applicable.
307
- * Contact your hosting provider if you have any doubts on changing this option.
308
-
309
- **For everyone - About Sitemap styling:**
310
-
311
- * New settings have been added that allow you to style your sitemap!
312
- * The colors are automatically calculated based on what you put in. This is the most advanced sitemap styling to date!
313
- * If your theme supports it, you can also insert a logo for it through WordPress Customizer.
314
- * The sitemap title links back to your homepage. All other external links are set to "nofollow".
315
- * These styles aren't seen by Search Engines. But it's a very nice addition for your fellow human visitors.
316
- * The styles are cached! To refresh this cache, simply hit `CRTL+SHIFT+R` or `CMD+SHIFT+R`.
317
-
318
- **For everyone - About the Performance settings:**
319
-
320
- * A few new settings have been added that allow you to adjust the plugin's caching mechanism.
321
- * There's a hidden option, only available when you use a dedicated object caching plugin. This option allows you to turn on Object Caching of the plugin.
322
- * If the object caching option is enabled, we recommend disabling the Description and Schema output cache. Because otherwise you'll get three times as many cache entries.
323
- * Feel free to play with these settings: By default, The SEO Framework outputs its generation time after its meta output to which you can compare.
324
-
325
- **For everyone - About Social Image selection:**
326
 
327
- * A new settings has been added to every post, page and applicable custom post type that allows you to select your social image.
328
- * This social image automatically gets cropped per Facebook's Open Graph Guidelines.
329
- * The default "aspect ratio" for the cropper is automatically set, we recommend not changing this aspect ratio.
330
- * You can manually fill in the image URL as well. However, this will disable preemptively caching of the image on the Social Site as we then can't calculate the size.
331
 
332
- **SEO tip of the Update - Know your Knowledge:**
333
 
334
- * Not all SEO techniques are actively used on Google outside of the United States.
335
- * For example, the Site Name Schema.org script might not have any effect.
336
- * This changes over time as Google updates its Search Engine all over the world.
337
- * Usage of experimental Schema.org scripts with The SEO Framework cause no harm to ranking.
 
338
 
339
- **For developers - About the structural changes:**
340
 
341
- * ***Are you an avid developer, and have extended The SEO Framework? Please carefully read the detailed changelog, or at least compare it to your implementations. All method, function, action and filter changes are listed there.***
342
- * *In essence, if you've programmed as described within the API, no changes should be made.*
343
- * This plugin is now using PHP 5.3+ namespaces and an autoloader.
344
- * This plugin now has magic methods that prevent the site from crashing if inaccessible methods or properties have been called.
345
- * This allowed me to easily remove redundant public methods and properties without ramification.
346
 
347
- **For developers - Many new filters and actions:**
348
 
349
- * Because we've pulled out most of the plugin and theme compatibility from the internal class scope, we've added filters and actions where they previously applied.
350
- * Documentation for these new filters and actions will be added soon. Stay tuned!
 
 
 
351
 
352
  **Detailed log:**
353
 
354
- ***What is work without [innovation](https://theseoframework.com/?p=1792#detailed)?***
355
 
356
  = Full changelog =
357
 
@@ -359,12 +267,6 @@ Transporting Terms and Taxonomies SEO data isn't supported.
359
 
360
  == Upgrade Notice ==
361
 
362
- = 2.8.2 =
363
- In the 2.8.0 update WordPress 4.3 and PHP 5.2 support have been dropped for better code quality.
364
-
365
- = 2.8.1 =
366
- In the 2.8.0 update WordPress 4.3 and PHP 5.2 support have been dropped for better code quality.
367
-
368
  = 2.8.0 =
369
  In the 2.8.0 update WordPress 4.3 and PHP 5.2 support have been dropped for better code quality.
370
 
@@ -395,4 +297,4 @@ Read how to here: [The SEO Framework Settings API](http://theseoframework.com/do
395
 
396
  = Want to test the latest version before it's released? =
397
 
398
- If there's a beta, it will be available [on Github](https://github.com/sybrew/the-seo-framework). Please note that changes there might not reflect the final outcome of the full version release. Use at own risk.
4
  Tags: google, bing, open graph, seo, xml sitemap, breadcrumbs, meta, search engine, pagerank, serp, facebook, twitter
5
  Requires at least: 4.4.0
6
  Tested up to: 4.8.0
7
+ Stable tag: 2.9.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
16
 
17
  An accessible, unbranded and extremely fast SEO solution for any WordPress website.
18
 
19
+ For optional advanced SEO options and output, check out our free companion plugin [Extension Manager](https://wordpress.org/plugins/the-seo-framework-extension-manager/).
20
+
21
  > <strong>This plugin strongly helps you create better SEO value for your content.</strong><br>
22
  > But at the end of the day, it all depends on how entertaining or well-constructed your content or product is.
23
  >
53
 
54
  * Title, with super-fast 'wrong themes' support.
55
  * Description, with anti-spam techniques.
56
+ * A canonical URL, with full Domain Mapping, subdomain and HTTPS support to prevent duplicated content.
57
  * Various Open Graph, Facebook and Twitter tags.
58
  * Special Open Graph description, which organically integrates with the Facebook and Twitter snippets.
59
  * Extended Open Graph Images support, including automated image manipulation.
62
  * Advanced Schema.org JSON-LD script for Breadcrumbs (just like the visual one) which extends page relation support in Google Search.
63
  * Schema.org JSON-LD script to show the correct site name in Google Breadcrumbs.
64
  * Publishing and editing dates, accurate to the day.
65
+ * Link relationships, with full Domain Mapping and HTTPS support.
66
  * Simple Sitemap with Pages, Posts and Custom Post Types (CPT), which listens to the in-post settings.
67
  * Feed excerpts and backlinks to prevent content scraping.
68
 
110
 
111
  = Compatibility =
112
 
113
+ * PHP 5.3 and later
114
+ * WordPress 4.4 and later
115
  * Full internationalization support through WordPress.org.
116
  * Extended Multibyte support (CJK).
117
  * Full Right to Left (RTL) language support.
118
  * Extended Color vision deficiency accessibility.
119
  * Screen reader accessibility.
120
+ * Full MultiSite support, this plugin is in fact built upon one.
121
  * Detection of robots.txt and sitemap.xml files.
122
  * Detection of theme Title output "doing it right" (or wrong).
123
  * Automatic detection of various other popular SEO tools.
140
  1. That's it!
141
  1. Let the plugin automatically work or fine-tune each page with the metaboxes beneath the content or on the taxonomy pages.
142
  1. Adjust the SEO settings through the SEO settings page if desired. Red checkboxes are rather left unchecked. Green checkboxes are default enabled.
143
+ 1. Optionally, also install the [Extension Manager](https://wordpress.org/plugins/the-seo-framework-extension-manager/) for additional SEO solutions.
144
 
145
  == Screenshots ==
146
 
147
+ 1. (version 2.7+) This plugin shows you what you can improve, at a glance. With full color vision deficiency support.
148
+ 2. (version 2.7+) Hover over any of the SEO Bar's items to see how you can improve the page's SEO. Red is bad, orange is okay, green is good. Blue is situational.
149
+ 3. (version 2.9+) The dynamic Post/Page SEO settings Metabox. Another version of this box is also implemented for Categories and Tags.
150
+ 4. (version 2.9+) The dynamic Post/Page SEO settings Metabox also fits neatly in the sidebar. For when you want to work faster.
151
+ 5. (version 2.7+) The SEO Settings Page. With over 90 settings, you are in full control. Using the Default Settings and filling in the Knowledge Graph Settings and Social Meta Settings is recommended to do.
152
 
153
  == Frequently Asked Questions ==
154
 
156
 
157
  Absolutely! It will stay free as well, without ads or nags!
158
 
159
+ = Is there a Premium version? =
160
+
161
+ Nope! This plugin is all-inclusive.
162
+
163
+ = Free & Premium Extensions =
164
+
165
+ For more advanced SEO options and output, we offer the free plugin [Extension Manager](https://wordpress.org/plugins/the-seo-framework-extension-manager/).
166
+
167
  = I have a feature request, I've found a bug, a plugin is incompatible... =
168
 
169
  Please visit [the support forums](https://wordpress.org/support/plugin/autodescription) and kindly tell me about it. I try to get back to you within 48 hours. :)
177
  = I am a developer; how can I help? =
178
 
179
  The SEO Framework is currently a one-man project. However, any input is greatly appreciated and everything will be considered.
180
+ Please visit the [GitHub project page](https://github.com/sybrew/the-seo-framework) to submit issues or even pull requests.
181
 
182
  = I want to remove or change stuff, but I can't find an option! =
183
 
184
  The SEO Framework is very pluggable on many fields. Please refer to the [Other Notes](https://wordpress.org/plugins/autodescription/other_notes/).
185
+ Please note that a free plugin is underway which will allow you to change all scalar filters from the dashboard. No ETA yet.
186
 
187
  = The sitemap doesn't contain categories, images, news, etc. is this OK? =
188
 
191
 
192
  = What's does the application/ld+json script do? =
193
 
194
+ The JSON-LD scripts are Search Engine helpers which tell Search Engines how to connect and index the site.
195
+ They can tell the Search Engine if your site contains an internal search engine, what sites you're socially connected to and what page structure you're using.
196
+ This is also referred to as Structured Data.
197
 
198
  = The meta data is not being updated, and I'm using a caching plugin. =
199
 
206
 
207
  == Changelog ==
208
 
209
+ = 2.9.0 - Equitable Erudition =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
+ *Courage is found in unlikely places - J.R.R. Tolkien*
212
 
213
  **Release date:**
214
 
215
+ * 25th March 2017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
  **Summarized:**
218
 
219
+ * This update focuses on fixing bugs and expanding the API for developers.
220
+ * To expand the API for per page (in-post) SEO settings, tabs had to be added in the SEO settings metabox.
221
+ * The JavaScript code has also been overhauled to improve performance and allow third party implementation.
222
+ * Moreover, the home page settings now allow you to upload a social image.
223
+ * Structured data markup has also been improved, like the inclusion of an alternative Sitename and fixes for Breadcrumb images.
224
+ * The sitemap can now include the blog page. The lastmod value of which listens to multiple pages to automatically determines what's best.
225
+ * Unfortunately, Twitter has removed support for photo cards. This update makes sure that the regarding settings correctly convert to the current format.
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
+ **Only one week left for the earliest of early-bird discounts:**
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
+ * With [The SEO Framework - Extension Manager](https://wordpress.org/plugins/the-seo-framework-extension-manager/)'s release, a celebratory discount has been introduced.
230
+ * If you wish to benefit from this lifetime discount, [visit the shop](https://premium.theseoframework.com/shop/) for more information.
231
+ * More awesome extensions are coming soon!
232
 
233
+ **Survey:**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
+ * After updating, please fill in our [Update Survey](https://theseoframework.com/?p=1781): tell us what you like or can be done better.
 
 
 
236
 
237
+ **For everyone: Tabbed In-post SEO layout**
238
 
239
+ * This release brings tabbed layout to the in-post SEO settings.
240
+ * With this change I've also altered the overall looks, with the help from [Daniel](https://github.com/danielpost).
241
+ * This layout allows extensions from the [Extension Manager](https://wordpress.org/plugins/the-seo-framework-extension-manager/) to be implemented much easier.
242
+ * This layout is self-responsive! This means it's not dependent on the browser-size, but on how much content will fit.
243
+ * This layout therefore allows the SEO settings to be placed in the right sidebar! Take a look at the [new screenshots](https://wordpress.org/plugins/autodescription/screenshots/).
244
 
245
+ **For everyone: Browser support**
246
 
247
+ * This release brings [CSS Flexbox](https://www.w3.org/TR/css-flexbox-1/) to the new in-post SEO settings metabox.
248
+ * The flexbox module is still experimental, in a way that not all browsers correctly support this to the fullest extend.
249
+ * However, support for as many browsers feasible has been implemented. Check out [the list](https://theseoframework.com/?p=1903#browser-support). Enjoy!
250
+ * The gist is that Chrome, Firefox, IE10 and Safari 6 or later are supported.
 
251
 
252
+ **SEO Tip of the Update - Trust in layout**
253
 
254
+ * Is your website glitchy and has placeholder images, unmatched colors or weirdly contrasting borders all over the place?
255
+ * Consider going for a more modern and clean layout. Strip out what isn't necessary. A clean layout implies professionalism and increases visitors' trust.
256
+ * Even if you're just starting out with your website, remove all that could be but really isn't. Because if you leave in placeholders for the future, it implies amateurism.
257
+ * People want their truth to be confirmed or their problems to be solved. If you can't confirm or solve the layout of your website, then they won't trust you to do so for their issues.
258
+ * Simply put: It doesn't have to be perfect, it just must be done.
259
 
260
  **Detailed log:**
261
 
262
+ ***It is some miles, but [it will shorten your journey tomorrow](https://theseoframework.com/?p=1903#detailed).***
263
 
264
  = Full changelog =
265
 
267
 
268
  == Upgrade Notice ==
269
 
 
 
 
 
 
 
270
  = 2.8.0 =
271
  In the 2.8.0 update WordPress 4.3 and PHP 5.2 support have been dropped for better code quality.
272
 
297
 
298
  = Want to test the latest version before it's released? =
299
 
300
+ If there's a beta, it will be available [on GitHub](https://github.com/sybrew/the-seo-framework). Please note that changes there might not reflect the final outcome of the full version release. Use at own risk.
seotips/seotips.txt CHANGED
@@ -139,3 +139,11 @@
139
  * For example, the Site Name Schema.org script might not have any effect.
140
  * This changes over time as Google updates its Search Engine all over the world.
141
  * Usage of experimental Schema.org scripts with The SEO Framework cause no harm to ranking.
 
 
 
 
 
 
 
 
139
  * For example, the Site Name Schema.org script might not have any effect.
140
  * This changes over time as Google updates its Search Engine all over the world.
141
  * Usage of experimental Schema.org scripts with The SEO Framework cause no harm to ranking.
142
+
143
+ = 2.9.0 - Trust in layout =
144
+
145
+ * Is your website glitchy and has placeholder images, unmatched colors or weirdly contrasting borders all over the place?
146
+ * Consider going for a more modern and clean layout. Strip out what isn't necessary. A clean layout implies professionalism and increases visitors' trust.
147
+ * Even if you're just starting out with your website, remove all that could be but really isn't. Because if you leave in placeholders for the future, it implies amateurism.
148
+ * People want their truth to be confirmed or their problems to be solved. If you can't confirm or solve the layout of your website, then they won't trust you to do so for their issues.
149
+ * Simply put: It doesn't have to be perfect, it just must be done.