Skip to content

Instantly share code, notes, and snippets.

@SalvatoreNoschese
Last active September 12, 2024 08:21
Show Gist options
  • Save SalvatoreNoschese/b33ea9f678f66d8f181b694738e7132c to your computer and use it in GitHub Desktop.
Save SalvatoreNoschese/b33ea9f678f66d8f181b694738e7132c to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: SimpleSitemapHTML
Description: Generates an HTML sitemap using a shortcode: [custom_sitemap]
Author: Salvatore Noschese
Author URI: https://salvatorenoschese.it
Version: 1.2
*/
// Deny direct access
defined('ABSPATH') || exit;
class SimpleSitemapHTML {
public function __construct() {
// Register the shortcode with parameters handling
add_shortcode('custom_sitemap', [$this, 'generate_sitemap']);
}
/**
* Generate the HTML sitemap content with optional parameters.
*
* @param array $atts Shortcode attributes.
* @return string The generated sitemap HTML.
*/
public function generate_sitemap($atts) {
// Set default attributes
$atts = shortcode_atts([
'posts_num' => 100, // default: latest 100 posts
'title_counter' => 'yes', // default: show counter
'terms_num' => 45, // default: 45 terms
'terms_counter' => true, // default: counter terms
'yoast_sitemap' => 'yes', // default: show yoast xml
], $atts, 'custom_sitemap');
if (!is_page()) {
return "&#91;custom_sitemap]";
}
$output = '<div class="custom-sitemap-shortcode">';
$output .= $this->render_pages_section($atts['title_counter']);
$output .= $this->render_posts_section($atts['posts_num'], $atts['title_counter']);
$output .= $this->render_taxonomy_section('Categories', 'category', $atts['title_counter'], $atts['terms_num'], $atts['terms_counter']);
$output .= $this->render_taxonomy_section('Tags', 'post_tag', $atts['title_counter'], $atts['terms_num'], $atts['terms_counter']);
if ($atts['yoast_sitemap'] === 'yes' && class_exists('WPSEO_Options') && WPSEO_Options::get('enable_xml_sitemap')) {
$output .= '<hr />';
$output .= '<p class="has-text-align-center">';
$output .= '<a href="' . esc_url(WPSEO_Sitemaps_Router::get_base_url('sitemap_index.xml')) . '" class="wp-element-button">';
$output .= esc_html__('See the XML sitemap.', 'wordpress-seo') . '</a></p>';
}
$output .= '</div>';
return $output;
}
/* pages */
private function render_pages_section($title_counter) {
$output = '<hr />';
$pages_title = esc_html__('Pages', 'default');
if ($title_counter === 'yes') {
$pages_title .= ' (' . esc_html(wp_count_posts('page')->publish - 1) . ')';
}
$output .= '<h2>' . $pages_title . '</h2>';
$output .= '<ul>';
$pages = wp_list_pages([
'title_li' => '',
'sort_column' => 'post_title',
'sort_order' => 'ASC',
'exclude' => get_the_ID(),
'echo' => 0
]);
$output .= $pages ? $pages : '<li>' . esc_html__('No pages found.', 'default') . '</li>';
$output .= '</ul>';
return $output;
}
/* posts */
private function render_posts_section($posts_num, $title_counter) {
$output = '<hr />';
$posts_title = esc_html__('Posts', 'default');
if ($title_counter === 'yes') {
$total_posts = wp_count_posts('post')->publish;
if ($posts_num != -1 && $posts_num < $total_posts) {
$posts_title .= ' (' . sprintf(_x('%1$s of %2$s', 'paging'), esc_html($posts_num), esc_html($total_posts)) . ')';
} else {
$posts_title .= ' (' . esc_html($total_posts) . ')';
}
}
$output .= '<h2>' . $posts_title . '</h2>';
$output .= '<ul>';
$posts = get_posts([
'post_type' => 'post',
'posts_per_page' => intval($posts_num),
'orderby' => 'date',
'order' => 'DESC',
]);
if ($posts) {
foreach ($posts as $post) {
$output .= '<li>';
$output .= '<a href="' . esc_url(get_permalink($post->ID)) . '" title="' . esc_attr(get_the_title($post->ID)) . '">';
$output .= esc_html(get_the_title($post->ID)) . '</a> ';
$output .= '<em>(' . esc_html(get_the_date(get_option('date_format'), $post->ID)) . ')</em>';
$output .= '</li>';
}
} else {
$output .= '<li>' . esc_html__('No posts found.', 'default') . '</li>';
}
$output .= '</ul>';
return $output;
}
/* taxonomies (categories + tags) */
private function render_taxonomy_section($title, $taxonomy, $title_counter, $terms_num, $terms_counter) {
$output = '<hr />';
$terms_title = esc_html__($title, 'default');
if ($title_counter === 'yes') {
$total_terms = wp_count_terms($taxonomy, ['hide_empty' => true]);
if ($terms_num != 0 && $terms_num < $total_terms) {
$terms_title .= ' (' . sprintf(_x('%1$s of %2$s', 'paging'), esc_html($terms_num), esc_html($total_terms)) . ')';
} else {
$terms_title .= ' (' . esc_html($total_terms) . ')';
}
}
$output .= '<h2>' . $terms_title . '</h2>';
$output .= '<ul>';
if (!empty($total_terms)) {
$output .= '<li>';
$output .= wp_tag_cloud([
'taxonomy' => $taxonomy,
'smallest' => 8,
'largest' => 22,
'unit' => 'pt',
'number' => intval($terms_num),
'orderby' => 'name',
'order' => 'ASC',
'format' => 'flat',
'show_count' => $terms_counter,
'echo' => false
]);
$output .= '</li>';
} else {
$output .= '<li>' . esc_html__('No terms found.', 'default') . '</li>';
}
$output .= '</ul>';
return $output;
}
}
// Initialize the plugin
new SimpleSitemapHTML();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment