<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MD. Samrat Hossen</title>
    <description>The latest articles on DEV Community by MD. Samrat Hossen (@samratemily).</description>
    <link>https://dev.to/samratemily</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3208826%2F162cb04b-a029-4e25-914d-9ba3dade83a0.jpg</url>
      <title>DEV Community: MD. Samrat Hossen</title>
      <link>https://dev.to/samratemily</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samratemily"/>
    <language>en</language>
    <item>
      <title>To modify woocommerce orders per page</title>
      <dc:creator>MD. Samrat Hossen</dc:creator>
      <pubDate>Mon, 29 Sep 2025 04:53:41 +0000</pubDate>
      <link>https://dev.to/samratemily/to-modify-woocommerce-orders-per-page-jec</link>
      <guid>https://dev.to/samratemily/to-modify-woocommerce-orders-per-page-jec</guid>
      <description>&lt;p&gt;Use this filter to modify posts per page at woocommerce orders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     /**
     * Modify number of orders displayed per page in My Account
     *
     * @param array $args Query arguments for fetching orders.
     * @return array Modified query arguments.
     */
    function modify_order_per_page( $args ) {
        $args['posts_per_page'] = 4; // Change 10 to the desired number of orders per page.
        return $args;
    }
   add_filter( 'woocommerce_my_account_my_orders_query', 'modify_order_per_page', 10, 1 );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>perpage</category>
      <category>woocommerce</category>
      <category>wordpress</category>
      <category>filter</category>
    </item>
    <item>
      <title>Plugin Admin Menu - Developer Guide</title>
      <dc:creator>MD. Samrat Hossen</dc:creator>
      <pubDate>Fri, 12 Sep 2025 05:14:42 +0000</pubDate>
      <link>https://dev.to/samratemily/plugin-admin-menu-developer-guide-mb0</link>
      <guid>https://dev.to/samratemily/plugin-admin-menu-developer-guide-mb0</guid>
      <description>&lt;p&gt;This guide explains how the &lt;strong&gt;WeLabs Plugin&lt;/strong&gt; admin menu is built with PHP and React, how settings are saved via the WordPress REST API, and how you can extend it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP&lt;/strong&gt; registers a top-level admin menu and submenus, and renders root containers for React.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; mounts on those containers to render Dashboard, Settings, Analytics, Tools, and Help.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST API&lt;/strong&gt; endpoints handle plugin settings and analytics.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; relies on nonces and capability checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key files
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/AdminMenu.php&lt;/code&gt; – menu registration, enqueue assets, print HTML roots
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/Settings.php&lt;/code&gt; – settings page and script localization
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/REST/*Controller.php&lt;/code&gt; – REST endpoints
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/admin.js&lt;/code&gt; – bootstraps React
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/Components/*&lt;/code&gt; – React components
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Highlights for Reliability
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Menu Registration &amp;amp; Enqueue&lt;/strong&gt; – Only enqueue scripts/styles on plugin pages; localize REST URL, nonce, and current page slug for consistent JS context.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Bootstrapping&lt;/strong&gt; – Check that DOM IDs printed in PHP match IDs queried in JS to avoid silent mount failures.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST API Usage&lt;/strong&gt; – Always sanitize (&lt;code&gt;sanitize_text_field&lt;/code&gt;, &lt;code&gt;absint&lt;/code&gt;) and check capabilities (&lt;code&gt;manage_options&lt;/code&gt;) in controllers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build Process&lt;/strong&gt; – Run &lt;code&gt;npm run build&lt;/code&gt; before pushing; ensure PHP paths point to &lt;code&gt;assets/build/admin/*&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt; – Log REST responses, verify nonces with &lt;code&gt;apiFetch.createNonceMiddleware&lt;/code&gt;, and test on a fresh WP install or local environment.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📄 Full Guide (.md)
&lt;/h2&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;h3&gt;
  
  
  Plugin Admin Menu – Developer Guide
&lt;/h3&gt;

&lt;p&gt;This guide walks you through how the WeLabs Plugin admin menu is built with PHP and powered by React, how settings are saved via the WordPress REST API, and how to extend it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP&lt;/strong&gt; registers a top-level admin menu with multiple submenus and renders "root" containers for React.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; mounts on those root containers and renders pages (Dashboard, Settings, Analytics, Tools, Help).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST API&lt;/strong&gt; endpoints handle read/write of plugin settings and other data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; uses nonces and capability checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Folder highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/AdminMenu.php&lt;/code&gt; – menu registration, enqueue assets, HTML containers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/Settings.php&lt;/code&gt; – classic settings page and script localization&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/REST/SettingsController.php&lt;/code&gt; – settings REST routes (read/update)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/REST/AnalyticsController.php&lt;/code&gt; – analytics REST routes (demo data)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/admin.js&lt;/code&gt; – React bootstrapping for each page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/Components/*&lt;/code&gt; – React components&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1) Register the Admin Menu in PHP
&lt;/h2&gt;

&lt;p&gt;Key file: &lt;code&gt;includes/Admin/AdminMenu.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registers a top-level menu &lt;code&gt;WeLabs Plugin&lt;/code&gt; and submenus &lt;code&gt;Dashboard&lt;/code&gt;, &lt;code&gt;Settings&lt;/code&gt;, &lt;code&gt;Analytics&lt;/code&gt;, &lt;code&gt;Tools&lt;/code&gt;, &lt;code&gt;Help &amp;amp; Support&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enqueues the compiled script/style only on these pages.&lt;/li&gt;
&lt;li&gt;Localizes data (REST URL, nonce, current page) to JS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Important parts to look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;register_admin_menu()&lt;/code&gt; – adds menu and submenus&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enqueue_admin_scripts( $hook )&lt;/code&gt; – enqueues &lt;code&gt;assets/build/admin/script.js&lt;/code&gt; and &lt;code&gt;admin.css&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;render_*_page()&lt;/code&gt; – prints a wrapper with a unique root div (e.g., &lt;code&gt;#welabs-plugin-dashboard&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_current_page_slug()&lt;/code&gt; – helps JS know which submenu is active&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extending:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add another submenu with &lt;code&gt;add_submenu_page( 'welabs-plugin', 'Title', 'Menu', 'manage_options', 'welabs-plugin-new', [ $this, 'render_new_page' ] );&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add a matching &lt;code&gt;render_new_page()&lt;/code&gt; method that outputs a unique root container div for React.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2) Enqueue and Localize Admin Assets
&lt;/h2&gt;

&lt;p&gt;Key files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/AdminMenu.php&lt;/code&gt; (WeLabs menu pages)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/Admin/Settings.php&lt;/code&gt; (classic settings page)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both enqueue the admin script built to &lt;code&gt;assets/build/admin/script.js&lt;/code&gt; and localize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;apiUrl&lt;/code&gt; or &lt;code&gt;apiRoot&lt;/code&gt; – REST base URL&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nonce&lt;/code&gt; – used to authenticate REST requests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;currentPage&lt;/code&gt; – helps JS know which page it's on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nonce is created with &lt;code&gt;wp_create_nonce( 'wp_rest' )&lt;/code&gt; and used in JS via &lt;code&gt;@wordpress/api-fetch&lt;/code&gt; nonce middleware.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3) React Bootstrapping
&lt;/h2&gt;

&lt;p&gt;Key file: &lt;code&gt;src/admin.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configures &lt;code&gt;apiFetch&lt;/code&gt; to use the localized REST nonce and root URL:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`js&lt;br&gt;
import apiFetch from '@wordpress/api-fetch';&lt;/p&gt;

&lt;p&gt;if ( window.welabsSettings ) {&lt;br&gt;
  apiFetch.use( apiFetch.createNonceMiddleware( window.welabsSettings.nonce ) );&lt;br&gt;
  apiFetch.use( apiFetch.createRootURLMiddleware( window.welabsSettings.apiRoot ) );&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mounts React apps to DOM nodes printed by PHP:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`js&lt;br&gt;
const dashboardContainer = document.getElementById( 'welabs-plugin-dashboard' );&lt;br&gt;
if ( dashboardContainer ) { /* render  */ }&lt;/p&gt;

&lt;p&gt;const settingsContainer = document.getElementById( 'CustomizedPluginWithReactSettings' );&lt;br&gt;
if ( settingsContainer ) { /* render  with routes */ }&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Extending:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new component under &lt;code&gt;src/Components/&lt;/code&gt; and mount it to a new root div you print in PHP.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4) Settings REST API (Read/Write)
&lt;/h2&gt;

&lt;p&gt;Key file: &lt;code&gt;includes/Admin/REST/SettingsController.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /customized-plugin-with-react/v1/settings&lt;/code&gt; – fetch current settings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /customized-plugin-with-react/v1/settings&lt;/code&gt; – update settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capability check via &lt;code&gt;current_user_can( 'manage_options' )&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Input sanitized with &lt;code&gt;sanitize_text_field()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example React usage (simplified):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`js&lt;br&gt;
import apiFetch from '@wordpress/api-fetch';&lt;/p&gt;

&lt;p&gt;// Read settings&lt;br&gt;
const settings = await apiFetch( { path: '/customized-plugin-with-react/v1/settings' } );&lt;/p&gt;

&lt;p&gt;// Write settings&lt;br&gt;
await apiFetch( {&lt;br&gt;
  path: '/customized-plugin-with-react/v1/settings',&lt;br&gt;
  method: 'POST',&lt;br&gt;
  data: {&lt;br&gt;
    customized_plugin_with_react_page_title: 'My Title',&lt;br&gt;
    customized_plugin_with_react_product_per_page: '12',&lt;br&gt;
  },&lt;br&gt;
} );&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5) Additional REST (Analytics)
&lt;/h2&gt;

&lt;p&gt;Key file: &lt;code&gt;includes/Admin/REST/AnalyticsController.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Demo route:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /customized-plugin-with-react/v1/analytics?time_range=7|30|90|365&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How to add your own:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new controller in &lt;code&gt;includes/Admin/REST/&lt;/code&gt; following the &lt;code&gt;WP_REST_Controller&lt;/code&gt; pattern.&lt;/li&gt;
&lt;li&gt;Register endpoints in &lt;code&gt;register_routes()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Initialize the controller in &lt;code&gt;includes/CustomizedPluginWithReact.php&lt;/code&gt; → &lt;code&gt;init_classes()&lt;/code&gt; and register in &lt;code&gt;register_rest_route()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  6) Security Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always check capabilities (&lt;code&gt;current_user_can( 'manage_options' )&lt;/code&gt;) for admin actions.&lt;/li&gt;
&lt;li&gt;Use nonces for REST (&lt;code&gt;wp_create_nonce( 'wp_rest' )&lt;/code&gt; + &lt;code&gt;apiFetch.createNonceMiddleware&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Sanitize all incoming data (&lt;code&gt;sanitize_text_field()&lt;/code&gt;, &lt;code&gt;absint()&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;Escape output in PHP (&lt;code&gt;esc_html__&lt;/code&gt;, &lt;code&gt;esc_attr&lt;/code&gt;, &lt;code&gt;esc_url&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7) Build &amp;amp; Assets
&lt;/h2&gt;

&lt;p&gt;Build command (runs &lt;code&gt;@wordpress/scripts&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm run build&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What it produces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS: &lt;code&gt;assets/build/admin/script.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CSS: &lt;code&gt;assets/build/admin.css&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Asset manifest: &lt;code&gt;assets/build/admin/script.asset.php&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ensure PHP points to these files when enqueuing.&lt;/p&gt;




&lt;h2&gt;
  
  
  8) Common Pitfalls &amp;amp; Fixes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"Class not found" – Confirm PSR-4 autoload and namespaces match &lt;code&gt;composer.json&lt;/code&gt; and file paths.&lt;/li&gt;
&lt;li&gt;React not mounting – Verify the root div IDs printed in PHP match &lt;code&gt;document.getElementById(...)&lt;/code&gt; in &lt;code&gt;src/admin.js&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;401/403 on REST – Ensure nonce is localized and &lt;code&gt;apiFetch&lt;/code&gt; nonce middleware is configured; confirm you are logged in and have &lt;code&gt;manage_options&lt;/code&gt; capability.&lt;/li&gt;
&lt;li&gt;Assets not loading – Run &lt;code&gt;npm run build&lt;/code&gt; and confirm &lt;code&gt;assets/build/*&lt;/code&gt; exists; verify enqueue paths.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9) How to Add a New Submenu + React Page (Quick Recipe)
&lt;/h2&gt;

&lt;p&gt;1) PHP – Add submenu and render method in &lt;code&gt;AdminMenu.php&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`php&lt;br&gt;
add_submenu_page(&lt;br&gt;
    'welabs-plugin',&lt;br&gt;
    _&lt;em&gt;( 'My Page', 'customized-plugin-with-react' ),&lt;br&gt;
    _&lt;/em&gt;( 'My Page', 'customized-plugin-with-react' ),&lt;br&gt;
    'manage_options',&lt;br&gt;
    'welabs-plugin-my-page',&lt;br&gt;
    [ $this, 'render_my_page' ]&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;public function render_my_page() {&lt;br&gt;
    ?&amp;gt;&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
        &lt;h1&gt;&amp;lt;?php esc_html_e( 'My Page', 'customized-plugin-with-react' ); ?&amp;gt;&lt;/h1&gt;
&lt;br&gt;
        &lt;br&gt;
    &lt;br&gt;
    &amp;lt;?php&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;

&lt;p&gt;2) React – Create &lt;code&gt;src/Components/MyPage.js&lt;/code&gt; and mount it in &lt;code&gt;src/admin.js&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`js&lt;br&gt;
import MyPage from './Components/MyPage';&lt;/p&gt;

&lt;p&gt;const myPageContainer = document.getElementById( 'welabs-plugin-my-page' );&lt;br&gt;
if ( myPageContainer ) {&lt;br&gt;
  const root = createRoot( myPageContainer );&lt;br&gt;
  root.render(  );&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3) Build assets and test:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm run build&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it! You now have a new submenu powered by React with REST-ready plumbing.&lt;br&gt;
`&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>react</category>
      <category>frontend</category>
    </item>
    <item>
      <title>WP_List_Table in WordPress</title>
      <dc:creator>MD. Samrat Hossen</dc:creator>
      <pubDate>Mon, 26 May 2025 08:36:00 +0000</pubDate>
      <link>https://dev.to/samratemily/wplisttable-in-wordpress-1nja</link>
      <guid>https://dev.to/samratemily/wplisttable-in-wordpress-1nja</guid>
      <description>&lt;p&gt;Using WP_List_Table To Render Custom Tables in the WordPress Admin&lt;br&gt;
To display a custom table in the WordPress admin using WP_List_TableFollow this structured approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a Custom Menu to the Admin
Start by registering a custom menu using the add_menu_page() or add_submenu_page() function. This will create a new page in the admin panel where your table will be displayed.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function add_a_menu_for_wp_list() {
    add_menu_page(
        'Custom Table',
        'Custom Table',
        'manage_options',
        'my-custom-table',
        [ $this, 'render_my_custom_admin_table']
    );
}

function render_my_custom_admin_table() {
    $table = new MyCustomListTable();
    $table-&amp;gt;prepare_items();
    echo '&amp;lt;div class="wrap"&amp;gt;';
    echo '&amp;lt;h1 class="wp-heading-inline"&amp;gt; WP List&amp;lt;/h1&amp;gt;';
    echo '&amp;lt;form method="post"&amp;gt;';
    $table-&amp;gt;display();
    echo '&amp;lt;/form&amp;gt;';
    echo '&amp;lt;/div&amp;gt;';
}
add_action( 'admin_menu', array( $this, 'add_a_menu_for_wp_list' ) );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Render the Table on the Menu Page
Inside the callback function for the admin menu, do the following:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create an instance of your custom table class (which extends WP_List_Table).&lt;br&gt;
&lt;code&gt;Call the prepare_items()&lt;/code&gt; method to prepare the data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Call the display()&lt;/code&gt; method to render the table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$table = new \WeLabs\Demo\MyCustomListTable();
$table-&amp;gt;prepare_items();
$table-&amp;gt;display();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Implement the prepare_items() Method
Inside your custom table class, the prepare_items() method is responsible for:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fetching data (e.g., from the database).&lt;br&gt;
Setting up columns, hidden columns, and sortable columns.&lt;br&gt;
Assigning the result to $this-&amp;gt;items.&lt;br&gt;
$this-&amp;gt;_column_headers = array( $this-&amp;gt;get_columns(), array(), array() );&lt;br&gt;
$this-&amp;gt;items = $data;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define Columns with get_columns()
The get_columns() method returns an associative array of columns where:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key is the column slug.&lt;br&gt;
The value is the column label.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function get_columns() {
    return array(
        'name'  =&amp;gt; esc_html__( 'Name', 'domain_name' ),
        'email' =&amp;gt; esc_html__( 'Email', 'domain_name' ),
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Render Individual Columns
For each column, define a method column_{column_name}($item) to control how data should be rendered.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function column_name( $item ) {
    return esc_html( $item-&amp;gt;name );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full code of the instance that extends WP_List_Table :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace Samrat\Demo;

if ( ! class_exists( 'WP_List_Table' ) ) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

use WP_List_Table;

class MyCustomListTable extends WP_List_Table {

    public function __construct() {
        parent::__construct( array(
            'singular' =&amp;gt; __( 'Item', 'domain_name' ),
            'plural'   =&amp;gt; __( 'Items', 'domain_name' ),
            'ajax'     =&amp;gt; false,
        ) );
    }

    /**
     * Define the columns displayed in the table.
     *
     * @return array
     */
    public function get_columns() {
        return array(
            'name'  =&amp;gt; esc_html__( 'Name', 'domain_name' ),
            'email' =&amp;gt; esc_html__( 'Email', 'domain_name' ),
        );
    }

    /**
     * Render the Name column.
     *
     * @param object $item
     * @return string
     */
    public function column_name( $item ) {
        return esc_html( $item-&amp;gt;name );
    }

    /**
     * Render the Email column.
     *
     * @param object $item
     * @return string
     */
    public function column_email( $item ) {
        return esc_html( $item-&amp;gt;email );
    }

    /**
     * Prepare table data, columns, and pagination.
     */
    public function prepare_items() {
        global $wpdb;
        $table_name = $wpdb-&amp;gt;prefix . 'custom_form';

        $data = $wpdb-&amp;gt;get_results( "SELECT * FROM {$table_name} ORDER BY created_at DESC" );

        // Define column headers
        $columns  = $this-&amp;gt;get_columns();
        $hidden   = array();
        $sortable = array(); // Add sortable columns if needed

        $this-&amp;gt;_column_headers = array( $columns, $hidden, $sortable );

        $this-&amp;gt;items = $data;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhowqqegsou7ggmtgis3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhowqqegsou7ggmtgis3.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading this article. :)&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
