Categories
Uncategorized

Day 9: Custom Meta Tables

By default, the data stored using custom meta boxes is stored in postmeta table. You may want to create your own table to store data related to your custom post type. They are called custom meta tables and they are created by extending Metadata API.

Following are the steps to create custom meta tables:

  • Create custom table to store metadata.
  • Make WordPress aware of meta table.
  • Optionally define wrapper class that makes it easier to interact with your metadata layer.

Create table

dbDelta() is a function provided by WordPress to create and modify tables.

$response = dbDelta(
    CREATE TABLE `wp_bookmeta` (
  `meta_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `book_id` bigint(20) NOT NULL DEFAULT '0',
  `meta_key` varchar(255) DEFAULT NULL,
  `meta_value` longtext,
  PRIMARY KEY (`meta_id`),
  KEY `book_id` (`book_id`),
  KEY `meta_key` (`meta_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

);

Where,

  • meta_id is the id of meta which is auto incremented.
  • book_id is the id of book post type to which metadata belongs to.
  • meta_key is the name of the metadata e.g. price.
  • meta_value is value of that key e.g. 20.

Registering table with WordPress

function pw_register_metadata_table() {

    global $wpdb;

    $wpdb->bookmeta = $wpdb->prefix . 'wp_bookmeta';

}

add_action( 'plugins_loaded', 'pw_register_metadata_table' );


You will have to pass ‘book’ as object type when interacting with meta table as ‘book’ is followed by ‘meta’. If you register it as ‘examplemeta’, you have to pass ‘example’ as object type.

Interacting with metadata

$added = add_metadata('book', $book_id, 'price', 20);
$value = get_metadata('book', $book_id, 'price', single=true);
$deleted = delete_metadata('book', $book_id, 'price');

update_metadata has same structure as add_metadata.

Categories
Uncategorized

Day 8: Custom Meta Boxes

A meta box is a draggable box shown on a post edit page, usually on sidebar. Category box, tags box are some of the in-built meta boxes. A meta box can be used to select or enter any information additional to the post. Let’s say you have a custom post type book. You can create a custom meta box your CPT book which will take input as author’s name, publisher, price, year, etc and save this information in wp_postmeta table.

Creating a meta box requires three steps:

  • Creating the box itself,
  • Define content of meta box,
  • How to handle input data from box.

Defining Meta Box and the content

add_action('add_meta_boxes', 'book_meta_box');
function book_meta_box(){
    add_meta_box(
        'book_info_box',
        'Book Information',
        'book_box_content,
        'book',
        'side'
    );
}

function book_box_content($post){
    echo '<label for="price"> Price </label>';
    echo '<input type="text" id="price" name="price" placeholder="Enter price" />';
}

Handling/saving input data

add_action('save_post', 'save_book_info');
function save_book_info($post_id, $post) {
    /* Verify the nonce before proceeding. */

    /* Get the post type object. */
    $post_type = get_post_type_object( $post->post_type );

    /* Check if the current user has permission to edit the post. */
    if ( !current_user_can( $post_type->cap->edit_post, $post_id))
        return $post_id;

    $book_price = $_POST['price'];
    update_post_meta( $post_id, 'book_price', $book_price );
}

Following are the frequently used functions for post meta:

Categories
Uncategorized

Day 7: Taxonomies

The main idea here is to create categories to group posts. The taxonomy can be hierarchical or flat. WordPress stores taxonomies in term_taxonomy table allowing developers to register custom taxonomies. Taxonomies have terms by which you can classify things, which are stored in terms table.

E.g. Taxonomy: Art, Terms: modern, classic, medieval,etc.

Categories and tags are the taxonomies provided by wordpress. Following code shows how to add custom taxonomy.

<?php
/*
* Plugin Name: Course Taxonomy
* Description: A short example showing how to add a taxonomy called Course.
* Version: 1.0
* Author: developer.wordpress.org
* Author URI: https://codex.wordpress.org/User:Aternus
*/
 
function wporg_register_taxonomy_course()
{
    $labels = [
        'name'              => _x('Courses', 'taxonomy general name'),
'singular_name'     => _x('Course', 'taxonomy singular name'),
'search_items'      => __('Search Courses'),
'all_items'         => __('All Courses'),
'parent_item'       => __('Parent Course'),
'parent_item_colon' => __('Parent Course:'),
'edit_item'         => __('Edit Course'),
'update_item'       => __('Update Course'),
'add_new_item'      => __('Add New Course'),
'new_item_name'     => __('New Course Name'),
'menu_name'         => __('Course'),
];
$args = [
'hierarchical'      => true, // make it hierarchical (like categories)
'labels'            => $labels,
'show_ui'           => true,
'show_admin_column' => true,
'query_var'         => true,
'rewrite'           => ['slug' => 'course'],
];
register_taxonomy('course', ['post'], $args);
}
add_action('init', 'wporg_register_taxonomy_course');

Take a look at register_taxonomy() function for a full list of accepted parameters and what each of these do.

With our Courses Taxonomy example, WordPress will automatically create an archive page and child pages for the course Taxonomy. The archive page will be at /course/ with child pages spawning under it using the Term’s slug (/course/%%term-slug%%/).

Using the taxonomy

WordPress has many functions for interacting with your Custom Taxonomy and the Terms within it.

Here are some examples:

  • the_terms: Takes a Taxonomy argument and renders the terms in a list.
  • wp_tag_cloud: Takes a Taxonomy argument and renders a tag cloud of the terms.
  • is_taxonomy: Allows you to determine if a given taxonomy exists.
Categories
Uncategorized

Day 6: Custom Post Types

Let’s say that you want to create a page on an e-commerce site which shows a product in detail. It is possible to create such a page in wordpress, using custom post types.

WordPress comes with five default post types: post, page, attachment, revision, and menu.

Example to register new post type, Products, which will be defined in database as ‘wporg_product’:

function wporg_custom_post_type() {
    register_post_type('wporg_product',
        array(
            'labels'      => array(
                'name'          => __('Products', 'textdomain'),
                'singular_name' => __('Product', 'textdomain'),
            ),
                'public'      => true,
                'has_archive' => true,
        )
    );
}
add_action('init', 'wporg_custom_post_type');

A custom post type gets its own slug within the site URL structure.

A post of type wporg_product will use the following URL structure by default: http://example.com/wporg_product/%product_name%.

Custom templates for post types

You can create custom templates for your custom post types. In the same way posts and their archives can be displayed using single.php and archive.php, you can create the templates:

  • single-{post_type}.php – for single posts of a custom post type
  • archive-{post_type}.php – for the archive

Query by Post Type

<?php
$args = array(
    'post_type'      => 'product',
    'posts_per_page' => 10,
);
$loop = new WP_Query($args);
while ( $loop->have_posts() ) {
    $loop->the_post();
    ?>
    <div class="entry-content">
        <?php the_title(); ?>
        <?php the_content(); ?>
    </div>
    <?php
}

Altering the main query

function wporg_add_custom_post_types($query) {
    if ( is_home() && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post', 'page', 'movie' ) );
    }
    return $query;
}
add_action('pre_get_posts', 'wporg_add_custom_post_types');

Above query shows posts of type ‘post’, ‘page’ and ‘movie’ on the home page of website.

Categories
Uncategorized

Day 5: Hooks, Actions & Filters

Actually I’ve lost count of days because I decided to complete the chapter of Plugin Development first, and then revisit it to write these blogs so that I’ll be clearer on these topics.

I’ll start with day 5 and add one important topic each day. Today’s topics will be hooks, actions and filters.

Hooks are the mechanisms using which we can attach our piece of code to the wordpress core. By definition given in codex:

Hooks are a way for one piece of code to interact/modify another piece of code.

There are two types of hooks:

  • Actions
  • Filters

Actions:

Actions allow you to add data or change how WordPress operates. Callback functions for Actions will run at a specific point in in the execution of WordPress, and can perform some kind of a task, like echoing output to the user or inserting something into the database.

Add action:

<?php
function wporg_custom()
{
    // do something
}
add_action('init', 'wporg_custom');

where ‘init’ is the hook i.e. the event at which ‘wporg_custom’ function will be executed.

Filters:

Filters give you the ability to change data during the execution of WordPress. Callback functions for Filters will accept a variable, modify it, and return it. They are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.

Add filter:

<?php
function wporg_filter_title($title)
{
    return 'The ' . $title . ' was filtered';
}
add_filter('the_title', 'wporg_filter_title');

Adding custom hooks and filters is also possible. For full reference, refer to Hooks chapter in Codex.

Categories
Uncategorized

Day 3-4: Revising PHP

It’s been years since I last touched PHP. I’ve learnt at least 10 different languages since then, so there’s obviously a need to visit the syntax of PHP again. I’m done revising it now by doing some hands-on, and following are the files:

General Syntax:

<?php
    echo 'First code of PHP<br>'; //echo
    $var = 'Variable declared and assigned'; //variable
    echo $var.' concat'; //concatenation
    unset($var); //destroy var
    $name = 'Kirito';
    $age = 23;
    echo '<br>';
    var_dump($age); //information about a variable
    echo '<br>';
    var_dump($name);
    $boolVar = true;
    var_dump($boolVar);

    echo '<br>$$ example<br>';
    $name="Rajeev";     //variable 'name' with value 'rajeev'

    $$name="Sanjeev";   //variable 'rajeev' with value 'sanjeev'

    echo $name."<br/>";

    echo $name."<br/>";

    echo $Rajeev."<br/>";

    define('CONSTVAR', 20);     //constant

    //Magic Constants
    echo __LINE__.'<br/>';
    echo __FILE__.'<br/>';
    echo PHP_VERSION.'<br/>';
    /*
    Not applicable in this file, but in case of class/functions:
    __FUNTION__
    __CLASS__
    __METHOD__
    */

    gettype($name); //get data type

    //arrays
    $arr = array(1, 2, 3);

    //append
    $arr[ ] = 4;
    for ($i=0; $i < count($arr); $i++) { 
        echo $arr[$i];
    }

    foreach($arr as $x){
        echo $x;
    }
    var_dump($arr);

    //multiple data types allowed
    $ar2 = array(1, 'KP');
    var_dump($ar2);

    //associative array
    echo '<br/>';
    $assoarr = array(1=>2, "KP"=>"PHP");
    $assoarr[2] = "Hi";
    foreach($assoarr as $key=>$val)
    {
        echo $key.": ".$val."<br/>";
    }

    //array iterator
    $iterator = new ArrayIterator($assoarr);
    while($iterator->valid())
    {
        echo "<br/>". $iterator->current() . " at " . $iterator->key();
        $iterator->next();
    }

    //create array from 10 to 1 with step = 1
    $arrRange = range(10, 1, 1);
    foreach($arrRange as $x)
    {
        echo '<br/>'. $x;
    }

    //select a random element from array arrRange
    $randomNum = array_rand($arrRange);
    echo '<br/>'. $randomNum;
    //class
class Demo
{
    public $num = 3;
    function __construct($n)
    {
        $this->num = $n;
    }
    function show()
    {
            echo '<br>Shwo called<br>';
    }

    function __destruct()
    {
        echo "<br/>Destruct<br/>";
    }
}

    $obj = new Demo(5);
    $obj->show();
    echo '<br/>'.$obj->num. "<br/>";
    unset($obj); //destruct the obj
    //null data type
    $blank = null;

    //resource data type
    //$con = mysqli_connect("localhost","root","","users");

    //functions to check data type
    is_int($var);
    is_nan($var);
    is_null($var);
    is_long($var);
    is_float($var);
    is_bool($var);
    //is_file()
    is_array($arr);
    is_object($obj);
    is_numeric($var);
    is_string($name);


    //cookie
    //name of cookie, value, time before expiry
    setcookie("user", "kp", time()+60*60);

    //mail
    // $headers .= "From:info@phptpoint.com";

    // $headers .= "Content-type: text/html; charset=iso-8859-1rn";

    //mail($to, $subject, $message, $headers);



?>

Example Login

<?php
		
error_reporting(1);
		
$id = $_POST['id'];
		
$pass = $_POST['pass'];
		
if(isset($_POST['signin'])) {	
    if($id=="kp" && $pass=="kp")           
    {
        header('location:https://www.phptpoint.com');           
    }
    else
	{
        echo "<font color='red'>Invalid id or password</font>";		
    }
		
}
	
?>

<body>
    <form method="post">
        <table border="1" align="center">
            <tr>
                <td>Enter Your Id</td>
                <td><input type="text" name="id"/></td>
            </tr>
        
            <tr>
                <td>Enter Your Password</td>
                <td><input type="password" name="pass"/></td>
            </tr>

            <tr>
                <td><input type="submit" name="signin" value="SignIn"/></td>
            </tr> 
        </table">
    </form>
</body>

OOP:

<?php

class BaseClass
{
    private $_num;
    function __construct($n)
    {
        $this->_num = $n;
        echo "<br>Constructor of base called.<br>";
    }

    public function kp($var)
    {
        echo "<br>kp: ".$var."<br>";
    }

    final public function tp()
    {
        echo "<br>This function cannot be overridden because of final keyword.<br>";
    }

    function __destruct()
    {
        echo "<br>Destructor of base called.<br>";
    }
}

final class DerivedClass extends BaseClass //final keyword here means that this class cannot be extended
{
    var $nn;
    function __construct($n)
    {
        parent::__construct($n);
        $this->nn = $n * 2;
    }

    // public function kp()
    // {
    //     echo "<br>kp called with derived" . "<br>";
    // }
}

$derObj = new DerivedClass(4);
$derObj->kp(5);
echo "<br>".$derObj->nn."<br>";
unset($derObj);
?>
Categories
Uncategorized

Day 2: Git

Finally it is time to learn git. I’ve always heard that it is one of the most important tools to learn as a software developer. So here are my notes.

Basics

Initialize a local git repository and add some source files in it:

cd ProjectDirectory
git init
touch index.html
touch app.js

To add files to the staging area (git commits files which are present in staging area only):

git add index.html

To remove a file from staging area:

git rm --cached index.html

To look at the the status of the local repository:

git status

Status gives information about which files are tracked (added to staging), which are changed and which are untracked(not added to staging).

If a file is modified, git status shows it as modified but shows that the modified version is not staged. Use git add to add the updated file to staging area again.

To commit files to repository:

git commit

Above command opens vi editor. remove the comment from line “initial commit” and exit. The files will be committed. Now if you run git status, it will show a message “Nothing to commit”.

To skip the vi editor step use following command:

git commit -m 'your comment'

There may be some files which we do not want to add to repository. To ignore those files/folders, create a file called ‘.gitignore’ and simply add the names of the files that you want to ignore. Let’s say you want to ignore log.txt, all .jpg files and a folder called dir, then the contents of .gitignore should be following:

log.txt
*.jpg
/dir

That’s all you have to do.

Branches

Let us say that you’re working in a team project and you have been assigned the task to create login page. You don’t want to directly modify the code in master branch until the code is complete, so you can create a login branch and commit changes there. To create a branch and switch the working to it, use following commands:

git branch loginBranch
git checkout loginBranch

Now if you create a new file ‘login.html’, modify already existing file ‘index.html’, stage and commit them, they will be committed to login branch only. If you switch branch to ‘master’ again, login.html will disappear and the changes we made in index.html will not show up.

Now if you have completed the login functionality and want to merge the branch to master, do the following:

git merge loginBranch

It will open vi editor and ask for a comment for why this merge is happening. Add a comment and loginBranch will be merged to master.

Working with remote repositories

Add a new repository to your github account using web browser. Use following command for adding a new origin:

git remote add origin 'link to private repository'

Link to private repository is given by github when you create a new repository.

To push your local repository to remote:

git push -u origin master

It will prompt for login and password of your github account, enter the info and the repository will be pushed. Now if you commit some changes, they will be committed to local repository only. To push the changes to remote, simply enter following command:

git push

To clone a public repository on a local machine, use:

git clone 'link to repository'

To pull changes committed to the project by your project partner to local repo, use:

git pull

That’s it for the basics.

Categories
Uncategorized

Day 1

VVV?

Looked at the different processes of installing wordpress today. First confusion was whether EasyEngine and VVV were both mandatory or alternatives to each other. Turns out that VVV is enough for local development. In the process, I came to know that vagrant is something similar to Docker, implementing the concept of containers. My knowledge about containers is limited, so not going to talk about it. I then moved onto learning database schema of wordpress which was intuitive enough.

As a software developer, I also need to increase my typing speed. My speed is good, but yet not enough. Going to try that too!!

Any fool can know. The point is to understand.

Albert Einstein

Categories
Uncategorized

Introduction

Hey! I’m Kirtiraj, pursuing my M.Tech at DAIICT, Gandhinagar. I’m starting this blog to document my journey towards learning wordpress plugin development and theming, for now. I’ll write a few lines about what I learnt each day. Stay tuned!

December 2025
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
293031  

Take the first step in faith. You don’t have to see the whole staircase, just take the first step.

Martin Luther King Jr.
Design a site like this with WordPress.com
Get started