3
3
*
4
4
* @package BasicSEO
5
5
* @author https://github.com/Torwald45
6
- * @version 1.8.1
6
+ * @version 1.8.2
7
7
* @pluginURI https://github.com/Torwald45/basic-seo
8
- * @changelog @pluginURI https://github.com/Torwald45/basic-seo/CHANGELOG.md
9
- * Features:
8
+ * @changelog https://github.com/Torwald45/basic-seo/blob/main/CHANGELOG.md
9
+ * @roadmap https://github.com/Torwald45/basic-seo/blob/main/ROADMAP.md
10
+ * Features:
10
11
* - Custom Title Tag for pages, posts and WooCommerce (shop page & categories)
11
12
* - Meta Description for pages, posts and WooCommerce (shop page & categories)
13
+ * - SEO columns in admin view for posts, pages, products and WooCommerce categories
12
14
* - Open Graph support (title, description, image)
13
15
* - XML Sitemap with HTML display (pages, posts, products, categories)
16
+ * - Error handling for XML Sitemap
14
17
* - Quick Edit support in admin panel
15
18
* - Breadcrumbs support via [basicseo-breadcrumb] shortcode
16
19
* - Media attachments redirect (prevents duplicate content)
@@ -143,18 +146,16 @@ function basicseotorvald_v1_add_columns($columns) {
143
146
return $ columns ;
144
147
}
145
148
146
- remove_all_filters ('manage_posts_columns ' );
147
- remove_all_filters ('manage_pages_columns ' );
148
- remove_all_filters ('manage_product_posts_columns ' );
149
-
150
- add_filter ('manage_posts_columns ' , 'basicseotorvald_v1_add_columns ' );
151
- add_filter ('manage_pages_columns ' , 'basicseotorvald_v1_add_columns ' );
152
- add_filter ('manage_product_posts_columns ' , 'basicseotorvald_v1_add_columns ' );
149
+ add_filter ('manage_posts_columns ' , 'basicseotorvald_v1_add_columns ' , 20 );
150
+ add_filter ('manage_pages_columns ' , 'basicseotorvald_v1_add_columns ' , 20 );
151
+ add_filter ('manage_product_posts_columns ' , 'basicseotorvald_v1_add_columns ' , 20 );
153
152
154
153
foreach (basicseotorvald_v1_get_supported_post_types () as $ post_type ) {
155
- add_filter ("manage_ {$ post_type }_posts_columns " , 'basicseotorvald_v1_add_columns ' );
154
+ add_filter ("manage_ {$ post_type }_posts_columns " , 'basicseotorvald_v1_add_columns ' , 20 );
156
155
}
157
156
157
+
158
+
158
159
// Display content in columns
159
160
function basicseotorvald_v1_column_content ($ column_name , $ post_id ) {
160
161
static $ displayed = array ();
@@ -310,6 +311,68 @@ function basicseotorvald_v1_save_product_cat_fields($term_id) {
310
311
add_action ('created_product_cat ' , 'basicseotorvald_v1_save_product_cat_fields ' );
311
312
add_action ('edited_product_cat ' , 'basicseotorvald_v1_save_product_cat_fields ' );
312
313
314
+ /**
315
+ * ==============================================
316
+ * WOOCOMMERCE CATEGORY COLUMNS
317
+ * ==============================================
318
+ */
319
+
320
+ // Add new columns to the product category list
321
+ function basicseotorvald_v1_add_product_cat_columns ($ columns ) {
322
+ $ new_columns = array ();
323
+
324
+ // Preserve checkbox column if exists
325
+ if (isset ($ columns ['cb ' ])) {
326
+ $ new_columns ['cb ' ] = $ columns ['cb ' ];
327
+ }
328
+
329
+ // Preserve thumbnail column if exists
330
+ if (isset ($ columns ['thumb ' ])) {
331
+ $ new_columns ['thumb ' ] = $ columns ['thumb ' ];
332
+ }
333
+
334
+ // Add name column (required)
335
+ $ new_columns ['name ' ] = $ columns ['name ' ];
336
+
337
+ // Add our new SEO columns
338
+ $ new_columns ['seo_title ' ] = 'Title Tag ' ;
339
+ $ new_columns ['seo_desc ' ] = 'Meta Description ' ;
340
+
341
+ // Preserve remaining standard columns
342
+ if (isset ($ columns ['description ' ])) {
343
+ $ new_columns ['description ' ] = $ columns ['description ' ];
344
+ }
345
+ if (isset ($ columns ['slug ' ])) {
346
+ $ new_columns ['slug ' ] = $ columns ['slug ' ];
347
+ }
348
+ if (isset ($ columns ['count ' ])) {
349
+ $ new_columns ['count ' ] = $ columns ['count ' ];
350
+ }
351
+
352
+ return $ new_columns ;
353
+ }
354
+ add_filter ('manage_edit-product_cat_columns ' , 'basicseotorvald_v1_add_product_cat_columns ' );
355
+
356
+ // Display content in the new columns
357
+ function basicseotorvald_v1_product_cat_column_content ($ content , $ column_name , $ term_id ) {
358
+ switch ($ column_name ) {
359
+ case 'seo_title ' :
360
+ $ title = get_term_meta ($ term_id , BSTV1_TERM_TITLE , true );
361
+ return $ title ? esc_html ($ title ) : '— ' ;
362
+
363
+ case 'seo_desc ' :
364
+ $ desc = get_term_meta ($ term_id , BSTV1_TERM_DESC , true );
365
+ return $ desc ? esc_html (wp_trim_words ($ desc , 10 , '... ' )) : '— ' ;
366
+ }
367
+ return $ content ;
368
+ }
369
+ add_filter ('manage_product_cat_custom_column ' , 'basicseotorvald_v1_product_cat_column_content ' , 10 , 3 );
370
+
371
+ /**
372
+ * END OF WOOCOMMERCE CATEGORY COLUMNS
373
+ * ==============================================
374
+ */
375
+
313
376
/**
314
377
* ==============================================
315
378
* META TAGS OUTPUT IN HEAD
@@ -445,23 +508,32 @@ function basicseotorvald_v1_generate_sitemap_index() {
445
508
$ post_types = get_post_types (['public ' => true ]);
446
509
unset($ post_types ['attachment ' ]);
447
510
448
- foreach ($ post_types as $ post_type ) {
449
- // Check if post type has any posts
450
- $ count = wp_count_posts ($ post_type );
451
- if ($ count ->publish > 0 ) {
452
- $ url = home_url ("/sitemap-post-type- {$ post_type }.xml " );
453
- $ output .= "<a href=' {$ url }'> {$ url }</a><br> \n" ;
511
+ if (empty ($ post_types )) {
512
+ $ output .= '<p>No public post types found.</p> ' ;
513
+ } else {
514
+ foreach ($ post_types as $ post_type ) {
515
+ // Check if post type has any posts
516
+ $ count = wp_count_posts ($ post_type );
517
+ if ($ count && $ count ->publish > 0 ) {
518
+ $ url = home_url ("/sitemap-post-type- {$ post_type }.xml " );
519
+ $ output .= "<a href=' " . esc_url ($ url ) . "'> " . esc_html ($ url ) . "</a><br> \n" ;
520
+ }
454
521
}
455
522
}
456
523
457
524
// Get all public taxonomies
458
525
$ taxonomies = get_taxonomies (['public ' => true ]);
459
- foreach ($ taxonomies as $ taxonomy ) {
460
- // Check if taxonomy has any terms
461
- $ terms = get_terms (['taxonomy ' => $ taxonomy , 'hide_empty ' => true ]);
462
- if (!empty ($ terms ) && !is_wp_error ($ terms )) {
463
- $ url = home_url ("/sitemap-taxonomy- {$ taxonomy }.xml " );
464
- $ output .= "<a href=' {$ url }'> {$ url }</a><br> \n" ;
526
+
527
+ if (empty ($ taxonomies )) {
528
+ $ output .= '<p>No public taxonomies found.</p> ' ;
529
+ } else {
530
+ foreach ($ taxonomies as $ taxonomy ) {
531
+ // Check if taxonomy has any terms
532
+ $ terms = get_terms (['taxonomy ' => $ taxonomy , 'hide_empty ' => true , 'number ' => 1 ]);
533
+ if (!empty ($ terms ) && !is_wp_error ($ terms )) {
534
+ $ url = home_url ("/sitemap-taxonomy- {$ taxonomy }.xml " );
535
+ $ output .= "<a href=' " . esc_url ($ url ) . "'> " . esc_html ($ url ) . "</a><br> \n" ;
536
+ }
465
537
}
466
538
}
467
539
@@ -471,25 +543,39 @@ function basicseotorvald_v1_generate_sitemap_index() {
471
543
// Generate sitemap for specific post type
472
544
function basicseotorvald_v1_generate_post_type_sitemap ($ post_type ) {
473
545
$ output = '<h1>XML Sitemap</h1> ' ;
546
+
547
+ // Verify post type exists
548
+ if (!post_type_exists ($ post_type )) {
549
+ return '<div class="error">Error: Post type does not exist.</div> ' ;
550
+ }
551
+
474
552
$ output .= '<table>
475
553
<tr>
476
554
<th>URL</th>
477
555
<th>Last Modified</th>
478
556
</tr> ' ;
479
557
480
- $ posts = get_posts ([
481
- 'post_type ' => $ post_type ,
482
- 'post_status ' => 'publish ' ,
483
- 'posts_per_page ' => -1 ,
484
- 'orderby ' => 'modified ' ,
485
- 'order ' => 'DESC '
486
- ]);
487
-
488
- foreach ($ posts as $ post ) {
489
- $ output .= '<tr>
490
- <td><a href=" ' . get_permalink ($ post ->ID ) . '"> ' . get_permalink ($ post ->ID ) . '</a></td>
491
- <td> ' . get_the_modified_date ('Y-m-d\TH:i:sP ' , $ post ->ID ) . '</td>
492
- </tr> ' ;
558
+ // no limit posts to 500 to prevent server overload
559
+ $ posts = get_posts ([
560
+ 'post_type ' => $ post_type ,
561
+ 'post_status ' => 'publish ' ,
562
+ 'posts_per_page ' => -1 ,
563
+ 'orderby ' => 'modified ' ,
564
+ 'order ' => 'DESC '
565
+ ]);
566
+
567
+ if (empty ($ posts )) {
568
+ $ output .= '<tr><td colspan="2">No published content found.</td></tr> ' ;
569
+ } else {
570
+ foreach ($ posts as $ post ) {
571
+ $ permalink = get_permalink ($ post ->ID );
572
+ if ($ permalink ) {
573
+ $ output .= '<tr>
574
+ <td><a href=" ' . esc_url ($ permalink ) . '"> ' . esc_html ($ permalink ) . '</a></td>
575
+ <td> ' . get_the_modified_date ('Y-m-d\TH:i:sP ' , $ post ->ID ) . '</td>
576
+ </tr> ' ;
577
+ }
578
+ }
493
579
}
494
580
495
581
$ output .= '</table> ' ;
@@ -503,22 +589,35 @@ function basicseotorvald_v1_generate_post_type_sitemap($post_type) {
503
589
// Generate sitemap for taxonomy
504
590
function basicseotorvald_v1_generate_taxonomy_sitemap ($ taxonomy ) {
505
591
$ output = '<h1>XML Sitemap</h1> ' ;
592
+
593
+ // Verify taxonomy exists
594
+ if (!taxonomy_exists ($ taxonomy )) {
595
+ return '<div class="error">Error: Taxonomy does not exist.</div> ' ;
596
+ }
597
+
506
598
$ output .= '<table>
507
599
<tr>
508
600
<th>URL</th>
509
601
<th>Last Modified</th>
510
602
</tr> ' ;
511
603
512
- $ terms = get_terms ([
513
- 'taxonomy ' => $ taxonomy ,
514
- 'hide_empty ' => true
515
- ]);
604
+ $ terms = get_terms ([
605
+ 'taxonomy ' => $ taxonomy ,
606
+ 'hide_empty ' => true
607
+ ]);
516
608
517
- foreach ($ terms as $ term ) {
518
- $ output .= '<tr>
519
- <td><a href=" ' . get_term_link ($ term ) . '"> ' . get_term_link ($ term ) . '</a></td>
520
- <td> ' . date ('Y-m-d\TH:i:sP ' ) . '</td>
521
- </tr> ' ;
609
+ if (empty ($ terms ) || is_wp_error ($ terms )) {
610
+ $ output .= '<tr><td colspan="2">No terms found or an error occurred.</td></tr> ' ;
611
+ } else {
612
+ foreach ($ terms as $ term ) {
613
+ $ term_link = get_term_link ($ term );
614
+ if (!is_wp_error ($ term_link )) {
615
+ $ output .= '<tr>
616
+ <td><a href=" ' . esc_url ($ term_link ) . '"> ' . esc_html ($ term_link ) . '</a></td>
617
+ <td> ' . date ('Y-m-d\TH:i:sP ' ) . '</td>
618
+ </tr> ' ;
619
+ }
620
+ }
522
621
}
523
622
524
623
$ output .= '</table> ' ;
@@ -556,6 +655,12 @@ function basicseotorvald_v1_handle_sitemap_request() {
556
655
if (post_type_exists ($ post_type )) {
557
656
echo basicseotorvald_v1_generate_post_type_sitemap ($ post_type );
558
657
exit ;
658
+ } else {
659
+ status_header (404 );
660
+ echo '<h1>Error 404: Sitemap not found</h1> ' ;
661
+ echo '<p>The requested post type does not exist.</p> ' ;
662
+ echo '<p><a href=" ' . home_url ('/sitemap.xml ' ) . '">Back to main sitemap</a></p> ' ;
663
+ exit ;
559
664
}
560
665
}
561
666
@@ -565,9 +670,25 @@ function basicseotorvald_v1_handle_sitemap_request() {
565
670
if (taxonomy_exists ($ taxonomy )) {
566
671
echo basicseotorvald_v1_generate_taxonomy_sitemap ($ taxonomy );
567
672
exit ;
673
+ } else {
674
+ status_header (404 );
675
+ echo '<h1>Error 404: Sitemap not found</h1> ' ;
676
+ echo '<p>The requested taxonomy does not exist.</p> ' ;
677
+ echo '<p><a href=" ' . home_url ('/sitemap.xml ' ) . '">Back to main sitemap</a></p> ' ;
678
+ exit ;
568
679
}
569
680
}
681
+
682
+ // If we got here, the sitemap URL pattern was invalid
683
+ if (strpos ($ current_url , 'sitemap ' ) !== false && strpos ($ current_url , '.xml ' ) !== false ) {
684
+ status_header (404 );
685
+ echo '<h1>Error 404: Sitemap not found</h1> ' ;
686
+ echo '<p>Invalid sitemap URL format.</p> ' ;
687
+ echo '<p><a href=" ' . home_url ('/sitemap.xml ' ) . '">Back to main sitemap</a></p> ' ;
688
+ exit ;
689
+ }
570
690
}
691
+
571
692
add_action ('init ' , 'basicseotorvald_v1_handle_sitemap_request ' );
572
693
573
694
/**
0 commit comments