<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:content="http://purl.org/rss/1.0/modules/content/">

  <channel>

    <title>Wavesdream</title>

    <link>https://wavesdream.com/</link>

    <description>My Notes</description>

    <language>en-us</language>

    <atom:link
      href="https://wavesdream.com/feed.xml"
      rel="self"
      type="application/rss+xml" />

    
    
    

    
    
    

    
    

    

    <item>

      <title>HTML Coding Guidelines for SEO, Accessibility, Schema &amp; WordPress</title>

      <link>https://wavesdream.com/posts/html-coding-guidelines-for-schema/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/html-coding-guidelines-for-schema/</guid>

      <pubDate>Sat, 05 Sep 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>If you are building HTML pages that will later be converted into a WordPress theme, it is important to structure the HTML correctly from the beginning.</p>
<p>The goal should be:</p>
<blockquote>
<p><strong>Semantic HTML + Accessibility + SEO-friendly structure + Schema.org readiness + Clean WordPress conversion</strong></p></blockquote>
<p>Below are 33 recommended practices to follow when coding your HTML pages.</p>
<hr>
<h3 id="1-overall-html-structure">1. Overall HTML Structure</h3>
<p>Start each page with valid HTML5, a language attribute, a proper <code>&lt;head&gt;</code>, and semantic <code>&lt;header&gt;</code>, <code>&lt;main&gt;</code>, and <code>&lt;footer&gt;</code> areas.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>If you are building HTML pages that will later be converted into a WordPress theme, it is important to structure the HTML correctly from the beginning.</p>
<p>The goal should be:</p>
<blockquote>
<p><strong>Semantic HTML + Accessibility + SEO-friendly structure + Schema.org readiness + Clean WordPress conversion</strong></p></blockquote>
<p>Below are 33 recommended practices to follow when coding your HTML pages.</p>
<hr>
<h3 id="1-overall-html-structure">1. Overall HTML Structure</h3>
<p>Start each page with valid HTML5, a language attribute, a proper <code>&lt;head&gt;</code>, and semantic <code>&lt;header&gt;</code>, <code>&lt;main&gt;</code>, and <code>&lt;footer&gt;</code> areas.</p>
<p>A basic structure should look like:</p>
<pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;

    &lt;title&gt;Page Title | Website Name&lt;/title&gt;
    &lt;meta name=&#34;description&#34; content=&#34;Clear page description.&#34;&gt;
    &lt;link rel=&#34;canonical&#34; href=&#34;https://example.com/page/&#34;&gt;
&lt;/head&gt;

&lt;body&gt;

    &lt;header&gt;
        &lt;!-- Logo + navigation --&gt;
    &lt;/header&gt;

    &lt;main&gt;
        &lt;!-- Main page content --&gt;
    &lt;/main&gt;

    &lt;footer&gt;
        &lt;!-- Footer content --&gt;
    &lt;/footer&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre><hr>
<h3 id="2-use-semantic-html5-tags">2. Use Semantic HTML5 Tags</h3>
<p>Prefer semantic HTML elements where they accurately describe the content.</p>
<p>Common semantic elements include:</p>
<ul>
<li><code>&lt;header&gt;</code></li>
<li><code>&lt;nav&gt;</code></li>
<li><code>&lt;main&gt;</code></li>
<li><code>&lt;section&gt;</code></li>
<li><code>&lt;article&gt;</code></li>
<li><code>&lt;aside&gt;</code></li>
<li><code>&lt;footer&gt;</code></li>
<li><code>&lt;figure&gt;</code></li>
<li><code>&lt;figcaption&gt;</code></li>
</ul>
<p>Instead of making everything a <code>&lt;div&gt;</code>, use the appropriate semantic element whenever possible.</p>
<h3 id="avoid">Avoid</h3>
<pre tabindex="0"><code>&lt;div class=&#34;header&#34;&gt;
    ...
&lt;/div&gt;

&lt;div class=&#34;navigation&#34;&gt;
    ...
&lt;/div&gt;

&lt;div class=&#34;content&#34;&gt;
    ...
&lt;/div&gt;

&lt;div class=&#34;footer&#34;&gt;
    ...
&lt;/div&gt;
</code></pre><h3 id="prefer">Prefer</h3>
<pre tabindex="0"><code>&lt;header&gt;
    ...
&lt;/header&gt;

&lt;nav&gt;
    ...
&lt;/nav&gt;

&lt;main&gt;
    ...
&lt;/main&gt;

&lt;footer&gt;
    ...
&lt;/footer&gt;
</code></pre><hr>
<h3 id="3-header-structure">3. Header Structure</h3>
<p>Use <code>&lt;header&gt;</code> for site branding and introductory content.</p>
<p>Use a real <code>&lt;a&gt;</code> element for the logo link and <code>&lt;nav&gt;</code> for navigation.</p>
<pre tabindex="0"><code>&lt;header class=&#34;site-header&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;

        &lt;a href=&#34;/&#34; class=&#34;site-logo&#34;&gt;
            &lt;img
                src=&#34;images/logo.png&#34;
                alt=&#34;Company Name&#34;
                width=&#34;180&#34;
                height=&#34;60&#34;&gt;
        &lt;/a&gt;

        &lt;nav
            class=&#34;main-navigation&#34;
            aria-label=&#34;Main navigation&#34;&gt;

            &lt;ul&gt;
                &lt;li&gt;
                    &lt;a href=&#34;/&#34;&gt;Home&lt;/a&gt;
                &lt;/li&gt;

                &lt;li&gt;
                    &lt;a href=&#34;/about/&#34;&gt;About&lt;/a&gt;
                &lt;/li&gt;

                &lt;li&gt;
                    &lt;a href=&#34;/services/&#34;&gt;Services&lt;/a&gt;
                &lt;/li&gt;

                &lt;li&gt;
                    &lt;a href=&#34;/contact/&#34;&gt;Contact&lt;/a&gt;
                &lt;/li&gt;
            &lt;/ul&gt;

        &lt;/nav&gt;

    &lt;/div&gt;

&lt;/header&gt;
</code></pre><h3 id="avoid-1">Avoid</h3>
<pre tabindex="0"><code>&lt;div class=&#34;logo&#34;&gt;
    &lt;img src=&#34;logo.png&#34;&gt;
&lt;/div&gt;

&lt;div class=&#34;menu&#34;&gt;
    &lt;div onclick=&#34;location.href=&#39;about.html&#39;&#34;&gt;
        About
    &lt;/div&gt;
&lt;/div&gt;
</code></pre><p>Use actual <code>&lt;a&gt;</code> links rather than clickable <code>&lt;div&gt;</code> elements.</p>
<hr>
<h3 id="4-main-content">4. Main Content</h3>
<p>Use one primary <code>&lt;main&gt;</code> element for the page&rsquo;s main content.</p>
<pre tabindex="0"><code>&lt;main&gt;

    &lt;section class=&#34;hero&#34;&gt;

        &lt;div class=&#34;container&#34;&gt;

            &lt;h1&gt;Professional Web Development Services&lt;/h1&gt;

            &lt;p&gt;
                We create fast and scalable websites for businesses.
            &lt;/p&gt;

            &lt;a href=&#34;/contact/&#34; class=&#34;btn&#34;&gt;
                Get Started
            &lt;/a&gt;

        &lt;/div&gt;

    &lt;/section&gt;

    &lt;section class=&#34;services&#34;&gt;

        &lt;div class=&#34;container&#34;&gt;

            &lt;h2&gt;Our Services&lt;/h2&gt;

            &lt;!-- Service content --&gt;

        &lt;/div&gt;

    &lt;/section&gt;

&lt;/main&gt;
</code></pre><h3 id="avoid-2">Avoid</h3>
<pre tabindex="0"><code>&lt;div id=&#34;main&#34;&gt;
    ...
&lt;/div&gt;
</code></pre><p>when <code>&lt;main&gt;</code> is appropriate.</p>
<hr>
<h3 id="5-maintain-a-proper-heading-hierarchy">5. Maintain a Proper Heading Hierarchy</h3>
<p>Maintain a logical:</p>
<p><strong>H1 → H2 → H3</strong></p>
<p>structure.</p>
<p>For example:</p>
<pre tabindex="0"><code>&lt;h1&gt;Digital Marketing Services&lt;/h1&gt;

&lt;h2&gt;Our Services&lt;/h2&gt;

&lt;h3&gt;SEO&lt;/h3&gt;

&lt;h3&gt;Social Media Marketing&lt;/h3&gt;

&lt;h3&gt;Google Ads&lt;/h3&gt;

&lt;h2&gt;Why Choose Us&lt;/h2&gt;

&lt;h3&gt;Experienced Team&lt;/h3&gt;

&lt;h3&gt;Transparent Pricing&lt;/h3&gt;
</code></pre><p>Do not choose heading levels merely because you want a particular font size. Use CSS to control visual appearance.</p>
<h3 id="avoid-3">Avoid</h3>
<pre tabindex="0"><code>&lt;h1&gt;Digital Marketing Services&lt;/h1&gt;

&lt;h4&gt;Our Services&lt;/h4&gt;

&lt;h2&gt;SEO&lt;/h2&gt;

&lt;h6&gt;Google Ads&lt;/h6&gt;
</code></pre><hr>
<h3 id="6-use-a-clear-primary-h1">6. Use a Clear Primary H1</h3>
<p>For normal pages, use one clear primary H1 that describes the page.</p>
<pre tabindex="0"><code>&lt;h1&gt;Web Development Services&lt;/h1&gt;
</code></pre><p>Avoid having multiple unrelated H1 headings simply because you want several large headings.</p>
<p>Use CSS when you need to make other headings visually large.</p>
<hr>
<h3 id="7-use-sections-correctly">7. Use Sections Correctly</h3>
<p>Use <code>&lt;section&gt;</code> for meaningful thematic sections.</p>
<pre tabindex="0"><code>&lt;section class=&#34;about&#34;&gt;

    &lt;h2&gt;About Our Company&lt;/h2&gt;

    &lt;p&gt;
        Company information goes here.
    &lt;/p&gt;

&lt;/section&gt;

&lt;section class=&#34;services&#34;&gt;

    &lt;h2&gt;Our Services&lt;/h2&gt;

    &lt;p&gt;
        Service information goes here.
    &lt;/p&gt;

&lt;/section&gt;
</code></pre><p>Avoid using <code>&lt;section&gt;</code> only as an arbitrary styling wrapper.</p>
<hr>
<h3 id="8-use-articles-for-independent-content">8. Use Articles for Independent Content</h3>
<p>Use <code>&lt;article&gt;</code> for content that can stand on its own.</p>
<p>Examples include:</p>
<ul>
<li>Blog posts</li>
<li>News articles</li>
<li>Individual posts</li>
<li>Self-contained content cards</li>
</ul>
<p>Example:</p>
<pre tabindex="0"><code>&lt;article class=&#34;blog-card&#34;&gt;

    &lt;figure&gt;

        &lt;img
            src=&#34;images/blog.jpg&#34;
            alt=&#34;WordPress development&#34;
            width=&#34;800&#34;
            height=&#34;500&#34;&gt;

    &lt;/figure&gt;

    &lt;div class=&#34;blog-content&#34;&gt;

        &lt;h2&gt;
            &lt;a href=&#34;/blog/wordpress-development/&#34;&gt;
                How to Build a WordPress Website
            &lt;/a&gt;
        &lt;/h2&gt;

        &lt;p&gt;
            Learn the basic steps involved in creating a WordPress website.
        &lt;/p&gt;

    &lt;/div&gt;

&lt;/article&gt;
</code></pre><hr>
<h3 id="9-use-images-correctly">9. Use Images Correctly</h3>
<p>Informative images should have meaningful <code>alt</code> text.</p>
<pre tabindex="0"><code>&lt;img
    src=&#34;images/team.jpg&#34;
    alt=&#34;Web development team working in office&#34;
    width=&#34;800&#34;
    height=&#34;600&#34;&gt;
</code></pre><p>For decorative images:</p>
<pre tabindex="0"><code>&lt;img
    src=&#34;images/shape.svg&#34;
    alt=&#34;&#34;
    aria-hidden=&#34;true&#34;&gt;
</code></pre><p>Where practical, specify image dimensions:</p>
<pre tabindex="0"><code>width=&#34;800&#34;
height=&#34;600&#34;
</code></pre><p>This can help reduce layout shifting.</p>
<hr>
<h3 id="10-write-useful-alt-text">10. Write Useful Alt Text</h3>
<p>Alt text should describe the actual image.</p>
<h3 id="good">Good</h3>
<pre tabindex="0"><code>&lt;img
    src=&#34;web-development.jpg&#34;
    alt=&#34;Web developer working on a website&#34;&gt;
</code></pre><h3 id="bad">Bad</h3>
<pre tabindex="0"><code>&lt;img
    src=&#34;web-development.jpg&#34;
    alt=&#34;best web development company web development services website development company&#34;&gt;
</code></pre><p>Do not use alt text as a place for keyword stuffing.</p>
<hr>
<h3 id="11-use-descriptive-links">11. Use Descriptive Links</h3>
<p>Link text should tell users where the link goes.</p>
<h3 id="good-1">Good</h3>
<pre tabindex="0"><code>&lt;a href=&#34;/wordpress-development/&#34;&gt;
    WordPress Development Services
&lt;/a&gt;
</code></pre><h3 id="avoid-4">Avoid</h3>
<pre tabindex="0"><code>&lt;a href=&#34;/wordpress-development/&#34;&gt;
    Click Here
&lt;/a&gt;
</code></pre><p>Also avoid using JavaScript and clickable <code>&lt;div&gt;</code> elements instead of normal links.</p>
<hr>
<h3 id="12-use-buttons-and-links-correctly">12. Use Buttons and Links Correctly</h3>
<p>Use <code>&lt;a&gt;</code> for navigation:</p>
<pre tabindex="0"><code>&lt;a href=&#34;/contact/&#34;&gt;
    Contact Us
&lt;/a&gt;
</code></pre><p>Use <code>&lt;button&gt;</code> for actions:</p>
<pre tabindex="0"><code>&lt;button type=&#34;submit&#34;&gt;
    Submit
&lt;/button&gt;
</code></pre><p>For opening a modal:</p>
<pre tabindex="0"><code>&lt;button type=&#34;button&#34;&gt;
    View Details
&lt;/button&gt;
</code></pre><p>A navigation link and a UI action are not the same thing.</p>
<hr>
<h3 id="13-build-accessible-forms">13. Build Accessible Forms</h3>
<p>Associate form inputs with proper <code>&lt;label&gt;</code> elements.</p>
<pre tabindex="0"><code>&lt;form&gt;

    &lt;div class=&#34;form-group&#34;&gt;

        &lt;label for=&#34;name&#34;&gt;
            Name
        &lt;/label&gt;

        &lt;input
            type=&#34;text&#34;
            id=&#34;name&#34;
            name=&#34;name&#34;
            autocomplete=&#34;name&#34;
            required&gt;

    &lt;/div&gt;

    &lt;div class=&#34;form-group&#34;&gt;

        &lt;label for=&#34;email&#34;&gt;
            Email Address
        &lt;/label&gt;

        &lt;input
            type=&#34;email&#34;
            id=&#34;email&#34;
            name=&#34;email&#34;
            autocomplete=&#34;email&#34;
            required&gt;

    &lt;/div&gt;

    &lt;button type=&#34;submit&#34;&gt;
        Submit
    &lt;/button&gt;

&lt;/form&gt;
</code></pre><p>Do not rely on placeholder text as a replacement for labels.</p>
<hr>
<h3 id="14-structure-navigation-properly">14. Structure Navigation Properly</h3>
<p>Use <code>&lt;nav&gt;</code> for navigation areas.</p>
<pre tabindex="0"><code>&lt;nav aria-label=&#34;Main navigation&#34;&gt;
    ...
&lt;/nav&gt;
</code></pre><p>If there are multiple navigation areas, give them useful accessible labels.</p>
<p>For example:</p>
<pre tabindex="0"><code>&lt;nav aria-label=&#34;Main navigation&#34;&gt;
    ...
&lt;/nav&gt;

&lt;nav aria-label=&#34;Footer navigation&#34;&gt;
    ...
&lt;/nav&gt;
</code></pre><hr>
<h3 id="15-use-lists-for-lists">15. Use Lists for Lists</h3>
<p>If content is actually a list, use <code>&lt;ul&gt;</code> or <code>&lt;ol&gt;</code>.</p>
<h3 id="unordered-list">Unordered list</h3>
<pre tabindex="0"><code>&lt;ul&gt;
    &lt;li&gt;Web Development&lt;/li&gt;
    &lt;li&gt;SEO&lt;/li&gt;
    &lt;li&gt;Digital Marketing&lt;/li&gt;
&lt;/ul&gt;
</code></pre><h3 id="ordered-list">Ordered list</h3>
<pre tabindex="0"><code>&lt;ol&gt;
    &lt;li&gt;Choose a plan&lt;/li&gt;
    &lt;li&gt;Submit your requirements&lt;/li&gt;
    &lt;li&gt;Start development&lt;/li&gt;
&lt;/ol&gt;
</code></pre><p>Avoid simulating lists with repeated <code>&lt;div&gt;</code> elements.</p>
<hr>
<h3 id="16-use-tables-for-tabular-data">16. Use Tables for Tabular Data</h3>
<p>Use <code>&lt;table&gt;</code> when presenting actual tabular information.</p>
<pre tabindex="0"><code>&lt;table&gt;

    &lt;caption&gt;Pricing Plans&lt;/caption&gt;

    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th scope=&#34;col&#34;&gt;Plan&lt;/th&gt;
            &lt;th scope=&#34;col&#34;&gt;Price&lt;/th&gt;
            &lt;th scope=&#34;col&#34;&gt;Users&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;

    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;Basic&lt;/td&gt;
            &lt;td&gt;₹999&lt;/td&gt;
            &lt;td&gt;5&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;

&lt;/table&gt;
</code></pre><p>Do not use tables for page layout.</p>
<hr>
<h3 id="17-use-strong-and-emphasis-semantically">17. Use Strong and Emphasis Semantically</h3>
<p>Use <code>&lt;strong&gt;</code> when something is important:</p>
<pre tabindex="0"><code>&lt;strong&gt;Important:&lt;/strong&gt; Please submit the form.
</code></pre><p>Use <code>&lt;em&gt;</code> when something needs emphasis:</p>
<pre tabindex="0"><code>&lt;em&gt;Limited time offer.&lt;/em&gt;
</code></pre><p>If the purpose is purely visual styling, use CSS instead.</p>
<hr>
<h3 id="18-do-not-use-br-for-layout">18. Do Not Use <code>&lt;br&gt;</code> for Layout</h3>
<p>Avoid using repeated <code>&lt;br&gt;</code> elements to create spacing or control page layout.</p>
<h3 id="avoid-5">Avoid</h3>
<pre tabindex="0"><code>&lt;h1&gt;
    Web Development&lt;br&gt;
    Services
&lt;/h1&gt;
</code></pre><p>when the line break is only for visual presentation.</p>
<p>Use CSS instead:</p>
<pre tabindex="0"><code>.hero-title {
    max-width: 700px;
}
</code></pre><p>Use <code>&lt;br&gt;</code> when an actual content line break is meaningful.</p>
<hr>
<h3 id="19-avoid-excessive-inline-css">19. Avoid Excessive Inline CSS</h3>
<p>Avoid putting large amounts of CSS directly into HTML.</p>
<h3 id="avoid-6">Avoid</h3>
<pre tabindex="0"><code>&lt;div style=&#34;color:red; margin-top:20px;&#34;&gt;
</code></pre><h3 id="prefer-1">Prefer</h3>
<pre tabindex="0"><code>&lt;div class=&#34;alert&#34;&gt;
</code></pre><p>and:</p>
<pre tabindex="0"><code>.alert {
    color: red;
    margin-top: 20px;
}
</code></pre><p>This will make your eventual WordPress theme easier to maintain.</p>
<hr>
<h3 id="20-avoid-excessive-div-nesting">20. Avoid Excessive <code>&lt;div&gt;</code> Nesting</h3>
<p>Avoid unnecessary HTML layers such as:</p>
<pre tabindex="0"><code>&lt;div&gt;
    &lt;div&gt;
        &lt;div&gt;
            &lt;div&gt;
                &lt;div&gt;
                    &lt;h2&gt;Services&lt;/h2&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</code></pre><p>Use only the wrappers needed for:</p>
<ul>
<li>Layout</li>
<li>Components</li>
<li>Styling</li>
<li>Actual semantic structure</li>
</ul>
<p>For example:</p>
<pre tabindex="0"><code>&lt;section class=&#34;services&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;

        &lt;h2&gt;Our Services&lt;/h2&gt;

        &lt;div class=&#34;services-grid&#34;&gt;
            ...
        &lt;/div&gt;

    &lt;/div&gt;

&lt;/section&gt;
</code></pre><hr>
<h3 id="21-always-use-the-lang-attribute">21. Always Use the <code>lang</code> Attribute</h3>
<p>Always declare the document language.</p>
<pre tabindex="0"><code>&lt;html lang=&#34;en&#34;&gt;
</code></pre><p>For Bengali:</p>
<pre tabindex="0"><code>&lt;html lang=&#34;bn&#34;&gt;
</code></pre><p>For Hindi:</p>
<pre tabindex="0"><code>&lt;html lang=&#34;hi&#34;&gt;
</code></pre><p>Use the correct language for the page.</p>
<hr>
<h3 id="22-use-a-proper-canonical-url">22. Use a Proper Canonical URL</h3>
<p>Indexable pages should generally have an appropriate canonical URL.</p>
<pre tabindex="0"><code>&lt;link
    rel=&#34;canonical&#34;
    href=&#34;https://example.com/about/&#34;&gt;
</code></pre><p>Do not hard-code the same canonical URL on every page.</p>
<p>When converting the HTML into WordPress, canonical URLs should ideally be generated dynamically or managed through your SEO setup.</p>
<hr>
<h3 id="23-use-schemaorg-json-ld">23. Use Schema.org JSON-LD</h3>
<p>Schema markup helps search engines understand what your page and its content represent.</p>
<p>For example:</p>
<pre tabindex="0"><code>&lt;script type=&#34;application/ld+json&#34;&gt;
{
    &#34;@context&#34;: &#34;https://schema.org&#34;,
    &#34;@type&#34;: &#34;Organization&#34;,
    &#34;name&#34;: &#34;ABC Company&#34;,
    &#34;url&#34;: &#34;https://example.com/&#34;
}
&lt;/script&gt;
</code></pre><p>For a modern website, JSON-LD is generally the cleanest approach.</p>
<p>Possible Schema types include:</p>
<ul>
<li>Organization</li>
<li>LocalBusiness</li>
<li>WebSite</li>
<li>WebPage</li>
<li>Service</li>
<li>Product</li>
<li>Article</li>
<li>BlogPosting</li>
<li>BreadcrumbList</li>
<li>Event</li>
<li>Course</li>
<li>Recipe</li>
</ul>
<p>Do not add every Schema type to every page. Use structured data that accurately represents the actual page.</p>
<p>When converting to WordPress, values such as company name, URL, logo, author, dates, product prices, availability, etc. should be generated dynamically where appropriate.</p>
<hr>
<h3 id="24-structure-breadcrumbs-properly">24. Structure Breadcrumbs Properly</h3>
<p>If your website has breadcrumbs, use navigation markup.</p>
<pre tabindex="0"><code>&lt;nav aria-label=&#34;Breadcrumb&#34;&gt;

    &lt;ol class=&#34;breadcrumbs&#34;&gt;

        &lt;li&gt;
            &lt;a href=&#34;/&#34;&gt;Home&lt;/a&gt;
        &lt;/li&gt;

        &lt;li&gt;
            &lt;a href=&#34;/services/&#34;&gt;Services&lt;/a&gt;
        &lt;/li&gt;

        &lt;li aria-current=&#34;page&#34;&gt;
            Web Development
        &lt;/li&gt;

    &lt;/ol&gt;

&lt;/nav&gt;
</code></pre><p>You can later generate corresponding <code>BreadcrumbList</code> Schema in WordPress.</p>
<hr>
<h3 id="25-structure-blog--article-pages-properly">25. Structure Blog / Article Pages Properly</h3>
<p>A blog post can use:</p>
<pre tabindex="0"><code>&lt;main&gt;

    &lt;article class=&#34;single-post&#34;&gt;

        &lt;header class=&#34;post-header&#34;&gt;

            &lt;h1&gt;How to Build a WordPress Website&lt;/h1&gt;

            &lt;p&gt;
                Published on
                &lt;time datetime=&#34;2026-09-03&#34;&gt;
                    September 3, 2026
                &lt;/time&gt;
            &lt;/p&gt;

        &lt;/header&gt;

        &lt;figure&gt;

            &lt;img
                src=&#34;images/wordpress.jpg&#34;
                alt=&#34;WordPress website development&#34;
                width=&#34;1200&#34;
                height=&#34;675&#34;&gt;

        &lt;/figure&gt;

        &lt;div class=&#34;post-content&#34;&gt;

            &lt;p&gt;...&lt;/p&gt;

            &lt;h2&gt;Getting Started&lt;/h2&gt;

            &lt;p&gt;...&lt;/p&gt;

            &lt;h2&gt;Choosing a Theme&lt;/h2&gt;

            &lt;p&gt;...&lt;/p&gt;

        &lt;/div&gt;

    &lt;/article&gt;

&lt;/main&gt;
</code></pre><p>This structure is also well suited for conversion into WordPress&rsquo;s <code>single.php</code> template.</p>
<hr>
<h3 id="26-use-the-time-element">26. Use the <code>&lt;time&gt;</code> Element</h3>
<p>Use <code>&lt;time&gt;</code> for dates and times.</p>
<pre tabindex="0"><code>&lt;time datetime=&#34;2026-09-03&#34;&gt;
    September 3, 2026
&lt;/time&gt;
</code></pre><p>For date and time:</p>
<pre tabindex="0"><code>&lt;time datetime=&#34;2026-09-03T18:30&#34;&gt;
    September 3, 2026 at 6:30 PM
&lt;/time&gt;
</code></pre><p>This is useful for:</p>
<ul>
<li>Blog publication dates</li>
<li>Event dates</li>
<li>Updated dates</li>
<li>Appointment/event times</li>
</ul>
<hr>
<h3 id="27-structure-hero-sections-properly">27. Structure Hero Sections Properly</h3>
<p>A hero section should contain meaningful content rather than just visual elements.</p>
<pre tabindex="0"><code>&lt;section class=&#34;hero&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;

        &lt;div class=&#34;hero-content&#34;&gt;

            &lt;p class=&#34;eyebrow&#34;&gt;
                Professional Web Solutions
            &lt;/p&gt;

            &lt;h1&gt;
                Build a Better Website for Your Business
            &lt;/h1&gt;

            &lt;p&gt;
                We design and develop fast, modern websites.
            &lt;/p&gt;

            &lt;div class=&#34;hero-actions&#34;&gt;

                &lt;a href=&#34;/contact/&#34; class=&#34;btn&#34;&gt;
                    Get Started
                &lt;/a&gt;

                &lt;a href=&#34;/services/&#34; class=&#34;btn btn-secondary&#34;&gt;
                    Explore Services
                &lt;/a&gt;

            &lt;/div&gt;

        &lt;/div&gt;

    &lt;/div&gt;

&lt;/section&gt;
</code></pre><p>Keep visual styling separate from the semantic HTML structure.</p>
<hr>
<h3 id="28-structure-the-footer-properly">28. Structure the Footer Properly</h3>
<p>Use <code>&lt;footer&gt;</code> for site-wide footer content.</p>
<pre tabindex="0"><code>&lt;footer class=&#34;site-footer&#34;&gt;

    &lt;div class=&#34;container&#34;&gt;

        &lt;div class=&#34;footer-column&#34;&gt;

            &lt;h2&gt;Company&lt;/h2&gt;

            &lt;ul&gt;
                &lt;li&gt;
                    &lt;a href=&#34;/about/&#34;&gt;About Us&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&#34;/services/&#34;&gt;Services&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&#34;/contact/&#34;&gt;Contact&lt;/a&gt;
                &lt;/li&gt;
            &lt;/ul&gt;

        &lt;/div&gt;

        &lt;div class=&#34;footer-column&#34;&gt;

            &lt;h2&gt;Contact&lt;/h2&gt;

            &lt;address&gt;
                ABC Technologies&lt;br&gt;
                Kolkata, West Bengal, India
            &lt;/address&gt;

        &lt;/div&gt;

    &lt;/div&gt;

&lt;/footer&gt;
</code></pre><p>Use <code>&lt;address&gt;</code> when providing genuine contact information.</p>
<hr>
<h3 id="29-build-accessible-mobile-menus">29. Build Accessible Mobile Menus</h3>
<p>Do not create a mobile menu button using a clickable <code>&lt;div&gt;</code>.</p>
<h3 id="avoid-7">Avoid</h3>
<pre tabindex="0"><code>&lt;div onclick=&#34;toggleMenu()&#34;&gt;
    ☰
&lt;/div&gt;
</code></pre><h3 id="prefer-2">Prefer</h3>
<pre tabindex="0"><code>&lt;button
    type=&#34;button&#34;
    class=&#34;menu-toggle&#34;
    aria-label=&#34;Open menu&#34;
    aria-expanded=&#34;false&#34;
    aria-controls=&#34;main-menu&#34;&gt;

    &lt;span aria-hidden=&#34;true&#34;&gt;☰&lt;/span&gt;

&lt;/button&gt;
</code></pre><p>JavaScript can update <code>aria-expanded</code> when the menu opens and closes.</p>
<hr>
<h3 id="30-do-not-hide-important-seo-content">30. Do Not Hide Important SEO Content</h3>
<p>Do not create content specifically for search engines and hide it from users.</p>
<p>Avoid using hidden content such as:</p>
<pre tabindex="0"><code>.hidden-seo-content {
    display: none;
}
</code></pre><p>when the purpose is to manipulate search engine rankings.</p>
<p>Your structured data should also describe genuine page content.</p>
<hr>
<h3 id="31-avoid-keyword-stuffing">31. Avoid Keyword Stuffing</h3>
<p>Do not repeat keywords unnaturally in:</p>
<ul>
<li>H1/H2 headings</li>
<li>Paragraphs</li>
<li>Links</li>
<li>Image alt text</li>
<li>Meta descriptions</li>
<li>Schema</li>
<li>URLs</li>
</ul>
<h3 id="bad-1">Bad</h3>
<pre tabindex="0"><code>&lt;h1&gt;
    Best Web Development Company in Kolkata - Best Website Development
    Company Kolkata - Web Developer Kolkata
&lt;/h1&gt;
</code></pre><h3 id="better">Better</h3>
<pre tabindex="0"><code>&lt;h1&gt;
    Web Development Services in Kolkata
&lt;/h1&gt;
</code></pre><p>Write useful content for visitors first.</p>
<hr>
<h3 id="32-keep-schema-data-accurate">32. Keep Schema Data Accurate</h3>
<p>Never invent structured data.</p>
<p>For example, do not add fake ratings:</p>
<pre tabindex="0"><code>&#34;aggregateRating&#34;: {
    &#34;ratingValue&#34;: &#34;5&#34;,
    &#34;reviewCount&#34;: &#34;500&#34;
}
</code></pre><p>unless the ratings and reviews actually exist and meet the applicable structured-data requirements.</p>
<p>Likewise, Schema should not contain incorrect:</p>
<ul>
<li>Prices</li>
<li>Product availability</li>
<li>Reviews</li>
<li>Ratings</li>
<li>Business information</li>
<li>Dates</li>
<li>Authors</li>
</ul>
<p><strong>Schema should describe the real page, not manipulate search engines.</strong></p>
<hr>
<h3 id="33-prepare-the-html-for-wordpress-conversion">33. Prepare the HTML for WordPress Conversion</h3>
<p>Since your workflow is:</p>
<p><strong>HTML → WordPress Theme</strong></p>
<p>build your HTML in modular components.</p>
<p>A good HTML structure might be:</p>
<pre tabindex="0"><code>HTML
│
├── Header
│   ├── Logo
│   └── Navigation
│
├── Main
│   ├── Hero
│   ├── Content Sections
│   ├── Services
│   ├── Testimonials
│   ├── FAQ
│   └── CTA
│
└── Footer
</code></pre><p>This can later map naturally to a WordPress theme:</p>
<pre tabindex="0"><code>WordPress Theme
│
├── header.php
├── footer.php
├── front-page.php
├── page.php
├── single.php
├── archive.php
├── 404.php
│
├── template-parts/
│   ├── hero.php
│   ├── services.php
│   ├── testimonials.php
│   └── faq.php
│
├── assets/
│   ├── css/
│   ├── js/
│   └── images/
│
└── functions.php
</code></pre><p>Avoid hard-coding values that will later need to come from WordPress.</p>
<p>Values such as these should eventually become dynamic:</p>
<ul>
<li>Page title</li>
<li>Meta description</li>
<li>Canonical URL</li>
<li>Logo</li>
<li>Images</li>
<li>Author</li>
<li>Publication date</li>
<li>Modified date</li>
<li>Product price</li>
<li>Product availability</li>
<li>Business information</li>
<li>Schema data</li>
</ul>
<hr>
<h3 id="quick-avoid-checklist">Quick Avoid Checklist</h3>
<p>Before converting your HTML into WordPress, check that you are <strong>not</strong> doing any of the following:</p>
<ul>
<li>Excessive generic <code>&lt;div&gt;</code> nesting</li>
<li>Fake buttons made from <code>&lt;div&gt;</code> or inappropriate links</li>
<li>Tables used for page layout</li>
<li>Informative images without alt attributes</li>
<li>Keyword-stuffed alt text</li>
<li>Keyword-stuffed headings</li>
<li>Random or incorrect heading hierarchy</li>
<li>Repeated <code>&lt;br&gt;</code> tags for layout</li>
<li>Large amounts of inline CSS</li>
<li>Large amounts of inline JavaScript</li>
<li>Hidden SEO content</li>
<li>Fake reviews or ratings</li>
<li>Fake Schema information</li>
<li>Incorrect canonical URLs</li>
<li>Same canonical URL on every page</li>
<li>Schema that does not match visible page content</li>
<li>Missing <code>&lt;title&gt;</code></li>
<li>Missing meta description</li>
<li>Missing <code>lang</code> attribute</li>
<li>Navigation implemented with clickable <code>&lt;div&gt;</code> elements</li>
<li>Forms without proper labels</li>
</ul>
<hr>
<h3 id="recommended-html-development-workflow">Recommended HTML Development Workflow</h3>
<p>For your HTML → WordPress workflow, follow this order:</p>
<pre tabindex="0"><code>1. Valid HTML5
       ↓
2. Semantic HTML
       ↓
3. Correct heading hierarchy
       ↓
4. Accessible navigation/forms/buttons
       ↓
5. Proper image alt text + dimensions
       ↓
6. Descriptive links
       ↓
7. Title + meta description + canonical
       ↓
8. Open Graph metadata
       ↓
9. Appropriate JSON-LD Schema
       ↓
10. Validate HTML
       ↓
11. Test accessibility
       ↓
12. Test Schema
       ↓
13. Convert to WordPress dynamically
</code></pre><h3 id="final-principle">Final Principle</h3>
<p><strong>Build clean, semantic, accessible HTML first. Add appropriate JSON-LD structured data second.</strong></p>
<p>Schema compliance does not mean adding Schema attributes to every HTML element. The important thing is that your structured data accurately represents the actual content of the page.</p>
<p>When the HTML is later converted into WordPress, make the appropriate content and Schema values dynamic rather than hard-coding them into the theme.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>How to Build ADA-Compliant Websites</title>

      <link>https://wavesdream.com/posts/how-to-build-ada-compliant-websites/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/how-to-build-ada-compliant-websites/</guid>

      <pubDate>Wed, 29 Jul 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>ADA Compliance means designing and developing a website so that everyone, including people with disabilities, can access and use it without barriers.</p>
<p>The term ADA comes from the Americans with Disabilities Act (1990), a U.S. civil rights law that prohibits discrimination against individuals with disabilities. Although the law is American, its accessibility principles are now followed worldwide because they improve usability for everyone.</p>
<p>For websites, ADA compliance is generally achieved by following the Web Content Accessibility Guidelines (WCAG) 2.2, most commonly at Level AA.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>ADA Compliance means designing and developing a website so that everyone, including people with disabilities, can access and use it without barriers.</p>
<p>The term ADA comes from the Americans with Disabilities Act (1990), a U.S. civil rights law that prohibits discrimination against individuals with disabilities. Although the law is American, its accessibility principles are now followed worldwide because they improve usability for everyone.</p>
<p>For websites, ADA compliance is generally achieved by following the Web Content Accessibility Guidelines (WCAG) 2.2, most commonly at Level AA.</p>
<p><strong>Why is ADA Compliance Important?</strong></p>
<p>Imagine trying to use a website if you:</p>
<ul>
<li>Cannot see the screen.</li>
<li>Cannot hear audio.</li>
<li>Cannot use a mouse.</li>
<li>Have limited hand movement.</li>
<li>Have colour blindness.</li>
<li>Have low vision.</li>
<li>Have dyslexia or cognitive difficulties.</li>
</ul>
<p>Many users rely on assistive technologies such as:</p>
<ul>
<li>Screen readers</li>
<li>Keyboard-only navigation</li>
<li>Voice control software</li>
<li>Screen magnifiers</li>
<li>Braille displays</li>
<li>High-contrast display modes</li>
</ul>
<p>If a website is not built with accessibility in mind, these users may be unable to access information or complete essential tasks.</p>
<p>Here I have created a list of rules (handbook) which can be followed while coding ADA compliant web page.</p>
<h3 id="1-semantic-html">1. Semantic HTML</h3>
<p>Semantic HTML helps browsers and assistive technologies understand page
structure.</p>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;header&gt;
  &lt;nav aria-label=&#34;Primary Navigation&#34;&gt;
    ...
  &lt;/nav&gt;
&lt;/header&gt;

&lt;main id=&#34;main&#34;&gt;

&lt;section&gt;

&lt;h2&gt;Services&lt;/h2&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;/section&gt;

&lt;/main&gt;

&lt;footer&gt;
...
&lt;/footer&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;div id=&#34;header&#34;&gt;

&lt;div id=&#34;menu&#34;&gt;

&lt;div id=&#34;content&#34;&gt;

&lt;div id=&#34;footer&#34;&gt;
</code></pre><p><strong>Why?</strong></p>
<p>Screen readers recognise semantic landmarks allowing users to jump
directly to Header, Navigation, Main Content and Footer.</p>
<hr>
<h3 id="2-heading-structure">2. Heading Structure</h3>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;h1&gt;ADA Compliance Guide&lt;/h1&gt;

&lt;h2&gt;Images&lt;/h2&gt;

&lt;h3&gt;Alternative Text&lt;/h3&gt;

&lt;h2&gt;Forms&lt;/h2&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;h1&gt;ADA Guide&lt;/h1&gt;

&lt;h4&gt;Images&lt;/h4&gt;

&lt;h6&gt;Forms&lt;/h6&gt;
</code></pre><p>Never skip heading levels.</p>
<hr>
<h3 id="3-images">3. Images</h3>
<h4 id="informative-image">Informative Image</h4>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;img
src=&#34;doctor.webp&#34;
alt=&#34;Doctor examining a patient with a stethoscope&#34;
width=&#34;900&#34;
height=&#34;600&#34;&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;img src=&#34;doctor.webp&#34;&gt;

&lt;img src=&#34;doctor.webp&#34; alt=&#34;image&#34;&gt;

&lt;img src=&#34;doctor.webp&#34; alt=&#34;photo&#34;&gt;
</code></pre><h4 id="decorative-image">Decorative Image</h4>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;img src=&#34;divider.svg&#34; alt=&#34;&#34;&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;img src=&#34;divider.svg&#34; alt=&#34;decorative line&#34;&gt;
</code></pre><hr>
<h3 id="4-image-formats">4. Image Formats</h3>
<h4 id="photographs">Photographs</h4>
<p><strong>WebP</strong></p>
<pre tabindex="0"><code>&lt;picture&gt;
 &lt;source srcset=&#34;hero.webp&#34; type=&#34;image/webp&#34;&gt;
 &lt;img src=&#34;hero.jpg&#34;
      alt=&#34;Students learning online&#34;&gt;
&lt;/picture&gt;
</code></pre><p>PNG for large photographs.</p>
<h4 id="logos">Logos</h4>
<p><strong>SVG</strong></p>
<pre tabindex="0"><code>&lt;img src=&#34;logo.svg&#34;
alt=&#34;ABC Company logo&#34;&gt;
</code></pre><p>JPG logo</p>
<p>Reason: Blurry when scaled.</p>
<hr>
<h3 id="5-links">5. Links</h3>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;a href=&#34;/pricing&#34;&gt;
View Pricing Plans
&lt;/a&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;a href=&#34;/pricing&#34;&gt;
Click Here
&lt;/a&gt;
</code></pre><p>Users of screen readers often browse only link text.</p>
<hr>
<h3 id="6-buttons">6. Buttons</h3>
<p>**DO*8</p>
<pre tabindex="0"><code>&lt;button type=&#34;submit&#34;&gt;
Save Changes
&lt;/button&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;div onclick=&#34;save()&#34;&gt;
Save
&lt;/div&gt;
</code></pre><p>Div elements are not keyboard accessible.</p>
<hr>
<h3 id="7-forms">7. Forms</h3>
<h4 id="labels">Labels</h4>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;label for=&#34;email&#34;&gt;
Email Address
&lt;/label&gt;

&lt;input
id=&#34;email&#34;
type=&#34;email&#34;
required&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;input
placeholder=&#34;Email Address&#34;&gt;
</code></pre><p>Placeholder text disappears and is not a replacement for labels.</p>
<h4 id="validation">Validation</h4>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;div
class=&#34;error&#34;
aria-live=&#34;polite&#34;&gt;

Please enter a valid email address.

&lt;/div&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>Invalid
</code></pre><hr>
<h3 id="8-keyboard-navigation">8. Keyboard Navigation</h3>
<p>Everything must be operable without a mouse.</p>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>:focus{
outline:3px solid #005FCC;
outline-offset:2px;
}
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>:focus{
outline:none;
}
</code></pre><hr>
<h3 id="9-colour-contrast">9. Colour Contrast</h3>
<p><strong>DO</strong></p>
<p>Background</p>
<pre tabindex="0"><code>#FAFAFA
</code></pre><p>Text</p>
<pre tabindex="0"><code>#1F1F1F
</code></pre><p>Contrast &gt; 4.5:1</p>
<p><strong>DON&rsquo;T</strong></p>
<p>Background</p>
<pre tabindex="0"><code>#FFFFFF
</code></pre><p>Text</p>
<pre tabindex="0"><code>#BEBEBE
</code></pre><p>Fails WCAG.</p>
<hr>
<h3 id="10-skip-link">10. Skip Link</h3>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;a class=&#34;skip-link&#34;
href=&#34;#main&#34;&gt;
Skip to Main Content
&lt;/a&gt;
</code></pre><hr>
<h3 id="11-tables">11. Tables</h3>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;table&gt;

&lt;thead&gt;

&lt;tr&gt;

&lt;th scope=&#34;col&#34;&gt;Name&lt;/th&gt;

&lt;th scope=&#34;col&#34;&gt;Phone&lt;/th&gt;

&lt;/tr&gt;

&lt;/thead&gt;

&lt;tbody&gt;

&lt;tr&gt;

&lt;th scope=&#34;row&#34;&gt;John&lt;/th&gt;

&lt;td&gt;123456&lt;/td&gt;

&lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;table&gt;

&lt;tr&gt;

&lt;td&gt;Name&lt;/td&gt;

&lt;td&gt;Phone&lt;/td&gt;

&lt;/tr&gt;

&lt;/table&gt;
</code></pre><hr>
<h3 id="12-aria">12. ARIA</h3>
<h4 id="native-html-preferred">Native HTML Preferred</h4>
<p><strong>DO</strong></p>
<pre tabindex="0"><code>&lt;button&gt;

Download PDF

&lt;/button&gt;
</code></pre><p><strong>DON&rsquo;T</strong></p>
<pre tabindex="0"><code>&lt;div
role=&#34;button&#34;&gt;

Download PDF

&lt;/div&gt;
</code></pre><hr>
<h3 id="13-videos">13. Videos</h3>
<p><strong>DO</strong></p>
<ul>
<li>Closed Captions</li>
<li>Transcript</li>
<li>Keyboard Controls</li>
</ul>
<p><strong>DON&rsquo;T</strong></p>
<p>Autoplay with sound.</p>
<hr>
<h3 id="14-css">14. CSS</h3>
<h4 id="recommended-variables">Recommended Variables</h4>
<pre tabindex="0"><code>:root{

--bg:#FAFAFA;
--surface:#FFFFFF;
--text:#1F1F1F;
--text-light:#4A4A4A;

--primary:#005FCC;
--primary-hover:#003D80;

--border:#D9D9D9;

--success:#0F7B0F;

--warning:#A65C00;

--danger:#B00020;

}
</code></pre><hr>
<h3 id="15-accessible-colour-palette">15. Accessible Colour Palette</h3>
<table>
  <thead>
      <tr>
          <th>Purpose</th>
          <th>Colour</th>
          <th>Hex Code</th>
          <th>Usage</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Background</td>
          <td><img src="https://placehold.co/20x20/FAFAFA/FAFAFA.png" alt="#FAFAFA"></td>
          <td><code>#FAFAFA</code></td>
          <td>Main page background</td>
      </tr>
      <tr>
          <td>Surface</td>
          <td><img src="https://placehold.co/20x20/FFFFFF/FFFFFF.png" alt="#FFFFFF"></td>
          <td><code>#FFFFFF</code></td>
          <td>Cards, panels, modals</td>
      </tr>
      <tr>
          <td>Text</td>
          <td><img src="https://placehold.co/20x20/1F1F1F/1F1F1F.png" alt="#1F1F1F"></td>
          <td><code>#1F1F1F</code></td>
          <td>Primary text</td>
      </tr>
      <tr>
          <td>Links</td>
          <td><img src="https://placehold.co/20x20/005FCC/005FCC.png" alt="#005FCC"></td>
          <td><code>#005FCC</code></td>
          <td>Hyperlinks and primary actions</td>
      </tr>
      <tr>
          <td>Hover</td>
          <td><img src="https://placehold.co/20x20/003D80/003D80.png" alt="#003D80"></td>
          <td><code>#003D80</code></td>
          <td>Link and button hover state</td>
      </tr>
      <tr>
          <td>Success</td>
          <td><img src="https://placehold.co/20x20/0F7B0F/0F7B0F.png" alt="#0F7B0F"></td>
          <td><code>#0F7B0F</code></td>
          <td>Success messages and confirmations</td>
      </tr>
      <tr>
          <td>Warning</td>
          <td><img src="https://placehold.co/20x20/A65C00/A65C00.png" alt="#A65C00"></td>
          <td><code>#A65C00</code></td>
          <td>Warning messages and alerts</td>
      </tr>
      <tr>
          <td>Error</td>
          <td><img src="https://placehold.co/20x20/B00020/B00020.png" alt="#B00020"></td>
          <td><code>#B00020</code></td>
          <td>Error messages and validation failures</td>
      </tr>
  </tbody>
</table>
<hr>
<h3 id="16-accessibility-testing-checklist">16. Accessibility Testing Checklist</h3>
<ul>
<li>Semantic HTML</li>
<li>Logical heading hierarchy</li>
<li>Alt text on meaningful images</li>
<li>Decorative images use empty alt</li>
<li>Keyboard navigation</li>
<li>Focus indicator visible</li>
<li>Labels for every form field</li>
<li>Contrast ≥ 4.5:1</li>
<li>Responsive at 200% zoom</li>
<li>Screen reader tested</li>
<li>WAVE</li>
<li>axe DevTools</li>
<li>Lighthouse Accessibility</li>
<li>HTML Validator</li>
</ul>
<hr>
<h3 id="final-development-workflow">Final Development Workflow</h3>
<ol>
<li>Build semantic HTML.</li>
<li>Add accessible forms.</li>
<li>Add keyboard support.</li>
<li>Verify colour contrast.</li>
<li>Optimise images (SVG/WebP).</li>
<li>Test with screen readers.</li>
<li>Run automated accessibility tools.</li>
<li>Fix every issue before deployment.</li>
</ol>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Host a Hugo Site on GitHub Pages</title>

      <link>https://wavesdream.com/posts/host-hugo-site-on-github-pages/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/host-hugo-site-on-github-pages/</guid>

      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>I wanted to host a Hugo blog completely free using GitHub Pages.</p>
<p>Initially, I faced several issues related to repository naming, GitHub Pages configuration, Git workflow conflicts, and deployment setup.</p>
<p>In this article, I’ll explain the complete process step-by-step so anyone can replicate it easily.</p>
<p><strong>Step 1: Create Hugo Site Locally</strong></p>
<p>I first created my Hugo website locally.</p>
<pre tabindex="0"><code>hugo new site myblog
cd myblog
</code></pre><p><strong>Step 2: Configure Hugo</strong></p>
<p>I updated the hugo.toml file.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>I wanted to host a Hugo blog completely free using GitHub Pages.</p>
<p>Initially, I faced several issues related to repository naming, GitHub Pages configuration, Git workflow conflicts, and deployment setup.</p>
<p>In this article, I’ll explain the complete process step-by-step so anyone can replicate it easily.</p>
<p><strong>Step 1: Create Hugo Site Locally</strong></p>
<p>I first created my Hugo website locally.</p>
<pre tabindex="0"><code>hugo new site myblog
cd myblog
</code></pre><p><strong>Step 2: Configure Hugo</strong></p>
<p>I updated the hugo.toml file.</p>
<pre tabindex="0"><code>baseURL = &#34;https://xyz.github.io/&#34;
publishDir = &#34;public&#34;
languageCode = &#34;en-us&#34;
title = &#34;Your Name&#34;

[pagination]
  pagerSize = 6

[taxonomies]
  category = &#34;categories&#34;
  tag = &#34;tags&#34;

[params]
  author = &#34;Your Name&#34;
  description = &#34;My Notes&#34;

[markup]
  [markup.goldmark.renderer]
    unsafe = true

[outputs]
  home = [&#34;HTML&#34;, &#34;JSON&#34;, &#34;RSS&#34;]
  section = [&#34;HTML&#34;, &#34;JSON&#34;, &#34;RSS&#34;]
</code></pre><p><strong>Step 3: Create GitHub Repository</strong></p>
<p>Initially, my repository name was: myblog. But GitHub Pages root domains only work when the repository name exactly matches: USERNAME.github.io</p>
<p>So I renamed the repository to: xyz.github.io</p>
<p><strong>Step 4: Update Local Git Remote</strong></p>
<p>After renaming the repository, my local Git remote still pointed to the old repository URL.</p>
<p>I updated it using:</p>
<pre tabindex="0"><code>git remote set-url origin https://github.com/xyz/xyz.github.io.git
</code></pre><p><strong>Step 5: Create GitHub Actions Workflow</strong></p>
<p>Inside the local Hugo project, I created this file:</p>
<pre tabindex="0"><code>.github/workflows/hugo.yml
</code></pre><p>Then added the deployment workflow:</p>
<pre tabindex="0"><code>name: Deploy Hugo site to Pages

on:
  push:
    branches:
      - main

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: latest
          extended: true

      - name: Build
        run: hugo --minify

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./public

  deploy:
    needs: build

    permissions:
      pages: write
      id-token: write

    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    runs-on: ubuntu-latest

    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
</code></pre><p><strong>Step 6: Configure GitHub Pages</strong></p>
<p>In the GitHub repository settings: Settings → Pages</p>
<p>I selected: Source → GitHub Actions</p>
<p>This allows GitHub Actions to automatically build and deploy the Hugo website.</p>
<p><strong>Step 7: Fix Git Push Issues</strong></p>
<p>After renaming the repository, I encountered Git errors like:</p>
<pre tabindex="0"><code>Updates were rejected because the remote contains work that you do not have locally

Need to specify how to reconcile divergent branches
</code></pre><p>The simplest solution for my case was:</p>
<pre tabindex="0"><code>git push origin main --force
</code></pre><p>This synchronized my local repository with GitHub.</p>
<p><strong>Step 8: Push Website to GitHub</strong></p>
<p>I committed and pushed everything:</p>
<pre tabindex="0"><code>git add .
git commit -m &#34;Initial Hugo blog deployment&#34;
git push origin main
</code></pre><p><strong>Step 9: Wait for Deployment</strong></p>
<p>I checked deployment progress under:</p>
<pre tabindex="0"><code>GitHub Repository → Actions
</code></pre><p>After successful deployment, the website became live at:</p>
<p><a href="https://xyz.github.io/">https://xyz.github.io/</a></p>
<p><strong>Step 10: Future Workflow</strong></p>
<p>Now my blogging workflow is simple. Whenever I add new content:</p>
<pre tabindex="0"><code>hugo new posts/my-post.md
git add .
git commit -m &#34;Added new blog post&#34;
git push origin main
</code></pre><p>I write the article locally, then push changes, GitHub Actions automatically rebuilds and republishes the website.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Responsive Media Query Guide &amp; Scalable CSS System</title>

      <link>https://wavesdream.com/posts/responsive-media-query-guide-scalable-css-system/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/responsive-media-query-guide-scalable-css-system/</guid>

      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Creating a truly responsive website is not just about adding breakpoints. It’s about building a smart system where text size, spacing, and layout adjust on their own for different screen sizes, so you don’t have to keep rewriting styles again and again.</p>
<p>I am explaining everything in simple way. It covers the right media query ranges to use, how to make text sizes adjust smoothly on different screens, and how to set global CSS styles that automatically scale across devices.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Creating a truly responsive website is not just about adding breakpoints. It’s about building a smart system where text size, spacing, and layout adjust on their own for different screen sizes, so you don’t have to keep rewriting styles again and again.</p>
<p>I am explaining everything in simple way. It covers the right media query ranges to use, how to make text sizes adjust smoothly on different screens, and how to set global CSS styles that automatically scale across devices.</p>
<p><strong>1. Recommended Responsive Media Query Range</strong></p>
<pre tabindex="0"><code>/* Base styles → Large desktops (≥1200px) */

/* Small desktops / large laptops */
@media (max-width: 1200px) {}

/* Landscape tablets / small laptops */
@media (max-width: 1080px) {}

/* Tablets */
@media (max-width: 992px) {}

/* Large mobiles / portrait tablets */
@media (max-width: 768px) {}

/* Small mobiles */
@media (max-width: 576px) {}
</code></pre><p><strong>2. Use Fluid Scaling</strong></p>
<p>The biggest mistake in responsive design is redefining font sizes in every breakpoint. Instead, use:</p>
<ul>
<li>rem for consistency</li>
<li>clamp() for fluid scaling</li>
</ul>
<p><strong>3. Global CSS</strong></p>
<p>This is your main CSS setup — write once, works everywhere.</p>
<p><em>Root Setup</em></p>
<pre tabindex="0"><code>:root {
  --base-font-size: 16px;

  --font-primary: &#39;Poppins&#39;, sans-serif;

  --color-text: #222;
  --color-heading: #111;

  --line-height-base: 1.6;
  --line-height-heading: 1.2;

  --spacing-xs: 0.5rem;
  --spacing-sm: 1rem;
  --spacing-md: 1.5rem;
  --spacing-lg: 2rem;
}
</code></pre><p><em>Base Typography</em></p>
<pre tabindex="0"><code>html {
  font-size: 100%; /* 16px */
}

body {
  font-family: var(--font-primary);
  font-size: 1rem;
  line-height: var(--line-height-base);
  color: var(--color-text);
}
</code></pre><p><em>Fluid Typography (no media query is needed)</em></p>
<pre tabindex="0"><code>h1 {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 700;
  line-height: var(--line-height-heading);
  margin-bottom: var(--spacing-md);
}

h2 {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 600;
  margin-bottom: var(--spacing-md);
}

h3 {
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 600;
}

h4 {
  font-size: clamp(1.25rem, 2.5vw, 1.5rem);
  font-weight: 500;
}
</code></pre><p><em>Paragraph &amp; Content Spacing</em></p>
<pre tabindex="0"><code>p {
  font-size: clamp(0.95rem, 1.2vw, 1.05rem);
  margin-bottom: var(--spacing-md);
}

strong {
  font-weight: 600;
}

small {
  font-size: 0.875rem;
}
</code></pre><p><em>Lists (UL / OL)</em></p>
<pre tabindex="0"><code>ul,
ol {
  margin-bottom: var(--spacing-md);
  padding-left: 1.2rem;
}

li {
  margin-bottom: var(--spacing-xs);
  line-height: var(--line-height-base);
}
</code></pre><p><em>Container System (important for layout scaling)</em></p>
<pre tabindex="0"><code>.container {
  width: 100%;
  max-width: 1200px;
  padding: 0 var(--spacing-sm);
  margin: 0 auto;
}
</code></pre><p><strong>4. Minimal Media Query Usage (layout Only)</strong></p>
<p>Now this media queries become clean and minimal:</p>
<pre tabindex="0"><code>@media (max-width: 992px) {
  .container {
    max-width: 90%;
  }
}

@media (max-width: 768px) {
  .grid {
    display: block;
  }
}

@media (max-width: 576px) {
  .section {
    padding: var(--spacing-md) 0;
  }
}
</code></pre><p><strong>Notes:</strong></p>
<ul>
<li>Use rem for spacing &amp; fonts</li>
<li>Use clamp() for responsive typography</li>
<li>Define global variables in :root</li>
<li>Use media queries only for layout changes</li>
</ul>
<p>Here is a fully working simple starter template HTML, CSS code for your reference.</p>
<pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
&lt;meta charset=&#34;UTF-8&#34;&gt;
&lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
&lt;title&gt;Responsive Starter Template&lt;/title&gt;
&lt;link href=&#34;https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&amp;display=swap&#34; rel=&#34;stylesheet&#34;&gt;

&lt;style&gt;
/* ================= ROOT VARIABLES ================= */
:root {
  --base-font-size: 16px;

  --font-primary: &#39;Poppins&#39;, sans-serif;

  --color-text: #222;
  --color-heading: #111;
  --color-primary: #2563eb;
  --color-light: #f9fafb;

  --line-height-base: 1.6;
  --line-height-heading: 1.2;

  --spacing-xs: 0.5rem;
  --spacing-sm: 1rem;
  --spacing-md: 1.5rem;
  --spacing-lg: 2rem;
}

/* ================= GLOBAL RESET ================= */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: clamp(14px, 1vw, 16px);
}

body {
  font-family: var(--font-primary);
  font-size: 1rem;
  line-height: var(--line-height-base);
  color: var(--color-text);
  background: #fff;
}

img {
  max-width: 100%;
  height: auto;
}

/* ================= TYPOGRAPHY ================= */
h1 {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 700;
  line-height: var(--line-height-heading);
  margin-bottom: var(--spacing-md);
}

h2 {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 600;
  margin-bottom: var(--spacing-md);
}

h3 {
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 600;
  margin-bottom: var(--spacing-sm);
}

h4 {
  font-size: clamp(1.25rem, 2.5vw, 1.5rem);
  font-weight: 500;
}

p {
  font-size: clamp(0.95rem, 1.2vw, 1.05rem);
  margin-bottom: var(--spacing-md);
}

ul, ol {
  margin-bottom: var(--spacing-md);
  padding-left: 1.2rem;
}

li {
  margin-bottom: var(--spacing-xs);
}

/* ================= LAYOUT ================= */
.container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--spacing-sm);
}

.section {
  padding: var(--spacing-lg) 0;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-md);
}

/* ================= HEADER ================= */
.header {
  background: #fff;
  border-bottom: 1px solid #eee;
}

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--spacing-sm) 0;
}

.nav a {
  text-decoration: none;
  color: var(--color-heading);
  margin-left: var(--spacing-sm);
}

/* ================= HERO ================= */
.hero {
  background: var(--color-light);
  text-align: center;
}

.hero p {
  max-width: 600px;
  margin: 0 auto var(--spacing-md);
}

.btn {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  background: var(--color-primary);
  color: #fff;
  border-radius: 5px;
  text-decoration: none;
}

/* ================= CARDS ================= */
.card {
  padding: var(--spacing-md);
  border: 1px solid #eee;
  border-radius: 8px;
}

/* ================= FOOTER ================= */
.footer {
  background: #111;
  color: #fff;
  text-align: center;
  padding: var(--spacing-md) 0;
}

/* ================= MEDIA QUERIES ================= */
@media (max-width: 992px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .grid {
    grid-template-columns: 1fr;
  }

  .nav {
    flex-direction: column;
  }
}

@media (max-width: 576px) {
  .section {
    padding: var(--spacing-md) 0;
  }
}

&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;!-- HEADER --&gt;
&lt;header class=&#34;header&#34;&gt;
  &lt;div class=&#34;container nav&#34;&gt;
    &lt;div&gt;&lt;strong&gt;Brand&lt;/strong&gt;&lt;/div&gt;
    &lt;nav&gt;
      &lt;a href=&#34;#&#34;&gt;Home&lt;/a&gt;
      &lt;a href=&#34;#&#34;&gt;About&lt;/a&gt;
      &lt;a href=&#34;#&#34;&gt;Services&lt;/a&gt;
      &lt;a href=&#34;#&#34;&gt;Contact&lt;/a&gt;
    &lt;/nav&gt;
  &lt;/div&gt;
&lt;/header&gt;

&lt;!-- HERO --&gt;
&lt;section class=&#34;hero section&#34;&gt;
  &lt;div class=&#34;container&#34;&gt;
    &lt;h1&gt;Responsive Design System&lt;/h1&gt;
    &lt;p&gt;This starter template uses fluid typography and minimal media queries for scalable design.&lt;/p&gt;
    &lt;a href=&#34;#&#34; class=&#34;btn&#34;&gt;Get Started&lt;/a&gt;
  &lt;/div&gt;
&lt;/section&gt;

&lt;!-- FEATURES --&gt;
&lt;section class=&#34;section&#34;&gt;
  &lt;div class=&#34;container&#34;&gt;
    &lt;h2&gt;Features&lt;/h2&gt;
    &lt;div class=&#34;grid&#34;&gt;
      &lt;div class=&#34;card&#34;&gt;
        &lt;h3&gt;Fluid Typography&lt;/h3&gt;
        &lt;p&gt;Automatically scales across devices.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&#34;card&#34;&gt;
        &lt;h3&gt;Minimal Media Queries&lt;/h3&gt;
        &lt;p&gt;Only used for layout adjustments.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&#34;card&#34;&gt;
        &lt;h3&gt;Reusable System&lt;/h3&gt;
        &lt;p&gt;Write once, use everywhere.&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/section&gt;

&lt;!-- CONTENT --&gt;
&lt;section class=&#34;section&#34;&gt;
  &lt;div class=&#34;container&#34;&gt;
    &lt;h2&gt;Sample Content&lt;/h2&gt;
    &lt;p&gt;This is a paragraph demonstrating spacing and typography consistency.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Clean spacing&lt;/li&gt;
      &lt;li&gt;Readable typography&lt;/li&gt;
      &lt;li&gt;Scalable layout&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/section&gt;

&lt;!-- FOOTER --&gt;
&lt;footer class=&#34;footer&#34;&gt;
  &lt;div class=&#34;container&#34;&gt;
    &lt;p&gt;© 2026 Your Company&lt;/p&gt;
  &lt;/div&gt;
&lt;/footer&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Managing Multiple Project Versions in the Same GitHub Repository</title>

      <link>https://wavesdream.com/posts/manage-multiple-project-versions-github-repository/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/manage-multiple-project-versions-github-repository/</guid>

      <pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>I have been working on a project for years, and suddenly I have to create a completely different version of the same codebase.</p>
<p>In my case, I have:</p>
<ul>
<li>
<p>Version 1 → Already in Git (Folder 1), synced with main branch</p>
</li>
<li>
<p>Version 2 → New code (Folder 2), no Git setup</p>
</li>
</ul>
<p>Now, my goal is</p>
<ul>
<li>
<p>Move existing code (Version 1) → version1 branch</p>
</li>
<li>
<p>Upload new code (Version 2) → main branch</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>I have been working on a project for years, and suddenly I have to create a completely different version of the same codebase.</p>
<p>In my case, I have:</p>
<ul>
<li>
<p>Version 1 → Already in Git (Folder 1), synced with main branch</p>
</li>
<li>
<p>Version 2 → New code (Folder 2), no Git setup</p>
</li>
</ul>
<p>Now, my goal is</p>
<ul>
<li>
<p>Move existing code (Version 1) → version1 branch</p>
</li>
<li>
<p>Upload new code (Version 2) → main branch</p>
</li>
</ul>
<p>I followed a clean and safe approach, which I am explaining step-by-step below. If you have ever come to such a situation, you may follow this process.</p>
<p><strong>Step 1: Create a New Branch for Version 1</strong></p>
<p>First, go to your existing project (Folder 1) and create a new branch from current main. It will safely move your code into version1 branch</p>
<pre tabindex="0"><code>cd /path/to/folder1
git checkout -b version1
git push origin version1
</code></pre><p><strong>Step 2: Setup Git in Version 2 Folder</strong></p>
<pre tabindex="0"><code>cd /path/to/folder2
git init
git remote add origin &lt;your-repository-url&gt;
</code></pre><p><strong>Step 3: Push Version 2 Code to Main Branch</strong></p>
<p>Create and switch to main branch:</p>
<pre tabindex="0"><code>git checkout -b main
git add .
git commit -m &#34;Initial commit for version 2&#34;
git push origin main --force
</code></pre><p>As the main brance already had version 1 code, so <strong>&ndash;force</strong> push is used to overwrite the main brance.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>HTML Form Validation Cheat Sheet</title>

      <link>https://wavesdream.com/posts/html-form-validation-cheat-sheet/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/html-form-validation-cheat-sheet/</guid>

      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>When I build a contact form or a complex application, I ensure that users enter the correct data that helps data accuracy and proper user experience.</p>
<p>In this article I am sharing a complete collection of commonly used HTML form validation patterns, attributes, and examples.</p>
<h2 id="1-basic-pattern-validations">1. Basic Pattern Validations</h2>
<p><strong>Only Alphabets</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Za-z\s]+&#34; title=&#34;Only alphabets allowed&#34;&gt;
</code></pre><p><strong>Only Numbers</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[0-9]+&#34; title=&#34;Only numeric digits allowed&#34;&gt;
</code></pre><p><strong>Exactly 10 Digits (Mobile)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;\d{10}&#34; maxlength=&#34;10&#34;
oninput=&#34;this.value = this.value.replace(/[^0-9]/g, &#39;&#39;).slice(0,10);&#34;
title=&#34;Enter exactly 10 digits&#34;&gt;
</code></pre><p><strong>Alphanumeric</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>When I build a contact form or a complex application, I ensure that users enter the correct data that helps data accuracy and proper user experience.</p>
<p>In this article I am sharing a complete collection of commonly used HTML form validation patterns, attributes, and examples.</p>
<h2 id="1-basic-pattern-validations">1. Basic Pattern Validations</h2>
<p><strong>Only Alphabets</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Za-z\s]+&#34; title=&#34;Only alphabets allowed&#34;&gt;
</code></pre><p><strong>Only Numbers</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[0-9]+&#34; title=&#34;Only numeric digits allowed&#34;&gt;
</code></pre><p><strong>Exactly 10 Digits (Mobile)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;\d{10}&#34; maxlength=&#34;10&#34;
oninput=&#34;this.value = this.value.replace(/[^0-9]/g, &#39;&#39;).slice(0,10);&#34;
title=&#34;Enter exactly 10 digits&#34;&gt;
</code></pre><p><strong>Alphanumeric</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Za-z0-9]+&#34; title=&#34;Only letters and numbers allowed&#34;&gt;
</code></pre><p><strong>Alphabets + Comma</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Za-z\s,]+&#34; title=&#34;Only alphabets and commas allowed&#34;&gt;
</code></pre><h2 id="2-common-real-world-validations">2. Common Real-World Validations</h2>
<p><strong>Email</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;email&#34; required&gt;
</code></pre><p><strong>Custom Email Pattern</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$&#34;&gt;
</code></pre><p><strong>Strong Password (Minimum 8 characters and at least 1 uppercase, lowercase, number, special character)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;password&#34;
pattern=&#34;(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&amp;]).{8,}&#34;
title=&#34;Min 8 chars, include uppercase, lowercase, number &amp; special char&#34;&gt;
</code></pre><p><strong>PAN Card (India)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Z]{5}[0-9]{4}[A-Z]{1}&#34; maxlength=&#34;10&#34;
title=&#34;Enter valid PAN (e.g. ABCDE1234F)&#34;&gt;
</code></pre><p><strong>Aadhaar Number</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;\d{12}&#34; maxlength=&#34;12&#34;
title=&#34;Enter 12 digit Aadhaar number&#34;&gt;
</code></pre><p><strong>IFSC Code</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Z]{4}0[A-Z0-9]{6}&#34; maxlength=&#34;11&#34;
title=&#34;Enter valid IFSC code&#34;&gt;
</code></pre><p><strong>URL</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;url&#34;&gt;
</code></pre><h2 id="3-length-validation">3. Length Validation</h2>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; minlength=&#34;3&#34; maxlength=&#34;20&#34; required&gt;
</code></pre><h2 id="4-number-range">4. Number Range</h2>
<pre tabindex="0"><code>&lt;input type=&#34;number&#34; min=&#34;1&#34; max=&#34;100&#34;&gt;
</code></pre><h2 id="5-date-validation">5. Date Validation</h2>
<pre tabindex="0"><code>&lt;input type=&#34;date&#34; min=&#34;2020-01-01&#34; max=&#34;2030-12-31&#34;&gt;
</code></pre><h2 id="6-custom-formats">6. Custom Formats</h2>
<p><strong>PIN Code (India)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;\d{6}&#34; maxlength=&#34;6&#34;
title=&#34;Enter valid 6 digit PIN code&#34;&gt;
</code></pre><p><strong>Username (No Spaces)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Za-z0-9_]{4,15}&#34;
title=&#34;4-15 characters, no spaces&#34;&gt;
</code></pre><p><strong>Name (No Numbers)</strong></p>
<pre tabindex="0"><code>&lt;input type=&#34;text&#34; pattern=&#34;[A-Za-z\s]{2,50}&#34;&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Spam Protection for WordPress Contact Form 7 Plugin</title>

      <link>https://wavesdream.com/posts/spam-protection-contact-form-7-wordpress/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/spam-protection-contact-form-7-wordpress/</guid>

      <pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>In WordPress contact forms, mainly using Contact Form 7 plugin, everyone notices spam messages, SEO spam or bots flooding into email inbox.</p>
<p>There are options to use Google reCAPTCHA or Cloudflare Turnstile but custom PHP validation is another valid way to protect against spam.</p>
<p>There are several filters available in Contact Form 7 to validate form fields before submission of the form.</p>
<p>Put this piece of code in the functions.php file of the active theme.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>In WordPress contact forms, mainly using Contact Form 7 plugin, everyone notices spam messages, SEO spam or bots flooding into email inbox.</p>
<p>There are options to use Google reCAPTCHA or Cloudflare Turnstile but custom PHP validation is another valid way to protect against spam.</p>
<p>There are several filters available in Contact Form 7 to validate form fields before submission of the form.</p>
<p>Put this piece of code in the functions.php file of the active theme.</p>
<pre tabindex="0"><code>add_filter(&#39;wpcf7_validate_textarea&#39;, &#39;cf7_custom_spam_filter&#39;, 10, 2);
add_filter(&#39;wpcf7_validate_textarea*&#39;, &#39;cf7_custom_spam_filter&#39;, 10, 2);
add_filter(&#39;wpcf7_validate_text&#39;, &#39;cf7_custom_spam_filter&#39;, 10, 2);
add_filter(&#39;wpcf7_validate_text*&#39;, &#39;cf7_custom_spam_filter&#39;, 10, 2);

function cf7_custom_spam_filter($result, $tag) {

    $value = isset($_POST[$tag-&gt;name]) ? trim($_POST[$tag-&gt;name]) : &#39;&#39;;
    $value_lower = strtolower($value);

    // Skip empty (let CF7 handle required validation)
    if ($value === &#39;&#39;) return $result;

    // 1. Block URLs / links
    if (preg_match(&#39;/(http|https|www\.|\.com|\.net|\.org|\.ru|\.cn)/i&#39;, $value)) {
        $result-&gt;invalidate($tag, &#34;Links are not allowed.&#34;);
        return $result;
    }

    // 2. Spam keywords
    $spam_keywords = [
        &#39;viagra&#39;,&#39;cialis&#39;,&#39;casino&#39;,&#39;loan&#39;,&#39;credit&#39;,&#39;seo&#39;,&#39;crypto&#39;,
        &#39;bitcoin&#39;,&#39;forex&#39;,&#39;trading&#39;,&#39;investment&#39;,&#39;betting&#39;,&#39;porn&#39;,
        &#39;adult&#39;,&#39;escort&#39;,&#39;sex&#39;,&#39;free money&#39;,&#39;earn money&#39;,&#39;work from home&#39;
    ];

    foreach ($spam_keywords as $keyword) {
        if (strpos($value_lower, $keyword) !== false) {
            $result-&gt;invalidate($tag, &#34;Spam content detected.&#34;);
            return $result;
        }
    }

    // 3. Gibberish symbols
    if (preg_match(&#39;/[^a-zA-Z0-9\s]{6,}/&#39;, $value)) {
        $result-&gt;invalidate($tag, &#34;Invalid input detected.&#34;);
        return $result;
    }

    // 4. Repeated characters
    if (preg_match(&#39;/(.)\1{5,}/&#39;, $value)) {
        $result-&gt;invalidate($tag, &#34;Invalid repeating characters.&#34;);
        return $result;
    }

    // 5. Length checks
    if (strlen($value) &lt; 3) {
        $result-&gt;invalidate($tag, &#34;Too short.&#34;);
        return $result;
    }

    if (strlen($value) &gt; 500) {
        $result-&gt;invalidate($tag, &#34;Input too long.&#34;);
        return $result;
    }

    // 6. Email inside text
    if (preg_match(&#39;/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/i&#39;, $value)) {
        $result-&gt;invalidate($tag, &#34;Email not allowed here.&#34;);
        return $result;
    }

    // 7. HTML tags
    if (preg_match(&#39;/&lt;[^&gt;]+&gt;/&#39;, $value)) {
        $result-&gt;invalidate($tag, &#34;HTML not allowed.&#34;);
        return $result;
    }

    return $result;
}
</code></pre><p><strong>This code validate the form fields by blocking</strong></p>
<ul>
<li>Links (http, www, domains)</li>
<li>Common spam keywords (like crypto, casino, etc.)</li>
<li>Repeated characters (like aaaaaa, $$$$$)</li>
<li>HTML tags (prevents script injection)</li>
</ul>
<p><strong>Important</strong></p>
<p>Make sure your message field is required otherwise some validation may be skipped.</p>
<pre tabindex="0"><code>[textarea* your-message]
</code></pre><p>Additionally, there is an option to add a simple math quiz inside the form which can further reduce spam by adding a simple human check.</p>
<pre tabindex="0"><code>[quiz math-quiz &#34;5+3=?|8&#34; &#34;10-4=?|6&#34;]
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Complete MySQL Commands Guide from Linux Terminal</title>

      <link>https://wavesdream.com/posts/complete-mysql-commands-guide-linux-terminal/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/complete-mysql-commands-guide-linux-terminal/</guid>

      <pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>While working on cloud server where PHPMyAdmin is not installed then using Linux terminal is the most efficient way to manage MySQL database and respective tables.</p>
<p>These are the all essential MySQL commands that can be executed from any Linux environment.</p>
<p><strong>1. Login to MySQL Server</strong></p>
<p>Login using root user:</p>
<pre tabindex="0"><code>mysql -u root -p
</code></pre><p>Login with host:</p>
<pre tabindex="0"><code>mysql -u username -p -h localhost
</code></pre><p>Login with port:</p>
<pre tabindex="0"><code>mysql -u username -p -P 3306
</code></pre><p><strong>2. Database Management Commands</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>While working on cloud server where PHPMyAdmin is not installed then using Linux terminal is the most efficient way to manage MySQL database and respective tables.</p>
<p>These are the all essential MySQL commands that can be executed from any Linux environment.</p>
<p><strong>1. Login to MySQL Server</strong></p>
<p>Login using root user:</p>
<pre tabindex="0"><code>mysql -u root -p
</code></pre><p>Login with host:</p>
<pre tabindex="0"><code>mysql -u username -p -h localhost
</code></pre><p>Login with port:</p>
<pre tabindex="0"><code>mysql -u username -p -P 3306
</code></pre><p><strong>2. Database Management Commands</strong></p>
<p><em><strong>Show all databases</strong></em></p>
<pre tabindex="0"><code>SHOW DATABASES;
</code></pre><p><em><strong>Create a new database</strong></em></p>
<pre tabindex="0"><code>CREATE DATABASE db_name;
</code></pre><p><em><strong>Create database with charset</strong></em></p>
<pre tabindex="0"><code>CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
</code></pre><p><em><strong>Select a database</strong></em></p>
<pre tabindex="0"><code>USE db_name;
</code></pre><p><em><strong>Delete a database</strong></em></p>
<pre tabindex="0"><code>DROP DATABASE db_name;
</code></pre><p><strong>3. Table Management Commands</strong></p>
<p><em><strong>Show tables</strong></em></p>
<pre tabindex="0"><code>SHOW TABLES;
</code></pre><p><em><strong>Create table</strong></em></p>
<pre tabindex="0"><code>CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
</code></pre><p><em><strong>Describe table structure</strong></em></p>
<pre tabindex="0"><code>DESCRIBE users;
</code></pre><p><em><strong>Show create table</strong></em></p>
<pre tabindex="0"><code>SHOW CREATE TABLE users;
</code></pre><p><em><strong>Rename table</strong></em></p>
<pre tabindex="0"><code>RENAME TABLE users TO customers;
</code></pre><p><em><strong>Delete table</strong></em></p>
<pre tabindex="0"><code>DROP TABLE users;
</code></pre><p><strong>4. Data Operations (CRUD)</strong></p>
<p><em><strong>Insert data</strong></em></p>
<pre tabindex="0"><code>INSERT INTO users (name, email) VALUES (&#39;John Doe&#39;, &#39;john@example.com&#39;);
</code></pre><p><em><strong>Insert multiple rows</strong></em></p>
<pre tabindex="0"><code>INSERT INTO users (name, email)
VALUES 
(&#39;User1&#39;, &#39;user1@mail.com&#39;),
(&#39;User2&#39;, &#39;user2@mail.com&#39;);
</code></pre><p><em><strong>Select all records</strong></em></p>
<pre tabindex="0"><code>SELECT * FROM users;
</code></pre><p><em><strong>Select specific columns</strong></em></p>
<pre tabindex="0"><code>SELECT name, email FROM users;
</code></pre><p><em><strong>Update data</strong></em></p>
<pre tabindex="0"><code>UPDATE users SET name=&#39;Jane Doe&#39; WHERE id=1;
</code></pre><p><em><strong>Delete data</strong></em></p>
<pre tabindex="0"><code>DELETE FROM users WHERE id=1;
</code></pre><p><strong>5. Filtering &amp; Sorting</strong></p>
<p><em><strong>Where condition</strong></em></p>
<pre tabindex="0"><code>SELECT * FROM users WHERE id=1;
</code></pre><p><em><strong>LIKE search</strong></em></p>
<pre tabindex="0"><code>SELECT * FROM users WHERE name LIKE &#39;%John%&#39;;
</code></pre><p><em><strong>Order by</strong></em></p>
<pre tabindex="0"><code>SELECT * FROM users ORDER BY id DESC;
</code></pre><p><em><strong>Limit results</strong></em></p>
<pre tabindex="0"><code>SELECT * FROM users LIMIT 10;
</code></pre><p><strong>6. User &amp; Permission Management</strong></p>
<p><em><strong>Create user</strong></em></p>
<pre tabindex="0"><code>CREATE USER &#39;user&#39;@&#39;localhost&#39; IDENTIFIED BY &#39;password&#39;;
</code></pre><p><em><strong>Grant privileges</strong></em></p>
<pre tabindex="0"><code>GRANT ALL PRIVILEGES ON db_name.* TO &#39;user&#39;@&#39;localhost&#39;;
</code></pre><p><em><strong>Revoke privileges</strong></em></p>
<pre tabindex="0"><code>REVOKE ALL PRIVILEGES ON db_name.* FROM &#39;user&#39;@&#39;localhost&#39;;
</code></pre><p><em><strong>Apply changes</strong></em></p>
<pre tabindex="0"><code>FLUSH PRIVILEGES;
</code></pre><p><em><strong>Delete user</strong></em></p>
<pre tabindex="0"><code>DROP USER &#39;user&#39;@&#39;localhost&#39;;
</code></pre><p><strong>7. Backup &amp; Restore</strong></p>
<p><em><strong>Backup database</strong></em></p>
<pre tabindex="0"><code>mysqldump -u root -p db_name &gt; backup.sql
</code></pre><p><em><strong>Backup all databases</strong></em></p>
<pre tabindex="0"><code>mysqldump -u root -p --all-databases &gt; alldb.sql
</code></pre><p><em><strong>Restore database</strong></em></p>
<pre tabindex="0"><code>mysql -u root -p db_name &lt; backup.sql
</code></pre><p><strong>8. Import &amp; Export Operations</strong></p>
<p><em><strong>Import SQL file</strong></em></p>
<pre tabindex="0"><code>mysql -u root -p db_name &lt; file.sql
</code></pre><p><em><strong>Export specific table</strong></em></p>
<pre tabindex="0"><code>mysqldump -u root -p db_name table_name &gt; table.sql
</code></pre><p><strong>9. Run MySQL Commands Directly from Terminal</strong></p>
<pre tabindex="0"><code>mysql -u root -p db_name -e &#34;SELECT * FROM users;&#34;
</code></pre><p><strong>10. MySQL Service Commands (Linux)</strong></p>
<p><em><strong>Check status</strong></em></p>
<pre tabindex="0"><code>systemctl status mysql
</code></pre><p><em><strong>Start MySQL</strong></em></p>
<pre tabindex="0"><code>sudo systemctl start mysql
</code></pre><p><em><strong>Stop MySQL</strong></em></p>
<pre tabindex="0"><code>sudo systemctl stop mysql
</code></pre><p><em><strong>Restart MySQL</strong></em></p>
<pre tabindex="0"><code>sudo systemctl restart mysql
</code></pre><p><strong>11. Performance &amp; Monitoring</strong></p>
<p><em><strong>Show running processes</strong></em></p>
<pre tabindex="0"><code>SHOW PROCESSLIST;
</code></pre><p><em><strong>Show variables</strong></em></p>
<pre tabindex="0"><code>SHOW VARIABLES;
</code></pre><p><em><strong>Show status</strong></em></p>
<pre tabindex="0"><code>SHOW STATUS;
</code></pre><p><strong>12. Useful Tips</strong></p>
<ul>
<li>Always use <code>WHERE</code> in UPDATE and DELETE queries</li>
<li>Take regular backups before major changes</li>
<li>Use strong passwords for database users</li>
<li>Monitor slow queries for performance tuning</li>
</ul>
<p>Conclusion</p>
<p>Mastering MySQL commands from the Linux terminal gives you full control over database operations, improves efficiency, and helps in faster troubleshooting. Whether you&rsquo;re managing databases, users, or backups, these commands are essential for every developer and system administrator.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>HTML Form to Google Sheet Integration</title>

      <link>https://wavesdream.com/posts/html-form-google-sheet-integration/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/html-form-google-sheet-integration/</guid>

      <pubDate>Fri, 16 Jan 2026 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>A few days ago, in a project, the client asked to implement a feature to create a web form in HTML with file upload ability. The form submission data is needed to be stored in a Google sheet, and the uploaded file will be stored in Google Drive.</p>
<p>In this article I am sharing the exact process I followed.</p>
<p><strong>Step 1: Prepare Google Sheet</strong></p>
<ol>
<li>
<p>Create a new Google Sheet (say <strong>Car Records</strong>).</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>A few days ago, in a project, the client asked to implement a feature to create a web form in HTML with file upload ability. The form submission data is needed to be stored in a Google sheet, and the uploaded file will be stored in Google Drive.</p>
<p>In this article I am sharing the exact process I followed.</p>
<p><strong>Step 1: Prepare Google Sheet</strong></p>
<ol>
<li>
<p>Create a new Google Sheet (say <strong>Car Records</strong>).</p>
</li>
<li>
<p>Go to <strong>Extensions → Apps Script</strong>.</p>
</li>
<li>
<p>Paste this script:</p>
</li>
</ol>
<p>function doPost(e) {
try {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = JSON.parse(e.postData.contents);</p>
<pre><code>// Create a folder in Google Drive (Change to your folder ID if you already created one)
var folderId = &quot;PASTE_YOUR_FOLDER_ID_HERE&quot;;  
var folder = DriveApp.getFolderById(folderId);

// Function to save Base64 image and return URL
function saveImage(base64, filename) {
  if (!base64) return &quot;&quot;;
  var contentType = base64.match(/data:(.*);base64/)[1];
  var bytes = Utilities.base64Decode(base64.split(&quot;,&quot;)[1]);
  var blob = Utilities.newBlob(bytes, contentType, filename);
  var file = folder.createFile(blob);
  file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  return file.getUrl();
}

var frontUrl = saveImage(data.front_image, &quot;front_&quot; + Date.now() + &quot;.jpg&quot;);
var sideUrl = saveImage(data.side_image, &quot;side_&quot; + Date.now() + &quot;.jpg&quot;);

// Save data in sheet
sheet.appendRow([
  new Date(),
  data.customer_name,
  data.mobile_number,
  data.dealer_name,
  data.car_number,
  data.chasis_number,
  frontUrl,
  sideUrl
]);

return ContentService.createTextOutput(
  JSON.stringify({ result: &quot;success&quot;, message: &quot;Data saved successfully!&quot; })
).setMimeType(ContentService.MimeType.JSON);
</code></pre>
<p>} catch (error) {
return ContentService.createTextOutput(
JSON.stringify({ result: &ldquo;error&rdquo;, message: error.message })
).setMimeType(ContentService.MimeType.JSON);
}
}</p>
<ul>
<li>
<p>Save it and click <strong>Deploy → New Deployment</strong> → choose <strong>Web app</strong>.</p>
<ul>
<li>
<p>Execution: <strong>Me</strong></p>
</li>
<li>
<p>Access: <strong>Anyone with the link</strong></p>
</li>
</ul>
</li>
<li>
<p>Copy the <strong>Web App URL</strong> (you’ll use it in the form).</p>
</li>
</ul>
<p>Replace <code>PASTE_YOUR_FOLDER_ID_HERE</code> with the ID of the folder in your Google Drive where you want to store images.</p>
<ul>
<li>Open the folder in Google Drive → Copy the part after <code>/folders/</code> in the URL.</li>
</ul>
<p><strong>Step 2: HTML Form</strong></p>
<p>Here’s your form with mandatory/optional fields and image upload (images converted to Base64 before sending to Google Sheet):</p>
<pre tabindex="0"><code>```html

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Car Form&lt;/title&gt;
  &lt;style&gt;
    form { max-width: 400px; margin: auto; }
    label { display: block; margin-top: 10px; }
    input, button { width: 100%; padding: 8px; }
    .success { color: green; margin-top: 10px; }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;form id=&#34;carForm&#34;&gt;
    &lt;label&gt;Customer Name *&lt;/label&gt;
    &lt;input type=&#34;text&#34; name=&#34;customer_name&#34; required&gt;

    &lt;label&gt;Mobile Number *&lt;/label&gt;
    &lt;input type=&#34;text&#34; name=&#34;mobile_number&#34; required&gt;

    &lt;label&gt;Dealer Name *&lt;/label&gt;
    &lt;input type=&#34;text&#34; name=&#34;dealer_name&#34; required&gt;

    &lt;label&gt;Car Number&lt;/label&gt;
    &lt;input type=&#34;text&#34; name=&#34;car_number&#34;&gt;

    &lt;label&gt;Chasis Number&lt;/label&gt;
    &lt;input type=&#34;text&#34; name=&#34;chasis_number&#34;&gt;

    &lt;label&gt;Front Image&lt;/label&gt;
    &lt;input type=&#34;file&#34; name=&#34;front_image&#34; accept=&#34;image/*&#34;&gt;

    &lt;label&gt;Side Image&lt;/label&gt;
    &lt;input type=&#34;file&#34; name=&#34;side_image&#34; accept=&#34;image/*&#34;&gt;

    &lt;button type=&#34;submit&#34;&gt;Submit&lt;/button&gt;
    &lt;p id=&#34;message&#34; class=&#34;success&#34;&gt;&lt;/p&gt;
  &lt;/form&gt;

  &lt;script&gt;
    const scriptURL = &#34;PASTE_YOUR_GOOGLE_SCRIPT_URL_HERE&#34;;

    document.getElementById(&#34;carForm&#34;).addEventListener(&#34;submit&#34;, async function(e) {
      e.preventDefault();
      const form = e.target;
      const msg = document.getElementById(&#34;message&#34;);

      const toBase64 = file =&gt; new Promise((resolve, reject) =&gt; {
        if (!file) return resolve(&#34;&#34;);
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () =&gt; resolve(reader.result);
        reader.onerror = error =&gt; reject(error);
      });

      const frontImg = await toBase64(form.front_image.files[0]);
      const sideImg = await toBase64(form.side_image.files[0]);

      const data = {
        customer_name: form.customer_name.value,
        mobile_number: form.mobile_number.value,
        dealer_name: form.dealer_name.value,
        car_number: form.car_number.value,
        chasis_number: form.chasis_number.value,
        front_image: frontImg,
        side_image: sideImg
      };

      fetch(scriptURL, {
        method: &#34;POST&#34;,
        body: JSON.stringify(data)
      })
      .then(response =&gt; response.json())
      .then(res =&gt; {
        msg.textContent = res.message;
        form.reset();
      })
      .catch(err =&gt; {
        msg.textContent = &#34;Error submitting form!&#34;;
      });
    });
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Useful AI Prompts</title>

      <link>https://wavesdream.com/posts/useful-ai-prompts/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/useful-ai-prompts/</guid>

      <pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Sometimes I need to generate content using AI for the websites of my clients. I notice that AI generates content using the same common pattern, and anyone can identify it as AI-generated content. AI-generated content may not be good for search engines while indexing the websites.</p>
<p>I tried different types of prompts, and finally these prompts are generating quite impressive content that seems to be human-written.</p>
<p><strong>New Content</strong></p>
<p><em>Write fresh and original content on the given topic. Use very simple Indian English. Write short and clear sentences. Avoid complex words and long sentences. The content should sound natural and human-written. Make it easy to understand for a 4th or 5th standard Indian student. Keep the tone friendly and positive. Do not use technical or difficult language.</em></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Sometimes I need to generate content using AI for the websites of my clients. I notice that AI generates content using the same common pattern, and anyone can identify it as AI-generated content. AI-generated content may not be good for search engines while indexing the websites.</p>
<p>I tried different types of prompts, and finally these prompts are generating quite impressive content that seems to be human-written.</p>
<p><strong>New Content</strong></p>
<p><em>Write fresh and original content on the given topic. Use very simple Indian English. Write short and clear sentences. Avoid complex words and long sentences. The content should sound natural and human-written. Make it easy to understand for a 4th or 5th standard Indian student. Keep the tone friendly and positive. Do not use technical or difficult language.</em></p>
<p><strong>Rephrase Content</strong></p>
<p><em>Rephrase the given content in very simple Indian English. Use short and clear sentences. Do not use complex or difficult words. Do not make long or complex sentences. The writing should look natural and human-written. It should be easy to understand for a 4th or 5th standard Indian student. Keep the meaning the same.</em></p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Create a Dynamic HTML Sitemap in WordPress with a Shortcode</title>

      <link>https://wavesdream.com/posts/dynamic-html-sitemap-wordpress-shortcode/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/dynamic-html-sitemap-wordpress-shortcode/</guid>

      <pubDate>Fri, 18 Jul 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>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.</p>
<p>By the end, you’ll have a clean, dynamic sitemap you can insert anywhere using [html_sitemap exclude=”product,portfolio”].</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>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.</p>
<p>By the end, you’ll have a clean, dynamic sitemap you can insert anywhere using [html_sitemap exclude=”product,portfolio”].</p>
<p>Here’s an example:</p>
<p>Pages</p>
<ul>
<li>Home</li>
<li>About Us</li>
<li>Contact</li>
</ul>
<p>Blog Posts</p>
<ul>
<li>How to Build a WordPress Site</li>
<li>Top 10 SEO Tips</li>
</ul>
<p>Products</p>
<ul>
<li>Product A</li>
<li>Product B</li>
</ul>
<p><strong>Add this code to your theme’s functions.php file or in a custom plugin:</strong></p>
<pre tabindex="0"><code>// [html_sitemap] shortcode with dynamic exclude option
function generate_html_sitemap($atts) {
    // Parse shortcode attributes
    $atts = shortcode_atts(array(
        &#39;exclude&#39; =&gt; &#39;&#39;, // Default: no exclusions
    ), $atts, &#39;html_sitemap&#39;);

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

    ob_start();

    echo &#39;&lt;div class=&#34;html-sitemap&#34;&gt;&#39;;

    // List Pages (exclude if &#34;page&#34; is in exclusions)
    if (!in_array(&#39;page&#39;, $excluded_post_types)) {
        echo &#39;&lt;h2&gt;Pages&lt;/h2&gt;&#39;;
        echo &#39;&lt;ul&gt;&#39;;
        wp_list_pages(array(
            &#39;title_li&#39;    =&gt; &#39;&#39;,
            &#39;sort_column&#39; =&gt; &#39;menu_order, post_title&#39;,
        ));
        echo &#39;&lt;/ul&gt;&#39;;
    }

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

    // List Custom Post Types
    $args = array(
        &#39;public&#39;   =&gt; true,
    );
    $custom_post_types = get_post_types($args, &#39;objects&#39;);

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

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

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

    echo &#39;&lt;/div&gt;&#39;;

    return ob_get_clean();
}
add_shortcode(&#39;html_sitemap&#39;, &#39;generate_html_sitemap&#39;);
</code></pre><p><strong>Optional: Add Some Styling</strong>
Add this to Appearance → Customize → Additional CSS in your WordPress admin.</p>
<pre tabindex="0"><code>.html-sitemap ul {
    list-style: disc;
    margin-left: 20px;
}

.html-sitemap h2 {
    margin-top: 20px;
    font-size: 1.5em;
    color: #333;
}
</code></pre><p><strong>Usage Examples</strong>:</p>
<ul>
<li>Default (show everything): [html_sitemap]</li>
<li>Exclude posts and products: [html_sitemap exclude=”post,product”]</li>
<li>Exclude pages only: [html_sitemap exclude=”page”]</li>
<li>Exclude multiple custom post types: [html_sitemap exclude=”portfolio,testimonials”]</li>
</ul>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Add GST Number Field to WooCommerce Checkout and Order Emails</title>

      <link>https://wavesdream.com/posts/add-gst-number-field-woocommerce-checkout-order-emails/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/add-gst-number-field-woocommerce-checkout-order-emails/</guid>

      <pubDate>Fri, 23 May 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>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.</p>
<p><strong>Step 1: Add GST Number Field to Checkout Page</strong>
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.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>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.</p>
<p><strong>Step 1: Add GST Number Field to Checkout Page</strong>
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.</p>
<pre tabindex="0"><code>// Add GST Number field to checkout
add_action(&#39;woocommerce_after_checkout_billing_form&#39;, &#39;add_gst_field_to_checkout&#39;);
function add_gst_field_to_checkout($checkout) {
    echo &#39;&lt;div id=&#34;gst_number_field&#34;&gt;&lt;h3&gt;&#39; . __(&#39;GST Number (Optional)&#39;) . &#39;&lt;/h3&gt;&#39;;

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

    echo &#39;&lt;/div&gt;&#39;;
}
</code></pre><p><strong>Step 2: Save the GST Number to Order Meta</strong>
Use the following code in your theme functions.php file to to save the entered GST number into the order’s metadata.</p>
<pre tabindex="0"><code>// Save GST number in order meta
add_action(&#39;woocommerce_checkout_update_order_meta&#39;, &#39;save_gst_number_order_meta&#39;);
function save_gst_number_order_meta($order_id) {
    if (!empty($_POST[&#39;gst_number&#39;])) {
        update_post_meta($order_id, &#39;_gst_number&#39;, sanitize_text_field($_POST[&#39;gst_number&#39;]));
    }
}
</code></pre><p><strong>Step 3: Show GST Number on Admin Order Page</strong>
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.</p>
<pre tabindex="0"><code>// Show GST number in admin order page
add_action(&#39;woocommerce_admin_order_data_after_billing_address&#39;, &#39;display_gst_in_admin_order&#39;, 10, 1);
function display_gst_in_admin_order($order) {
    $gst_number = get_post_meta($order-&gt;get_id(), &#39;_gst_number&#39;, true);
    if (!empty($gst_number)) {
        echo &#39;&lt;p&gt;&lt;strong&gt;&#39; . __(&#39;GST Number&#39;) . &#39;:&lt;/strong&gt; &#39; . esc_html($gst_number) . &#39;&lt;/p&gt;&#39;;
    }
}
</code></pre><p><strong>Step 4: Show GST Number in Order Emails</strong>
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.</p>
<pre tabindex="0"><code>// Add GST number to emails below billing address
add_filter(&#39;woocommerce_email_customer_details_fields&#39;, &#39;add_gst_to_order_email&#39;, 10, 3);
function add_gst_to_order_email($fields, $sent_to_admin, $order) {
    $gst_number = get_post_meta($order-&gt;get_id(), &#39;_gst_number&#39;, true);
    if (!empty($gst_number)) {
        $fields[&#39;gst_number&#39;] = array(
            &#39;label&#39; =&gt; __(&#39;GST Number&#39;),
            &#39;value&#39; =&gt; $gst_number,
        );
    }
    return $fields;
}
</code></pre><p>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.</p>
<p>Plugin version of the same codes is also available on <a href="https://github.com/sanjaybhowmick/wc-gst-checkout-field">Github</a>.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Generate Product XML Feed in WooCommerce for Facebook and Google Merchant</title>

      <link>https://wavesdream.com/posts/woocommerce-product-xml-feed-facebook-google-merchant/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/woocommerce-product-xml-feed-facebook-google-merchant/</guid>

      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>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.</p>
<p>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?</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>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.</p>
<p>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?</p>
<p><strong>Why build your own feed?</strong></p>
<ul>
<li>No need for extra plugins</li>
<li>Full control over structure and attributes</li>
<li>Supports all WooCommerce product types</li>
<li>Dynamically includes all variation attributes</li>
<li>Can be used for Facebook, Google, or any XML-based product platform</li>
</ul>
<p>Step 1: Create the XML feed file</p>
<p>Create a new file in your website root directory name it as product-feed-xml.php. Paste the following code inside it.</p>
<pre tabindex="0"><code>&lt;?php
require_once(&#39;wp-load.php&#39;);
ob_clean(); // Clean any prior output to prevent XML errors
header(&#39;Content-Type: application/xml; charset=utf-8&#39;);
echo &#39;&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;&#39;;
?&gt;
&lt;rss version=&#34;2.0&#34; xmlns:g=&#34;http://base.google.com/ns/1.0&#34;&gt;
&lt;channel&gt;
&lt;title&gt;Your Store Feed&lt;/title&gt;
&lt;link&gt;&lt;?php echo esc_url(site_url()); ?&gt;&lt;/link&gt;
&lt;description&gt;WooCommerce Product Feed&lt;/description&gt;
&lt;?php
$args = [
&#39;post_type&#39;      =&gt; [&#39;product&#39;, &#39;product_variation&#39;],
&#39;post_status&#39;    =&gt; &#39;publish&#39;,
&#39;posts_per_page&#39; =&gt; -1
];
$loop = new WP_Query($args);
if ($loop-&gt;have_posts()) {
while ($loop-&gt;have_posts()) {
$loop-&gt;the_post();
$product = wc_get_product(get_the_ID());
if (!$product || !$product-&gt;is_visible()) continue;
$is_variation = $product-&gt;is_type(&#39;variation&#39;);
$parent_id = $is_variation ? $product-&gt;get_parent_id() : $product-&gt;get_id();
$parent = wc_get_product($parent_id);

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

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

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

&lt;?php
// Output all variation attributes dynamically
$attributes = $product-&gt;get_attributes();
foreach ($attributes as $attribute_name =&gt; $attribute) {
$label = wc_attribute_label($attribute_name);
$value = $product-&gt;get_attribute($attribute_name);
if (!empty($value)) {
$tag_name = strtolower(preg_replace(&#39;/[^a-z0-9_]/i&#39;, &#39;_&#39;, $label));
echo &#34;    &lt;g:&#34; . esc_html($tag_name) . &#34;&gt;&#34; . esc_html($value) . &#34;&lt;/g:&#34; . esc_html($tag_name) . &#34;&gt;n&#34;;
}
}
?&gt;
&lt;/item&gt;
&lt;?php
}
}
wp_reset_postdata();
?&gt;
&lt;/channel&gt;
&lt;/rss&gt;
</code></pre><p>Step 2: Access and test the feed
Visit: <a href="https://yourdomain.com/product-feed-xml.php">https://yourdomain.com/product-feed-xml.php</a></p>
<p>You’ll see a fully structured XML file that can be submitted to:<br>
<a href="https://www.facebook.com/commerce_manager/">Facebook Commerce Manager</a><br>
[Google Merchant Center<br>
](http://Google Merchant Center)You can schedule Facebook or Google to fetch your feed daily using the public feed URL: <a href="https://yourdomain.com/product-feed-xml.php">https://yourdomain.com/product-feed-xml.php</a> and you do not need to manually upload a CSV or XML file.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Build a Custom YouTube Feed Plugin for WordPress</title>

      <link>https://wavesdream.com/posts/custom-youtube-feed-plugin-wordpress/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/custom-youtube-feed-plugin-wordpress/</guid>

      <pubDate>Sat, 10 May 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>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.</p>
<p><strong>Key Features</strong></p>
<ul>
<li>Multiple Channel Support: Add videos from multiple YouTube channels</li>
<li>Individual Video Support: Include specific videos by URL</li>
<li>Responsive Grid Layout: 3-column grid that adapts to screen size</li>
<li>Popup Video Player: Lightbox-style playback with Magnific Popup</li>
<li>Smart Caching: 24-hour cache to reduce API calls</li>
<li>Easy Pagination: Automatic pagination for large video collections</li>
<li>Admin Dashboard: Simple interface for managing channels and settings</li>
</ul>
<p><strong>Installation</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>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.</p>
<p><strong>Key Features</strong></p>
<ul>
<li>Multiple Channel Support: Add videos from multiple YouTube channels</li>
<li>Individual Video Support: Include specific videos by URL</li>
<li>Responsive Grid Layout: 3-column grid that adapts to screen size</li>
<li>Popup Video Player: Lightbox-style playback with Magnific Popup</li>
<li>Smart Caching: 24-hour cache to reduce API calls</li>
<li>Easy Pagination: Automatic pagination for large video collections</li>
<li>Admin Dashboard: Simple interface for managing channels and settings</li>
</ul>
<p><strong>Installation</strong></p>
<ul>
<li>Upload the plugin files to your WordPress plugins directory (/wp-content/plugins/)</li>
<li>Activate the plugin through the WordPress admin panel</li>
<li>Navigate to Settings → YouTube Channels to configure your API key and channels</li>
</ul>
<p><strong>Requirements</strong></p>
<ul>
<li>WordPress 5.0 or higher</li>
<li>PHP 7.0 or higher</li>
<li>YouTube Data API v3 key (free)</li>
</ul>
<p><strong>Usage</strong>
Shortcode: Add videos to any post or page using the shortcode:</p>
<pre tabindex="0"><code>[youtube_videos]
</code></pre><p><strong>Admin Settings</strong></p>
<ul>
<li>API Key: Enter your YouTube Data API key (required)</li>
<li>Videos Per Channel: Set how many videos to show from each channel</li>
<li>Channel URLs: Add YouTube channel URLs (supports all URL formats)</li>
<li>Individual Videos: Add specific video URLs</li>
<li>Cache Management</li>
<li>The plugin automatically caches videos for 24 hours. You can manually clear the cache from the admin panel.</li>
</ul>
<p><strong>Customization</strong>
CSS Styling: The plugin includes default CSS that can be overridden in your theme’s stylesheet. Key classes:</p>
<p>.youtube-videos-grid - The main video container<br>
.youtube-video - Individual video items<br>
.youtube-pagination - Pagination controls</p>
<p>JavaScript: The plugin uses Magnific Popup for video playback. Customize the popup behavior by modifying the initialization in the shortcode output.</p>
<p><strong>GitHub Repository</strong>
<a href="https://github.com/sanjaybhowmick/wp-custom-youtube-feed">View on GitHub</a></p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Fetch Data from Google Sheet and Show in HTML Using PHP</title>

      <link>https://wavesdream.com/posts/fetch-google-sheet-data-html-using-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/fetch-google-sheet-data-html-using-php/</guid>

      <pubDate>Tue, 06 May 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>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.</p>
<h4 id="setup-instructions">Setup Instructions</h4>
<p><strong>Step 1: Get Your Google Sheet ID</strong>
Open your Google Sheet in a web browser<br>
Look at the URL in the address bar - it will look like:<br>
<a href="https://docs.google.com/spreadsheets/d/BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ/edit#gid=0">https://docs.google.com/spreadsheets/d/BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ/edit#gid=0</a><br>
The long string between /d/ and /edit is your Sheet ID (in this example: BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ)</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>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.</p>
<h4 id="setup-instructions">Setup Instructions</h4>
<p><strong>Step 1: Get Your Google Sheet ID</strong>
Open your Google Sheet in a web browser<br>
Look at the URL in the address bar - it will look like:<br>
<a href="https://docs.google.com/spreadsheets/d/BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ/edit#gid=0">https://docs.google.com/spreadsheets/d/BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ/edit#gid=0</a><br>
The long string between /d/ and /edit is your Sheet ID (in this example: BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ)</p>
<p><strong>Step 2: Create a Google API Key</strong></p>
<ul>
<li>Go to the Google <a href="https://console.cloud.google.com/">Cloud Console</a></li>
<li>Create a new project or select an existing one</li>
<li>Navigate to “APIs &amp; Services” &gt; “Library”</li>
<li>Search for “Google Sheets API” and enable it</li>
<li>Go to “APIs &amp; Services” &gt; “Credentials”</li>
<li>Click “Create Credentials” and select “API key”</li>
<li>Copy your new API key</li>
<li>(Optional) Restrict the API key to only work with the Sheets API for security</li>
</ul>
<p><strong>Step 3: Configure the PHP Code</strong><br>
Replace these values in the code:</p>
<p>$sheetID = “BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ”; // Your Sheet ID<br>
$apiKey = “xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”; // Your API Key<br>
$rows_count = 8; // Number of rows to display</p>
<p>**Step 4: Sheet Configuration<br>
**Your Google Sheet must have a named range or sheet tab that matches what you put in the API URL (in this example: Sheet1)</p>
<p>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<br>
Here is the entire code.</p>
<pre tabindex="0"><code>&lt;?php
// Google Sheets API configuration
$sheetID = &#34;BmzaSyBzQ0cRTrbf_vxrB75nh8AoV3BtawPiiCQ&#34;; // Replace with your actual Sheet ID
$apiKey = &#34;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&#34;; // Replace with your API Key
$apiURL = &#34;https://sheets.googleapis.com/v4/spreadsheets/$sheetID/values/Sheet1?key=$apiKey&#34;;

$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[&#39;values&#39;]) &amp;&amp; count($data[&#39;values&#39;]) &gt; 1) {
for ($i = 1; $i &lt;= min($rows_count, count($data[&#39;values&#39;]) - 1); $i++) {    

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

&lt;?php } ?&gt;
&lt;div class=&#34;row&#34;&gt;
&lt;div&gt;&lt;?php echo $column_1;?&gt;&lt;/div&gt;
&lt;div&gt;&lt;?php echo $column_2;?&gt;&lt;/div&gt;
&lt;div&gt;&lt;?php echo $column_3;?&gt;&lt;/div&gt;
&lt;div&gt;&lt;?php echo $column_4;?&gt;&lt;/div&gt;
&lt;div&gt;&lt;?php echo $column_5;?&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;?php } ?&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Disable the Comment System Completely in WordPress</title>

      <link>https://wavesdream.com/posts/disable-comment-system-completely-wordpress/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/disable-comment-system-completely-wordpress/</guid>

      <pubDate>Fri, 02 May 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Here’s a comprehensive function to completely disable the WordPress comment system. Add this code to your theme’s functions.php file or in a custom plugin.</p>
<pre tabindex="0"><code>&lt;?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, &#39;comments&#39;)) {
            remove_post_type_support($post_type, &#39;comments&#39;);
            remove_post_type_support($post_type, &#39;trackbacks&#39;);
        }
    }
    
    // Close comments on all existing posts
    update_option(&#39;close_comments_for_old_posts&#39;, 1);
    update_option(&#39;close_comments_days_old&#39;, 0);
    update_option(&#39;comment_registration&#39;, 1);
    update_option(&#39;default_ping_status&#39;, &#39;closed&#39;);
    update_option(&#39;default_comment_status&#39;, &#39;closed&#39;);
    
    // Redirect any comment feed requests to homepage
    add_action(&#39;template_redirect&#39;, function() {
        if (is_comment_feed()) {
            wp_redirect(home_url(), 301);
            exit;
        }
    });
    
    // Remove comments page from admin menu
    add_action(&#39;admin_menu&#39;, function() {
        remove_menu_page(&#39;edit-comments.php&#39;);
        remove_submenu_page(&#39;options-general.php&#39;, &#39;options-discussion.php&#39;);
    });
    
    // Remove comments links from admin bar
    add_action(&#39;wp_before_admin_bar_render&#39;, function() {
        global $wp_admin_bar;
        $wp_admin_bar-&gt;remove_menu(&#39;comments&#39;);
    });
    
    // Remove dashboard comments widget
    add_action(&#39;wp_dashboard_setup&#39;, function() {
        remove_meta_box(&#39;dashboard_recent_comments&#39;, &#39;dashboard&#39;, &#39;normal&#39;);
    });
    
    // Disable comments REST API endpoint
    add_filter(&#39;rest_endpoints&#39;, function($endpoints) {
        unset($endpoints[&#39;/wp/v2/comments&#39;]);
        unset($endpoints[&#39;/wp/v2/comments/(?P&lt;id&gt;[d]+)&#39;]);
        return $endpoints;
    });
    
    // Remove comment form completely (front-end)
    add_filter(&#39;comments_open&#39;, &#39;__return_false&#39;, 20, 2);
    add_filter(&#39;pings_open&#39;, &#39;__return_false&#39;, 20, 2);
    add_filter(&#39;comments_array&#39;, &#39;__return_empty_array&#39;, 10, 2);
    
    // Remove comment-reply script
    add_action(&#39;wp_enqueue_scripts&#39;, function() {
        wp_deregister_script(&#39;comment-reply&#39;);
    }, 100);
    
    // Remove comment form from templates
    add_action(&#39;init&#39;, function() {
        // Remove comment-reply script
        remove_action(&#39;wp_head&#39;, &#39;feed_links_extra&#39;, 3);
        
        // Remove comment form from wp_head
        remove_action(&#39;wp_head&#39;, &#39;feed_links&#39;, 2);
        
        // Remove comment form from content
        remove_filter(&#39;the_content&#39;, &#39;wpautop&#39;);
        add_filter(&#39;the_content&#39;, function($content) {
            if (is_singular()) {
                $content = preg_replace(&#39;/&lt;div[^&gt;]+id=&#34;respond&#34;[^&gt;]*&gt;.*?&lt;/div&gt;/is&#39;, &#39;&#39;, $content);
                $content = preg_replace(&#39;/&lt;h3[^&gt;]+id=&#34;reply-title&#34;[^&gt;]*&gt;.*?&lt;/h3&gt;/is&#39;, &#39;&#39;, $content);
                $content = preg_replace(&#39;/&lt;form[^&gt;]+id=&#34;commentform&#34;[^&gt;]*&gt;.*?&lt;/form&gt;/is&#39;, &#39;&#39;, $content);
            }
            return $content;
        });
    });
}
add_action(&#39;init&#39;, &#39;disable_comments_system&#39;);

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

// Hide comments in admin for all post types
add_action(&#39;admin_init&#39;, function() {
    $post_types = get_post_types();
    foreach ($post_types as $post_type) {
        if (post_type_supports($post_type, &#39;comments&#39;)) {
            remove_post_type_support($post_type, &#39;comments&#39;);
            remove_post_type_support($post_type, &#39;trackbacks&#39;);
        }
    }
});
?&gt;
</code></pre><p><strong>The function will:</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Here’s a comprehensive function to completely disable the WordPress comment system. Add this code to your theme’s functions.php file or in a custom plugin.</p>
<pre tabindex="0"><code>&lt;?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, &#39;comments&#39;)) {
            remove_post_type_support($post_type, &#39;comments&#39;);
            remove_post_type_support($post_type, &#39;trackbacks&#39;);
        }
    }
    
    // Close comments on all existing posts
    update_option(&#39;close_comments_for_old_posts&#39;, 1);
    update_option(&#39;close_comments_days_old&#39;, 0);
    update_option(&#39;comment_registration&#39;, 1);
    update_option(&#39;default_ping_status&#39;, &#39;closed&#39;);
    update_option(&#39;default_comment_status&#39;, &#39;closed&#39;);
    
    // Redirect any comment feed requests to homepage
    add_action(&#39;template_redirect&#39;, function() {
        if (is_comment_feed()) {
            wp_redirect(home_url(), 301);
            exit;
        }
    });
    
    // Remove comments page from admin menu
    add_action(&#39;admin_menu&#39;, function() {
        remove_menu_page(&#39;edit-comments.php&#39;);
        remove_submenu_page(&#39;options-general.php&#39;, &#39;options-discussion.php&#39;);
    });
    
    // Remove comments links from admin bar
    add_action(&#39;wp_before_admin_bar_render&#39;, function() {
        global $wp_admin_bar;
        $wp_admin_bar-&gt;remove_menu(&#39;comments&#39;);
    });
    
    // Remove dashboard comments widget
    add_action(&#39;wp_dashboard_setup&#39;, function() {
        remove_meta_box(&#39;dashboard_recent_comments&#39;, &#39;dashboard&#39;, &#39;normal&#39;);
    });
    
    // Disable comments REST API endpoint
    add_filter(&#39;rest_endpoints&#39;, function($endpoints) {
        unset($endpoints[&#39;/wp/v2/comments&#39;]);
        unset($endpoints[&#39;/wp/v2/comments/(?P&lt;id&gt;[d]+)&#39;]);
        return $endpoints;
    });
    
    // Remove comment form completely (front-end)
    add_filter(&#39;comments_open&#39;, &#39;__return_false&#39;, 20, 2);
    add_filter(&#39;pings_open&#39;, &#39;__return_false&#39;, 20, 2);
    add_filter(&#39;comments_array&#39;, &#39;__return_empty_array&#39;, 10, 2);
    
    // Remove comment-reply script
    add_action(&#39;wp_enqueue_scripts&#39;, function() {
        wp_deregister_script(&#39;comment-reply&#39;);
    }, 100);
    
    // Remove comment form from templates
    add_action(&#39;init&#39;, function() {
        // Remove comment-reply script
        remove_action(&#39;wp_head&#39;, &#39;feed_links_extra&#39;, 3);
        
        // Remove comment form from wp_head
        remove_action(&#39;wp_head&#39;, &#39;feed_links&#39;, 2);
        
        // Remove comment form from content
        remove_filter(&#39;the_content&#39;, &#39;wpautop&#39;);
        add_filter(&#39;the_content&#39;, function($content) {
            if (is_singular()) {
                $content = preg_replace(&#39;/&lt;div[^&gt;]+id=&#34;respond&#34;[^&gt;]*&gt;.*?&lt;/div&gt;/is&#39;, &#39;&#39;, $content);
                $content = preg_replace(&#39;/&lt;h3[^&gt;]+id=&#34;reply-title&#34;[^&gt;]*&gt;.*?&lt;/h3&gt;/is&#39;, &#39;&#39;, $content);
                $content = preg_replace(&#39;/&lt;form[^&gt;]+id=&#34;commentform&#34;[^&gt;]*&gt;.*?&lt;/form&gt;/is&#39;, &#39;&#39;, $content);
            }
            return $content;
        });
    });
}
add_action(&#39;init&#39;, &#39;disable_comments_system&#39;);

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

// Hide comments in admin for all post types
add_action(&#39;admin_init&#39;, function() {
    $post_types = get_post_types();
    foreach ($post_types as $post_type) {
        if (post_type_supports($post_type, &#39;comments&#39;)) {
            remove_post_type_support($post_type, &#39;comments&#39;);
            remove_post_type_support($post_type, &#39;trackbacks&#39;);
        }
    }
});
?&gt;
</code></pre><p><strong>The function will:</strong></p>
<ul>
<li>Remove comment support from all post types</li>
<li>Close comments on all existing posts</li>
<li>Disable comments and pingbacks by default</li>
<li>Remove comment-related admin menu items</li>
<li>Remove comment links from the admin bar</li>
<li>Remove the comments dashboard widget</li>
<li>Disable the comments REST API endpoints</li>
<li>Redirect comment feeds to the homepage</li>
</ul>
<p><strong>Additional Steps for Stubborn Comment Forms {.wp-block-heading}</strong><br>
If the comment form still appears after adding this code. Check your theme files: Some themes hard-code the comment form. Look in these files:</p>
<ul>
<li>comments.php</li>
<li>single.php</li>
<li>page.php</li>
<li>content-single.php</li>
<li>Any files with comment_form() calls</li>
</ul>
<p>Add CSS to hide comments (as last resort)</p>
<pre tabindex="0"><code>add_action(&#39;wp_head&#39;, function() {
    echo &#39;&lt;style&gt;
        #comments, #respond, .comments-area, .comment-respond, 
        .comment-form, .comments-title, .comment-list {
            display: none !important;
        }
    &lt;/style&gt;&#39;;
});
</code></pre><p>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.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Block HTTrack and Other Web Scrapers</title>

      <link>https://wavesdream.com/posts/block-httrack-and-web-scrapers/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/block-httrack-and-web-scrapers/</guid>

      <pubDate>Tue, 22 Apr 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>There are several web scrappers tools are available by which your website can be downloaded as static files.</p>
<p>To block these webscrappers, just create a .htaccess file inside your website root directory and put the following code.</p>
<pre tabindex="0"><code>##Block bad bots
RewriteEngine On 
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
RewriteCond %{HTTP_USER_AGENT} ^Bot mailto:craftbot@yahoo.com [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]
</code></pre>
      ]]></description>

      <content:encoded><![CDATA[
<p>There are several web scrappers tools are available by which your website can be downloaded as static files.</p>
<p>To block these webscrappers, just create a .htaccess file inside your website root directory and put the following code.</p>
<pre tabindex="0"><code>##Block bad bots
RewriteEngine On 
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
RewriteCond %{HTTP_USER_AGENT} ^Bot mailto:craftbot@yahoo.com [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]
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Change Default Sender Name and Sender Email in WordPress</title>

      <link>https://wavesdream.com/posts/change-default-sender-name-email-wordpress/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/change-default-sender-name-email-wordpress/</guid>

      <pubDate>Tue, 08 Apr 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>When you get any email from your self hosted WordPress website, form name of that email will be <strong>WordPress</strong> which is quite annoying to you or your clients.</p>
<p>You can overwrite this by adding this small piece of code in the functions.php file of your theme.</p>
<pre tabindex="0"><code>function custom_wp_mail_from_name($email_from_name) {
    return &#39;Your Website Name&#39;; // Change this to your desired name
}
add_filter(&#39;wp_mail_from_name&#39;, &#39;custom_wp_mail_from_name&#39;);
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 &#39;no-reply@yourdomain.com&#39;; // Change this to your desired email
}
add_filter(&#39;wp_mail_from&#39;, &#39;custom_wp_mail_from&#39;);
</code></pre>
      ]]></description>

      <content:encoded><![CDATA[
<p>When you get any email from your self hosted WordPress website, form name of that email will be <strong>WordPress</strong> which is quite annoying to you or your clients.</p>
<p>You can overwrite this by adding this small piece of code in the functions.php file of your theme.</p>
<pre tabindex="0"><code>function custom_wp_mail_from_name($email_from_name) {
    return &#39;Your Website Name&#39;; // Change this to your desired name
}
add_filter(&#39;wp_mail_from_name&#39;, &#39;custom_wp_mail_from_name&#39;);
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 &#39;no-reply@yourdomain.com&#39;; // Change this to your desired email
}
add_filter(&#39;wp_mail_from&#39;, &#39;custom_wp_mail_from&#39;);
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Create a WordPress Admin Menu Page, Fetch Data from a Custom MySQL Table, and Export to CSV</title>

      <link>https://wavesdream.com/posts/wordpress-admin-menu-custom-mysql-table-export-csv/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/wordpress-admin-menu-custom-mysql-table-export-csv/</guid>

      <pubDate>Thu, 03 Apr 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>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:</p>
<p><strong>Step 1:</strong> 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:</p>
<pre tabindex="0"><code>&lt;?php
global $wpdb;
$table_name = $wpdb-&gt;prefix . &#39;custom_data&#39;;

$sql = &#34;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;&#34;;

require_once(ABSPATH . &#39;wp-admin/includes/upgrade.php&#39;);
dbDelta($sql);
?&gt;
</code></pre><p><strong>Step 2:</strong> Add the following code to your theme’s functions.php file or create a custom plugin file to define the custom menu page:</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>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:</p>
<p><strong>Step 1:</strong> 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:</p>
<pre tabindex="0"><code>&lt;?php
global $wpdb;
$table_name = $wpdb-&gt;prefix . &#39;custom_data&#39;;

$sql = &#34;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;&#34;;

require_once(ABSPATH . &#39;wp-admin/includes/upgrade.php&#39;);
dbDelta($sql);
?&gt;
</code></pre><p><strong>Step 2:</strong> Add the following code to your theme’s functions.php file or create a custom plugin file to define the custom menu page:</p>
<pre tabindex="0"><code>&lt;?php
// Add menu page
function custom_menu_page()
{
    add_menu_page(
        &#39;Custom Data&#39;,
        &#39;Custom Data&#39;,
        &#39;manage_options&#39;,
        &#39;custom-data&#39;,
        &#39;custom_menu_page_callback&#39;
    );
}
add_action(&#39;admin_menu&#39;, &#39;custom_menu_page&#39;);

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

    // Retrieve custom table data
    $table_name = $wpdb-&gt;prefix . &#39;custom_data&#39;;
    $results = $wpdb-&gt;get_results(&#34;SELECT * FROM $table_name&#34;, ARRAY_A);

    // Display custom table data
    echo &#39;&lt;div class=&#34;wrap&#34;&gt;&#39;;
    echo &#39;&lt;h1&gt;Custom Data&lt;/h1&gt;&#39;;

    // Export to CSV/Excel button
    echo &#39;&lt;form method=&#34;post&#34; action=&#34;&#39; . admin_url(&#39;admin-post.php&#39;) . &#39;&#34;&gt;&#39;;
    echo &#39;&lt;input type=&#34;hidden&#34; name=&#34;action&#34; value=&#34;export_custom_data&#34;&gt;&#39;;
    echo &#39;&lt;button type=&#34;submit&#34; class=&#34;button&#34;&gt;Export to CSV/Excel&lt;/button&gt;&#39;;
    echo &#39;&lt;/form&gt;&#39;;

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

    echo &#39;&lt;/div&gt;&#39;;
}

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

    // Retrieve custom table data
    $table_name = $wpdb-&gt;prefix . &#39;custom_data&#39;;
    $results = $wpdb-&gt;get_results(&#34;SELECT * FROM $table_name&#34;, ARRAY_A);

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

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

        fclose($output);
        exit;
    }
}
add_action(&#39;admin_post_export_custom_data&#39;, &#39;export_custom_data_action&#39;);
add_action(&#39;admin_post_nopriv_export_custom_data&#39;, &#39;export_custom_data_action&#39;);
?&gt;
</code></pre><p><strong>Step 3:</strong> Save the changes to the functions.php file or your custom plugin file.</p>
<p><strong>Step 4:</strong> 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<br>
“Export to CSV/Excel” that allows you to download the data in CSV/Excel format.</p>
<p><strong>Note:</strong> 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.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>PHP Script to Download File from a Specific Folder</title>

      <link>https://wavesdream.com/posts/php-script-download-file-from-specific-folder/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/php-script-download-file-from-specific-folder/</guid>

      <pubDate>Tue, 11 Mar 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Below is a simple example of a PHP script that allows you to download file from a specific folder. You can link to this PHP file with the file name as a parameter.<br>
Create a file named download.php and add the following code:</p>
<pre tabindex="0"><code>&lt;?php
// Specify the folder where your files are stored
$folderPath = &#39;/path/to/your/files/&#39;;

// Get the file name from the query parameter
if (isset($_GET[&#39;file&#39;])) {
    $fileName = basename($_GET[&#39;file&#39;]);
    $filePath = $folderPath . $fileName;

    // Check if the file exists
    if (file_exists($filePath)) {
        // Set headers for download
        header(&#39;Content-Description: File Transfer&#39;);
        header(&#39;Content-Type: application/octet-stream&#39;);
        header(&#39;Content-Disposition: attachment; filename=&#34;&#39; . $fileName . &#39;&#34;&#39;);
        header(&#39;Expires: 0&#39;);
        header(&#39;Cache-Control: must-revalidate&#39;);
        header(&#39;Pragma: public&#39;);
        header(&#39;Content-Length: &#39; . filesize($filePath));

        // Read the file and output it to the browser
        readfile($filePath);
        exit;
    } else {
        echo &#39;File not found.&#39;;
    }
} else {
    echo &#39;File parameter missing.&#39;;
}
?&gt;
</code></pre><p>Replace ‘/path/to/your/files/’ with the actual path to the folder where your files are stored. Now, you can link to this script by providing the file name as a parameter, like this:</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Below is a simple example of a PHP script that allows you to download file from a specific folder. You can link to this PHP file with the file name as a parameter.<br>
Create a file named download.php and add the following code:</p>
<pre tabindex="0"><code>&lt;?php
// Specify the folder where your files are stored
$folderPath = &#39;/path/to/your/files/&#39;;

// Get the file name from the query parameter
if (isset($_GET[&#39;file&#39;])) {
    $fileName = basename($_GET[&#39;file&#39;]);
    $filePath = $folderPath . $fileName;

    // Check if the file exists
    if (file_exists($filePath)) {
        // Set headers for download
        header(&#39;Content-Description: File Transfer&#39;);
        header(&#39;Content-Type: application/octet-stream&#39;);
        header(&#39;Content-Disposition: attachment; filename=&#34;&#39; . $fileName . &#39;&#34;&#39;);
        header(&#39;Expires: 0&#39;);
        header(&#39;Cache-Control: must-revalidate&#39;);
        header(&#39;Pragma: public&#39;);
        header(&#39;Content-Length: &#39; . filesize($filePath));

        // Read the file and output it to the browser
        readfile($filePath);
        exit;
    } else {
        echo &#39;File not found.&#39;;
    }
} else {
    echo &#39;File parameter missing.&#39;;
}
?&gt;
</code></pre><p>Replace ‘/path/to/your/files/’ with the actual path to the folder where your files are stored. Now, you can link to this script by providing the file name as a parameter, like this:</p>
<pre tabindex="0"><code>&lt;strong&gt;&lt;a href=”download.php?file=myfile.txt”&gt;Download&lt;/a&gt;&lt;/strong&gt;
</code></pre><p>Make sure to adjust the link and file names accordingly. Note that this is a basic example, and you may need to add additional security measures based on your specific requirements, such as checking user permissions and validating file types.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Update Cache of an Elementor Website</title>

      <link>https://wavesdream.com/posts/update-cache-elementor-website/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/update-cache-elementor-website/</guid>

      <pubDate>Tue, 11 Feb 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>When you move your WordPress site to a new domain, some design problems can happen. This is common if you use Elementor. Your website may look broken. Some styles may not load. The layout may look different.</p>
<p>This happens because Elementor saves design data and links with the old domain. After moving the site, these do not update on their own.</p>
<p>In this guide, you will learn simple steps to fix this. You will update links, refresh styles, and make your website look normal again.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>When you move your WordPress site to a new domain, some design problems can happen. This is common if you use Elementor. Your website may look broken. Some styles may not load. The layout may look different.</p>
<p>This happens because Elementor saves design data and links with the old domain. After moving the site, these do not update on their own.</p>
<p>In this guide, you will learn simple steps to fix this. You will update links, refresh styles, and make your website look normal again.</p>
<ol>
<li>
<p><strong>Login to WordPress Admin</strong> of your new domain.</p>
</li>
<li>
<p>Go to:<br>
<strong>Elementor → Tools → General</strong></p>
<ul>
<li>
<p>Click <strong>Regenerate CSS &amp; Data</strong>.</p>
</li>
<li>
<p>Click <strong>Sync Library</strong> (to refresh template library).</p>
</li>
</ul>
</li>
<li>
<p>Go to:<br>
<strong>Elementor → Tools → Replace URL</strong></p>
<ul>
<li>
<p>Enter your <strong>old domain</strong> in the “Search” field.</p>
</li>
<li>
<p>Enter your <strong>new domain</strong> in the “Replace” field.</p>
</li>
<li>
<p>Run the replacement (this updates serialized Elementor data in the database).</p>
</li>
</ul>
</li>
<li>
<p><strong>Clear Caches</strong></p>
<ul>
<li>
<p>If you’re using a caching plugin (e.g., WP Rocket, LiteSpeed, W3 Total Cache), clear the cache.</p>
</li>
<li>
<p>If you’re on Cloudflare or server-side cache, purge that too.</p>
</li>
</ul>
</li>
<li>
<p><strong>Re-save Permalinks</strong></p>
<ul>
<li>
<p>Go to <strong>Settings → Permalinks</strong>.</p>
</li>
<li>
<p>Simply click <strong>Save Changes</strong> (this flushes rewrite rules).</p>
</li>
</ul>
</li>
<li>
<p><strong>Optional (if styles are still missing):</strong></p>
<ul>
<li>
<p>Go to <strong>Elementor → Settings → Advanced → CSS Print Method</strong> and switch between <strong>External File</strong> and <strong>Inline</strong>, then save.</p>
</li>
<li>
<p>This forces Elementor to re-generate CSS files.</p>
</li>
</ul>
</li>
</ol>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Upload Image and PDF File Using PHP</title>

      <link>https://wavesdream.com/posts/upload-image-pdf-file-using-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/upload-image-pdf-file-using-php/</guid>

      <pubDate>Mon, 10 Feb 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Here is a PHP script that allows users to upload image and PDF files with a maximum size of 5 MB. The uploaded files will be renamed using the current timestamp:</p>
<pre tabindex="0"><code>&lt;?php
if ($_SERVER[&#34;REQUEST_METHOD&#34;] == &#34;POST&#34; &amp;&amp; isset($_FILES[&#34;file&#34;])) {
    $allowedExtensions = array(&#34;jpg&#34;, &#34;jpeg&#34;, &#34;png&#34;, &#34;pdf&#34;);
    $maxFileSize = 5 * 1024 * 1024; // 5 MB in bytes

    $targetDirectory = &#34;uploads/&#34;;
    $timestamp = time();
    $targetFileName = $timestamp . &#34;_&#34; . basename($_FILES[&#34;file&#34;][&#34;name&#34;]);
    $targetPath = $targetDirectory . $targetFileName;
    
    $fileExtension = strtolower(pathinfo($targetFileName, PATHINFO_EXTENSION));

    if (in_array($fileExtension, $allowedExtensions) &amp;&amp; $_FILES[&#34;file&#34;][&#34;size&#34;] &lt;= $maxFileSize) {
        if (move_uploaded_file($_FILES[&#34;file&#34;][&#34;tmp_name&#34;], $targetPath)) {
            echo &#34;File uploaded successfully.&#34;;
        } else {
            echo &#34;Error uploading file.&#34;;
        }
    } else {
        echo &#34;Invalid file. Allowed file types: jpg, jpeg, png, pdf. Max file size: 5 MB.&#34;;
    }
}
?&gt;
</code></pre><p>This is HTML form for file upload.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Here is a PHP script that allows users to upload image and PDF files with a maximum size of 5 MB. The uploaded files will be renamed using the current timestamp:</p>
<pre tabindex="0"><code>&lt;?php
if ($_SERVER[&#34;REQUEST_METHOD&#34;] == &#34;POST&#34; &amp;&amp; isset($_FILES[&#34;file&#34;])) {
    $allowedExtensions = array(&#34;jpg&#34;, &#34;jpeg&#34;, &#34;png&#34;, &#34;pdf&#34;);
    $maxFileSize = 5 * 1024 * 1024; // 5 MB in bytes

    $targetDirectory = &#34;uploads/&#34;;
    $timestamp = time();
    $targetFileName = $timestamp . &#34;_&#34; . basename($_FILES[&#34;file&#34;][&#34;name&#34;]);
    $targetPath = $targetDirectory . $targetFileName;
    
    $fileExtension = strtolower(pathinfo($targetFileName, PATHINFO_EXTENSION));

    if (in_array($fileExtension, $allowedExtensions) &amp;&amp; $_FILES[&#34;file&#34;][&#34;size&#34;] &lt;= $maxFileSize) {
        if (move_uploaded_file($_FILES[&#34;file&#34;][&#34;tmp_name&#34;], $targetPath)) {
            echo &#34;File uploaded successfully.&#34;;
        } else {
            echo &#34;Error uploading file.&#34;;
        }
    } else {
        echo &#34;Invalid file. Allowed file types: jpg, jpeg, png, pdf. Max file size: 5 MB.&#34;;
    }
}
?&gt;
</code></pre><p>This is HTML form for file upload.</p>
<pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;File Upload&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form method=&#34;POST&#34; enctype=&#34;multipart/form-data&#34;&gt;
        &lt;input type=&#34;file&#34; name=&#34;file&#34; accept=&#34;.jpg, .jpeg, .png, .pdf&#34; required&gt;
        &lt;button type=&#34;submit&#34;&gt;Upload&lt;/button&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p><strong>Here’s what the script does:</strong></p>
<ul>
<li>It checks if the form has been submitted and if a file has been uploaded.</li>
<li>It sets the allowed file extensions ($allowedExtensions) and maximum file size ($maxFileSize).</li>
<li>It defines the target directory ($targetDirectory), generates a new</li>
<li>file name using the current timestamp, and constructs the target path.</li>
<li>It checks if the uploaded file has an allowed extension and if its size is within limits.</li>
<li>If the file meets the criteria, it moves the file to the target directory using move_uploaded_file() and echoes a success message.</li>
<li>If the file does not meet the criteria, it echoes an error message.</li>
<li>The HTML form allows users to select a file with the accept attribute specifying the allowed file types. After submitting the form, the PHP script processes the file upload.</li>
</ul>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>MySQL Columns Total and Show Highest Totals</title>

      <link>https://wavesdream.com/posts/mysql-column-total-highest-totals/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/mysql-column-total-highest-totals/</guid>

      <pubDate>Fri, 10 Jan 2025 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>To get the total of a MySQL field and then select the three highest totals from the table, you can use the following PHP script:</p>
<pre tabindex="0"><code>&lt;?php
// Assuming you have already established a MySQL connection

// Retrieve the total of a field and select the three highest totals
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$dbname = &#34;your_database_name&#34;;

// Create a new MySQL connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check the connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

// Prepare and execute the SQL statement to get the total and select three highest totals
$sql = &#34;SELECT SUM(field_name) AS total FROM table_name GROUP BY field_name ORDER BY total DESC LIMIT 3&#34;;
$result = $conn-&gt;query($sql);

if ($result &amp;&amp; $result-&gt;num_rows &gt; 0) {
    echo &#34;Three highest totals: &lt;br&gt;&#34;;
    while ($row = $result-&gt;fetch_assoc()) {
        $total = $row[&#39;total&#39;];
        echo $total . &#34;&lt;br&gt;&#34;;
    }
} else {
    echo &#34;No records found.&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p>Make sure to replace ‘your_username’, ‘your_password’, ‘your_database_name’, ‘field_name’, and ‘table_name’ with the actual values for your MySQL configuration and table structure.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>To get the total of a MySQL field and then select the three highest totals from the table, you can use the following PHP script:</p>
<pre tabindex="0"><code>&lt;?php
// Assuming you have already established a MySQL connection

// Retrieve the total of a field and select the three highest totals
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$dbname = &#34;your_database_name&#34;;

// Create a new MySQL connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check the connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

// Prepare and execute the SQL statement to get the total and select three highest totals
$sql = &#34;SELECT SUM(field_name) AS total FROM table_name GROUP BY field_name ORDER BY total DESC LIMIT 3&#34;;
$result = $conn-&gt;query($sql);

if ($result &amp;&amp; $result-&gt;num_rows &gt; 0) {
    echo &#34;Three highest totals: &lt;br&gt;&#34;;
    while ($row = $result-&gt;fetch_assoc()) {
        $total = $row[&#39;total&#39;];
        echo $total . &#34;&lt;br&gt;&#34;;
    }
} else {
    echo &#34;No records found.&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p>Make sure to replace ‘your_username’, ‘your_password’, ‘your_database_name’, ‘field_name’, and ‘table_name’ with the actual values for your MySQL configuration and table structure.</p>
<p>In this script, the SQL query uses the SUM function to calculate the total of the specified field (field_name) and groups the results by the field values. It then orders the results in descending order of the totals and limits the result set to the top three rows.</p>
<p>The script retrieves the three highest totals from the query results and prints them on the screen. If no records are found, it displays a message indicating that no records were found. Please make sure to adjust the SQL query and table/column names according to your specific table structure and requirements.</p>
<p><strong>Get total of a mysql field and then select 3 all records which have heighest total from the table</strong></p>
<p>To get the total of a MySQL field and then select all records that have the highest total from the table, you can use the following PHP script:</p>
<pre tabindex="0"><code>&lt;?php
// Assuming you have already established a MySQL connection

// Retrieve the total of a field and select all records with the highest total
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$dbname = &#34;your_database_name&#34;;

// Create a new MySQL connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check the connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

// Prepare and execute the SQL statement to get the total and select all records with the highest total
$sql = &#34;SELECT *, SUM(field_name) AS total FROM table_name GROUP BY id HAVING total = (SELECT MAX(total) FROM (SELECT SUM(field_name) AS total FROM table_name GROUP BY id) AS temp)&#34;;
$result = $conn-&gt;query($sql);

if ($result &amp;&amp; $result-&gt;num_rows &gt; 0) {
    echo &#34;Records with the highest total: &lt;br&gt;&#34;;
    while ($row = $result-&gt;fetch_assoc()) {
        // Access the record data
        $id = $row[&#39;id&#39;];
        $fieldValue = $row[&#39;field_name&#39;];
        $total = $row[&#39;total&#39;];

        // Process or display the record as needed
        echo &#34;ID: $id, Field Value: $fieldValue, Total: $total &lt;br&gt;&#34;;
    }
} else {
    echo &#34;No records found.&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p>Make sure to replace ‘your_username’, ‘your_password’, ‘your_database_name’, ‘field_name’, and ‘table_name’ with the actual values for your MySQL configuration and table structure.</p>
<p>In this script, the SQL query uses the SUM function to calculate the total of the specified field (field_name) for each record in the table. It then groups the results by the id column and selects only those records where the total is equal to the maximum total value across all records.</p>
<p>The script retrieves the records with the highest total from the query results and prints them on the screen. If no records are found, it displays a message indicating that no records were found. Please make sure to adjust the SQL query and table/column names according to your specific table structure and requirements.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Compare Any Changed Data of HTML Table Among Different Rows</title>

      <link>https://wavesdream.com/posts/compare-changed-html-table-rows/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/compare-changed-html-table-rows/</guid>

      <pubDate>Wed, 11 Dec 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>In a HTML table where have multiple rows of same data with some difference in any cell. Now you want to highlight that specific cell data which is changed only.</p>
<p>We can achieve this using JavaScript. Here’s a basic example of how you could implement this functionality:</p>
<pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
&lt;meta charset=&#34;UTF-8&#34;&gt;
&lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
&lt;title&gt;Highlight Changed Data&lt;/title&gt;
&lt;style&gt;
    .changed {
        background-color: yellow;
    }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;table id=&#34;data-table&#34;&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;Column 1&lt;/th&gt;
            &lt;th&gt;Column 2&lt;/th&gt;
            &lt;th&gt;Column 3&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;Initial Value 1&lt;/td&gt;
            &lt;td&gt;Initial Value 2&lt;/td&gt;
            &lt;td&gt;Initial Value 3&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Changed Value 1&lt;/td&gt;
            &lt;td&gt;Changed Value 2&lt;/td&gt;
            &lt;td&gt;Changed Value 3&lt;/td&gt;
        &lt;/tr&gt;
        &lt;!-- Add more rows as needed --&gt;
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;script&gt;
    window.onload = function () {
        const table = document.getElementById(&#39;data-table&#39;);
        const rows = table.getElementsByTagName(&#39;tr&#39;);

        for (let i = rows.length - 1; i &gt; 0; i--) {
            const currentRow = rows[i];
            const previousRow = rows[i - 1];

            if (!previousRow) {
                break; // Exit loop if no previous row (first row)
            }

            const currentCells = currentRow.getElementsByTagName(&#39;td&#39;);
            const previousCells = previousRow.getElementsByTagName(&#39;td&#39;);

            for (let j = 0; j &lt; currentCells.length; j++) {
                const currentCell = currentCells[j];
                const previousCell = previousCells[j];

                if (currentCell.textContent !== previousCell.textContent) {
                    currentCell.classList.add(&#39;changed&#39;);
                }
            }
        }
    };
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre><ul>
<li>This code compares each cell of each row with the corresponding cell of the previous row.</li>
<li>If the content of a cell is different from the content of the corresponding cell in the previous row, it adds a changed class to highlight the change.</li>
</ul>
<p>Note: You can customise the appearance of the changed cells by modifying the CSS class .changed.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>In a HTML table where have multiple rows of same data with some difference in any cell. Now you want to highlight that specific cell data which is changed only.</p>
<p>We can achieve this using JavaScript. Here’s a basic example of how you could implement this functionality:</p>
<pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
&lt;meta charset=&#34;UTF-8&#34;&gt;
&lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
&lt;title&gt;Highlight Changed Data&lt;/title&gt;
&lt;style&gt;
    .changed {
        background-color: yellow;
    }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;table id=&#34;data-table&#34;&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;Column 1&lt;/th&gt;
            &lt;th&gt;Column 2&lt;/th&gt;
            &lt;th&gt;Column 3&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;Initial Value 1&lt;/td&gt;
            &lt;td&gt;Initial Value 2&lt;/td&gt;
            &lt;td&gt;Initial Value 3&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Changed Value 1&lt;/td&gt;
            &lt;td&gt;Changed Value 2&lt;/td&gt;
            &lt;td&gt;Changed Value 3&lt;/td&gt;
        &lt;/tr&gt;
        &lt;!-- Add more rows as needed --&gt;
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;script&gt;
    window.onload = function () {
        const table = document.getElementById(&#39;data-table&#39;);
        const rows = table.getElementsByTagName(&#39;tr&#39;);

        for (let i = rows.length - 1; i &gt; 0; i--) {
            const currentRow = rows[i];
            const previousRow = rows[i - 1];

            if (!previousRow) {
                break; // Exit loop if no previous row (first row)
            }

            const currentCells = currentRow.getElementsByTagName(&#39;td&#39;);
            const previousCells = previousRow.getElementsByTagName(&#39;td&#39;);

            for (let j = 0; j &lt; currentCells.length; j++) {
                const currentCell = currentCells[j];
                const previousCell = previousCells[j];

                if (currentCell.textContent !== previousCell.textContent) {
                    currentCell.classList.add(&#39;changed&#39;);
                }
            }
        }
    };
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre><ul>
<li>This code compares each cell of each row with the corresponding cell of the previous row.</li>
<li>If the content of a cell is different from the content of the corresponding cell in the previous row, it adds a changed class to highlight the change.</li>
</ul>
<p>Note: You can customise the appearance of the changed cells by modifying the CSS class .changed.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Export MySQL Data into CSV Using PHP</title>

      <link>https://wavesdream.com/posts/export-mysql-data-to-csv-using-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/export-mysql-data-to-csv-using-php/</guid>

      <pubDate>Mon, 25 Nov 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>To fetch data from a MySQL database and export it to CSV using PHP, you can follow these steps:</p>
<pre tabindex="0"><code>&lt;?php
// Database connection details
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$dbname = &#34;your_database_name&#34;;

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

// Fetch data from your table
$sql = &#34;SELECT * FROM your_table&#34;;
$result = $conn-&gt;query($sql);

// Check if any rows are returned
if ($result-&gt;num_rows &gt; 0) {
    // Define CSV filename
    $filename = &#34;exported_data.csv&#34;;

    // Set headers for CSV download
    header(&#39;Content-Type: text/csv&#39;);
    header(&#39;Content-Disposition: attachment; filename=&#34;&#39; . $filename . &#39;&#34;&#39;);

    // Create a file pointer connected to the output stream
    $output = fopen(&#39;php://output&#39;, &#39;w&#39;);

    // Output CSV header
    $header = array(&#39;ID&#39;, &#39;Name&#39;, &#39;Email&#39;);
    fputcsv($output, $header);

    // Output data from rows
    while ($row = $result-&gt;fetch_assoc()) {
        fputcsv($output, $row);
    }

    // Close the file pointer
    fclose($output);
} else {
    echo &#34;No data found&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p><strong>Explanation:</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>To fetch data from a MySQL database and export it to CSV using PHP, you can follow these steps:</p>
<pre tabindex="0"><code>&lt;?php
// Database connection details
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$dbname = &#34;your_database_name&#34;;

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

// Fetch data from your table
$sql = &#34;SELECT * FROM your_table&#34;;
$result = $conn-&gt;query($sql);

// Check if any rows are returned
if ($result-&gt;num_rows &gt; 0) {
    // Define CSV filename
    $filename = &#34;exported_data.csv&#34;;

    // Set headers for CSV download
    header(&#39;Content-Type: text/csv&#39;);
    header(&#39;Content-Disposition: attachment; filename=&#34;&#39; . $filename . &#39;&#34;&#39;);

    // Create a file pointer connected to the output stream
    $output = fopen(&#39;php://output&#39;, &#39;w&#39;);

    // Output CSV header
    $header = array(&#39;ID&#39;, &#39;Name&#39;, &#39;Email&#39;);
    fputcsv($output, $header);

    // Output data from rows
    while ($row = $result-&gt;fetch_assoc()) {
        fputcsv($output, $row);
    }

    // Close the file pointer
    fclose($output);
} else {
    echo &#34;No data found&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p><strong>Explanation:</strong></p>
<ul>
<li>Database Connection: Replace your_username, your_password, your_database_name, and your_table with your actual database credentials</li>
<li>and table name.</li>
<li>Fetch Data: The SQL query retrieves data from the specified table.</li>
<li>CSV Headers: The header function is used to set headers for CSV download.</li>
<li>CSV File Creation: We use fopen to create a file pointer connected to the output stream (php://output). Then, fputcsv is used to write the</li>
<li>CSV header and data.</li>
<li>Download CSV: Headers are set to prompt the user to download the CSV file with the specified filename.</li>
<li>When you run this script, it will fetch data from your MySQL table and export it to a CSV file, which will be downloaded by the user.</li>
</ul>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Print Total of a Variable Inside a While Loop Outside the Loop in PHP</title>

      <link>https://wavesdream.com/posts/print-total-variable-outside-while-loop-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/print-total-variable-outside-while-loop-php/</guid>

      <pubDate>Thu, 21 Nov 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>To accumulate values from a MySQL query inside a while loop and then calculate the total value outside the loop, you can use a variable to store the total value while iterating through the records. Here’s an<br>
example in PHP:</p>
<pre tabindex="0"><code>&lt;?php
// Your database connection parameters
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$database = &#34;your_database&#34;;

// Create a connection to the MySQL database
$conn = new mysqli($servername, $username, $password, $database);

// Check the connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

$totalValue = 0; // Initialize total value

// Your SQL query
$sql = &#34;SELECT value_column FROM your_table_name WHERE your_conditions&#34;;

$result = $conn-&gt;query($sql);

if ($result-&gt;num_rows &gt; 0) {
    while ($row = $result-&gt;fetch_assoc()) {
        // Access value column and accumulate the values
        $value = $row[&#39;value_column&#39;];
        $totalValue += $value;
        
        // You can also store values in an array if needed
        // $valuesArray[] = $value;
    }
    
    echo &#34;Total value: $totalValue&#34;; // Print total value
    // If you stored values in an array, you can print or manipulate the array here
    // print_r($valuesArray);
} else {
    echo &#34;No records found.&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p>This PHP script fetches records from the database, accumulates the values from a specific column (value_column), and calculates the total value by adding up these values inside the while loop. After the loop, it prints the total value obtained. If you need to store these values in an array for further processing, you can uncomment and modify the $valuesArray[] = $value; line accordingly.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>To accumulate values from a MySQL query inside a while loop and then calculate the total value outside the loop, you can use a variable to store the total value while iterating through the records. Here’s an<br>
example in PHP:</p>
<pre tabindex="0"><code>&lt;?php
// Your database connection parameters
$servername = &#34;localhost&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$database = &#34;your_database&#34;;

// Create a connection to the MySQL database
$conn = new mysqli($servername, $username, $password, $database);

// Check the connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

$totalValue = 0; // Initialize total value

// Your SQL query
$sql = &#34;SELECT value_column FROM your_table_name WHERE your_conditions&#34;;

$result = $conn-&gt;query($sql);

if ($result-&gt;num_rows &gt; 0) {
    while ($row = $result-&gt;fetch_assoc()) {
        // Access value column and accumulate the values
        $value = $row[&#39;value_column&#39;];
        $totalValue += $value;
        
        // You can also store values in an array if needed
        // $valuesArray[] = $value;
    }
    
    echo &#34;Total value: $totalValue&#34;; // Print total value
    // If you stored values in an array, you can print or manipulate the array here
    // print_r($valuesArray);
} else {
    echo &#34;No records found.&#34;;
}

// Close the database connection
$conn-&gt;close();
?&gt;
</code></pre><p>This PHP script fetches records from the database, accumulates the values from a specific column (value_column), and calculates the total value by adding up these values inside the while loop. After the loop, it prints the total value obtained. If you need to store these values in an array for further processing, you can uncomment and modify the $valuesArray[] = $value; line accordingly.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Import CSV Data into MySQL Using PHP</title>

      <link>https://wavesdream.com/posts/import-csv-data-into-mysql-using-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/import-csv-data-into-mysql-using-php/</guid>

      <pubDate>Thu, 21 Nov 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Here’s a detailed example of how to import data from a CSV file into a MySQL database using PHP. The script processes each row one by one, displays a success message for each successfully inserted row, and stops the process if any error occurs, showing the error message.</p>
<p><strong>Prerequisites:</strong> Ensure you have a MySQL database and table set up to store the CSV data. Adjust the database connection details and table schema as needed.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Here’s a detailed example of how to import data from a CSV file into a MySQL database using PHP. The script processes each row one by one, displays a success message for each successfully inserted row, and stops the process if any error occurs, showing the error message.</p>
<p><strong>Prerequisites:</strong> Ensure you have a MySQL database and table set up to store the CSV data. Adjust the database connection details and table schema as needed.</p>
<p><strong>Database Setup:</strong> Assume you have a MySQL table named csv_import with columns id, name, and email.</p>
<pre tabindex="0"><code>CREATE TABLE csv_import (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
</code></pre><p>Here’s a PHP script that handles the CSV import process:</p>
<pre tabindex="0"><code>&lt;?php
// Database connection details
$servername = &#34;your_servername&#34;;
$username = &#34;your_username&#34;;
$password = &#34;your_password&#34;;
$dbname = &#34;your_dbname&#34;;

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn-&gt;connect_error) {
    die(&#34;Connection failed: &#34; . $conn-&gt;connect_error);
}

if (isset($_POST[&#39;submit&#39;])) {
    $csvFile = $_FILES[&#39;csv&#39;][&#39;tmp_name&#39;];

    if (is_file($csvFile)) {
        // Open the CSV file
        if (($handle = fopen($csvFile, &#34;r&#34;)) !== FALSE) {
            $rowNumber = 0;

            // Process each row of the CSV file
            while (($data = fgetcsv($handle, 1000, &#34;,&#34;)) !== FALSE) {
                $rowNumber++;

                // Skip the header row
                if ($rowNumber == 1) {
                    continue;
                }

                $name = $conn-&gt;real_escape_string($data[0]);
                $email = $conn-&gt;real_escape_string($data[1]);

                // Insert the data into the database
                $sql = &#34;INSERT INTO csv_import (name, email) VALUES (&#39;$name&#39;, &#39;$email&#39;)&#34;;
                
                if ($conn-&gt;query($sql) === TRUE) {
                    echo &#34;Row $rowNumber inserted successfully.&lt;br&gt;&#34;;
                } else {
                    echo &#34;Error inserting row $rowNumber: &#34; . $conn-&gt;error . &#34;&lt;br&gt;&#34;;
                    break;
                }
            }

            fclose($handle);
        } else {
            echo &#34;Error opening the CSV file.&#34;;
        }
    } else {
        echo &#34;Invalid file.&#34;;
    }
}
$conn-&gt;close();
?&gt;
</code></pre><p>Here the HTML to upload CSV file</p>
<pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;CSV Import&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=&#34;&#34; method=&#34;post&#34; enctype=&#34;multipart/form-data&#34;&gt;
        &lt;label for=&#34;csv&#34;&gt;Choose CSV file:&lt;/label&gt;
        &lt;input type=&#34;file&#34; name=&#34;csv&#34; id=&#34;csv&#34; required&gt;
        &lt;button type=&#34;submit&#34; name=&#34;submit&#34;&gt;Import CSV&lt;/button&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p><strong>Explanation:</strong></p>
<ul>
<li>Database Connection: Establish a connection to the MySQL database using the mysqli extension.</li>
<li>Form Handling: The script checks if the form is submitted and processes the uploaded CSV file.</li>
<li>CSV File Processing: It opens the CSV file and processes each row one by one using a while loop.</li>
<li>It skips the header row.</li>
<li>It escapes the data using $conn-&gt;real_escape_string to prevent SQL injection.</li>
<li>It inserts the data into the csv_import table.</li>
<li>It shows a success message for each inserted row.</li>
<li>If any error occurs, it shows an error message and stops the process.</li>
<li>HTML Form: The form allows the user to upload a CSV file.</li>
</ul>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Important WordPress Theme Functions Every Developer Should Know</title>

      <link>https://wavesdream.com/posts/important-wordpress-theme-functions/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/important-wordpress-theme-functions/</guid>

      <pubDate>Thu, 05 Sep 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p><strong>Updated as on April 9, 2026</strong></p>
<p>I have been working on WordPress for years and I still carry aroung a standard functions.php file while develop a new WordPress theme.</p>
<p>I am explaining here how to modernizing functions.php file so it will work seamlessly with WordPress 6 +.</p>
<p><strong>These are the list of very common and useful features included here.</strong></p>
<ul>
<li>Initial theme setup with navigation menu, featured image, custom image size, excerpt support</li>
<li>Sidebar registration</li>
<li>Image compression while uploading</li>
<li>Responsive image fixing</li>
<li>Enable sidebar widget</li>
<li>Shorten post / page title by word limit</li>
<li>Shorten excerpt by word limit</li>
<li>Shorten content by word limit</li>
<li>Strip images from content</li>
<li>Display the content of a page by page ID</li>
<li>Display the content of a page by page slug</li>
<li>Anti spam email shortcode inside content editor</li>
<li>Change default sender name and sender email address</li>
<li>Remove WordPress version from Head</li>
<li>Enqueue script and CSS</li>
<li>Disable admin bar for all users but admins in the front end</li>
<li>Disable default widgets</li>
</ul>
<p>Add these codes in functions.php file of the active theme.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p><strong>Updated as on April 9, 2026</strong></p>
<p>I have been working on WordPress for years and I still carry aroung a standard functions.php file while develop a new WordPress theme.</p>
<p>I am explaining here how to modernizing functions.php file so it will work seamlessly with WordPress 6 +.</p>
<p><strong>These are the list of very common and useful features included here.</strong></p>
<ul>
<li>Initial theme setup with navigation menu, featured image, custom image size, excerpt support</li>
<li>Sidebar registration</li>
<li>Image compression while uploading</li>
<li>Responsive image fixing</li>
<li>Enable sidebar widget</li>
<li>Shorten post / page title by word limit</li>
<li>Shorten excerpt by word limit</li>
<li>Shorten content by word limit</li>
<li>Strip images from content</li>
<li>Display the content of a page by page ID</li>
<li>Display the content of a page by page slug</li>
<li>Anti spam email shortcode inside content editor</li>
<li>Change default sender name and sender email address</li>
<li>Remove WordPress version from Head</li>
<li>Enqueue script and CSS</li>
<li>Disable admin bar for all users but admins in the front end</li>
<li>Disable default widgets</li>
</ul>
<p>Add these codes in functions.php file of the active theme.</p>
<pre tabindex="0"><code>&lt;?php
/**
 * Theme Setup
 */
function mytheme_setup() {

    // Navigation Menus
    register_nav_menus([
        &#39;top-menu&#39;    =&gt; __(&#39;Header Navigation&#39;, &#39;mytheme&#39;),
        &#39;bottom-menu&#39; =&gt; __(&#39;Footer Navigation&#39;, &#39;mytheme&#39;),
    ]);

    // Featured Images
    add_theme_support(&#39;post-thumbnails&#39;);

    // Custom Image Sizes
    add_image_size(&#39;blog_featured&#39;, 600, 300, true);

    // Add excerpt support to pages
    add_post_type_support(&#39;page&#39;, &#39;excerpt&#39;);
}
add_action(&#39;after_setup_theme&#39;, &#39;mytheme_setup&#39;);


/**
 * Sidebar Registration
 */
function mytheme_widgets_init() {
    register_sidebar([
        &#39;name&#39;          =&gt; __(&#39;Sidebar&#39;, &#39;mytheme&#39;),
        &#39;id&#39;            =&gt; &#39;sidebar&#39;,
        &#39;description&#39;   =&gt; __(&#39;Main Sidebar&#39;, &#39;mytheme&#39;),
        &#39;before_widget&#39; =&gt; &#39;&lt;div class=&#34;widget %2$s&#34;&gt;&#39;,
        &#39;after_widget&#39;  =&gt; &#39;&lt;/div&gt;&#39;,
        &#39;before_title&#39;  =&gt; &#39;&lt;h3 class=&#34;widget-title&#34;&gt;&#39;,
        &#39;after_title&#39;   =&gt; &#39;&lt;/h3&gt;&#39;,
    ]);
}
add_action(&#39;widgets_init&#39;, &#39;mytheme_widgets_init&#39;);


/**
 * Image Quality (Modern WebP/JPEG)
 */
add_filter(&#39;wp_editor_set_quality&#39;, function() {
    return 82;
});


/**
 * Remove width &amp; height attributes (responsive images fix)
 */
function mytheme_remove_image_dimensions($html) {
    return preg_replace(&#39;/(width|height)=&#34;\d*&#34;\s?/&#39;, &#39;&#39;, $html);
}
add_filter(&#39;post_thumbnail_html&#39;, &#39;mytheme_remove_image_dimensions&#39;);
add_filter(&#39;image_send_to_editor&#39;, &#39;mytheme_remove_image_dimensions&#39;);


/**
 * Trim Title by Words
 */
function mytheme_short_title($length = 8, $after = &#39;...&#39;) {
    $title = wp_strip_all_tags(get_the_title());
    $words = explode(&#39; &#39;, $title);

    if (count($words) &gt; $length) {
        $words = array_slice($words, 0, $length);
        return implode(&#39; &#39;, $words) . $after;
    }

    return $title;
}


/**
 * Custom Excerpt Length
 */
function mytheme_excerpt($limit = 25) {
    return wp_trim_words(get_the_excerpt(), $limit, &#39;...&#39;);
}


/**
 * Custom Content Trim
 */
function mytheme_content($limit = 25) {
    return wp_trim_words(
        wp_strip_all_tags(get_the_content()),
        $limit,
        &#39;...&#39;
    );
}


/**
 * Remove Images from Content
 */
function mytheme_strip_images($content) {
    return preg_replace(&#39;/&lt;img[^&gt;]+&gt;/i&#39;, &#39;&#39;, $content);
}
// Usage: add_filter(&#39;the_content&#39;, &#39;mytheme_strip_images&#39;);


/**
 * Get Page Content by ID
 */
function mytheme_get_page_content_by_id($page_id) {
    $page = get_post($page_id);

    if (!$page) return &#39;&#39;;

    return apply_filters(&#39;the_content&#39;, $page-&gt;post_content);
}


/**
 * Get Page Content by Slug
 */
function mytheme_get_page_content_by_slug($slug) {
    $page = get_page_by_path($slug);

    if (!$page) return &#39;&#39;;

    return apply_filters(&#39;the_content&#39;, $page-&gt;post_content);
}


/**
 * Email Shortcode [email]example@mail.com[/email]
 */
function mytheme_email_shortcode($atts, $content = null) {
    if (!$content) return &#39;&#39;;

    $email = antispambot($content);

    return &#39;&lt;a href=&#34;&#39; . esc_attr(&#39;mailto:&#39; . $email) . &#39;&#34;&gt;&#39; . esc_html($email) . &#39;&lt;/a&gt;&#39;;
}
add_shortcode(&#39;email&#39;, &#39;mytheme_email_shortcode&#39;);


/**
 * Mail Sender Customization
 */
add_filter(&#39;wp_mail_from&#39;, function() {
    return &#39;info@yourdomain.com&#39;;
});

add_filter(&#39;wp_mail_from_name&#39;, function() {
    return get_bloginfo(&#39;name&#39;);
});


/**
 * Remove WP Version
 */
add_filter(&#39;the_generator&#39;, &#39;__return_empty_string&#39;);


/**
 * Enqueue Scripts &amp; Styles
 */
function mytheme_enqueue_assets() {

    // CSS
    wp_enqueue_style(
        &#39;mytheme-style&#39;,
        get_stylesheet_uri(),
        [],
        wp_get_theme()-&gt;get(&#39;Version&#39;)
    );

    // JS
    wp_enqueue_script(
        &#39;mytheme-custom&#39;,
        get_template_directory_uri() . &#39;/js/custom.js&#39;,
        [&#39;jquery&#39;],
        null,
        true
    );
}
add_action(&#39;wp_enqueue_scripts&#39;, &#39;mytheme_enqueue_assets&#39;);


/**
 * Disable Admin Bar for Non-Admins
 */
add_filter(&#39;show_admin_bar&#39;, function($show) {
    return current_user_can(&#39;administrator&#39;) ? $show : false;
});


/**
 * Remove Default Widgets (Optional)
 */
function mytheme_unregister_widgets() {
    unregister_widget(&#39;WP_Widget_Pages&#39;);
    unregister_widget(&#39;WP_Widget_Calendar&#39;);
    unregister_widget(&#39;WP_Widget_Archives&#39;);
    unregister_widget(&#39;WP_Widget_Meta&#39;);
    unregister_widget(&#39;WP_Widget_Search&#39;);
    unregister_widget(&#39;WP_Widget_Tag_Cloud&#39;);
}
// add_action(&#39;widgets_init&#39;, &#39;mytheme_unregister_widgets&#39;, 11);
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Exclude the Latest Post in a WordPress Custom Query Loop</title>

      <link>https://wavesdream.com/posts/exclude-latest-post-wordpress-custom-query-loop/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/exclude-latest-post-wordpress-custom-query-loop/</guid>

      <pubDate>Sun, 21 Apr 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>When you build a website in WordPress, sometimes you may not want to show the latest post in a custom section.</p>
<p>For example, on a news website, the latest post is already shown in a big banner at the top. Now below that, you want to show more posts—but you don’t want to repeat the same latest post again.</p>
<p>In this article, you will learn a simple way to skip the latest post using a custom loop. We will use a small setting called offset in WP_Query to control this easily.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>When you build a website in WordPress, sometimes you may not want to show the latest post in a custom section.</p>
<p>For example, on a news website, the latest post is already shown in a big banner at the top. Now below that, you want to show more posts—but you don’t want to repeat the same latest post again.</p>
<p>In this article, you will learn a simple way to skip the latest post using a custom loop. We will use a small setting called offset in WP_Query to control this easily.</p>
<pre tabindex="0"><code>&lt;?php
$args = array(
    &#39;post_type&#39;      =&gt; &#39;post&#39;,  // Change this to your custom post type if needed
    &#39;posts_per_page&#39; =&gt; 5,       // Adjust the number of posts to display
    &#39;offset&#39;         =&gt; 1,       // Skip the latest post
    &#39;orderby&#39;        =&gt; &#39;date&#39;,
    &#39;order&#39;          =&gt; &#39;DESC&#39;
);

$query = new WP_Query($args);

if ($query-&gt;have_posts()) : 
    while ($query-&gt;have_posts()) : $query-&gt;the_post(); ?&gt;
        &lt;article&gt;
            &lt;h2&gt;&lt;a href=&#34;&lt;?php the_permalink(); ?&gt;&#34;&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;&lt;/h2&gt;
            &lt;?php the_excerpt(); ?&gt;
        &lt;/article&gt;
    &lt;?php endwhile;
    wp_reset_postdata();
else :
    echo &#39;&lt;p&gt;No posts found.&lt;/p&gt;&#39;;
endif;
?&gt;
</code></pre><p><strong>How It Works</strong></p>
<ul>
<li>
<p><code>offset =&gt; 1</code> skips the latest post.</p>
</li>
<li>
<p><code>posts_per_page</code> controls how many posts are displayed.</p>
</li>
<li>
<p><code>wp_reset_postdata()</code> ensures WordPress restores the global post data after the loop.</p>
</li>
</ul>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Group Posts in Pairs in a WordPress Custom Query</title>

      <link>https://wavesdream.com/posts/group-posts-pairs-wordpress-custom-query/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/group-posts-pairs-wordpress-custom-query/</guid>

      <pubDate>Tue, 12 Mar 2024 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Sometimes, when you build a website using WordPress, you may want to show posts in a clean layout. For example, imagine you are creating a blog or product page where you want to show 2 items in one row. But by default, posts come one after another, not in groups.</p>
<p>To do this, you need to group every 2 posts inside a single container. In this article, we will show you a simple way to do this using a counter in a custom query loop. This method helps you control the layout easily without using any extra plugins.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Sometimes, when you build a website using WordPress, you may want to show posts in a clean layout. For example, imagine you are creating a blog or product page where you want to show 2 items in one row. But by default, posts come one after another, not in groups.</p>
<p>To do this, you need to group every 2 posts inside a single container. In this article, we will show you a simple way to do this using a counter in a custom query loop. This method helps you control the layout easily without using any extra plugins.</p>
<pre tabindex="0"><code>&lt;?php
// Define your custom query
$args = array(
    &#39;post_type&#39; =&gt; &#39;post&#39;, // Change to your post type
    &#39;posts_per_page&#39; =&gt; -1, // Adjust the number of posts
);

$query = new WP_Query($args);

if ($query-&gt;have_posts()) :
    $counter = 0; // Initialize a counter
    echo &#39;&lt;div class=&#34;outer-container&#34;&gt;&#39;; // Optional: Wrap everything in an outer container
    while ($query-&gt;have_posts()) : $query-&gt;the_post();
        
        // Open a new div for every 2 posts
        if ($counter % 2 == 0) {
            echo &#39;&lt;div class=&#34;inner-container&#34;&gt;&#39;; // Start a new container
        }

        // Display your post content here
        ?&gt;
        &lt;div class=&#34;post-item&#34;&gt;
            &lt;h2&gt;&lt;?php the_title(); ?&gt;&lt;/h2&gt;
            &lt;div class=&#34;post-excerpt&#34;&gt;
                &lt;?php the_excerpt(); ?&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;?php

        $counter++; // Increment the counter

        // Close the div after every 2 posts
        if ($counter % 2 == 0) {
            echo &#39;&lt;/div&gt;&#39;; // Close the container
        }

    endwhile;

    // Close the last div if it&#39;s not closed yet
    if ($counter % 2 != 0) {
        echo &#39;&lt;/div&gt;&#39;;
    }
    
    echo &#39;&lt;/div&gt;&#39;; // Close the outer container
else :
    echo &#39;&lt;p&gt;No posts found.&lt;/p&gt;&#39;;
endif;

wp_reset_postdata();
?&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Popular Web Server Error Codes Explained</title>

      <link>https://wavesdream.com/posts/popular-web-server-error-codes/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/popular-web-server-error-codes/</guid>

      <pubDate>Fri, 20 Oct 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Many a time when we try to visit any particular web page, we get an error code displaying in lieu of the original page. Have you ever surprised what that error code meant? Here is a list of the most popular error codes and their description. The first thing you should do anytime you get an error code is to make sure that you have entered the correct web page addressed.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Many a time when we try to visit any particular web page, we get an error code displaying in lieu of the original page. Have you ever surprised what that error code meant? Here is a list of the most popular error codes and their description. The first thing you should do anytime you get an error code is to make sure that you have entered the correct web page addressed.</p>
<ul>
<li>100 Continue</li>
<li>101 Switching Protocols</li>
<li>102 Processing</li>
<li>200 OK</li>
<li>201 Created</li>
<li>202 Accepted</li>
<li>203 Non-Authoritative Information</li>
<li>204 No Content</li>
<li>205 Reset Content</li>
<li>206 Partial Content</li>
<li>207 Multi-Status</li>
<li>300 Multiple Choices</li>
<li>301 Moved Permanently</li>
<li>302 Found</li>
<li>303 See Other</li>
<li>304 Not Modified</li>
<li>305 Use Proxy</li>
<li>307 Temporary Redirect</li>
<li>400 Bad Request</li>
<li>401 Authorization Required</li>
<li>402 Payment Required</li>
<li>403 Forbidden</li>
<li>404 Not Found</li>
<li>405 Method Not Allowed</li>
<li>406 Not Acceptable</li>
<li>407 Proxy Authentication Required</li>
<li>408 Request Time-out</li>
<li>409 Conflict</li>
<li>410 Gone</li>
<li>411 Length Required</li>
<li>412 Precondition Failed</li>
<li>413 Request Entity Too Large</li>
<li>414 Request-URI Too Large</li>
<li>415 Unsupported Media Type</li>
<li>416 Requested Range Not Satisfiable</li>
<li>417 Expectation Failed</li>
<li>422 Unprocessed Entity</li>
<li>423 Locked</li>
<li>424 Failed Dependency</li>
<li>425 No code</li>
<li>426 Upgrade Required</li>
<li>500 Internal Server Error</li>
<li>501 Method Not Implemented</li>
<li>502 Bad Gateway</li>
<li>503 Service Temporarily Unavailable</li>
<li>504 Gateway Time-out</li>
<li>505 HTTP Version Not Supported</li>
<li>506 Variant Also Negotiates</li>
<li>507 Insufficient Storage</li>
<li>510 Not Extended</li>
</ul>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Useful GIT Commands</title>

      <link>https://wavesdream.com/posts/useful-git-commands/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/useful-git-commands/</guid>

      <pubDate>Tue, 12 Sep 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>List of all the useful GIT commands which I use for my daily web development work.</p>
<p><strong>Repository Setup / Initialize new repo</strong></p>
<pre tabindex="0"><code>git init
</code></pre><p><strong>Set global email</strong></p>
<pre tabindex="0"><code>git config –global user.email “your@email.com”
</code></pre><p><strong>Clone existing repo</strong></p>
<pre tabindex="0"><code>git clone https://github.com/username/repo.git
</code></pre><p><strong>Check remote repository</strong></p>
<pre tabindex="0"><code>git remote -v
</code></pre><p><strong>Add remote repository</strong></p>
<pre tabindex="0"><code>git remote add origin https://github.com/username/repo.git
</code></pre><p><strong>Remove remote origin / repository</strong></p>
<pre tabindex="0"><code>git remote remove origin
</code></pre><p>Or</p>
<pre tabindex="0"><code>git remote rm origin
</code></pre><p>Verify it has been removed</p>
<pre tabindex="0"><code>git remote -v
</code></pre><p><strong>Check status</strong></p>
<pre tabindex="0"><code>git status
</code></pre><p><strong>Pull latest changes</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>List of all the useful GIT commands which I use for my daily web development work.</p>
<p><strong>Repository Setup / Initialize new repo</strong></p>
<pre tabindex="0"><code>git init
</code></pre><p><strong>Set global email</strong></p>
<pre tabindex="0"><code>git config –global user.email “your@email.com”
</code></pre><p><strong>Clone existing repo</strong></p>
<pre tabindex="0"><code>git clone https://github.com/username/repo.git
</code></pre><p><strong>Check remote repository</strong></p>
<pre tabindex="0"><code>git remote -v
</code></pre><p><strong>Add remote repository</strong></p>
<pre tabindex="0"><code>git remote add origin https://github.com/username/repo.git
</code></pre><p><strong>Remove remote origin / repository</strong></p>
<pre tabindex="0"><code>git remote remove origin
</code></pre><p>Or</p>
<pre tabindex="0"><code>git remote rm origin
</code></pre><p>Verify it has been removed</p>
<pre tabindex="0"><code>git remote -v
</code></pre><p><strong>Check status</strong></p>
<pre tabindex="0"><code>git status
</code></pre><p><strong>Pull latest changes</strong></p>
<pre tabindex="0"><code>git pull origin main
</code></pre><p><strong>Stage all files</strong></p>
<pre tabindex="0"><code>git add .
</code></pre><p><strong>Stage specific file</strong></p>
<pre tabindex="0"><code>git add filename.js
</code></pre><p><strong>Commit changes</strong></p>
<pre tabindex="0"><code>git commit -m “Your message”
</code></pre><p><strong>Push to GitHub</strong></p>
<pre tabindex="0"><code>git push origin main
</code></pre><p><strong>View commit log</strong></p>
<pre tabindex="0"><code>git log
</code></pre><p><strong>Compact log</strong></p>
<pre tabindex="0"><code>git log –oneline
</code></pre><p><strong>See file changes</strong></p>
<pre tabindex="0"><code>git diff
</code></pre><p><strong>See staged changes</strong></p>
<pre tabindex="0"><code>git diff –staged
</code></pre><p><strong>Check branches</strong></p>
<pre tabindex="0"><code>git branch
</code></pre><p><strong>Create branch</strong></p>
<pre tabindex="0"><code>git branch new-branch
</code></pre><p><strong>Switch branch</strong></p>
<pre tabindex="0"><code>git checkout new-branch
</code></pre><p>OR modern way:</p>
<pre tabindex="0"><code>git switch new-branch
</code></pre><p><strong>Create + switch</strong></p>
<pre tabindex="0"><code>git checkout -b new-branch
</code></pre><p><strong>Merge branch</strong></p>
<pre tabindex="0"><code>git merge branch-name
</code></pre><p><strong>Unstage file</strong></p>
<pre tabindex="0"><code>git restore –staged filename
</code></pre><p><strong>Discard local changes</strong></p>
<pre tabindex="0"><code>git restore filename
</code></pre><p><strong>Reset last commit (keep changes)</strong></p>
<pre tabindex="0"><code>git reset –soft HEAD~1
</code></pre><p><strong>Reset last commit (remove changes)</strong></p>
<pre tabindex="0"><code>git reset –hard HEAD~1
</code></pre><p><code>--hard</code> deletes changes permanently.</p>
<p><strong>Fetch without merging</strong></p>
<pre tabindex="0"><code>git fetch
</code></pre><p><strong>Check if branch is behind</strong></p>
<pre tabindex="0"><code>git status
</code></pre><p><strong>Force sync with remote (use carefully)</strong></p>
<pre tabindex="0"><code>git reset –hard origin/main
</code></pre><p><strong>Stashing (Very Useful) When you want to temporarily save work without committing</strong></p>
<pre tabindex="0"><code>git stash
</code></pre><p><strong>See stash list</strong></p>
<pre tabindex="0"><code>git stash list
</code></pre><p><strong>Apply stash</strong></p>
<pre tabindex="0"><code>git stash apply
</code></pre><p><strong>Remove stash</strong></p>
<pre tabindex="0"><code>git stash drop
</code></pre><p><strong>Show remote branch info</strong></p>
<pre tabindex="0"><code>git branch -r
</code></pre><p><strong>Show config</strong></p>
<pre tabindex="0"><code>git config –list
</code></pre><p><strong>Set global username</strong></p>
<pre tabindex="0"><code>git config –global user.name “Your Name”
</code></pre><p><strong>Create tag</strong></p>
<pre tabindex="0"><code>git tag v1.0
</code></pre><p><strong>Push tag</strong></p>
<pre tabindex="0"><code>git push origin v1.0
</code></pre><p><strong>Remove any file from Git tracking (cache)</strong></p>
<pre tabindex="0"><code>git rm --cached folder/filename
</code></pre><p><strong>Remove all deleted files from Git tracking (cache)</strong></p>
<pre tabindex="0"><code>git add -u
</code></pre><p>Or</p>
<pre tabindex="0"><code>git add --update
</code></pre><p><strong>Completely re-build Git index (cache)</strong></p>
<pre tabindex="0"><code>git rm -r --cached .
git add .
git commit -m &#34;Refresh Git index&#34;
git push
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>PHP Function to Get Difference Between Dates</title>

      <link>https://wavesdream.com/posts/php-function-get-difference-between-dates/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/php-function-get-difference-between-dates/</guid>

      <pubDate>Sat, 15 Jul 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>Below is a PHP function that calculates and displays the difference in days between two dates. This function will take two date strings as inputs, convert them to DateTime objects, and then calculate the difference in days.</p>
<p>Here’s how you can define and use the function:</p>
<pre tabindex="0"><code>&lt;?php
// Calculate day difference
function calculateDayDifference($date1, $date2) {
    // Create DateTime objects for the two dates
    $datetime1 = new DateTime($date1);
    $datetime2 = new DateTime($date2);

    // Calculate the difference
    $interval = $datetime1-&gt;diff($datetime2);

    // Get the difference in days
    $days_interval = $interval-&gt;days;

    return  $days_interval;
}

// Example usage
$date1 = &#34;2023-07-01&#34;;
$date2 = &#34;2023-07-15&#34;;

echo calculateDayDifference($date1, $date2);
?&gt;
</code></pre><p><strong>Explanation:</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>Below is a PHP function that calculates and displays the difference in days between two dates. This function will take two date strings as inputs, convert them to DateTime objects, and then calculate the difference in days.</p>
<p>Here’s how you can define and use the function:</p>
<pre tabindex="0"><code>&lt;?php
// Calculate day difference
function calculateDayDifference($date1, $date2) {
    // Create DateTime objects for the two dates
    $datetime1 = new DateTime($date1);
    $datetime2 = new DateTime($date2);

    // Calculate the difference
    $interval = $datetime1-&gt;diff($datetime2);

    // Get the difference in days
    $days_interval = $interval-&gt;days;

    return  $days_interval;
}

// Example usage
$date1 = &#34;2023-07-01&#34;;
$date2 = &#34;2023-07-15&#34;;

echo calculateDayDifference($date1, $date2);
?&gt;
</code></pre><p><strong>Explanation:</strong></p>
<p>Creating DateTime Objects:</p>
<p><strong>new DateTime($date1): This converts the first date string into a DateTime object.</strong></p>
<p><strong>new DateTime($date2): This converts the second date string into a DateTime object.</strong></p>
<p>Calculating the Difference:</p>
<p><strong>$datetime1-&gt;diff($datetime2): This calculates the difference between the two DateTime objects. The result is a DateInterval object.</strong></p>
<p>Getting the Difference in Days:</p>
<p><strong>$interval-&gt;days: This retrieves the difference in days from the DateInterval object.</strong></p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Get Current Page URL Without Query Parameters in PHP</title>

      <link>https://wavesdream.com/posts/get-current-page-url-without-query-parameters-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/get-current-page-url-without-query-parameters-php/</guid>

      <pubDate>Fri, 14 Jul 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>When you work with websites using PHP, sometimes you need the clean page URL without extra parameters.</p>
<p>For example, your URL may look like this:</p>
<pre tabindex="0"><code>https://example.com/page?ref=google&amp;utm_source=ads
</code></pre><p>But in many real cases, you only need:</p>
<pre tabindex="0"><code>https://example.com/page
</code></pre><p>This is useful when you are tracking pages, saving URLs in the database, or avoiding duplicate links.</p>
<p>In this article, you will learn a simple way to get the current page URL and remove all query parameters using PHP.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>When you work with websites using PHP, sometimes you need the clean page URL without extra parameters.</p>
<p>For example, your URL may look like this:</p>
<pre tabindex="0"><code>https://example.com/page?ref=google&amp;utm_source=ads
</code></pre><p>But in many real cases, you only need:</p>
<pre tabindex="0"><code>https://example.com/page
</code></pre><p>This is useful when you are tracking pages, saving URLs in the database, or avoiding duplicate links.</p>
<p>In this article, you will learn a simple way to get the current page URL and remove all query parameters using PHP.</p>
<pre tabindex="0"><code>&lt;?php
function getCurrentPageURLWithoutParameters() {
    $protocol = &#39;http://&#39;;
    if (!empty($_SERVER[&#39;HTTPS&#39;]) &amp;&amp; $_SERVER[&#39;HTTPS&#39;] !== &#39;off&#39; || $_SERVER[&#39;SERVER_PORT&#39;] == 443) {
        $protocol = &#39;https://&#39;;
    }
    
    $host = $_SERVER[&#39;HTTP_HOST&#39;];
    $requestUri = $_SERVER[&#39;REQUEST_URI&#39;];
    
    // Remove query string from request URI
    $requestUri = strtok($requestUri, &#39;?&#39;);
    
    return $protocol . $host . $requestUri;
}

// Usage
$currentUrlWithoutParams = getCurrentPageURLWithoutParameters();
echo $currentUrlWithoutParams;
?&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

    <item>

      <title>Clean a WordPress Database Infected with Malware</title>

      <link>https://wavesdream.com/posts/clean-wordpress-database-infected-malware/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/clean-wordpress-database-infected-malware/</guid>

      <pubDate>Sat, 03 Jun 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>I just finished a new job to clean a WordPress website that was compromised with malicious codes. Removing the malicious codes from the theme files is easy, but the complex job is to remove them from MySQL database tables.</p>
<p>Here is the step-by-step process.</p>
<p>Note: for referene purpose, I have used table prefix as <em>wp_</em>. In your case, you need to use your actutal table prefix.</p>
<p><strong>Check for hidden admin users (again, properly)</strong></p>
      ]]></description>

      <content:encoded><![CDATA[
<p>I just finished a new job to clean a WordPress website that was compromised with malicious codes. Removing the malicious codes from the theme files is easy, but the complex job is to remove them from MySQL database tables.</p>
<p>Here is the step-by-step process.</p>
<p>Note: for referene purpose, I have used table prefix as <em>wp_</em>. In your case, you need to use your actutal table prefix.</p>
<p><strong>Check for hidden admin users (again, properly)</strong></p>
<p>Even if you deleted users, sometimes roles remain or are reassigned.</p>
<pre tabindex="0"><code>SELECT u.ID, u.user_login, u.user_email FROM wt_users u JOIN wt_usermeta um ON u.ID = um.user_id WHERE um.meta_key = &#39;wt_capabilities&#39; AND um.meta_value LIKE &#39;%administrator%&#39;;
</code></pre><p>Only expected admins should appear.</p>
<p><strong>Scan for suspicious content (VERY IMPORTANT)</strong></p>
<p>Malware often hides in:</p>
<ul>
<li>posts</li>
<li>options</li>
<li>widgets</li>
<li>plugin settings</li>
</ul>
<p><strong>Search for common malicious patterns</strong></p>
<pre tabindex="0"><code>SELECT * FROM wt_posts   
WHERE post_content LIKE &#39;%&lt;script%&#39;   
OR post_content LIKE &#39;%eval(%&#39;   
OR post_content LIKE &#39;%base64_decode%&#39;   
OR post_content LIKE &#39;%iframe%&#39;;

SELECT * FROM wt_options   
WHERE option_value LIKE &#39;%&lt;script%&#39;   
OR option_value LIKE &#39;%base64%&#39;   
OR option_value LIKE &#39;%eval(%&#39;;
</code></pre><p><strong>Check wp_options (most common infection point)</strong></p>
<p>Focus on <strong>autoloaded options</strong>:</p>
<pre tabindex="0"><code>SELECT option_name FROM wt_options WHERE autoload = &#39;yes&#39;;
</code></pre><p>Then inspect suspicious ones manually:</p>
<pre tabindex="0"><code>SELECT option_name, option_value FROM wt_options WHERE option_name IN (&#39;siteurl&#39;,&#39;home&#39;,&#39;active_plugins&#39;);
</code></pre><p>Look for:</p>
<ul>
<li>Unknown URLs</li>
<li>Injected JS</li>
<li>Unknown plugins</li>
</ul>
<p><strong>Check for rogue admin-related options</strong></p>
<pre tabindex="0"><code>SELECT * FROM wt_options WHERE option_name LIKE &#39;%user%&#39; OR option_name LIKE &#39;%role%&#39;;
</code></pre><p><strong>Check scheduled malware (Action Scheduler / Cron)</strong></p>
<p>Since you saw <code>actionscheduler</code> tables:</p>
<pre tabindex="0"><code>SELECT * FROM wt_actionscheduler_actions WHERE hook LIKE &#39;%eval%&#39; OR hook LIKE &#39;%malicious%&#39; OR hook LIKE &#39;%wp_%&#39;;
</code></pre><p>Also check WP Cron:</p>
<pre tabindex="0"><code>SELECT option_value FROM wt_options WHERE option_name = &#39;cron&#39;;
</code></pre><p>Malware often hides scheduled reinfection scripts here.</p>
<p><strong>Check for hidden injected links (SEO spam)</strong></p>
<pre tabindex="0"><code>SELECT ID, post_title FROM wt_posts WHERE post_content LIKE &#39;%href=% AND post_content LIKE &#39;%http%&#39;;
</code></pre><p>Look for casino / pharma / unknown domains.</p>
<p><strong>Check usermeta for hidden capabilities</strong></p>
<pre tabindex="0"><code>SELECT * FROM wt_usermeta WHERE meta_key LIKE &#39;%capabilities%&#39; AND meta_value NOT LIKE &#39;%administrator%&#39; AND meta_value LIKE &#39;%admin%&#39;;
</code></pre><p><strong>Look for suspicious option names</strong></p>
<p>Hackers often create random options:</p>
<pre tabindex="0"><code>SELECT option_name FROM wt_options WHERE option_name REGEXP &#39;^[a-zA-Z0-9]{20,}$&#39;;
</code></pre><p><strong>Clean orphaned data (safe cleanup)</strong></p>
<pre tabindex="0"><code>DELETE pm FROM wt_postmeta pm LEFT JOIN wt_posts p ON pm.post_id = p.ID WHERE p.ID IS NULL;

DELETE um FROM wt_usermeta um LEFT JOIN wt_users u ON um.user_id = u.ID WHERE u.ID IS NULL;
</code></pre><p><strong>Add security</strong></p>
<ul>
<li>Wordfence / Sucuri</li>
<li>Disable file editing:</li>
</ul>
<p>define(&lsquo;DISALLOW_FILE_EDIT&rsquo;, true);</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Delete Users from the WordPress Database Safely</title>

      <link>https://wavesdream.com/posts/delete-users-from-wordpress-database/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/delete-users-from-wordpress-database/</guid>

      <pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>I just finished a new job to clean a WordPress website that was compromised with malicious codes. While investigating I noticed that there were several unidentified admin users created on the WordPress website from the infected code.</p>
<p>This is a very common issue for compromised WordPress websites.</p>
<p>The best solution is to remove all these unidentified admin users from the WordPress MySQL database and all their respective instances too. Here is the step-by-step process.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>I just finished a new job to clean a WordPress website that was compromised with malicious codes. While investigating I noticed that there were several unidentified admin users created on the WordPress website from the infected code.</p>
<p>This is a very common issue for compromised WordPress websites.</p>
<p>The best solution is to remove all these unidentified admin users from the WordPress MySQL database and all their respective instances too. Here is the step-by-step process.</p>
<p>Note: for referene purpose, I have used table prefix as <em>wp_</em>. In your case, you need to use your actutal table prefix.</p>
<p><strong>Delete user meta (capabilities, roles, etc.)</strong></p>
<pre tabindex="0"><code>DELETE FROM wp_usermeta WHERE user_id IN (4,5,6,7,8);
</code></pre><p><strong>Delete users</strong></p>
<pre tabindex="0"><code>DELETE FROM wp_users WHERE ID IN (4,5,6,7,8);
</code></pre><p><strong>Reassign posts to admin (recommended)</strong></p>
<p>Replace <code>1</code> with your main admin user ID</p>
<pre tabindex="0"><code>UPDATE wp_posts SET post_author = 1 WHERE post_author IN (4,5,6,7,8);
</code></pre><p><strong>Delete all their posts</strong></p>
<pre tabindex="0"><code>DELETE FROM wp_posts WHERE post_author IN (4,5,6,7,8);
</code></pre><p><strong>Delete comments by those users</strong></p>
<pre tabindex="0"><code>DELETE FROM wp_comments WHERE user_id IN (4,5,6,7,8);
</code></pre><p><strong>Clean comment meta (optional but good)</strong></p>
<pre tabindex="0"><code>DELETE cm FROM wp_commentmeta cm LEFT JOIN wp_comments c ON cm.comment_id = c.comment_ID WHERE c.comment_ID IS NULL;
</code></pre><p><strong>Clean orphaned usermeta (optional, extra safety)</strong></p>
<pre tabindex="0"><code>DELETE um FROM wp_usermeta um LEFT JOIN wp_users u ON um.user_id = u.ID WHERE u.ID IS NULL;
</code></pre><p><strong>Extra Security Check (VERY IMPORTANT)</strong></p>
<p>After cleanup, check if database still has hidden admin roles:</p>
<pre tabindex="0"><code>SELECT * FROM wp_usermeta WHERE meta_key = &#39;wp_capabilities&#39; AND meta_value LIKE &#39;%administrator%&#39;;
</code></pre><p>If any unknown users still appear, do investigate immediately.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Generate Random Number in PHP</title>

      <link>https://wavesdream.com/posts/generate-random-number-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/generate-random-number-php/</guid>

      <pubDate>Fri, 31 Mar 2023 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>In PHP, you can generate a random number between 1 and 9 using the rand() or mt_rand() functions. Here are examples of both:</p>
<p>Using rand() Function:</p>
<p><strong>$randomNumber = rand(1, 9);<br>
echo “Random number between 1 and 9: ” . $randomNumber;</strong></p>
<p>Using mt_rand() Function:</p>
<p><strong>$randomNumber = mt_rand(1, 9);<br>
echo “Random number between 1 and 9: ” . $randomNumber;</strong></p>
<p>Both functions will generate a random integer between the specified range, inclusive of both 1 and 9.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>In PHP, you can generate a random number between 1 and 9 using the rand() or mt_rand() functions. Here are examples of both:</p>
<p>Using rand() Function:</p>
<p><strong>$randomNumber = rand(1, 9);<br>
echo “Random number between 1 and 9: ” . $randomNumber;</strong></p>
<p>Using mt_rand() Function:</p>
<p><strong>$randomNumber = mt_rand(1, 9);<br>
echo “Random number between 1 and 9: ” . $randomNumber;</strong></p>
<p>Both functions will generate a random integer between the specified range, inclusive of both 1 and 9.</p>
<p>Here’s how you might use this in a simple PHP script:</p>
<pre tabindex="0"><code>&lt;?php
// Generate a random number between 1 and 9 using rand()
$randomNumberRand = rand(1, 9);
echo &#34;Random number using rand(): &#34; . $randomNumberRand . &#34;&lt;br&gt;&#34;;

// Generate a random number between 1 and 9 using mt_rand()
$randomNumberMtRand = mt_rand(1, 9);
echo &#34;Random number using mt_rand(): &#34; . $randomNumberMtRand;
?&gt;
</code></pre><p><strong>Why Use mt_rand()?</strong></p>
<p>While both rand() and mt_rand() are suitable for generating random numbers, mt_rand() is generally preferred because it is based on the Mersenne Twister algorithm, which is faster and has a better distribution of numbers. Feel free to use either function depending on your requirements.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Convert Indian Currency from Numeric to Words in PHP</title>

      <link>https://wavesdream.com/posts/convert-indian-currency-numeric-to-words-php/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/convert-indian-currency-numeric-to-words-php/</guid>

      <pubDate>Fri, 30 Sep 2022 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>To convert a numeric value to Indian currency format (words), you can use a custom function. Here’s an example of how you can achieve this:</p>
<p>This function <strong>convertToIndianCurrencyWords()</strong> converts a numeric value into its Indian currency format representation in words.</p>
<pre tabindex="0"><code>&lt;?php
function convertToIndianCurrencyWords($number) {
    $ones = array(
        0 =&gt; &#39;&#39;, 1 =&gt; &#39;One&#39;, 2 =&gt; &#39;Two&#39;, 3 =&gt; &#39;Three&#39;, 4 =&gt; &#39;Four&#39;,
        5 =&gt; &#39;Five&#39;, 6 =&gt; &#39;Six&#39;, 7 =&gt; &#39;Seven&#39;, 8 =&gt; &#39;Eight&#39;, 9 =&gt; &#39;Nine&#39;
    );

    $teens = array(
        11 =&gt; &#39;Eleven&#39;, 12 =&gt; &#39;Twelve&#39;, 13 =&gt; &#39;Thirteen&#39;, 14 =&gt; &#39;Fourteen&#39;,
        15 =&gt; &#39;Fifteen&#39;, 16 =&gt; &#39;Sixteen&#39;, 17 =&gt; &#39;Seventeen&#39;, 18 =&gt; &#39;Eighteen&#39;,
        19 =&gt; &#39;Nineteen&#39;
    );

    $tens = array(
        1 =&gt; &#39;Ten&#39;, 2 =&gt; &#39;Twenty&#39;, 3 =&gt; &#39;Thirty&#39;, 4 =&gt; &#39;Forty&#39;, 5 =&gt; &#39;Fifty&#39;,
        6 =&gt; &#39;Sixty&#39;, 7 =&gt; &#39;Seventy&#39;, 8 =&gt; &#39;Eighty&#39;, 9 =&gt; &#39;Ninety&#39;
    );

    $hundreds = array(
        &#39;&#39;, &#39;Hundred&#39;, &#39;Thousand&#39;, &#39;Lakh&#39;, &#39;Crore&#39;
    );

    $words = array();

    if ($number &lt; 0) {
        $words[] = &#39;Minus&#39;;
        $number = abs($number);
    }

    $numString = (string)$number;

    $numDigits = strlen($numString);
    $numChunks = ceil($numDigits / 2);
    $numChunkLen = $numDigits % 2 ?: 2;
    $numChunkPos = 0;

    for ($i = 0; $i &lt; $numChunks; ++$i) {
        $numChunk = substr($numString, $numChunkPos, $numChunkLen);
        $numChunk = (int)$numChunk;

        if ($numChunk != 0) {
            $numChunkWords = array();

            if ($numChunk &gt;= 10 &amp;&amp; $numChunk &lt;= 19) {
                $numChunkWords[] = $teens[$numChunk];
            } elseif ($numChunk &gt;= 20) {
                $tensDigit = (int)($numChunk / 10);
                $numChunkWords[] = $tens[$tensDigit];

                $onesDigit = $numChunk % 10;
                if ($onesDigit != 0) {
                    $numChunkWords[] = $ones[$onesDigit];
                }
            } elseif ($numChunk != 0) {
                $numChunkWords[] = $ones[$numChunk];
            }

            if (!empty($numChunkWords)) {
                $words = array_merge($words, $numChunkWords);
                if ($numChunkPos &gt; 0) {
                    $words[] = $hundreds[$i];
                }
            }
        }

        $numChunkPos += $numChunkLen;
        $numChunkLen = 2;
    }

    return implode(&#39; &#39;, $words);
}

$number = 123456789; // Example number
$words = convertToIndianCurrencyWords($number);

echo ucfirst($words) . &#39; Rupees Only&#39;; // Output: Twelve Crore Thirty Four Lakh Fifty Six Thousand Seven Hundred Eighty Nine Rupees Only
?&gt;
</code></pre><p>Adjust the code as needed for different ranges or specific formatting requirements. The example provided here is a basic implementation for Indian currency representation.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>To convert a numeric value to Indian currency format (words), you can use a custom function. Here’s an example of how you can achieve this:</p>
<p>This function <strong>convertToIndianCurrencyWords()</strong> converts a numeric value into its Indian currency format representation in words.</p>
<pre tabindex="0"><code>&lt;?php
function convertToIndianCurrencyWords($number) {
    $ones = array(
        0 =&gt; &#39;&#39;, 1 =&gt; &#39;One&#39;, 2 =&gt; &#39;Two&#39;, 3 =&gt; &#39;Three&#39;, 4 =&gt; &#39;Four&#39;,
        5 =&gt; &#39;Five&#39;, 6 =&gt; &#39;Six&#39;, 7 =&gt; &#39;Seven&#39;, 8 =&gt; &#39;Eight&#39;, 9 =&gt; &#39;Nine&#39;
    );

    $teens = array(
        11 =&gt; &#39;Eleven&#39;, 12 =&gt; &#39;Twelve&#39;, 13 =&gt; &#39;Thirteen&#39;, 14 =&gt; &#39;Fourteen&#39;,
        15 =&gt; &#39;Fifteen&#39;, 16 =&gt; &#39;Sixteen&#39;, 17 =&gt; &#39;Seventeen&#39;, 18 =&gt; &#39;Eighteen&#39;,
        19 =&gt; &#39;Nineteen&#39;
    );

    $tens = array(
        1 =&gt; &#39;Ten&#39;, 2 =&gt; &#39;Twenty&#39;, 3 =&gt; &#39;Thirty&#39;, 4 =&gt; &#39;Forty&#39;, 5 =&gt; &#39;Fifty&#39;,
        6 =&gt; &#39;Sixty&#39;, 7 =&gt; &#39;Seventy&#39;, 8 =&gt; &#39;Eighty&#39;, 9 =&gt; &#39;Ninety&#39;
    );

    $hundreds = array(
        &#39;&#39;, &#39;Hundred&#39;, &#39;Thousand&#39;, &#39;Lakh&#39;, &#39;Crore&#39;
    );

    $words = array();

    if ($number &lt; 0) {
        $words[] = &#39;Minus&#39;;
        $number = abs($number);
    }

    $numString = (string)$number;

    $numDigits = strlen($numString);
    $numChunks = ceil($numDigits / 2);
    $numChunkLen = $numDigits % 2 ?: 2;
    $numChunkPos = 0;

    for ($i = 0; $i &lt; $numChunks; ++$i) {
        $numChunk = substr($numString, $numChunkPos, $numChunkLen);
        $numChunk = (int)$numChunk;

        if ($numChunk != 0) {
            $numChunkWords = array();

            if ($numChunk &gt;= 10 &amp;&amp; $numChunk &lt;= 19) {
                $numChunkWords[] = $teens[$numChunk];
            } elseif ($numChunk &gt;= 20) {
                $tensDigit = (int)($numChunk / 10);
                $numChunkWords[] = $tens[$tensDigit];

                $onesDigit = $numChunk % 10;
                if ($onesDigit != 0) {
                    $numChunkWords[] = $ones[$onesDigit];
                }
            } elseif ($numChunk != 0) {
                $numChunkWords[] = $ones[$numChunk];
            }

            if (!empty($numChunkWords)) {
                $words = array_merge($words, $numChunkWords);
                if ($numChunkPos &gt; 0) {
                    $words[] = $hundreds[$i];
                }
            }
        }

        $numChunkPos += $numChunkLen;
        $numChunkLen = 2;
    }

    return implode(&#39; &#39;, $words);
}

$number = 123456789; // Example number
$words = convertToIndianCurrencyWords($number);

echo ucfirst($words) . &#39; Rupees Only&#39;; // Output: Twelve Crore Thirty Four Lakh Fifty Six Thousand Seven Hundred Eighty Nine Rupees Only
?&gt;
</code></pre><p>Adjust the code as needed for different ranges or specific formatting requirements. The example provided here is a basic implementation for Indian currency representation.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Convert All Date Data Format from VARCHAR to DATE in Any MySQL Table</title>

      <link>https://wavesdream.com/posts/convert-varchar-to-date-mysql-table/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/convert-varchar-to-date-mysql-table/</guid>

      <pubDate>Sun, 12 Jun 2022 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>I am working on a project which was majorly developed by any otehr developer. My work is to update every module and add some functionality. This is a financial application and already have huge amount data in the database and I have to work on existing data.</p>
<p>I noticed that all the <strong>Dates</strong> are stored into MySQL tables in <strong>VARCHAR</strong> format instead of <strong>DATE</strong> format. So, basically I can not implement any date related filetering feature.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>I am working on a project which was majorly developed by any otehr developer. My work is to update every module and add some functionality. This is a financial application and already have huge amount data in the database and I have to work on existing data.</p>
<p>I noticed that all the <strong>Dates</strong> are stored into MySQL tables in <strong>VARCHAR</strong> format instead of <strong>DATE</strong> format. So, basically I can not implement any date related filetering feature.</p>
<p>Now, my primary task is to convert all VARCHAR date to actual DATE format.</p>
<p>Here’s a method I followed to achieve this:</p>
<p>Assuming my varchar date column is named date_column and my table is named my_table, I can follow these steps:</p>
<ol>
<li>
<p>Add a New Date Column: First, add a new date column to my table.</p>
<p><strong>ALTER TABLE my_table ADD new_date_column DATE;</strong></p>
</li>
<li>
<p>Update New Date Column: Update the newly added date column using the STR_TO_DATE function to convert the varchar dates to date format.</p>
<p><strong>UPDATE my_table SET new_date_column = STR_TO_DATE(date_column, ‘my_date_format’);</strong></p>
<p>Replace ‘my_date_format’ with the format of the varchar dates in my column. For example, if my dates are in the format ‘YYYY-MM-DD’, use ‘%Y-%m-%d’.</p>
</li>
<li>
<p>Drop Old Date Column: If I am confident that the new date column contains the correct data, I can drop the old varchar date column.</p>
<p><strong>ALTER TABLE my_table DROP COLUMN date_column;</strong></p>
</li>
<li>
<p>Rename New Date Column: Finally, rename the new date column to the original column name.</p>
<p><strong>ALTER TABLE my_table CHANGE new_date_column date_column DATE;</strong></p>
</li>
</ol>
<p>Note: Anything of you will follow this process, make sure to take a backup of my data before making such changes to your database. Incorrectly manipulating your database structure can lead to data loss. If possible, it’s recommended to keep dates in the appropriate date or datetime format rather than varchar to avoid these kinds of issues.</p>
<p>Also, be aware that converting varchar data to date format directly in the database can be resource-intensive, especially if you have a large amount of data. It’s usually better to clean and format data before inserting it into the database in the correct format.</p>

      ]]></content:encoded>

    </item>

    

    <item>

      <title>Display Child Pages of a Parent Page in WordPress</title>

      <link>https://wavesdream.com/posts/display-child-pages-parent-page-wordpress/</link>

      <guid isPermaLink="true">https://wavesdream.com/posts/display-child-pages-parent-page-wordpress/</guid>

      <pubDate>Wed, 18 May 2022 00:00:00 +0000</pubDate>

      <author>Sanjay Bhowmick</author>

      <description><![CDATA[
<p>When you build a website in WordPress, pages are often arranged in a parent and child structure.</p>
<p>For example, you may have a main “Services” page. Under that, you create child pages like “Web Design”, “SEO”, and “Digital Marketing”. Now you want to show all these subpages automatically on the Services page.</p>
<p>In this article, you will learn a simple way to get all subpages of a parent page and show them in a clean list using WP_Query.</p>
      ]]></description>

      <content:encoded><![CDATA[
<p>When you build a website in WordPress, pages are often arranged in a parent and child structure.</p>
<p>For example, you may have a main “Services” page. Under that, you create child pages like “Web Design”, “SEO”, and “Digital Marketing”. Now you want to show all these subpages automatically on the Services page.</p>
<p>In this article, you will learn a simple way to get all subpages of a parent page and show them in a clean list using WP_Query.</p>
<pre tabindex="0"><code>&lt;?php
$parent_page_id = 10; // Change this to your parent page ID

$args = array(
    &#39;post_type&#39;      =&gt; &#39;page&#39;,
    &#39;post_parent&#39;    =&gt; $parent_page_id, // Get child pages of this parent
    &#39;orderby&#39;        =&gt; &#39;menu_order&#39;, // Order by menu order
    &#39;order&#39;          =&gt; &#39;ASC&#39;, // Display in ascending order
    &#39;posts_per_page&#39; =&gt; -1 // Get all child pages
);

$subpages = new WP_Query($args);

if ($subpages-&gt;have_posts()) : ?&gt;
    &lt;ul class=&#34;subpages-list&#34;&gt;
        &lt;?php while ($subpages-&gt;have_posts()) : $subpages-&gt;the_post(); ?&gt;
            &lt;li&gt;
                &lt;a href=&#34;&lt;?php the_permalink(); ?&gt;&#34;&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;
            &lt;/li&gt;
        &lt;?php endwhile; ?&gt;
    &lt;/ul&gt;
&lt;?php
    wp_reset_postdata(); // Reset query
else :
    echo &#39;&lt;p&gt;No subpages found.&lt;/p&gt;&#39;;
endif;
?&gt;
</code></pre>
      ]]></content:encoded>

    </item>

    

  </channel>

</rss>