MdMasud

WordPress, Laravel, Flutter

Blogs

  • How I Automatically Routed Service Requests to the Right Branch in WordPress Using Gravity Forms, ACF, and Postcode Matching

    How I Automatically Routed Service Requests to the Right Branch in WordPress Using Gravity Forms, ACF, and Postcode Matching

    One of the most rewarding things about working with WordPress is finding elegant ways to connect the front end with real-world business logic. Recently, I built a feature for a client that automatically routes customer service requests to the correct branch of the company — based entirely on the postcode entered in a Gravity Form.

    Here’s a breakdown of how I did it using Gravity Forms, Advanced Custom Fields (ACF), and some clean PHP logic.

    The Problem: Which Branch Covers This Area?

    The client has multiple branches across the UK, each covering a specific set of postcode areas — like EH12, AB10, G1, etc. When a customer submits a service request through the form on their website, the business needs that request to be automatically forwarded to the branch responsible for that postcode.

    Manual routing wasn’t an option. It had to be smart, scalable, and easy to manage.

    The Stack

    • WordPress (custom theme)
    • Gravity Forms for form handling
    • Advanced Custom Fields (ACF) to attach postcode coverage info to taxonomy terms
    • Custom PHP logic to handle the postcode matching and data routing

    The Data Structure

    Each branch is stored as a custom taxonomy term (location) in WordPress. Each term has an ACF repeater field called postcode_area_coverage, and inside that repeater, a subfield named code holds the outward postcode areas like EH12, G1, AB10.

    So the structure looks like this:

    location (taxonomy term)
    └── postcode_area_coverage (repeater)
    ├── code: EH1
    ├── code: EH2
    └── code: EH12

    The Gravity Form

    The form collects the usual user details, including a postcode field. Behind the scenes, I validate the format of the postcode, extract the outward part (everything before the space), and match it against the postcode coverage of each branch.

    Once matched, I automatically store the matched branch in a hidden Gravity Forms field. That field can then be used to:

    • Route notifications
    • Display confirmation messages
    • Track analytics

    Extracting the Outward Code from a Full Postcode

    if (preg_match('/^([A-Z]{1,2}[0-9][0-9A-Z]?)/', strtoupper(trim($postcode)), $matches)) {
        $outward = $matches[1]; // e.g. "EH12" from "EH12 5AB"
    }

    This snippet takes the full UK postcode submitted in the form and extracts the outward code (first part). That’s what I use to match against each branch’s coverage.

    Matching the Postcode to a Branch via ACF Repeater

    $terms = get_terms(['taxonomy' => 'location', 'hide_empty' => false]);
    foreach ($terms as $term) {
        $coverage = get_field('postcode_area_coverage', 'location_' . $term->term_id);
        foreach ($coverage as $row) {
            if (strtoupper($row['code']) === $outward) {
                return $term->term_id; // Match found
            }
        }
    }

    Here, I loop through each location taxonomy term, check their ACF postcode coverage, and find a match with the user’s outward postcode. Once matched, I return that branch’s ID.

    Updating a Gravity Form Field After Submission

    GFAPI::update_entry_field($entry['id'], self::LOCATION_SELECTED_FROM_POSTCODE, $branch_id);

    After finding the correct branch, I updated a hidden field in the submitted Gravity Form entry so it stores which branch should handle the request. This value is later used to route notifications.

    At the End

    • The business now handles customer requests faster and more efficiently.
    • Postcode coverage can be updated by non-technical users directly in the WordPress admin.
    • The system is scalable — just add a new location with postcode areas, and it’s instantly supported.

    It’s always fun to bridge the gap between user input and smart business logic. This was a great example of how custom taxonomy, ACF, and Gravity Forms can work together to create something genuinely useful — with no need for heavyweight plugins or complex integrations.

  • Automating Postcode Area Coverage in WordPress with ACF and CSV Import

    In a recent project, I had to bulk-import postcode data into a WordPress site using Advanced Custom Fields (ACF). Each postcode had to be linked to a custom taxonomy term (location), and each term had a repeater field named postcode_area_coverage, which stores multiple entries under a subfield called code.

    The data came from a simple CSV file provided by the business manager. Instead of manually entering data term by term, I wrote a script that matched postcodes to taxonomy terms based on email addresses and updated everything programmatically.

      The Data Format

      The CSV I received looked like this:

      EH1,,branch1@email.com  
      EH2,,branch1@email.com  
      AB10,,branch2@email.com  
      

      The logic was straightforward: match each postcode to the correct location using the associated email, then populate the repeater field accordingly.

      I wrote a PHP script that handled the following:

      • Loaded all location terms from the taxonomy.
      • Built a reference map using each term’s ACF email field.
      • Read the CSV file row by row.
      • Matched each row’s email to a location term.
      • Grouped the postcodes by term ID.
      • Updated the postcode_area_coverage repeater using update_field().

      The Code.

      <?php
      
      include('wp-load.php'); // adjust path as needed to load WordPress context
      
      $location_ref = [];
      $taxonomy = 'location';
      
      // Step 1: Build reference map of emails to term IDs
      $locations = get_terms([
          'taxonomy' => $taxonomy,
          'hide_empty' => false,
      ]);
      
      if (!empty($locations) && !is_wp_error($locations)) {
          foreach ($locations as $location) {
              $email_field = get_field('email', 'location_' . $location->term_id);
              if ($email_field) {
                  $location_ref[trim($email_field)] = [
                      'term' => $location->term_id,
                      'email' => trim($email_field)
                  ];
              }
          }
      }
      
      $postcodes_csv = 'postcode.csv'; // path to your CSV file
      $data_array = [];
      $orphan_postcode = [];
      
      if (($fh = fopen($postcodes_csv, 'r')) !== false) {
          while (($data = fgetcsv($fh, 1000, ',')) !== false) {
              $postcode = trim($data[0] ?? '');
              $email = trim($data[2] ?? '');
      
              if ($postcode) {
                  if ($email && isset($location_ref[$email])) {
                      $term_id = $location_ref[$email]['term'];
                      $data_array[$term_id][] = ['code' => $postcode]; // 'code' is the ACF subfield
                  } else {
                      $orphan_postcode[] = $postcode;
                  }
              }
          }
          fclose($fh);
      }
      
      // Step 2: Update each term’s repeater field
      foreach ($data_array as $term_id => $postcodes) {
          update_field('postcode_area_coverage', $postcodes, $taxonomy . '_' . $term_id);
      }
      
      // Optional: Printing orphan postcodes for debugging
      if (!empty($orphan_postcode)) {
          echo "Postcodes with no matching email:<br>";
          echo implode(', ', $orphan_postcode);
      }
      
      

      What This Does

      • Reads the CSV line by line.
      • Trims and sanitises inputs to avoid matching issues.
      • Maps each row to the correct taxonomy term using the email ACF field.
      • Builds an array in ACF repeater format ([ ['code' => 'EH1'], ... ]).
      • Uses update_field() to push postcode data into each term.

      Why I Like This Approach

      • It’s fast and scalable.
      • It makes use of existing ACF structures — no custom database tables or plugins needed.
      • It’s repeatable: anytime the business updates postcode data, I just run the script again.

      This was a small but satisfying piece of dev work — a perfect example of automating the boring stuff. If you’re working with taxonomy terms, ACF, or bulk content in WordPress, scripting these kinds of updates can save hours of time and prevent manual errors.

    • How to Keep Dropdown Submenu Open After Gravity Form AJAX Submit

      While working on a WordPress site, I embedded a Gravity Form inside a dropdown submenu of the navigation menu. The submenu appears on hover, and inside it, users can submit an enquiry form via Gravity Forms using AJAX.

      Everything worked fine, until the form was successfully submitted.

      Good : If validation failed, the form stayed open and errors were visible.

      Bad : But when the form successfully submitted, the confirmation message would briefly flash — and the submenu would immediately disappear, making it look like nothing happened.

      This wasn’t a great user experience, especially if users didn’t realise their form had gone through.

      Why It Happens

      When Gravity Forms submits via AJAX, it dynamically replaces the form’s content with the confirmation message. This causes a DOM update that disrupts the hover state of the submenu, especially if it’s tied to :hover CSS.

      So, the submenu disappears — not because of an error, but because the browser no longer sees the user as “hovering” during or right after the form update.

      The Solution

      The fix is to manually reapply a class to keep the submenu open when the form is successfully submitted, then remove that class when the user moves the mouse away.

      You don’t need any complex JavaScript frameworks — just a few lines of jQuery and a little CSS.

      jQuery(document).ready(function($) {
       var menuItem = $('#menu-item-1798'); // ID of the parent menu item
      
       // When the form is successfully submitted via AJAX
       $(document).on('gform_confirmation_loaded', function(event, formId) {
        if (formId === 5) { // Replace with your actual form ID
         menuItem.addClass('keep-open');
        }
       });
      
       // When user moves their mouse out of the menu item, close it
       menuItem.on('mouseleave', function() {
        if (menuItem.hasClass('keep-open')) {
         menuItem.removeClass('keep-open');
        }
       });
      });

      Optional CSS

      Add proper style to your stylesheet to ensure the menu stays visible when the keep-open class is active.

      The Output

      With this small enhancement:

      • The submenu remains open after a successful Gravity Form submission.
      • Users can clearly see the confirmation message.
      • The menu closes cleanly once the user moves away.

       It works beautifully without any plugin overhead or redesigns.

      Have you run into a similar problem? Got a cleaner approach ? Drop your thoughts in the comments!

    • Why Neovim is a Game-Changer for Developers

      When I first started using Neovim, it felt overwhelming, especially since I was accustomed to code editors like VS Code and NetBeans for development. However, after a few days of exploration and practice, I began to see a significant boost in my productivity. For developers seeking a powerful, customisable, and efficient text editor, Neovim offers a unique advantage over many other editors. While the learning curve can be steep for newcomers, the benefits of using Neovim, especially when configured properly, are immense. Here’s why Neovim can supercharge your development workflow.

      1. Supercharge Productivity with Shorthand Commands

      Neovim thrives on modal editing—its command, insert, and visual modes allow developers to perform complex text manipulations with minimal keystrokes. Custom mappings and plugins make it possible to:

      • Jump to specific lines, blocks, or characters effortlessly.
      • Perform multi-line edits in seconds.
      • Create macros to repeat tasks, saving countless hours during repetitive coding tasks.

      With practice, these features can cut down editing time significantly.

      Basic Shorthand Commands

      To truly harness the power of Neovim, you can start with these essential commands. They cover everything from navigation to editing and can significantly reduce the time spent on repetitive tasks:

      Navigation

      • h,j,k, Move the cursor left, down, up and right respectively
      • w Move the cursor to the beginning of the next word.
      • b Move the cursor to the beginning of the previous word.
      • e Move the cursor to the end of the current word.
      • gg Move the cursor to the beginning of the file.
      • G Move the cursor to the end of the file.

      Editing

      • i Enter insert mode at the current cursor position.
      • I Enter insert mode at the beginning of the current line.
      • a Enter insert mode after the current cursor position.
      • A Enter insert mode at the end of the current line.
      • o Insert a new line below the current line and enter insert mode.
      • O Insert a new line above the current line and enter insert mode.
      • r Replace the character under the cursor.
      • R Enter replace mode.
      • x Delete the character under the cursor.
      • X Delete the character before the cursor.
      • dd Delete the current line.
      • yy Copy(yank) the current line.
      • p or P Paste after/before the cursor.
      • u Undo the last change.
      • Ctrl - r Redo the last undone change.
      • Esc Exit insert mode.

      Saving and quitting

      • :w Save the current file.
      • :q Quit the editor.
      • :wq Save and quit the editor.
      • :q! Quit without saving changes.

      Splitting windows

      • :split Split the window horizontally.
      • :vsplit Split the window vertically.
      • :q Close the current window.

      Search

      • /{pattern} Search for the specified pattern.
      • n Jump to the next match of the current search pattern.
      • N Jump to the previous match of the current search pattern.

      Help

      • :help {pattern} Search for the specified pattern.
      • :help user-manual Open the Neovim user manual in a browser.

      If you’re new to Neovim, check out this list for a deeper dive into mastering these commands.

      2. Perfect Search and Navigation

      Neovim provides a robust built-in search system with support for:

      • Regex searches to find specific patterns in your code.
      • Search highlighting to spot results instantly.
      • Search history, so you can quickly repeat previous queries.

      Combined with plugins like Telescope, searching across files and projects becomes effortless. Whether it’s locating a method, function, or a deeply nested file, Neovim ensures you never lose your way.

      3. Efficient Code Exploration

      Navigating large files or projects can be daunting, but Neovim makes it intuitive:

      • Use tags to jump to function or variable definitions with :tag.
      • Explore file structures with tree-based plugins like NvimTree or Fern.
      • Jump between related code blocks, functions, or variables with plugins like Hop or EasyMotion.

      For large-scale projects, these features significantly reduce the time spent scrolling and searching.

      4. Unmatched Customisability

      Neovim’s Lua-based configuration allows developers to tailor their setup to suit specific needs. This flexibility enables:

      • Custom keybindings to streamline frequently used commands.
      • Personalized color schemes for a visually pleasing workspace.
      • Integration with modern development tools like LSP (Language Server Protocol) and treesitter for enhanced syntax highlighting and code intelligence.

      The ability to fine-tune every aspect of your editor ensures it works exactly the way you want it to.

      5. Plugin Ecosystem

      Neovim’s active community continually develops plugins that extend its functionality:

      • Auto-completion: With tools like nvim-cmp, get intelligent code suggestions.
      • Git Integration: View changes inline or manage repositories directly using Fugitive or Lazygit.
      • Debugging: Plugins like nvim-dap enable a full debugging environment within Neovim.

      These plugins elevate Neovim into a full-fledged IDE.

      6. Lightweight and Fast

      Unlike many modern editors that can be resource-intensive, Neovim remains lightweight and fast. It starts up quickly and can handle large files without lag, making it an excellent choice for both local and remote development.

      7. Cross-Platform Compatibility

      Neovim runs on macOS, Linux, and Windows, ensuring a consistent development environment regardless of the operating system. With its terminal-based interface, you can even use it over SSH for remote work.

      8. A Tool That Grows With You

      Neovim’s steep learning curve is an investment that pays off. The more you use it, the more efficient you become. Over time, you’ll discover advanced features like:

      • Buffer management for working on multiple files.
      • Command chaining for executing complex tasks with a single keypress.
      • Extending functionality with Lua scripting.

      Neovim is more than just an editor—it’s a productivity powerhouse for developers. If you’re looking to elevate your development workflow, I highly recommend giving Neovim a try. Although it might feel challenging at first, like it did for me, the productivity gains and customisation potential make it an invaluable tool for developers.

    • Welcome to My Developer Blog

      Welcome to My Developer Blog

      Hello

      Welcome to My Personal Blog on the World of Web Development! I’m excited to share this space with you—a hub for all things web development. Whether you’re a fellow developer, a student diving into code for the first time, or a business owner curious about what makes a website tick, you’re in the right place.

      On this blog, I’ll be covering a range of development topics, from the basics to more advanced projects and tips.
      Here’s a glimpse of what you can expect:

      WordPress Development:

      Tips, tricks, and tutorials on everything from theme customization to plugin development.

      PHP and Laravel

      Insights into backend development, focusing on PHP fundamentals and building robust applications with Laravel.

      JavaScript & jQuery

      From beginner-friendly JavaScript guides to advanced use of jQuery, we’ll explore the most versatile language in web development.

      React & Next.js

      Frontend frameworks like React and Next.js will feature heavily, especially when it comes to building dynamic, user-friendly interfaces.

      HTML, CSS & Bootstrap

      We’ll cover essentials, design tips, and responsive layout strategies that form the backbone of any website.

      I’ll also share project ideas, troubleshooting tips, and the lessons I learn along the way. Whether you’re interested in practical how-tos, deep dives into frameworks, or ways to stay updated in this ever-evolving field, I hope my blog becomes a valuable resource for you.