Author: admin

  • How To Create Custom Table List In WordPress Admin Page

    Introduction

    1. In this tutorial, you will learn how to add an admin table which is similar to admin posts or pages or comments table list
    2. Our table list is a merged list of all searchable post types post which are in draft mode i.e. not yet published or still work in progress posts
    3. Based on this tutorial you will learn how to implement the following features
      1. Search box
      2. Filter dropdown (Post type)
      3. Bulk action (Trash multiple posts at a time)
      4. Action quick links (Each post have edit, trash & view)
      5. Pagination
    4. Our custom table is a child class of the official table class: WP_List_Table
    5. We will explore each and every method in its individual section
    6. GitHub link to directly activate as a plugin while learn/play with the source
    Sample Admin Table

    Complete Source Code

    Include Base Class

    1. In the complete source code gist (from now onwards we call it as main gist/file), you can find that we included our base class at line no: 24 though most of the time the class Drafts_List_Table directly extend the class WP_List_Table without the include once but WordPress functioning based on hooking process so sometimes our class may be called before hooked and globally included the WP_List_Table therefore it’s always better to check if it’s included or not and included the class file
    2. Also instead of hopping here and there, we can add the snippet which is related to the current context so we include partial code gist like this

    Extend Base Class

    1. We extend our table class Drafts_List_Table from core WordPress class WP_List_Table at line no: 35 like this

    Class Constant & Property

    1. The class Drafts_List_Table have one constant POSTS_PER_PAGE and one private property $allowed_post_types (main source code line no: 40)
    2. The POSTS_PER_PAGE is to stores an integer value which is the number of maximum posts to be shown in the table per page
    3. The property $allowed_post_types have an array of post types that can be queried and used to list out all posts that come under these post types

    Constructor

    1. Our constructor (main source code line no: 52) is not that much fancy it has two simple statement one is a parent constructor call with three arguments singular, plural both for labeling purpose and ajax accepts boolean to decide whether HTTP calls are ajax based or not
    2. The other one calls the class method allowed_post_types() and stores the return value in the private property allowed_post_types

    Get Allowed Post Types

    1. This method is placed inside this class is for tutorial purpose only (but for the real-life project, my suggestion is to create a utility or helper module which may have more helper classes like one for UI works, another API services, and other for wrapping commonly used DB queries likewise we can build n-number of classes for different common purposes)
    1. Let’s place the architectural suggestions aside and focus on this tutorial, the method allowed_post_types ( main source code line no: 71 ) will return the post types in the array
    2. Line no 9: by using WP core function get_post_types we fetch the post types in our web application here we pass an argument public with the boolean value true therefore it returns only publicly accessible post types
    3. Visit documentation for more details about the function get_post_types
    4. We unset the attachment post type to exclude that kind of posts from the table list and finally returned the remaining post type as an array

    Convert Slug String To Human Readable

    1. Yes, this method (main source code line no: 85) also another good candidate for the utility method
    2. This method converts the slug to readable format i.e. it replaces all underscore symbol with white space and title cased the words

    Convert Post Types Human Readable

    1. The method allowed_post_types_readable (main source code line no: 94) is iterate on all allowed post type and convert the post type’s slug into human-readable
    2. The inner working of this method is using the PHP function array_map we pass our human_readable as a callback that applies on each value of the private array property allowed_post_types
    3. The newly generated array is assigned to the variable $formatted and the same is returned

    Create Custom WP_Query Object

    1. This method get_posts_object (main source code line no: 108) is the data fetching method of this custom admin table class
    1. As this method is a little lengthier let’s try to refer to each statement using its gist line number for easier understanding, here all the line numbers pointing to the gist get_posts_object.php
    2. Line no 9: fetching private array property allowed_post_types then assign it to the method’s local variable $post_types
    3. Line no 11: we declare a local variable $post_args which holds initial argument we pass to the WP_Query instance constructor call
    4. The $post_args is an associative array with the following key-value pair
      1. The key post_type holds the array of post types
      2. The key post_status holds the array of statuses to fetch here we pass only one value i.e. draft
      3. The key posts_per_page holds the integer value which controls how many posts to show on the page
    5. Line no 17: the local variable $paged is fetch page number from query string by using the PHP function filter_input to validate if it’s an integer or not using the filter id FILTER_VALIDATE_INT
    6. Line no 19: if the variable $paged having truth value then assign the value stored in $paged to $post_args array key paged
    7. Line no 23: the local variable $post_type is fetching post type (which we can use to filter the table to show only specific post type posts only) from query string by using the PHP function filter_input, sanitized the incoming string using the id FILTER_SANITIZE_STRING
    8. Line no 25: if the variable $post_type having truth value then assign the value stored in $post_type to $post_args array key post_type
    9. Line no 29: the variable $orderby accepts the table column name, as the value get from the query string it’s good to sanitize it
    10. WordPress provided a sanitize function sanitize_sql_orderby which is specifically deal with the order by clause with or without sort order
    11. Using the sanitize_sql_orderby function we sanitized the column name
    12. Line no 30: the filtered query string order’s value is passed to WordPress function esc_sql for escaping if any SQL injection character present
    13. Don’t accept user’s data blankly always do escaping, sanitization, and validation (skip sub-points if you need)
      1. Four years back got a chance to audit a project, the theme is adding a music file name and it’s CDN path to DB in the insert query without escaping or doing some other alternative like a prepared statement or PDO the source code inserts the file name
      2. When sending back the review to the concerned team they asked “why we need to escape? it’s just a filename of an MP3 file”
      3. I replied that we need to escape the filename because various bands have an apostrophe in their band name like Guns N' Roses therefore please escape the user input
      4. Thank god the application is Indian based music and running happily without unintentional SQL injection by the web application user because most of the Indian name or band name doesn’t have an apostrophe
      5. But the piece of advice is, in order to break your web application no need to hire a hacker just make it famous, and more user using it you will get to know why I’m insisting this
    14. Line no 32: if the variable $orderby is empty then set a default value date, then our posts are sorted by the date column
    15. Line no 36: if the variable $order is empty then set a default value desc, then our posts are sorted in descending order i.e. reverse chronological order
    16. Line no 40: assigning the order by value into the variable $post_args associative index orderby which we pass an argument to the WP_Query class first parameter
    17. Line no 41: this statement also similar to the previous one at line no 40
    18. Line no 43: in the variable $search fetching the query string s and passed it to the esc_sql function, this query string s only available when the user did a search
    19. Line no 44: as said in the previous point the s available only on search therefore before assigning we doing a conditional check to verify it’s not empty
    20. Line no 45: once the not empty condition passed we assign the search value into the associative index s of the variable $post_args
    21. Line no 48: finally we pass the $post_orgs to the class WP_Query and return the query class object

    No Items Text Display

    1. The method no_items is overridden method of the base class WP_List_Table
    2. The purpose of this method is to display the information when no posts are available
    3. Line no 7: displaying the message about no posts which properly escaped for HTML and can be translated by using the WordPress function esc_html_e

    Display Default Column

    1. Line no 10: the overridden method column_default is used to handle the column output
    2. Internally this method is called for each column this method accepts two parameters
      1. $item have all the current row’s columns values in associative key-value pair
      2. $column_name current column name
    3. Line no 11: declared and initialized the variable $result with empty string which we use to assign the column data to be shown
    4. Line no 12: switch statement will switch and create the column value based on the passed column name
      1. Line no 13: the date case is used to display date in two variant either by date if the post created date is more than one day else returns how human saying the date for e.g. 10 minutes ago
      2. Line no 14: using the WordPress template function get_the_time retrieve the post created time with formatting, get_the_time to learn more
      3. Line no 15: the function get_post_timestamp is used to retrieve the draft post published time in unix timestamp format, get_post_timestamp to learn more
      4. Line no 16: took the seconds difference of current unix timestamp (using PHP function time) and post created time and assign it to the variable $time_diff
      5. Line no 18: we’re checking the time is less than a day if so then display the time in human readable format using the WordPress formatting function human_time_diff
      6. Line no 22: else will show the date in the format Y/m/d
      7. The remaining cases ( author and type) are self explanatory
    5. Line no 37: return the variable $result which have the value to show in the specific column

    Display Table Header

    1. The method get_columns ( main source code line no: 200 ) is an inherited must overridden method which is responsible for displaying the table headers
    2. For a quick view please see the snippet of the main source below
    1. This method simply returns the array of key-value pair of columns which have a set of an internal name as key and it’s display value as the value

    Title Column Callback

    1. The method column_title (main source code Line no: 216) is used to display the HTML in the table column Title
    2. Internally this method is called by the parent method single_row_columns elseif is called the column_title method dynamically using the callback logic
    1. Line no 10: using the WordPress function get_edit_post_link we fetch the edit link for the current post in the table row looping flow
    2. Line no 11: get_permalink is used to fetch the current post permalink
    3. Line no 12: get_delete_post_link is used to fetch the delete link of the current post
    4. Line no 14 – 36: is simple HTML generation to display in the Title column by returning the variable $output, in these statements, the only thing we need to focus on is a template function _post_states
    5. The function _post_states is used to display post states as HTML for e.g. in the Introduction section if you see the sample image there are two things displayed in post states Draft, Elementor
    6. The state Draft is fetched by core WordPress whereas Elementor fetched by Elementor plugin to notate this post is formed by Elementor page builder

    Column Checkbox

    1. The method column_cb (main source code line no: 251) is a simple method to display a checkbox in each row to select the post for bulk action like trashing an unneeded post

    Build Table Data

    1. The method prepare_items (main source code line no: 264) is the core part to create the data for the table note here I’m saying about an array of information to show on the table, not the HTML design part
    1. Line no 9: called the method get_columns to fetch an array of column names to be shown in the header of the table
    2. Line no 10: called the method get_sortable_columns to fetch an array of sortable data in the format of an internal name as key and sorting option as a value such as array( column_internal_name, sorting_type) and assign it to the variable $sortable (don’t worry we will see more detail when we explain this method we will see the detailed way)
    3. Line no 13: the parent class property _column_headers accepts an array of arrays as in this order first array of columns to be shown in the table, second an array of columns which are hidden one, third array of sortable columns, fourth a string denote which column is primary one
    4. Line no 16: called the method process_bulk_action which is responsible for bulk actions like trashing the posts
    5. Line no 18: called the method get_posts_object which return the WP_Query instance with whatever filters and sorting options are applied, that instance is assigned to the variable $get_posts_obj
    6. Line no 20: check if the queried WP_Query instance have posts object using the method $get_posts_obj->have_posts()
    7. Line no 22: if posts are available then begin the looping while ( $get_posts_obj->have_posts() )
    8. Line no 24: the WP_Query method the_post is used to retrieve the next post internally which sets WP_Query property in_the_loop to true and retrieves the next post
    9. Line no 26: form the array of data therefore each index have an array of values to show in each row of the table, the formation of this array mostly using WordPress template functions
    10. Line no 34: the function wp_reset_postdata is used to reset the global variable $post to the main query’s current post after completing our custom query loop
    11. Line no 37: Assign our looped collection of table data to the parent class WP_List_Table property items therefore other methods that require data can access from this property
    12. Line no 39: the parent class method set_pagination_args is responsible to set pagination related information to the parent class property _pagination_args here we basically set up our pagination using three items
      1. total_items we pass the WP_Query property found_posts
      2. per_page we pass the WP_Query property post_count
      3. total_pages we pass the WP_Query property max_num_pages

    Create Bulk Action Dropdown

    1. This method (main source code line no: 309) return array of key-value pairs which is used to show in the bulk action dropdown (if you like to know how the HTML formed by retrieving the return value of this method then please check bulk_actions method of the parent class WP_List_Table)

    Process Bulk Actions

    1. This method process_bulk_action (main source code line no: 320) is used to do bulk actions like trashing the post likewise you can change the state of many posts (for e.g. change the set of posts from draft to publish) or process many posts data altogether (for e.g. trigger email to multi-selected users and change the custom state pending to invited)
    1. Line no 9: in the conditional statement, we check whether the current action is trash if so then execute the inner block
    2. Line no 10: the variable $post_ids hold get query value draft_id which is a collection of ids of the posts that need to be trashed
    3. Line no 12: verify is the variable $post_ids is an array
    4. Line no 13: convert all elements in the array into an integer value the reason is we received it from the get query therefore it will be a string and sometimes may have illegitimate data if the user intentionally add some junk data, here we iterated over each element using array_map
    5. Line no 15: we check this in if condition to confirm at least one element present in the $post_ids array
    6. Line no 16: pass all the ids to the WordPress function wp_trash_post which will trash the posts

    Display Actions, Filters, and Pagination

    1. The method display_tablenav (main source code LINE NO: 341) is an overridden method that is responsible for displaying bulk actions, filters dropdown, and pagination which accepts a single argument with a value of either top or bottom based on that display the block of HTML at the top or bottom of the table
    1. Line no 12: created the navigation wrapper div with a dynamic class top or bottom based on the argument $which value
    2. Line no 14: verify is the table has items to display
    3. Line no 16: if has items then display the bulk action dropdown
    4. Line no 20: the method extra_tablenav is used to display additional filter we will see more detail about this method in the next section
    5. Line no 21: the method pagination is the parent class method that handles the pagination of the table

    Extra Table Navigation HTML

    1. The method extra_tablenav (main source code line no: 367) is used to display additional filter controls here using the argument $which we controlled our filter to display only at the top of the table
    1. Line no 12: conditionally show our filter only at the top by checking the $which argument value is equal to top
    2. Line no 13: create a multidimensional associative array $drafts_dropdown_arg which we pass to the method html_dropdown we will see more about this method in the next section
    3. In the variable $drafts_dropdown_arg the options index has the value to show in the dropdown
    4. The container index has the class name to add to the dropdown component’s container div
    5. The next two indexes label and select represents its tag name, and it holds attributes of that tag in the inner array as key-value pair
    6. Line no 31: using the WordPress function submit_button echoes our submit button

    UI Helper HTML Dropdown

    1. The method html_dropdown (main source code line no: 399) is used to generate HTML dropdown dynamically which is wrapped inside container div also to be clear this method needs to be added to the utility class Helper therefore the same method can be used in many other places too but for this tutorial, I added this inside the same class
    1. This method is simple string interpolation of passed argument into the custom HTML it’s pretty easy to understand, and I believe there is no need for a very detailed explanation

    Sortable Column

    1. The method get_sortable_columns (main source code line no: 434) is an overridden method that simply returns an associative array
    1. Line no 11: the key is the column internal name and the value is an array that represents the behavior of the sorting
    2. Here we followed the format 'internal-name' => array( 'column', 'is_descending')
    3. The boolean false is no need to pass explicitly (see implementation logic) but for clarity here I passed instead of that if you alter it to true means on initial page load that column will be sorted in descending order

    Column CSS

    1. This anonymous function (main source code line no: 448) inject custom HTML in the header part because we used the admin_head tag (this snippet only load in the admin part, not for the user-facing frontend pages if you would like to load on frontend then use the tag wp_head)
    1. Line no 9: fetch the current page name from the global get query string
    2. Line no 10: check the page name is not equal to all-drafts then bypass the upcoming execution by executing the void return statement
    3. Line no 15: add CSS width property to the column type i.e. post type column therefore which will give more space or real-estate to the column Title

    Admin Menu For Drafts Table

    1. Using the hook admin_menu (main source code line no: 465) we hooked our drafts table admin page
    1. add_menu_page for more details about each argument and its purpose

    Instantiate Draft Table

    1. The function bootload_drafts_table (main source code line no: 483) is a callback function attached to the add_menu_page, we pass this as a second from the last argument
    1. Line no 7: instantiate custom admin table class Drafts_List_Table
    2. Line no 12: pass draft table page menu slug all-drafts as hidden value therefore whenever the user does a submit action like searching, after every new request the filtered table is shown at the right page
    3. Line no 15: the method prepare_items is the workhorse of this class which handles all table data generation and processing logic
    4. Line no 16: search_box is the overridden method that accepts two parameters are a label of the submit button and an HTML id attribute for the search input field here we pass the first argument i.e. label as Search and the second argument i.e. id as search
    5. Line no 17: display is a parent class method that is responsible for displaying or echoing the HTML table with dynamic data, actions, filters, and pagination

    Conclusion

    1. Through this tutorial, you learned how we can create a custom admin table on WordPress
    2. Simultaneously using this knowledge you understand how WordPress posts, pages, and comments table are formed
    3. Not only WordPress core many plugins like WooCommerce, SEO by Rank Math, and many other plugins more or less follow the same procedure therefore it’s easy for you to understand their admin table source
    4. By learning this tutorial now you’re comfortable with WordPress core class WP_List_Table

  • How To Limit The Cart Quantity Of Discounted Product

    Introduction

    1. In this tutorial, you will learn how to control the quantity of the specific set of products based on a logical condition
    2. Here in this tutorial, we considered the condition if the discounted product added more than our defined quantity it will notify/alert the end-user but once you understand the concept the same can be applied in different scenarios with little modifications
    3. Through this process, you will learn the following from the technical/development side
      1. woocommerce_add_to_cart_validation filter hook
      2. woocommerce_update_cart_validation filter hook
      3. wc_add_notice WooCommerce notice function
      4. wc_get_product function to get product instance
      5. get_regular_price product instance method
      6. get_sale_price product instance method
      7. generate_cart_id cart instance method
      8. find_product_in_cart cart instance method
      9. get_cart_item cart instance method
    4. Sample notice

    Add to cart validation

    1. Line 2: we defined a named constant MAX_QUANTITY where it helps how much discounted product a user can add to a cart
    2. Line 4: we called the filter hook function add_filter with the tag woocommerce_add_to_cart_validation for the function validate_discounted_prdct_qty_limitation
    3. The filter woocommerce_add_to_cart_validation is responsible for doing validation while adding the product to the cart
    4. Line 19: Lets we see the inner working of the hooked function validate_discounted_prdct_qty_limitation
    5. The hooked function has three arguments
      1. $passed Boolean value to pass or fail the validation
      2. $product_id an integer value which is the product id that is the primary key of that product
      3. $quantity an integer which has the intended quantity of the product
    6. Line 20: we call the function wc_get_product where we passed our product id which returns the right product object by making using of a factory pattern class WC_Product_Factory which return any one of the product object types WC_Product_Simple, WC_Product_Grouped, WC_Product_External, WC_Product_Variable, etc.,
    7. Line 22: we get the products parent id if the product doesn’t have a parent which return 0 else it returns the parent product id
    8. Line 23: if the product id isn’t empty (possible for variable products child product or for any custom product type) then assign the variable $product_id with the product’s parent id
    9. Line 27: we call our validator function validate_product_qty and return it
    10. On the shop page, when the threshold limit is crossed instead of showing the notice on shop page WooCommerce redirects to a specific product page and alerts the notice which is the default flow of the ajax add to cart functionality

    Update cart validation

    1. Line 3: we hooked our custom function on_update_cart_limit_qty to the hook tag woocommerce_update_cart_validation which is responsible for update cart validation
    2. Therefore this custom function solely control the WooCommerce cart page validation and previous section we explored the hook woocommerce_add_to_cart_validation which can be triggered on the shop page or product page
    3. Line 19: the function on_update_cart_limit_qty is a simple one-line function which calls the validation function validate_product_qty
    4. Lets we see the arguments of this function
      1. $passed Boolean value to pass or fail the validation
      2. $cart_item_key string value, to be clear WooCommerce generated MD5 which is used as a key for every cart item in the cart
      3. $values array value, currently updated product cart item properties
      4. $quantity int value, which has the product’s updated quantity

    Show validate message

    1. Line 12: you may be surprised by seeing this function as earlier we saw that this function as the validation function but here it just the message notification function
    2. The reason for this is we abstracted our validation logic in other business logic function is_discounted_prdct_qty_exceeded so you can reuse all the function up to we discussed (including this) without modifying anything and interpolate your desired validation business logic function into the if condition or even if you’re using these functions as object-oriented methods then you can inject the validation business logic as dependency injection (DI)
    3. This function accepts three arguments they are
      1. $product_id int value, which holds the product’s id (Primary Key)
      2. $quantity int value, validating product quantity which can be verified against our MAX_QUANTITY constant
      3. $action_type string value, a switcher key which accepts either add or update as value depends on this value we slightly modify the quantity calculation logic in the function is_discounted_prdct_qty_exceeded
    4. Line 13: here whatever argument values we received are directly passed to the validation business logic function is_discounted_prdct_qty_exceeded
    5. Line 15: the variable $output_string holds the string returned by the WordPress function wp_sprintf
    6. Line 21: the WooCommerce function wc_add_notice is used to display the validation message
    7. If product quantity exceeded the threshold limit then we return false else true

    Validation business logic

    1. Lets we see about the helper function is_discounted_prdct_qty_exceeded
    2. Line 13: We passed the argument $product_id to the WooCommerce function wc_get_product which return the WC_Product object, if the product exists for the given product id else, return null if not found and if anything wrong return false
    3. Line 14: we call the method get_regular_price of the WC_Product object variable $product_obj this method is responsible to return the product’s regular price i.e. actual price
    4. Line 15: the method get_sale_price is similar to get_regular_price but it returns the discounted price
    5. Line 17: we called the cart instance method generate_cart_id which return the unique cart id of the passed product id
    6. Line 18: the cart instance method find_product_in_cart return the cart item key if the product is in the cart else return an empty string, this method is used to find whether our product is already in the cart or not
      1. We will use this variable in if condition while adding a product to the cart we will see the purpose of this variable later
    7. Line 20: this conditional logic is used to check whether our product is the discounted one or not
      1. ! empty( $sale_price ) here we check whether our sale price is not empty
      2. (float) $sale_price < (float) $regular_price here we check if the sale price is lesser than the regular price to decide whether the product is discounted or not
    8. Line 23: this conditional block is executed only when we are adding the product to the cart and the same product already present in the cart
      1. 'add' === $action_type here we checking is our action type is add if true means the next expression will be executed
      2. ! empty( $find_product_in_cart ) here we check if the product already in the cart
      3. The reason for checking this condition is considering like this if the product which we are adding is already in the cart with a quantity 2 and the currently adding product quantity is 3 means we need to check the sum of both cart and added product quantity which will be 5 against our threshold value 3 instead of that if we check only added quantity with the threshold value it will pass but it’s wrong therefore we summed up both added product and cart quantity
    9. Line 26: fetching a particular product’s data in the cart using the cart instance method get_cart_item using the cart item key which we get by passing the variable $cart_id
    10. Line 27: the variable $cart_item holds an array which has all the details of a particular product in the cart, we fetching the product’s cart quantity $cart_item['quantity'] and sum with the add to cart quantity finally assign the total sum to the variable $quantity
    11. Line 30: conditional check to check whether we crossed the threshold quantity if so then return true
    12. Line 36: if the conditions are fails then return false to indicate threshold is either not reached or not applicable for this product

    Conclusion

    1. In this tutorial, you learned how to control the quantity of the products in the cart
    2. You can find the full source code in the GitHub

  • How To Add Quantity Input In Shop Page

    Introduction

    1. This tutorial will teach you how to add a quantity input text box with the number type for each product in the shop page
    2. Something like this
    Product quantity counter
    1. When a user clicks the add to cart ajax button instead of adding one quantity of the product it will add the quantity present in the input box to the cart part page

    Rendering Input Quantity Box

    1. To render the quantity input box we are using the filter woocommerce_loop_add_to_cart_link
    2. You can find the official WooCommerce source code in GitHub where the filter hook is created
    3. Here is the code snippet for rendering the quantity box just above the add to cart button
    1. Lets we see line by line what this little function doing
    2. Line 1: hooking our quantity input rendering function to the filter hook with default priority 10 and the last argument passed for the function add_filter is about how many arguments the filter expects
    3. Line 3: here we declared our filter hook function with woocommerce_loop_add_to_cart_link expected two arguments $html and $product
      1. The $html argument holds the HTML of the ajax add to cart button
      2. The $product argument holds the product’s WooCommerce PHP object of any one of the following WC_Product_Simple or WC_Product_Variable or WC_Product_Grouped or WC_Product_External
      3. Learn more about all product types in the official documentation
    4. Line 6: we do a short circuit conditional check and add input quantity to only satisfying products
    5. Let’s explore each condition
      1. The first condition is $product which just check the variable’s value if it’s null or false or zero or empty string then discard the inner block of the if condition
      2. The second condition is $product->is_type('simple') which checks the current iterated product is of a type simple
      3. The third condition is $product->is_purchasable() which checks whether the product is a purchasable one
      4. The fourth condition is $product->is_in_stock() which checks whether the product is available in the stock
      5. The fifth condition is !$product->is_sold_individually() which checks negation of whether the product is sold individually without any quantities
    6. If all the above-mentioned condition is true then quantity input is rendered as in Line 7 using the WooCommerce template function woocommerce_quantity_input(array(), $product)
      1. This template function woocommerce_quantity_input accepts three optional parameters
      2. The first parameter is arguments for the HTML input number we pass an empty array so use the default values
      3. The second parameter accepts either WC_Product object or null, the default value is null
      4. If the second parameter is null then it fetches the product object from the $GLOBALS array but here we passed looped product object variable $product even though it’s not necessary to pass because the filter woocommerce_loop_add_to_cart_link assigns the current product to the $GLOBALS array
      5. The third boolean parameter by default accepts true, if true it echoes the HTML else return the HTML
    7. Line 9: returns the add to cart button HTML
    8. Now we completely explored quantity input HTML rendering functionality next we will see quantity updating plain JavaScript function

    Quantity Updating Functionality

    1. We hooked our function to the hook action wp_footer which prints the JS data or scripts just before the closing body tag
    2. You can find the official WordPress source code in GitHub where the action hook is created
    3. Here is the code snippet for updating the quantity data attribute of the add to cart button when the user updates the input quantity
    1. Inspect the add to cart button after adding this function you will see the quantity is updated with the value present in the quantity input box
    1. Let’s explore the frontend part functionality which is hooked to the action wp_footer
    2. Line 2: we hooked our frontend function update_quantity_attribute to the action hook wp_footer
    3. Line 3: declared the frontend function
    4. Line 6: opened the script tag
    5. Line 7: declared a JS variable simpleProductInput and assigned a DOM node list which we fetched using the JS method querySelectorAll of the document object
    6. Let us explore the string parameter '.product-type-simple .quantity > input' passed to the method querySelectorAll
      1. The method querySelectorAll behaves just like CSS selector so whatever DOM matched to the argument passed to the method is fetched as JS node list
      2. .product-type-simple is the class selector which fetches the DOM element which has the class product-type-simple
      3. If we further extend our selector like .product-type-simple .quantity which fetches the element matches with class value quantity and present inside the element with the class value product-type-simple
      4. The angle bracket > denotes child combinator selector which means it selects only direct children element
      5. input selects the dom element with HTML tag input
      6. So what our selector .product-type-simple .quantity > input is doing?
      7. It selects the input DOM present in each simple product
    7. Line 9: loop and fetch every targeted dom node from the dom node list
    8. Line 10: the method dom.addEventListener accepts two parameters
    9. The first one is to bind/add an event input it’s just like the events click, change, etc. to each input tag and the second parameter is listener anonymous function
    10. Let’s see the inner working of the anonymous function which accepts a single argument Event object e
      1. Inside the anonymous function, we chained a sequence of methods which is called as method chaining
      2. e.target.parentElement.nextElementSibling.setAttribute('data-quantity', e.target.value)
      3. e.target property points to DOM object which triggers the current event here it is the quantity input box
      4. e.target.parentElement returns the parent element of the target which is HTML div rendered over the quantity input tag
      5. e.target.parentElement.nextElementSibling returns the next element which sibling to the targeted DOM
      6. Closely note here we used nextElementSibling instead of nextSibling because the nextSibling fetches immediate next node it may be an element node or text node or comment node but nextElementSibling fetches the element node like P, Div, Span, etc. here we fetch anchor tag of the add to cart button
      7. Finally, we set the quantity what present in the input tag to the anchor tag add to cart button data attribute using the method setAttribute('data-quantity', e.target.value)
      8. Which accepts two parameters, the first one is the name of the attribute data-quantity and the second one is the value assigned to that attribute
      9. Here the value is quantity input’s value because it is the target of the current event
    11. That’s all finally we enclose the script and function

    Conclusion

    1. In this tutorial, you learned how to intercept the shop page’s product loop and insert our desired logic or HTML
    2. Learned about types of product object such as WC_Product_Simple, WC_Product_Variable, WC_Product_Grouped and WC_Product_External
    3. Learned about product object methods such as is_type, is_purchasable, is_in_stock and is_sold_individually
    4. Learned about woocommerce_quantity_input which return or echo HTML of the quantity input
    5. Learned about Javascript event, method chaining, CSS selector and update or override the HTML attributes
    6. We implemented the functionality to add desired quantity instead of adding a single quantity in the cart
  • How To Create Custom AJAX Posts Load More Plugin In WordPress

    Introduction

    1. This tutorial will explain how to create your own custom AJAX load more plugin very easily and responsively
    2. This plugin is developed using plain JS instead of the jQuery library
    3. This plugin will load a set of posts of the specific category in grid-card fashion with a load more button
    4. To load remaining posts of that specific category click the load more button
    5. You can download the plugin source from GitHub
    6. Each card holds post image, title, excerpt and read more button for reference you can check the below image
    Single Card of 3 infinite scroll grid

    Let’s Explore The ShortCode

    1. As described in the readme file of the GitHub source the shortcode can be expressed as [vg_ajax_posts category_name="post-formats" posts_per_page="6"]
    2. In the above shortcode vg_ajax_posts is the shortcode’s name which has two attributes
    3. The first attribute is category_name which accepts any post category slug
    4. The second attribute is posts_per_page which accepts the maximum number of posts to show on every fetch

    Let’s Explore The Plugin’s main class

    1. This 100 lines of code are the kernel of this plugin lets we inspect each method of the class VG_Infinite_Scroll in its own sections
    2. If you closely noted all the methods are static method to callback the method in hooks without object instantiation

    Method get_custom_posts:

    1. line 24 : the method accepts a single parameter $atts which is an array that contains key-value options passed in the shortcode
    2. line 28: we calling WordPress function shortcode_atts with the first parameter as default value array and the second parameter as user passed value through shortcode
    3. The function shortcode_atts will check if the user passed keys are available in the first parameter if present then it will push that to output array which is returned by this function if not present then the default value is considered and push to the output array
    4. If any attribute’s key passed in the shortcode is not match with any key of the default array then that attributes are simply ignored
    5. line 33: we calling Transient API function set_transient which set or update the value to the given key
    6. The transient data can be cached timely fashion say 1 day or no expiration this can be in database or Redis or Memcache based on your configuration by default the transient cache storage is the database
    7. This function accepts three parameters they are transient name, transient value, TTL (Time To Live) the third parameter accepts some predefined constants as we passed DAY_IN_SECONDS
    8. The reason here why we add our shortcode attributes to the transient data is we can use it in AJAX call
    9. line 34: we call the static method posts_ui which return the HTML structure of the series of posts of the specific category we will see more about this function on its own section as for now just note that it returns the HTML of our cards structure
    10. line 36: we wrap our series of cards into the parent HTML which forms 3 columns or 1 column card(s) based on the screen resolution to be clear it returns an HTML to render to form the grid of posts in the card layout
    11. This static method is hooked into the shortcode with the shortcode name vg_ajax_posts have you noted this is the name we used to call our shortcode in the backend page or post editor

    Method posts_ui:

    1. The posts_ui is the private static method which is used to generate the cards HTML and return that HTML
    2. Line 42: we pass our shortcode attributes to the function set_query_var the purpose of this function is globalizing the value by assigning the key-value pair to the global variable $wp_query here the first parameter is the key of data type string and the second parameter is the value of data type mixed
    3. Line 44: called the one of the PHP output control function ob_start() which initiates the output buffering it means all the generated output will be stored in an internal buffer
    4. Line 45: called the method load_template which will output the template by referencing the path which we passed as the first parameter
    5. The rendered HTML is stored in a temporary buffer
    6. Line 46: called the PHP function ob_get_contents() which returns the content of the output buffer which we initiated at line 44 and assign it to the variable $output
    7. Line 47: called the PHP function ob_end_clean() which clean and silently discard the buffer contents
    8. Line 49: return the rendered HTML lets we see about that template file which is located in the plugin root path templates/vg-posts-content.php
    1. Line 2: instantiates a WP_Query object with the parameter $att assign it to the variable $vg_posts_ui_query
    2. Line 4: we call WP_Query member method have_posts() in a conditional statement to check if we have posts for our queried query
    3. If we have posts for our query the conditional statement will allow further execution as the method have_posts() return boolean True
    4. Line 6: method the_post() retrieves the next post in every loop till the loop ends
    5. The remaining HTML part between the <article>...</article> tag is a self-explanatory one

    Method fetch_remaining_posts:

    1. This method is used for AJAX call to fetch remaining posts using offset
    2. Line 59: we call the function get_transient with the key get_custom_posts_att which retrieve the transient value
    3. Line 60: we fetch our offset post data from AJAX and push it to the array variable $att with the associative index offset
    4. Line 62: we call our template rendering method posts_ui with the query parameter passed through $att
    5. Finally, we terminate the method call using the function die()

    Method get_post_count:

    1. This method is used to get the total number of posts present in a queried post category
    2. Line 73: we fetch our shortcode’s transient data
    3. Line 74: to fetch total count we have to unset our posts_per_page element from the transient data
    4. Line 76: instantiate WP_Query with arguments to filter
    5. Line 78: return count of the number of posts found

    Method add_assets:

    1. This method is responsible for importing static content like JS, CSS and pass data to client end i.e. to HTML page
    2. Line 88 & 89: we import our plugin’s required JS & CSS using the enqueuing process
    3. Line 90: function wp_localize_script is used to passing data to main.js by using same handle name as we used in enqueuing the main.js file in the first argument, the second argument string value is used as JS object in the frontend, the third argument holds the object’s properties as key-value pair

    Hooking Class Method

    1. Line 97: The function add_shortcode creates a new shortcode here with the name vg_ajax_posts
    2. The second parameter is the callback to call
    3. Our callback function is a class method so we call by passing an array the first index holds the class name as a string and the second index holds the method name as a string
    4. Line 98: hooked our assets method to the action wp_enqueue_scripts, irrespective of its name ends with scripts which is responsible for bringing the CSS and JS to the frontend
    5. Line 99 & 100: these two actions are like two sides of a coin either one will be triggered these two hooks responsible fire an ajax call
    6. You can check the source code of the ajax implementation in WordPress

    Let’s Explore The Plain JavaScript

    Override Native Fetch Function

    1. Line 3: Assign the native JavaScript fetch function to a variable
    2. Line 6: declare a function fetch under the window object to override the existing fetch function
    3. Because the native fetch function doesn’t support event to identify ajax start and end so we overrode that function
    4. Line 9 & 10: two new event with the name fetchStart and fetchEnd created
    5. Line 13: call the native fetch with the argument passed to our custom fetch and assign the native fetch return value to the variable fetchCall
    6. Line 16: the fetchStart event is dispatched the listening function codes will be executed during the event dispatch
    7. Line 18 – 24: fetchEnd event is dispatched either during the call success or any exception is thrown
    8. Line 26: return the variable fetchCall which was assigned with native fetch return

    Listening To The Events

    1. Line 29: implemented an event listener function for fetchStart event
    2. Line 30: added our spinner class vg-spinner to load more button which displays a loading spinner animation to indicate posts are fetching
    3. Line 31: turned off the pointer event i.e. clicking of the load more button won’t trigger any functionality by assigning none to the pointerEvents property
    4. The reason to disabled pointer event is to avoid consecutive ajax call
    5. Line 34: implemented an event listener function for fetchEnd event
    6. Here we do quite the opposite of what we did in previous listener function
    7. Line 35: removed our spinner animation by removing the CSS class vg-spinner to indicate ajax fetch has been completed
    8. Line 36: turned on the pointer event by assigning the pointerEvents property with the value auto which results in event triggering capability enabled to the load more button
    9. Line 38 – 42: the reason for wrapping our core logic inside an anonymous function of setTimeout is used to avoid the race condition of execution our code even before the button generated and rendered in the DOM
    10. The conditional statement compares whether the displayed post card element count is equal to the total record count fetched from WP localize variable
    11. If it is equal then conditional statement be boolean true which results in the execution of inner block whose functionality is to hide the load more button after fetching all posts of the particular category

    Frontend Kernel Function

    1. Line 45 – 54: this anonymous function which is called on the onLoad event is the heart (no! no! brain) of functionality which triggers our ajax function actionAjax()
    2. Line 46: fetch the DOM object of the load more button and assign it to the variable loadMoreButtonObj
    3. Line 48: conditional check to confirm loadMoreButtonObj is set to a value and it’s not an undefined one
    4. Line 49: if the condition is validated to true then to the load more button click event we register our ajax function actionAjax()

    Get Loaded Posts Count

    1. Line 56: the function get_loaded_post_count() is the simple function to get the count of total loaded posts
    2. Line 57: here we called length property of the method querySelectorAll which retrieves all the matched DOM object for the passed selector string as an argument

    JavaScript AJAX Call

    1. Line 60: we declared our ajax function actionAjax
    2. Line 61: called our overridden fetch API function with the localized object property fetch_remaining_post.ajaxurl
    3. This fetch API will work in all modern browser if your’s is legacy one then go for a polyfill
    4. To learn more about fetch API read the MDN documentation
    5. The fetch API second parameter is the object with key-value pair of additional properties to handle the current ajax call
    6. Line 62: call our ajax in POST method type instead of the default Get method type
    7. Line 63: we set a header to handle our data as form data
    8. Line 64 – 67: we pass our query parameters through URLSearchParams utility method
    9. Line 69: the first chained promise takes the fetch API’s response object and the text() method of this object returns all the streamed text in Unicode string
    10. Line 70: the second chained promise execute after retrieval of all streamed data and append it at the end of the post grid

    Conclusion

    1. Through this tutorial, you learned to create a plugin to load posts excerpts elegantly
    2. Learned about backend technologies like WordPress plugin creation, shortcode hook, Transient API, passing value to JavaScript, doing Ajax call
    3. Learned about overriding native function, fetch API to do ajax call, adding and listening custom event, promise function and catch the exception, using CSS like selector to fetch DOM object, manipulating DOM using its method and properties, hooking a function in JavaScript events, method chaining
    4. The thing we left is CSS file of this plugin which is self-explanatory so we left it out for you as homework to play and learn with the CSS
  • WooCommerce Custom Products Per Page Dropdown

    Introduction

    1. In this tutorial, you will learn to add dropdown which controls maximum how many products to show on a page.
    2. This tutorial is the continuation of custom sorting tutorial
    3. We will add a dropdown with selection options 4, 8, 16, 32 and All to control our products per page logic
    4. We will add our code logic to our existing plugin repository in GitHub in a new branch v2
    5. For your easy understanding of the logic lets, we see each and individual method with its filter separately in it’s each section instead of skimming the code from top to bottom
    6. Lets we examine each part individually to understand the logic crystal clear

    Explanation: Adding query string variables

    1. Here we will explore the snippet of the method add_query_vars_products_per_page from our plugin class VG_Sort which add our query variable show to the query variable array
    2. Direct link to the method in code repository branch v2
    1. This method accepts a single parameter $vars on line 8 (line 8 is relative to the snippet, not the full code in repository this applicable to the upcoming explanations too) which holds all the publicly allowed query variables
    2. On line 9 we added our query variable show which accepts the number of products to show per page
    3. Once our query variable string also appended to the existing query vars array we return the variable $vars
    4. This whole method is a callback method which attached to the filter query_vars please check the line number 15 for better understanding
    5. Now we can use the query var show in our code we will see that in the next section

    Explanation: Method controls product per page

    1. Here we will explore the snippet of the method custom_products_per_page of the plugin class VG_Sort this method is core logic which controls the number of products to show per page
    2. Direct link to the method in code repository branch v2
    1. This method accepts a single parameter $per_page which accepts integer value by default WooCommerce assigns 16
    2. The shop page more technically we can say product archive page which shows 16 products per page
    3. Now we will change this argument variable $per_page value to see how this affect the number of products showing on a page
    4. On line 10 we are using the WordPress helper function get_query_var which is used to fetch variable for WP_Query class we already appended our variable show we can use that in the query string
      1. The function get_query_var holds the two arguments the first one is query string variable’s name the second one is the default value if the query string show is not added in the URL
    5. From line 13 to 24 we used the switch case which handles how many products to show
      1. Inside the switch statement if the variable $count matches with any case statement for example if it is matched with 8 then $per_page assigned with the value stored in variable $count
      2. If the $count not matched with the any of the case statement then default value of 16 will be assigned to variable $per_page
    6. At last, we return the variable $per_page
    7. Once you attached this callback method to the filter loop_shop_per_page, you can test this functionality by passing query string like http://example.com/shop/?show=4 to your shop page directly

    Explanation: Template For Product Per Page Dropdown

    1. In the previous section, we implemented core logic behind the number of products to show in a page and we tested it by passing value for the query string show
    2. Lets we see the method template_products_per_page of the class VG_Sort
    3. Direct link to the method in code repository branch v2
    1. On line 9 we call the method wc_get_template which is responsible for rendering the dropdown for products per page logic
      1. This method first parameter is template name, in the method we used products-per-page.php
      2. The second parameter is an optional array parameter where we can pass any value to our template by passing an associative array
      3. The third parameter is denoting the template path
      4. The fourth parameter is where we pass the path for our template which points to the directory templates which is present inside the plugin directory itself
        1. The function plugin_dir_path identifies the plugin directory by accepting the file name here we use PHP magic constant __FILE__ which returns the file name with the full path
        2. We append the string templates/ to the plugin_dir_path returned string which is point to the directory present inside our plugin root path
    2. On line 12 we hooked our method to action function woocommerce_before_shop_loop which call our render method template_products_per_page before products rendering
    3. On that time, our HTML content present in the path plugin-root/templates/products-per-page.php will be outputted on the archive page

    Explanation: Dropdown HTML

    1. In the previous section, we saw how our template is outputting, now we will see the HTML part of that rendered template plugin-root/templates/products-per-page.php
    2. Direct link to the template in code repository branch v2
    1. The HTML is straight forward so will explain important aspects only instead of explaining like what is form, label, etc
    2. On line 7 for our form, we added our class vg-sort-show to the class attribute
    3. On line 9 for the select tag, we added the attribute onchange with the value this.form.submit() which triggers the form submission when we change the value for e.g. from 4 to 16 it will trigger the form submission
    4. In every option tag, we called the WordPress function selected which accepts three parameters and outputs selected="selected" attribute
      1. The first parameter holds the first value to compare
      2. The second parameter holds the second value to compare (which is optional)
      3. The third parameter is control whether to echo the selected attribute or not (which is optional)
      4. Official documentation
    5. On line 17 the function wc_query_string_form_fields (official documentation) is used to outputs hidden form inputs for each query string variable

    Explanation: Dropdown CSS Enqueuing

    1. We are reached the final section of this tutorial this part is responsible for styling and positioning our products per page dropdown
    2. Direct link to the method in code repository branch v2
    3. Lets we explore the method add_assets of the plugin class VG_Sort
    1. On line 9 we imported our CSS main.css which is located in plugin-root/assets/css/main.css using WordPress function wp_enqueue_style the first parameter is handle name it should be unique and the second parameter is CSS file’s URL
    2. plugin_dir_url is similar to plugin_dir_path but it returns URL instead of filesystem directory path which is appended to our CSS file
    3. This callback method is hooked to the action wp_enqueue_scripts on line 12 which is responsible for register and enqueue our asset file in the rendered HTML page

    Explanation: Dropdown CSS File

    1. The CSS file is located in the path plugin-root/asset/css/main.css
    2. Direct link to the CSS file in code repository branch v2
    1. On line 1 we are applying our CSS to form class vg-sort-show
    2. On line 2 we provided rule float: right to move our form towards the right end of the parent element
    3. On line 3 we applying o to both top and right margin 1rem to bottom to align parallel to the sort dropdown and to provide spacing between this and sort dropdown added 1.5rem to margin left
    4. On line 4 applied padding 0.75rem to top and bottom then 0 for left and right
    5. For CSS I referred CSS class woocommerce-ordering of official WooCommerce layout CSS (just inspect the default sort by dropdown form and apply whatever CSS opt for you by referring that)

    Conclusion

    1. You learned totally new concept when compared to previous tutorial, instead of altering existing one you added something brand new product per page dropdown
    2. Learned to create new HTML template and render it on the fly with help of a hook function
    3. Learned to add assets to your plugin
    4. Learned few WordPress and WooCommerce functions
  • WooCommerce Custom Product Sorting

    Introduction

    1. In this tutorial you will learn how to add custom sorting for the product archive page
    2. Renaming the existing sorting option
    3. Re-ordering the option in sort dropdown
    4. Overriding sorting form template and add meaningful title for the sorting dropdown
    5. Quick overview of how to create plugin (Yes, all our customisation are plugin based except adding title to the sorting dropdown)

    Quick Overview Plugin Creation

    1. Go to the following path wp-content/plugins in your WordPress Project
    2. Create a new directory and name it like vg-woo-sort
    3. For naming the plugin I follow the following convention either my initial or project initial hyphen plugin name
    4. Inside the directory vg-woo-sort create a new PHP file vg-woo-sort.php
    5. Once you created the file, for security purpose add this line first which blocks the direct access to our script
    1. Then add few plugin headers (Plugin Name is must)
    1. Finally go to your Plugins menu in WP Admin Panel you will find your new minimal plugin kindly activate it

    Customise Sorting Dropdown

    1. WordPress plugin functionalities can be developed either by procedural or object oriented
    2. Our plugin is developed through object oriented even though it’s simple
    3. Our plugin class VG_Sort has two callback method custom_woocommerce_get_catalog_ordering_args and custom_woocommerce_catalog_orderby
    4. Lets we see each method’s inner working in its individual section

    Plugin & Template Full Code

    1. You can find the full code for both plugin and template code in github
    2. The plugin’s core code
    1. The template’s core code

    Explanation: Ordering Method

    1. Here we will explore the snippet of the method custom_woocommerce_get_catalog_ordering_args from our plugin class VG_Sort
    1. Here and in all explanation sections the line number denotes each individual snippet’s line number not the full code section
    2. In line no 7 our method accepts single argument $args which is associative array which represents the products sort ordering configs
    3. For inspection purpose once you attached this method with the filter function add print statement print_r($args) next to line 7 and refresh your shop page
    4. In your shop page at the top the argument $args array is printed
    5. Here is the sample for the default sorting option Array ( [orderby] => menu_order title [order] => ASC [meta_key] => )
      1. The first key orderby holds two sorting values
      2. Firstly it sort with menu_order and then product’s title
      3. menu_order which can be adjusted to each products in their backend product edit page
      4. By changing the Menu order value for individual product which is under the container product data you will find set of tabs, in that tabs click the Advanced tab
      5. By changing the number from 0 to any number positive value which push the product to last and negative value will pull the product to the first
      6. If, for more than one product the Menu order is same then it will sort by title
      7. The key order is used to arrange the products either in ascending or descending
      8. The key meta_key is used to sort the product based on some custom key
      9. You can use any key-value pair as described in the official documentation
    6. In line 8 we assign $orderby_value variable by checking the get query string parameter if it’s set then we sanitise it using WP sanitise function wc_clean else assign it from option using WP function get_option which retrieves an option value for the passed option name
    7. The line between 13 and 19 is the core logic to create new sort order for the product archive page
    8. In both conditional statement we compare the get parameter value with the desired order by string and alter the $args parameter (for $args key-value we already discussed in 5th point please refer that if you need to explore more)
    9. Finally in our callback method we return the variable $args

    Explanation: Rename & Reorder Method

    1. Here we will explore the snippet of the method custom_woocommerce_catalog_orderby from our plugin class VG_Sort which is used for renaming & reordering
    1. We assume that you attached/hooked this method to the filter function woocommerce_default_catalog_orderby_options and woocommerce_catalog_orderby then only whatever you print and check will work
    2. This method’s main functionality is renaming and reordering the sort dropdown to do that first we need to know the selection option’s name and its display value
    3. So kindly add print statement print_r($sortby) next to the line 2 i.e. after the method definition and refresh the product archive page to check the argument array’s key-value
    4. It will print the array like this Array ( [menu_order] => Default sorting [popularity] => Sort by popularity [rating] => Sort by average rating [date] => Sort by latest [price] => Sort by price: low to high [price-desc] => Sort by price: high to low ) just above the sort order dropdown
    5. As you clearly noted the key, you came to know that now we will override this array’s value also we reorder the key
    6. We override it from the line 3 to 12
      1. If you don’t need any one of the ordering for example if you don’t need default order [menu_order] => Default sorting then remove that key value from the array
      2. We renamed each sort order by overriding the value like from Sort by average rating to Average rating
      3. Our new array constitutes our new sorting key-value too to display option to sort the product alphabetical or reverse alphabetical
    7. Finally we return the variable $sortby

    Explanation: Callback’s Filter

    1. We used totally three filters namely woocommerce_get_catalog_ordering_args, woocommerce_default_catalog_orderby_options and woocommerce_catalog_orderby
    1. woocommerce_get_catalog_ordering_args is the filter action deal with sorting operation
      1. woocommerce_get_catalog_ordering_args filter official API documentation
    2. woocommerce_default_catalog_orderby_options and woocommerce_catalog_orderby is the filter action deal with display sorting selection
      1. woocommerce_default_catalog_orderby_options filter official API documentation
      2. woocommerce_catalog_orderby filter official API documentation

    Explanation: Custom Template

    1. Our custom template constitutes a minimal change to clone of core template we will see detailed explanation
    1. While exploring the filter action woocommerce_default_catalog_orderby in official documentation which is present inside the function woocommerce_catalog_ordering
    2. As you skim down to the end of the function you will find at the last it calls the function wc_get_template with the first parameter as loop/orderby.php
    3. Based on our analysis we have to override the partial or sub template orderby.php which located inside the directory loop of the WooCommerce plugin templates directory (To understand the overriding concept read the article about template overriding)
    4. We copied the loop/orderby.php into our current theme in the following path woocommerce/loop/orderby.php
    5. Now we can start rewrite the HTML in our newly copied template orderby.php
    6. We enclosed our select tag inside the label tag and prefixed the select with the string value Sort By: (as you see now there is no repetition of sort by string inside the option)

    Conclusion

    1. You learned to add new sorting to your existing product archive page
    2. To modify the existing sort option
    3. To modify the template which render the sort order select option
    4. Now you have a clear understanding about sort order dropdown
    5. We covered all the logic and modification related to the sort order dropdown now you are solid to modify in and around of products sort order
  • WooCommerce Theme Overriding

    Introduction

    1. For every task there are many good and bad ways to do that
    2. WooCommerce theming also fall under this prey like directly editing the WooCommerce template files
    3. In one fine day WooCommerce may release a new version, you unintentionally update the WooCommerce plugin which results in replace of your beautiful custom shop page into default template
    4. So to avoid this we have to override our WooCommerce template in our theme directory
    5. Let’s we see it in detail

    Detect Template to Override

    1. To detect which template your current page renders you can place this snippet in your activated theme’s functions.php file
    2. Let’s we see the explanation for this snippet
    3. On line 2 of the snippet we using WordPress provided API helper function add_action which hook our function (we pass it as second parameter) in specific point or event in the context of first parameter (the action’s name wp_head technically it is called as tag)
    4. add_action accepts totally 4 parameters in that 2 are mandatory
    5. The first parameter (mandatory) is tag which is the name of that action hook like wp_head, muplugins_loaded, shutdown
    6. The second parameter (mandatory) is the function to be called at the time hook action triggers
    7. The third parameter (optional) execution priority
    8. The fourth parameter (optional) is accepts number which denotes number of arguments the hooked function accepts
    9. In our anonymous function we echoed global variable $template which output the full path of the rendering template file

    Override Product Listing Page

    1. Assume that you declared the template path identifying snippet in your theme’s functions.php file
    2. Go to any page in your WordPress you will find at the top of your page the rendering template’s file path
    3. Now go to your shop page where you will find the template path as in the given image
    4. Now we will override this without disturbing the original file
    5. In order to do that first create a directory with the name woocommerce in your active theme directory for example wp-content/themes/twenty-twenty-child/
    6. Copy the template file archive-product.php from WooCommerce plugin for path reference see the image in 3rd point and paste it in your newly created directory woocommerce i.e. inside your theme
    7. Hurray! You succeeded you learned overriding the WooCommerce template

    Edit Customised Shop Page

    1. To check whether we correctly implemented we will change few things in copied file archive-product.php in our theme directory not in the WooCommerce plugin’s template directory
    2. Open the file and replace the header section with the following snippet
    3. If you has an eagle eye you clearly note that the change is one line
    4. In line 3 changed the h1 text case to upper
    5. By default WooCommerce function woocommerce_page_title echoed the title instead of that we passed boolean false as first parameter to that function to return the title as a string
    6. woocommerce_page_title function’s return is passed as an argument to the php string function strtoupper
    7. Now if you refresh your shop page you will find that the title is uppercase
    8. We only covered tip of the iceberg of WooCommerce to customise archive page

    Conclusion

    1. You learned why must avoid overriding the WooCommerce plugin’s template directly
    2. You understand the basics of action hooks and some action hook tags
    3. You can able to detect the current page’s template
    4. You can able to modify the WooCommerce template file without disturbing the plugin’s template directory
  • Create Executable Images

    Introduction

    1. In this tutorial you will learn how to create executable image file
    2. Using the image you can perform any programmatic logic behind displaying an image
    3. The image created using PHP may not look unusual except the file extension will be .php
    4. We will overcome this drawback with Apache’s htaccess file with rewrite rules to masquerade our PHP file as image file

    Prerequisite

    1. Though you can use any image library like ImageMagick for this masquerading technique but we are planned to use GD image library
    2. GD is an open source graphics library
    3. GD library ‘s PHP official documentation link: GD Documentation

    Verification

    1. To check whether your server have installed PHP extension GD, execute the following command in your terminal/CLI php -i | grep 'GD'
    2. If you are uncomfortable with CLI you can create a PHP file in your webserver with calling the function phpinfo(); and load the page in browser and search for the GD
    3. If search not found the GD library then your server don’t have GD library

    GD Installation

    1. If GD library is not installed follow this section else skip it
    2. Installing for Debian based distro but you can follow the same command for red hat based distro by instead of using apt package manager use yum
    3. Package installation command: sudo apt install php-gd
    4. Once installed, GD library is activated and available in PHP CLI
    5. To make the GD module available as extension in Apache server execute the following command to restart with newly installed extensions are loaded
    6. Command: sudo systemctl restart apache2
    7. Verify once again as described in the Verification section to confirm GD installed

    Basic image on the fly

    1. In line 2 we call the GD function imagecreatetruecolor(640, 480) which create an image 640 px wide and 480 px height and assign this resource to a handle variable $handle
    2. In line 4 we call color allocating function imagecolorallocate($handle, 0, 255, 0)
    3. Where function imagecolorallocate accepts four parameters as follows handle, red, green, blue color’s value between 0 and 255
    4. In line 6 we call the function imagefilledrectangle(...) with first parameter as $handle an image resource, second parameter as x’s start coordinate integer value, third parameter as y’s start coordinate, fourth and fifth parameters are x’s and y’s end coordinate to form the rectangle, Last sixth parameter as color identifier value which is $green
    5. In line 9 we call the function header which is used to send a raw HTTP header to the called client side
    6. In header function call we pass the image type JPEG as content
    7. So the script will me considered as image and rendered as image
    8. In line 10 we call the function imagejpeg which have one mandatory parameter resource handle and two optional parameters $filename the path where dynamic image to be saved and $quality quality of the generated image by default it is 75 (minimum 0 and maximum 100)
    9. Finally on line 12 we call the another GD function imagedestroy destroy an image resource and free up the space
    10. Hurray! We created basic dynamic image which is in memory image i.e. it is in volatile layer RAM instead of persistent storage like HDD or SSD
    11. Next we use this in HTML file

    1. Use like the above image tag by replacing URL of src attribute to your server URL path
    2. Once embedded the image i.e. your PHP script in HTML file refresh the page in browser
    3. You will see the green colored big rectangle image

    Dynamic captcha image

    1. Let’s leverage what you learned in the previous section to create something more useful
    2. A random string generator which can be used as captcha validator
    3. The final script will display captcha string and some user’s client side details
    4. For this upgraded code we use most of the code in our basic image creation php file and use a helper function to generate random string

    1. In the above script most of logics between line 1 and 17 are explained in basic usage section
    2. In line 11 and 12 we call the GD function imagestring(...)
    3. The function requires six parameters they are $image the image resource’s handle, $font variable predefined font size between 1 and 5 or load registered fonts, $x x coordinate of upper left corner, $y y coordinate of upper left corner, $string the string to be written or rendered (here we pass our random string by calling the helper function rand_string or show render last accessed time in ATOM standard using date predefined constant), $color Color identifier generated by imagecolorallocate

    Random string generator helper function

    1. Let’s see helper function rand_string($length = 6)
    2. In line 23 we define the function rand_string with optional parameter $length with default value 6
    3. In line 26 we call the function range three times with arguments for start and end parameters are 0-9, a-z, A-Z
    4. range function return the array of elements from start to end here it fetches properly the sequence of integer, small and capital alphabet using ASCII code range
    5. Then three arrays are merged in to a single array using function array_merge and assigns it to the local variable $master_list
    6. In line 27 we call the array function shuffle by passing our $master_list array as parameter which will shuffle the array (Warning: this function uses new key so be cautious while using with associative array)
    7. In line 29 we call the function array_slice with first parameter as an array which is used as a source for the sliced array, the second parameter is offset from where the offset should be started we passed 0 so it will start from first element (Array’s index starts from zero), the third parameter is for the total element in the sliced array which is dynamically controlled by the optional parameter of our function
    8. So if we pass value 10 for the parameter $length then the default value of 6 is override into 10 and return 10 element from the shuffled array
    9. Which is assigned to the variable $sub_element
    10. In line 30 we make use of the variable $sub_element which is used as the argument for the function implode
    11. The implode function will convert our array into a string and assign it to the variable $to_string
    12. The implode function is little bizarre because it accepts first parameter as glue to join an array if only one parameter (array datatype) given to implode it will join all elements and form the string and reordering the argument is possible but it is deprecated so don’t call like this implode($array, $glue) though without glue is acceptable
    13. Finally in line 32 we return the random string generated by our helper function rand_string

    GD function use cases

    1. The use cases for GD is so many though this tutorial is for masquerading php script to image will share some use cases
    2. You can use it add dynamic watermark over the image
    3. You can use it to adjust the alpha channel or transparency of the image
    4. You can create random collage of the image
    5. To reduce the image quality (we used it to deliver low quality of the image to basic subscriber and high quality for premium user)
    6. To create image in various resolution (We used to save various resolution image in S3 using AWS elastic transcoder and lambda but same can be achieved for image using GD)
    7. As the image is dynamic you can control the access, expiry of the image
    8. Can be used for ethical hacking that’s why many email client won’t allow images download automatically if user need image they can take the risk and allow image to load
    9. Write copyright with dynamic year as watermark
    10. To track user activity many ad based company uses dynamic images for analytics

    Masquerading file extension from php to jpeg

    1. First create a file .htaccess in your tutorial project root directory
    2. Then add the given below snippet in your .htaccess file

    3. When you opened the PHP script URL as https://myhost.com/image.jpg if it throws not found error then your .htaccess is not called
    4. So you have to troubleshoot the configuration file which is in the path /etc/apache2/apache2.conf
    5. Open the file as a root user and find the following snippet in the configuration file
    6. Change the line AllowOverride None to AllowOverride All and save the file
    7. Once you reconfigured apache2.conf file restart the apache server by running the following command sudo systemctl restart apache2 to reflect the .htaccess
    8. Reload dynamic masqueraded image page (https://myhost.com/image.jpg)
    9. If still problem persists enable the rewrite module by executing the following command sudo a2enmod rewrite and restart the apache server once again

    .htaccess brief explanation

    1. First of all our .htaccess file is a basic one so don’t use this file as a production one but you use this snippet for any reference to change the file name or extension based on certain regular expression
    2. RewriteEngine On enables runtime rewrite engine
    3. RewriteBase / will be used as a relative path for our rewrite rule need more details here’s the link RewriteBase purpose
    4. RewriteRule ^image\.jpg image.php [L,QSA] is main rule which will rewrite URL from php extension to jpg likewise you can rename to anything like gif, bmp, etc., for more details RewriteRule purpose

    Sample dynamic image

    Conclusion

    1. Finally you learned the masquerading technique using Apache httpd server
    2. You learned about GD library and it’s use cases
    3. You learned how to created dynamic image on the fly
  • Inside the PHP

    Introduction

    1. Ever wonder what’s inside the PHP. How every language construct, function works.
    2. How optional parameters handled. Why certain functions behave weird and want know their inner working.
    3. That’s why I bring this tutorial to how easily navigate to the function declaration and understand it easily.
    4. Since PHP is opensource you can see all source code easily in github (clone of official git repository) but quickly finding the desired function in github is cumbersome but don’t worry we will find some alternative solution in this tutorial
    5. The PHP compiler/interpreter which is written in C and C++ which uses Lexical analyser, Yacc (Yet another compiler compiler), configurator to identify computer hardware and operating system finally virtual machine such as zend virtual machine shortly ZVM which runs our code

    Lets Explore Directory Structure and Pattern

    1. Most of the PHP source which is in C language looks very similar to PHP so understanding the code won’t be difficult.
    2. If the official documentation is more abstract you can get this procedure as a handy tool to understand the function very well.
    3. To explore the PHP source we are going to use Adam Harvey‘s PHP source browser. Lexer link: https://php-lxr.adamharvey.name/source/
    4. The PHP lexer’s home page have a search form in the left and source selection box in the right for simplification going to select php-7.3 in selection box.
    5. In selection box please double click the php-7.3 to goto the source listing.
    6. In the directory listing you will find some important directory like ext which contains core functions with the function’s name as sub-directories name, main comprises memory allocation code, directory scanning code, etc., Zend is the zend engine code which contains compiler, language features and VM (Virtual Machine).
    7. As you explored the ext and Zend directory it’s clear that in official documentation items which are found under “Language Reference” are related to zend directory and “Function Reference” are related to ext directory.
    8. Let’s we go into the Zend directory’s file zend_builtin_functions.c please click here which will redirect you to function lists in that c file.
    9. As you note down the code, you will see list of very familiar functions like zend_version, func_num_args, strlen, property_exists, class_exists, etc.,
    10. To dive deep into the internal code understanding process we chosen the string function explode.
    11. Here is the explode documentation link: explode()

    Explode() overview

    1. The function explode supports PHP 4, 5, 7 (Newbie Hint: There is no PHP 6 because core team planned to release PHP 6 long back with unicode support but not released. So to avoid confusion and marketing advantage PHP 7 is released after PHP 5).
    2. Explode function has two required parameters and one optional parameter totally three parameters.
    3. It return either boolean false or Array.
    4. From version 5.1.0 negative limit also supported.
    5. For more details about this function please review official document which is linked in last point of the previous section.
    6. Let’s we move to the internal working of this function.

    Search using LXR utility

    1. Go to the lexer home page. Link: https://php-lxr.adamharvey.name/source/
    2. In HTML form’s first field (Field Label: Full Search) type explode and click the button Search.
    3. It will show many matched results to narrow down we have to change the search term to "PHP_FUNCTION explode". Note: must enclose search term with double quotes.
    4. The search result lists the two files php_string.h and string.c
    5. The file php_string.h is similar to interface/ abstract class for a complete class. The file extension h denotes it’s a header file for main c file.
    6. Lets move on to our main objective file string.c by clicking the line number in the search result it will redirect us to the explode function’s declaration. Link: Line no: 1155.

    Explode() internal function call chain

    1. Explode function declaration starts with PHP_FUNCTION(explode) on line 1155.
    2. The declaration is enclosed inside between the markers {{{ and }}}. Note: Scroll up to see the marker.
    3. We can easily identify where the function declaration starts and ends using this markers.
    4. Here the PHP_FUNCTION is not a c inbuilt syntax it’s a C macro.
    5. The macro always start with #define
    6. So we will search in the lxr home page with search term "#define PHP_FUNCTION" or directly click here
    7. Once searched, the search list have the file name php.h in that click the line number 409
    8. In redirected source code page you will find that #define PHP_FUNCTION is points to other macro ZEND_FUNCTION
    9. Even though the hyperlink on ZEND_FUNCTION redirects you to the search form with filtered list it shows more records
    10. We will use alternative search term to filter more accurately for our need
    11. Once we used "#define ZEND_FUNCTION" as search term the utility page will list a file: zend_API.h in that list click the line number 64 or click here to redirect directly
    12. click here to redirect to lxr utility with search term
    13. The zend_API.h file’s line number 64 contains the following code
      #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
    14. As you noted the 64th line have another two macros ZEND_NAMED_FUNCTION and ZEND_FN
    15. Lets we see inner function ZEND_FN
    16. In lxr search form add this search term "#define ZEND_FN" in full search field and click the search button or click here to go directly
    17. In result list you will find a file name zend_API.h with line no 61, please click the line number or click here to redirect
    18. Which have the following code #define ZEND_FN(name) zif_##name (in C the operator ## is for concatenation and it is called as token concatenation operator so it will return the concated string zif_explode)
    19. The ZEND_FN is passed as argument to the macro function ZEND_NAMED_FUNCTION
    20. In lxr search form add this search term "#define ZEND_NAMED_FUNCTION" in full search field and click the search button or click here to go directly
    21. It contains the following code #define ZEND_NAMED_FUNCTION(name) void ZEND_FASTCALL name(INTERNAL_FUNCTION_PARAMETERS)
    22. The function ZEND_FASTCALL will be interpreted as void ZEND_FASTCALL zif_explode(INTERNAL_FUNCTION_PARAMETERS)
    23. If we search for "#define ZEND_FASTCALL" it shows a list of search results in that click the first one’s line number or click here to go directly
    24. After redirected scroll up little and you will see the full block of C preprocessor conditional block
    25. This block is set of conditional call to choose the type of compiler as we know for windows, linux and other supported OS the compiler will be different
    26. Lets we arrange functions chain as a sequence block for easy mind map have a look on it
      PHP_FUNCTION(explode)ZEND_FUNCTION(explode)ZEND_NAMED_FUNCTION(ZEND_FN(explode))ZEND_NAMED_FUNCTION((zif_##explode))
    27. Readers thanks for your patience to follow the flow
    28. The reason to see the above steps before your eagerly expected internal flow of explode or name any core function is to understand that the PHP execute the core function in some better optimised way than the standard userland functions
    29. So our explode function starts the journey from PHP_FUNCTION(explode) to optimised call zif_explode

    Explode() function definition in C language

    1. As in previous section the explode code starts at the line number 1153 with the markup {{{ and ends at the line number 1192 with the markup }}}
    2. Line 1155 : is the macro call and that call itself has a separate section which is explained in the previous section
    3. The lines 11571159: are the C local variables and some of the variables are used for arguments we passed in explode function’s parameters
    4. The lines 11611166: are used to copy the runtime input parameters to the local variables
      1. Line 1161: is a macro call ZEND_PARSE_PARAMETERS_START(2, 3) this function is used to initiate the process of copying runtime value into the local variable which defined just above this macro call
      2. This function has two parameters the first one for number of mandatory parameters and the second one is total number of parameters
      3. Line 1162: is macro function Z_PARAM_STR(delim) which accepts string value
      4. This macro copy the delimiter string value passed as first parameter in the explode function to the local variable delim
      5. Line 1163: Z_PARAM_STR(str) copy the string value passed as second parameter in the explode function to the local variable str
      6. Line 1164: Z_PARAM_OPTIONAL is used indicate from here to end of parse parameter block all the variables are optional one
      7. Line 1165: Z_PARAM_LONG(limit) is a function used to copy the PHP’s int datatype value to the C’s long datatype variable
      8. explode function’s third parameter $limit which is optional whose value is copied to the C variable limit
      9. If not passed then ZEND_LONG_MAX macro’s constant will be set, it’s based on 32 bit or 64 bit system the value’s size may vary
      10. Line 1166: ZEND_PARSE_PARAMETERS_END(); denotes the end of the parameters parsing and copying to local C variable and this is end of this block, note in this block this line only ends with semicolon to denote the block’s completion
    5. The lines 11681171 is a block which check delim is a empty string by checking the length and throws error
      1. Line 1168: if (ZSTR_LEN(delim) == 0) uses the macro function ZSTR_LEN which counts the character in the string and returns it’s length which compares with integer 0
      2. If boolean comparison is true, then code execution move into the block else if false then it skips the block completely
      3. Line 1169: php_error_docref(NULL, E_WARNING, "Empty delimiter"); is a error throwing macro function which throw warning error
      4. The first parameter of function php_error_docref is char datatype with NULL as a value and the remaining two parameters are self explanatory
      5. Line 1170: is a macro which compare it to constant macro value 2 which is for zend false type IS_FALSE you can find it by going upto the beginning of this macro’s call by clicking and follow the hyperlink from RETURN_FALSE which redirects it to ZVAL_FALSE and go on
    6. Line 1173: array_init(return_value) is an array API function which initialize a hash table for an array, additional info: internally PHP array itself a hash map (If possible in future will put a tutorial on Array’s internal!)
    7. The lines 11751181 is a block which is used to free up zval when the source string which need to be explode but passed as empty string and execute return to return result from the PHP_FUNCTION macro function
      1. Line 1175: if (ZSTR_LEN(str) == 0) checks if the passed string (to explode) length is equal to zero
      2. Line 1176: if (limit >= 0) checks the optional third parameter of the explode function (in C it’s local variable is limit) is greater than or equal to zero
      3. If limit variable’s boolean comparison is true then calls the inner block
      4. Line 1177: ZVAL_EMPTY_STRING(&tmp); which empties the tmp zval
      5. Line 1178: zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp); first using Z_ARRVAL_P is used to fetching the value of array type and passed it to the function zend_hash_index_add_new which is hash table API wrapper around the function _zend_hash_index_add_or_update_i for reference document doxygen document
      6. 1180: is a simple return to return empty array
    8. The lines 11831190 is a decision logic block based on the limit value it will split the string from left to right upto the limit lastly it have the whole left out string in last index or right to left upto the limit and remaining string will be neglected and the final else part is to handle limit of 0 or 1 which return the complete string as an array with whole string in first index
      1. Line 1183: if (limit > 1) which is straightforward boolean logic which checks is local variable limit is greater than integer 1
      2. Line 1184: php_explode(delim, str, return_value, limit); is the PHPAPI macro call with all parameters easy to understand except the third one return_value which is zval* provided by the macro function PHP_FUNCTION
      3. Line 1185: else if (limit < 0) which is straightforward boolean logic which checks is local variable limit is lesser than integer 0 i.e. negative number
      4. Line 1186: php_explode_negative_limit(delim, str, return_value, limit); is the PHPAPI macro call with all parameters same as php_explode but this API is for negative limit
      5. Line 1187: is the last block of this if-else ladder
      6. Line 1188: ZVAL_STR_COPY(&tmp, str); is a macro which is used to copy the string in the local variable str to zval generic pointer type local variable tmp
      7. Line 1189: is similar to the point 7.5 of this section

    Conclusion

    1. Now you are ready to explore any PHP function easily by applying the same procedure we discussed
    2. You learned the directory structure of the PHP source
    3. You learned how to use lxr utility
    4. You learned how PHP_FUNCTION macro is working
  • How to do REST API call and read/write excel file using Python 3

    Introduction

    1. Today we are going to see how to read the excel’s each cell and pass the value to the REST API request
    2. On successful response we will parse the JSON response
    3. Read the JSON element and write it to the excel

    Prerequisite

    1. In your terminal or CLI run pip3 install package_name (Based on your OS instead of pip3 run pip. In some OS both python2 and python3 installed then check your pip version pip --version or pip3 --version and execute the command)
    2. We need the following packages to be installed requests and openpyxl
      1. Command: pip3 install requests openpyxl
    3. Once installed please follow next heading to do the coding part

    Coding

    1. The first three lines import the packages
    2. requests on line 1 is used to do the REST API call
    3. openpyxl on line 2 is used to do excel related things
    4. time on line 3 is used to delay the API call to a certain limit of time
    5. In line 6 we assigned API URL to the variable API_URL
    6. From line 9 to line 23 the function extract_country_details() declaration is present
    7. Lets we see inner working of this function
      1. In line 9, we declared function with single parameter search_term
      2. In line between 11 and 14 we declared the dictionary variable with two element which will be pass as a query parameter for the API call
      3. In line 16, we declared a new variable response and assigned it with the response we get from API call by using/importing the package import requests and call it’s method get() with two arguments
      4. The first argument is the URL which we used to fetch the content
      5. The second argument is keyword argument which means we assign our dictionary variable’s value to the argument params it will be query string for our API call
      6. In line 18 convert/decode the received response to JSON object by calling json() method
      7. In line 20 and 21 we check response status is not equal to 200 if so then return the string 'error'
      8. If everything goes well in line 23 we return the first index content of variable json
    8. The second function from line 26 to 42 which is write_country_details() is used to learn read and write excel using the package openpyxl let’s we see the inner workings
      1. In line 27 we are assigning our excel filename top5_populated_countries.xlsx to the variable filename. The excel file is in same path as our country.py
      2. In line 29 we are calling the openpyxl package’s method load_workbook(filename) with file path as parameter and assigning it to the variable wb (wb is short notation of workbook)
      3. In line 30 for the variable ws (worksheet) we assigning the workbook object’s member variable wb.active which holds the active sheet by default it will be the first worksheet
      4. In line 31 for the variable wc (workcolumn) we assigning the A column of the worksheet
      5. In line 33 we assign value 1 to the variable i
      6. In line 34 to 40 the for loop is present we will see for loop in detail
      7. In line 34 we looping workbook’s column A if you closely noted we left the first row of workbook by calling wc[1:] the [1:] denotes that start from 1st index to till the last index instead of 0th index
      8. In line 35 during each looping we increment the variable i
      9. In line 36 we are calling the method extract_country_details by passing A column’s cell value and assigning to the variable country_details
      10. In line 37 we called time.sleep(10) which is for pausing the script for 10 seconds so it won’t execute the next line till 10 seconds
      11. The purpose of sleep timer is to avoid continuous hit to the API server because some servers may block the API call if we hitting continuously without a gap
      12. In line 38 we fetching associative/named index capital from dictionary variable country_details and assigning it to the worksheet column B’s cell B2 in ws object
      13. In line 39 & 40 the logic is similar to line 38
      14. The loop between line 34 and 40 will loop until the last value of A column which have list of country name
      15. Finally in line 42 we calling workbook’s method save with filepath as argument which will write the fetched details such as each country’s capital, region and population in B, C & D column
    9. We explored two functions definition finally at the line 45 we calling our function write_country_details()

    Conclusion

    1. We learned how to call API service, read excel and write excel
    2. Please click here to download the excel file used in this script exercise