How to create dynamic HTML sitemap in WordPress with a shortcode (and exclude post types)

An HTML sitemap is a simple way to display all your website’s content in one place. It helps visitors and search engines quickly navigate your site’s structure. In this tutorial, we’ll show you how to create a WordPress shortcode that generates an HTML sitemap displaying Pages, Posts, and Custom Post Types (CPTs) – with an option to exclude certain post types you don’t want to display.

By the end, you’ll have a clean, dynamic sitemap you can insert anywhere using [html_sitemap exclude=”product,portfolio”].

Here’s an example:

Pages
- Home
- About Us
- Contact

Blog Posts
- How to Build a WordPress Site
- Top 10 SEO Tips

Products
- Product A
- Product B

Add this code to your theme’s functions.php file or in a custom plugin:

// [html_sitemap] shortcode with dynamic exclude option
function generate_html_sitemap($atts) {
    // Parse shortcode attributes
    $atts = shortcode_atts(array(
        'exclude' => '', // Default: no exclusions
    ), $atts, 'html_sitemap');

    // Convert exclude attribute into array
    $excluded_post_types = array();
    if (!empty($atts['exclude'])) {
        $excluded_post_types = array_map('trim', explode(',', $atts['exclude']));
    }

    ob_start();

    echo '<div class="html-sitemap">';

    // List Pages (exclude if "page" is in exclusions)
    if (!in_array('page', $excluded_post_types)) {
        echo '<h2>Pages</h2>';
        echo '<ul>';
        wp_list_pages(array(
            'title_li'    => '',
            'sort_column' => 'menu_order, post_title',
        ));
        echo '</ul>';
    }

    // List Posts (exclude if "post" is in exclusions)
    if (!in_array('post', $excluded_post_types)) {
        echo '<h2>Blog Posts</h2>';
        $posts = get_posts(array(
            'numberposts' => -1,
            'post_type'   => 'post',
            'post_status' => 'publish',
            'orderby'     => 'title',
            'order'       => 'ASC',
        ));
        if (!empty($posts)) {
            echo '<ul>';
            foreach ($posts as $post) {
                echo '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a></li>';
            }
            echo '</ul>';
        }
    }

    // List Custom Post Types
    $args = array(
        'public'   => true,
    );
    $custom_post_types = get_post_types($args, 'objects');

    if (!empty($custom_post_types)) {
        foreach ($custom_post_types as $post_type) {
            if (in_array($post_type->name, $excluded_post_types)) {
                continue; // Skip excluded post types
            }

            // Skip 'post' and 'page' since they’re handled above
            if ($post_type->name === 'post' || $post_type->name === 'page') {
                continue;
            }

            echo '<h2>' . esc_html($post_type->labels->name) . '</h2>';
            $cpt_posts = get_posts(array(
                'numberposts' => -1,
                'post_type'   => $post_type->name,
                'post_status' => 'publish',
                'orderby'     => 'title',
                'order'       => 'ASC',
            ));
            if (!empty($cpt_posts)) {
                echo '<ul>';
                foreach ($cpt_posts as $cpt_post) {
                    echo '<li><a href="' . get_permalink($cpt_post->ID) . '">' . esc_html($cpt_post->post_title) . '</a></li>';
                }
                echo '</ul>';
            }
        }
    }

    echo '</div>';

    return ob_get_clean();
}
add_shortcode('html_sitemap', 'generate_html_sitemap');

Optional: Add Some Styling

Add this to Appearance → Customize → Additional CSS in your WordPress admin.

.html-sitemap ul {
    list-style: disc;
    margin-left: 20px;
}

.html-sitemap h2 {
    margin-top: 20px;
    font-size: 1.5em;
    color: #333;
}

Usage Examples

Default (show everything): [html_sitemap]

Exclude posts and products: [html_sitemap exclude=”post,product”]

Exclude pages only: [html_sitemap exclude=”page”]

Exclude multiple custom post types: [html_sitemap exclude=”portfolio,testimonials”]

How to add a GST number field to WooCommerce checkout and order emails

If you’re running a WooCommerce store in India or working with B2B clients, you may need to collect GST numbers during checkout. In this tutorial, you’ll learn how to add an optional GST number field on the WooCommerce checkout page, save it with the order, and display it in the admin panel as well as in the order confirmation emails.

Step 1: Add GST Number Field to Checkout Page

Use the following code in your theme functions.php file to add a new optional field for the GST number just below the billing fields.

// Add GST Number field to checkout
add_action('woocommerce_after_checkout_billing_form', 'add_gst_field_to_checkout');
function add_gst_field_to_checkout($checkout) {
    echo '<div id="gst_number_field"><h3>' . __('GST Number (Optional)') . '</h3>';

    woocommerce_form_field('gst_number', array(
        'type'        => 'text',
        'class'       => array('form-row-wide'),
        'label'       => __('GST Number'),
        'placeholder' => __('Enter your GST number if applicable'),
        'required'    => false,
    ), $checkout->get_value('gst_number'));

    echo '</div>';
}

Step 2: Save the GST Number to Order Meta

Use the following code in your theme functions.php file to to save the entered GST number into the order’s metadata.

// Save GST number in order meta
add_action('woocommerce_checkout_update_order_meta', 'save_gst_number_order_meta');
function save_gst_number_order_meta($order_id) {
    if (!empty($_POST['gst_number'])) {
        update_post_meta($order_id, '_gst_number', sanitize_text_field($_POST['gst_number']));
    }
}

Step 3: Show GST Number on Admin Order Page

Admins should be able to view the GST number from the WooCommerce dashboard under the order details. Use the following code in your theme functions.php file.

// Show GST number in admin order page
add_action('woocommerce_admin_order_data_after_billing_address', 'display_gst_in_admin_order', 10, 1);
function display_gst_in_admin_order($order) {
    $gst_number = get_post_meta($order->get_id(), '_gst_number', true);
    if (!empty($gst_number)) {
        echo '<p><strong>' . __('GST Number') . ':</strong> ' . esc_html($gst_number) . '</p>';
    }
}

Step 4: Show GST Number in Order Emails

To include the GST number in the order emails (for both admin and customer), below the billing address section, add the following code in your theme functions.php file.

// Add GST number to emails below billing address
add_filter('woocommerce_email_customer_details_fields', 'add_gst_to_order_email', 10, 3);
function add_gst_to_order_email($fields, $sent_to_admin, $order) {
    $gst_number = get_post_meta($order->get_id(), '_gst_number', true);
    if (!empty($gst_number)) {
        $fields['gst_number'] = array(
            'label' => __('GST Number'),
            'value' => $gst_number,
        );
    }
    return $fields;
}

Note: Always test this on a staging site before applying to a live WooCommerce store. If you use custom themes or plugins that modify the checkout or email templates, adjust the code accordingly.

Plugin version of the same codes is also available on Github.

How to generate Facebook & Google product XML feed in WooCommerce without a plugin

If you’re running a WooCommerce store and want to connect your products to Facebook Catalogue or Google Merchant Center, you usually rely on a plugin. However, plugins can add bloat, slow down your website, or offer limited control.

This guide shows you how to generate a dynamic XML product feed from WooCommerce without installing any plugin. The feed is fully compatible with Facebook Commerce Manager and Google Shopping, supports both simple and variable products, and includes custom attributes like size, colour, and more.Why Build Your Own Feed?

Why build your own feed?

  • No need for extra plugins
  • Full control over structure and attributes
  • Supports all WooCommerce product types
  • Dynamically includes all variation attributes
  • Can be used for Facebook, Google, or any XML-based product platform

Step 1: Create the XML feed file

Create a new file in your website root directory name it as product-feed-xml.php. Paste the following code inside it.

<?php
require_once('wp-load.php');
ob_clean(); // Clean any prior output to prevent XML errors

header('Content-Type: application/xml; charset=utf-8');

echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>Your Store Feed</title>
<link><?php echo esc_url(site_url()); ?></link>
<description>WooCommerce Product Feed</description>

<?php
$args = [
'post_type'      => ['product', 'product_variation'],
'post_status'    => 'publish',
'posts_per_page' => -1
];

$loop = new WP_Query($args);

if ($loop->have_posts()) {
while ($loop->have_posts()) {
$loop->the_post();
$product = wc_get_product(get_the_ID());

if (!$product || !$product->is_visible()) continue;

$is_variation = $product->is_type('variation');
$parent_id = $is_variation ? $product->get_parent_id() : $product->get_id();
$parent = wc_get_product($parent_id);

// Prices
$currency = get_woocommerce_currency();
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$price = $regular_price ?: $sale_price;

if (!$price) continue; // skip product with no price

// Other fields
$id = $product->get_id();
$title = $product->get_name();
$description = strip_tags($parent->get_short_description() ?: $parent->get_description());
$availability = $product->is_in_stock() ? 'in stock' : 'out of stock';
$condition = 'new';
$link = get_permalink($parent_id);
$image = wp_get_attachment_url($product->get_image_id() ?: $parent->get_image_id());
$category_list = wp_get_post_terms($parent_id, 'product_cat', ['fields' => 'names']);
$product_type = implode(" > ", $category_list);
$item_group_id = $is_variation ? $parent_id : '';
$brand = 'Your Brand'; // Customize if needed
?>
<item>
<g:id><?php echo $id; ?></g:id>
<title><![CDATA[<?php echo $title; ?>]]></title>
<description><![CDATA[<?php echo $description; ?>]]></description>
<link><?php echo esc_url($link); ?></link>
<g:image_link><?php echo esc_url($image); ?></g:image_link>
<g:availability><?php echo $availability; ?></g:availability>
<g:condition><?php echo $condition; ?></g:condition>
<g:price><?php echo number_format($price, 2); ?> <?php echo $currency; ?></g:price>
<?php if ($sale_price): ?>
<g:sale_price><?php echo number_format($sale_price, 2); ?> <?php echo $currency; ?></g:sale_price>
<?php endif; ?>
<g:brand><?php echo esc_html($brand); ?></g:brand>
<g:product_type><![CDATA[<?php echo $product_type; ?>]]></g:product_type>
<?php if ($item_group_id): ?>
<g:item_group_id><?php echo $item_group_id; ?></g:item_group_id>
<?php endif; ?>

<?php
// Output all variation attributes dynamically
$attributes = $product->get_attributes();
foreach ($attributes as $attribute_name => $attribute) {
$label = wc_attribute_label($attribute_name);
$value = $product->get_attribute($attribute_name);
if (!empty($value)) {
$tag_name = strtolower(preg_replace('/[^a-z0-9_]/i', '_', $label));
echo "    <g:" . esc_html($tag_name) . ">" . esc_html($value) . "</g:" . esc_html($tag_name) . ">\n";
}
}
?>
</item>
<?php
}
}
wp_reset_postdata();
?>
</channel>
</rss>

Step 2: Access and test the feed

Visit: https://yourdomain.com/product-feed-xml.php

You’ll see a fully structured XML file that can be submitted to:

You can schedule Facebook or Google to fetch your feed daily using the public feed URL: https://yourdomain.com/product-feed-xml.php and you do not need to manually upload a CSV or XML file.

WordPress custom YouTube feed plugin

The Custom YouTube Feed plugin allows WordPress site owners to display videos from multiple YouTube channels and individual videos in an attractive grid layout. The plugin features pagination, popup video playback, and automatic caching for improved performance.

Key Features

  • Multiple Channel Support: Add videos from multiple YouTube channels
  • Individual Video Support: Include specific videos by URL
  • Responsive Grid Layout: 3-column grid that adapts to screen size
  • Popup Video Player: Lightbox-style playback with Magnific Popup
  • Smart Caching: 24-hour cache to reduce API calls
  • Easy Pagination: Automatic pagination for large video collections
  • Admin Dashboard: Simple interface for managing channels and settings

Installation

  1. Upload the plugin files to your WordPress plugins directory (/wp-content/plugins/)
  2. Activate the plugin through the WordPress admin panel
  3. Navigate to Settings → YouTube Channels to configure your API key and channels

Requirements

  • WordPress 5.0 or higher
  • PHP 7.0 or higher
  • YouTube Data API v3 key (free)

Usage

Shortcode

Add videos to any post or page using the shortcode:

[youtube_videos]

Admin Settings

  1. API Key: Enter your YouTube Data API key (required)
  2. Videos Per Channel: Set how many videos to show from each channel
  3. Channel URLs: Add YouTube channel URLs (supports all URL formats)
  4. Individual Videos: Add specific video URLs

Cache Management

The plugin automatically caches videos for 24 hours. You can manually clear the cache from the admin panel.

Customization

CSS Styling

The plugin includes default CSS that can be overridden in your theme’s stylesheet. Key classes:

  • .youtube-videos-grid – The main video container
  • .youtube-video – Individual video items
  • .youtube-pagination – Pagination controls

JavaScript

The plugin uses Magnific Popup for video playback. Customize the popup behavior by modifying the initialization in the shortcode output.

GitHub Repository

View on GitHub

Support

For support, feature requests, or bug reports, please open an issue on GitHub.

License

GPLv2 or later

Fetch data from Google Sheet and show in HTML using PHP

This documentation explains how to use the provided PHP code to fetch data from Google Sheets and display it in a custom layout using HTML/CSS.

Setup Instructions

1. Get Your Google Sheet ID

  1. Open your Google Sheet in a web browser
  2. Look at the URL in the address bar – it will look like:
https://docs.google.com/spreadsheets/d/BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ/edit#gid=0

The long string between /d/ and /edit is your Sheet ID (in this example: BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ)

2. Create a Google API Key

  1. Go to the Google Cloud Console
  2. Create a new project or select an existing one
  3. Navigate to “APIs & Services” > “Library”
  4. Search for “Google Sheets API” and enable it
  5. Go to “APIs & Services” > “Credentials”
  6. Click “Create Credentials” and select “API key”
  7. Copy your new API key
  8. (Optional) Restrict the API key to only work with the Sheets API for security

3. Configure the PHP Code

Replace these values in the code:

$sheetID = "BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ"; // Your Sheet ID
$apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Your API Key
$rows_count = 8; // Number of rows to display

4. Sheet Configuration

Your Google Sheet must have a named range or sheet tab that matches what you put in the API URL (in this example: Sheet1)

Make sure your Sheet is either:

  • Publicly accessible (set to “Anyone with the link can view”)
  • Or shared with the email address associated with your API key

Here is the entire code.

<?php
// Google Sheets API configuration
$sheetID = "BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ"; // Replace with your actual Sheet ID
$apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Replace with your API Key
$apiURL = "https://sheets.googleapis.com/v4/spreadsheets/$sheetID/values/Sheet1?key=$apiKey";

$rows_count = 8; // Number of rows to be displayed

// Fetch the Google Sheets data
$response = file_get_contents($apiURL);
$data = json_decode($response, true);
if (isset($data['values']) && count($data['values']) > 1) {
for ($i = 1; $i <= min($rows_count, count($data['values']) - 1); $i++) {	

// Get the column wise data from Google Sheet, if no value then show N/A
$column_1 = isset($data['values'][$i][0]) ? htmlspecialchars($data['values'][$i][0]) : "N/A";
$column_2 = isset($data['values'][$i][1]) ? htmlspecialchars($data['values'][$i][1]) : "N/A";
$column_3 = isset($data['values'][$i][2]) ? htmlspecialchars($data['values'][$i][2]) : "N/A";
$column_4 = isset($data['values'][$i][3]) ? htmlspecialchars($data['values'][$i][3]) : "N/A";
$column_5 = isset($data['values'][$i][4]) ? htmlspecialchars($data['values'][$i][4]) : "N/A";
?>

<?php } ?>
<div class="row">
<div><?php echo $column_1;?></div>
<div><?php echo $column_2;?></div>
<div><?php echo $column_3;?></div>
<div><?php echo $column_4;?></div>
<div><?php echo $column_5;?></div>
</div>
<?php } ?>

Disable WordPress Comment System Completely

Here’s a comprehensive function to completely disable the WordPress comment system:

<?php
// Completely disable WordPress comments and related functionality
function disable_comments_system() {
    // Disable support for comments and trackbacks in post types
    foreach (get_post_types() as $post_type) {
        if (post_type_supports($post_type, 'comments')) {
            remove_post_type_support($post_type, 'comments');
            remove_post_type_support($post_type, 'trackbacks');
        }
    }
    
    // Close comments on all existing posts
    update_option('close_comments_for_old_posts', 1);
    update_option('close_comments_days_old', 0);
    update_option('comment_registration', 1);
    update_option('default_ping_status', 'closed');
    update_option('default_comment_status', 'closed');
    
    // Redirect any comment feed requests to homepage
    add_action('template_redirect', function() {
        if (is_comment_feed()) {
            wp_redirect(home_url(), 301);
            exit;
        }
    });
    
    // Remove comments page from admin menu
    add_action('admin_menu', function() {
        remove_menu_page('edit-comments.php');
        remove_submenu_page('options-general.php', 'options-discussion.php');
    });
    
    // Remove comments links from admin bar
    add_action('wp_before_admin_bar_render', function() {
        global $wp_admin_bar;
        $wp_admin_bar->remove_menu('comments');
    });
    
    // Remove dashboard comments widget
    add_action('wp_dashboard_setup', function() {
        remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
    });
    
    // Disable comments REST API endpoint
    add_filter('rest_endpoints', function($endpoints) {
        unset($endpoints['/wp/v2/comments']);
        unset($endpoints['/wp/v2/comments/(?P<id>[\d]+)']);
        return $endpoints;
    });
    
    // Remove comment form completely (front-end)
    add_filter('comments_open', '__return_false', 20, 2);
    add_filter('pings_open', '__return_false', 20, 2);
    add_filter('comments_array', '__return_empty_array', 10, 2);
    
    // Remove comment-reply script
    add_action('wp_enqueue_scripts', function() {
        wp_deregister_script('comment-reply');
    }, 100);
    
    // Remove comment form from templates
    add_action('init', function() {
        // Remove comment-reply script
        remove_action('wp_head', 'feed_links_extra', 3);
        
        // Remove comment form from wp_head
        remove_action('wp_head', 'feed_links', 2);
        
        // Remove comment form from content
        remove_filter('the_content', 'wpautop');
        add_filter('the_content', function($content) {
            if (is_singular()) {
                $content = preg_replace('/<div[^>]+id="respond"[^>]*>.*?<\/div>/is', '', $content);
                $content = preg_replace('/<h3[^>]+id="reply-title"[^>]*>.*?<\/h3>/is', '', $content);
                $content = preg_replace('/<form[^>]+id="commentform"[^>]*>.*?<\/form>/is', '', $content);
            }
            return $content;
        });
    });
}
add_action('init', 'disable_comments_system');

// Remove comment form from theme templates (additional safety)
add_filter('theme_page_templates', function($templates) {
    unset($templates['comments.php']);
    return $templates;
});

// Hide comments in admin for all post types
add_action('admin_init', function() {
    $post_types = get_post_types();
    foreach ($post_types as $post_type) {
        if (post_type_supports($post_type, 'comments')) {
            remove_post_type_support($post_type, 'comments');
            remove_post_type_support($post_type, 'trackbacks');
        }
    }
});
?>
  1. Add this code to your theme’s functions.php file or in a custom plugin
  2. The function will:
    • Remove comment support from all post types
    • Close comments on all existing posts
    • Disable comments and pingbacks by default
    • Remove comment-related admin menu items
    • Remove comment links from the admin bar
    • Remove the comments dashboard widget
    • Disable the comments REST API endpoints
    • Redirect comment feeds to the homepage

Additional Steps for Stubborn Comment Forms

If the comment form still appears after adding this code:

  1. Check your theme files: Some themes hard-code the comment form. Look in these files:
    • comments.php
    • single.php
    • page.php
    • content-single.php
    • Any files with comment_form() calls
  2. Add CSS to hide comments (as last resort)
add_action('wp_head', function() {
    echo '<style>
        #comments, #respond, .comments-area, .comment-respond, 
        .comment-form, .comments-title, .comment-list {
            display: none !important;
        }
    </style>';
});
  1. Check for any other plugins that might be adding comment functionality.

This enhanced solution should remove all traces of the comment system, including forms that appear when logged in as an admin.

Block HTtrack or any other web scrapper

There are several web scrappers tools are available by which your website can be downloaded as static files. The simplest way to block these web scrappers is to add the following blocking bots code in your website .htaccess file.

##Block bad bots
RewriteEngine On 
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
RewriteCond %{HTTP_USER_AGENT} ^Bot\ mailto:[email protected] [OR]
RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR]
RewriteCond %{HTTP_USER_AGENT} ^Custo [OR]
RewriteCond %{HTTP_USER_AGENT} ^DISCo [OR]
RewriteCond %{HTTP_USER_AGENT} ^Download\ Demon [OR]
RewriteCond %{HTTP_USER_AGENT} ^eCatch [OR]
RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [OR]
RewriteCond %{HTTP_USER_AGENT} ^Express\ WebPictures [OR]
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro [OR]
RewriteCond %{HTTP_USER_AGENT} ^EyeNetIE [OR]
RewriteCond %{HTTP_USER_AGENT} ^FlashGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetRight [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetWeb! [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go!Zilla [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go-Ahead-Got-It [OR]
RewriteCond %{HTTP_USER_AGENT} ^GrabNet [OR]
RewriteCond %{HTTP_USER_AGENT} ^Grafula [OR]
RewriteCond %{HTTP_USER_AGENT} ^HMView [OR]
RewriteCond %{HTTP_USER_AGENT} HTTrack [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Stripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^InterGET [OR]
RewriteCond %{HTTP_USER_AGENT} ^Internet\ Ninja [OR]
RewriteCond %{HTTP_USER_AGENT} ^JetCar [OR]
RewriteCond %{HTTP_USER_AGENT} ^JOC\ Web\ Spider [OR]
RewriteCond %{HTTP_USER_AGENT} ^larbin [OR]
RewriteCond %{HTTP_USER_AGENT} ^LeechFTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mass\ Downloader [OR]
RewriteCond %{HTTP_USER_AGENT} ^MIDown\ tool [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mister\ PiX [OR]
RewriteCond %{HTTP_USER_AGENT} uuuu7u^Navroad [OR]
RewriteCond %{HTTP_USER_AGENT} ^NearSite [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetAnts [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Octopus [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Explorer [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Navigator [OR]
RewriteCond %{HTTP_USER_AGENT} ^PageGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^Papa\ Foto [OR]
RewriteCond %{HTTP_USER_AGENT} ^pavuk [OR]
RewriteCond %{HTTP_USER_AGENT} ^pcBrowser [OR]
RewriteCond %{HTTP_USER_AGENT} ^RealDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^ReGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^SiteSnagger [OR]
RewriteCond %{HTTP_USER_AGENT} ^SmartDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperBot [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperHTTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Surfbot [OR]
RewriteCond %{HTTP_USER_AGENT} ^tAkeOut [OR]
RewriteCond %{HTTP_USER_AGENT} ^Teleport\ Pro [OR]
RewriteCond %{HTTP_USER_AGENT} ^VoidEYE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Image\ Collector [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebAuto [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebCopier [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebFetch [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebGo\ IS [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebLeacher [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebReaper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebSauger [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ eXtractor [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ Quester [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebStripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebWhacker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Wget [OR]
RewriteCond %{HTTP_USER_AGENT} ^Widow [OR]
RewriteCond %{HTTP_USER_AGENT} ^WWWOFFLE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]

WordPress change default from name and email id

When you get any email from your self hosted WordPress website, form name of that email will be WordPress which is quite annoying to you or your clients.

You can overwrite this by adding this small piece of code in the functions.php file of your theme.

function custom_wp_mail_from_name($email_from_name) {
    return 'Your Website Name'; // Change this to your desired name
}
add_filter('wp_mail_from_name', 'custom_wp_mail_from_name');

Also you can change the default from email id of the email generated from WordPress website by adding this another function in the functions.php file of your theme.

function custom_wp_mail_from($email) {
    return '[email protected]'; // Change this to your desired email
}
add_filter('wp_mail_from', 'custom_wp_mail_from');

WordPress custom menu page, fetch data from custom MySQL table and export to CSV

To create a custom menu page in WordPress, retrieve custom table data from MySQL, and display it with the ability to export to CSV/Excel, you can follow these steps:

  1. Create a custom table in your WordPress database to store your data. You can use the $wpdb global variable to interact with custom tables in WordPress. Here’s an example of creating a custom table:
<?php
global $wpdb;
$table_name = $wpdb->prefix . 'custom_data';

$sql = "CREATE TABLE IF NOT EXISTS $table_name (
    id INT(11) NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    phone VARCHAR(20) NOT NULL,
    PRIMARY KEY (id)
) $charset_collate;";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
?>

Add the following code to your theme’s functions.php file or create a custom plugin file to define the custom menu page:

<?php
// Add menu page
function custom_menu_page()
{
    add_menu_page(
        'Custom Data',
        'Custom Data',
        'manage_options',
        'custom-data',
        'custom_menu_page_callback'
    );
}
add_action('admin_menu', 'custom_menu_page');

// Menu page callback function
function custom_menu_page_callback()
{
    global $wpdb;

    // Retrieve custom table data
    $table_name = $wpdb->prefix . 'custom_data';
    $results = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);

    // Display custom table data
    echo '<div class="wrap">';
    echo '<h1>Custom Data</h1>';

    // Export to CSV/Excel button
    echo '<form method="post" action="' . admin_url('admin-post.php') . '">';
    echo '<input type="hidden" name="action" value="export_custom_data">';
    echo '<button type="submit" class="button">Export to CSV/Excel</button>';
    echo '</form>';

    // Display data in a table
    if ($results) {
        echo '<table>';
        echo '<thead><tr><th>Name</th><th>Email</th><th>Phone</th></tr></thead>';
        echo '<tbody>';
        foreach ($results as $row) {
            echo '<tr>';
            echo '<td>' . $row['name'] . '</td>';
            echo '<td>' . $row['email'] . '</td>';
            echo '<td>' . $row['phone'] . '</td>';
            echo '</tr>';
        }
        echo '</tbody>';
        echo '</table>';
    } else {
        echo '<p>No data found.</p>';
    }

    echo '</div>';
}

// Export to CSV/Excel action
function export_custom_data_action()
{
    global $wpdb;

    // Retrieve custom table data
    $table_name = $wpdb->prefix . 'custom_data';
    $results = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);

    if ($results) {
        // Set headers for CSV/Excel file
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="custom_data.csv"');
        $output = fopen('php://output', 'w');

        // Write data rows to CSV/Excel file
        foreach ($results as $row) {
            fputcsv($output, $row);
        }

        fclose($output);
        exit;
    }
}
add_action('admin_post_export_custom_data', 'export_custom_data_action');
add_action('admin_post_nopriv_export_custom_data', 'export_custom_data_action');
?>

3. Save the changes to the functions.php file or your custom plugin file.

4. In your WordPress admin dashboard, you will see a new menu page called “Custom Data.” Clicking on this menu item will display the custom table data in a table format. The page will also have a button labeled “Export to CSV/Excel” that allows you to download the data in CSV/Excel format.

Note: Make sure to update the table name, column names, and the export file name according to your custom table structure and requirements.

This code creates a custom table, retrieves the data from the table using $wpdb, and displays it in an HTML table on the custom menu page. It also includes a form that, upon submission, triggers an action to export the data to CSV/Excel. The exported file is downloaded with the name “custom_data.csv” and includes the data rows from the custom table.

« Older posts

© 2025 Wavesdream Blog

Theme by Anders NorénUp ↑