Author: Pratik Londhe

  • day 36

    • Profile command
    • wp doctor command
    • Changing slug of CPT, from theme

    Profile command

    Install using

    wp package install wp-cli/profile-command:@stable

    Or for latest dev version use this

    wp package install wp-cli/profile-command:dev-master

    wp profile stage

    • We can use this command to get the loading time of each stage of wordpress load

    We can use this to see where the site is taking time to load

    We can the drill down into specific stage using wp profile stage <stage>

    wp profile stage main_query

    This will give the data hook wise which then we can use to again drill down to specific hook

    wp profile hook <hook name>

    It will show which function is hooked into it, in which file and on which line

    It is a very useful command when figuring out why exactly the site is loading slow.


    wp doctor command

    The wp doctor command runs some checks on our site from that we can diagnose our site

    To install wp doctor use

    wp package install wp-cli/doctor-command:@stable

    or for dev version

    wp package install wp-cli/doctor-command:dev-master

    Below is the list of checks it runs

    • autoload-options-size : Warns when autoloaded options size exceeds threshold of 900 kb.
    • core-update : Errors when new WordPress minor release is available; warns for major release.
    • plugin-active-count : Warns when there are greater than 80 plugins activated.

    These are just few, we can get the whole list using command wp doctor list


    Changing slug of CPT, from theme

    Why would we ever want to do this? , well in my case I forgot to remove the rewrite argument in CPT registration, which changes the default slug from something that I do not want.

    Why not change the CPT code itself?, the CPT code is in the remote envrionment and I am working on the theme branch makes no sense to change the code inside plugin to hotfix this issue

    Below is the code I tested if works

    function change_person_slug( $args, $post_type ) {
    
    	/*item post type slug*/   
    	if ( 'rt-person' === $post_type ) {
    	   $args['rewrite']['slug'] = 'rt-person';
    	}
     
    	return $args;
     }
     add_filter( 'register_post_type_args', 'change_person_slug', 10, 2 );
    

    We have to refresh the permalinks by going to admin and clicking save on permalinks. As it will need to get refreshed.

  • day 35

    • Adding auth to WP REST API
    • Using wp_filesystem
    • The is_admin() tag

    We can a permission callback to the custom REST route we are registering so it can be used to authenticate the requests.

    It is important to secure endpoints that update the site data in any way using proper auth.

    WP REST handles the authentication, we just have to enable it and use it.

    register_rest_route(
    			'movie-library/v1',
    			'/rt-movie',
    			array(
    				'methods'             => WP_REST_Server::CREATABLE,
    				'callback'            => array( $this, 'rt_movie_post_callback' ),
    				'permission_callback' => array( $this, 'rt_movie_permission_callback' ),
    
    			)
    		);
    
    public function rt_movie_permission_callback( $request ) {
    
    		if ( current_user_can( 'edit_posts' ) ) {
    			return false;
    		}
    
    		return true;
    	}
    
    

    Using wp file system


    When doing any kind of file operations in the wp environment, we can use the wp file system, It is used by the core to perform updates and internal use.

    To use the wp file system, first we have to initialize it and use the global $wp_filesystem object

    if ( ! function_exists( 'WP_Filesystem' ) ) {
    			require_once ABSPATH . 'wp-admin/includes/file.php';
    		}
    		WP_Filesystem();
    global $wp_filesystem;
    
    

    Then we can use it to create files like this

    $wp_filesystem->put_contents( 'myfile.txt, 'hello' );
    

    is_admin() tag

    This conditional is used to check if the current request is for the admin page, so we can use this to enable some functionality only in the admin back-end

    It does not check if current user is admin or logged in, just if requested for admin page, returns true. Do not use this for authentication at all, use the capability and roles for that

  • end of week 7

    • Creating custom route in WP_REST
    • CRUD on options from CLI

    About everything in WordPress is extensible, even the rest API allows us to create our own endpoints and serve data over them.

    It is fairly simple to register a new endpoint, for that we have to use the function register_rest_route()

    To this function we have to pass the namespace and the route as parameters

    This function internally calls the method register_route() of the class WP_REST_Server

    then our route is added to the array of endpoints registered on the server.

    Here’s the code to do that

    First we need to create a function that will handle request and return something

    <?php
    function  return_hello( $data ) {
    	return "Hello!";
    	}
    	
    

    Then we have to create another function that will register all the routes, we are currently registering only one here

    <?php	
    function register_routes(){
    	register_rest_route( 'pratik/v1', '/hi', array(
    	'methods' => 'GET',
    	'callback' => 'return_hello',
    	) );
    	}
    

    We have registered the route /hi in the namespace pratik/v1

    Now we have to hook into the rest init and register this route

    	add_action( 'rest_api_init','register_routes');
    
    

    Done, let’s check it out if it works


    CRUD on options from CLI

    We can access the options of a site from cli using the wp options command

    It has subcommands as below:-

    • delete : Deletes an option.
    • add : Adds a new option value.
    • get : Gets the value for an option
    • list : Lists options and their values..

    If this was not enough, we can extend the WP CLI too!

  • day 33

    • Installing the WP CLI
    • Few Commands
    • Updating CPT support on the fly
    • How is text domain loaded for theme and plugin?

    Installing WP CLI

    We can download the phar file of wp-cli using curl

    after downloading, to verify we can run it using the php and check

    Now, as per the official docs, if we want to be able to use this normally like using wp only then we have to first make this executable and then move it to /usr/local/bin/wp

    chmod +x wp-cli.phar
    sudo mv wp-cli.phar /usr/local/bin/wp

    And now we can use it by wp

    Another more simpler way to install it using homebrew (for mac user)

    brew install wp-cli

    Few commands

    We can pretty much do anything in wordpress using the cli, we can install single site or multisite or convert single site to multisite installation

    We can update the wordpress and database, we can verify the md5 checksum.

    We can manage plugins, themes, posts, users etc.

    To install wordpress use wp core install but before that first we have to download using wp core download

    After downloading, we have to create wp-config file.

    Below Are few commands I tried

    We can install plugins, activate them, remove them etc


    load_theme_textdomain() vs load_plugin_textdomain()

    Why there are two different functions for theme and plugin textdomain loading?, same question I was asked in QnA. I had no idea how to answer it

    After looking at the code inside both of this functions, they are basically same functions, they both load the text domains

    why different functions then?, one reason could be to separate the context in which this functions are used, the main function used to load textdomain is load_textdomain


    How to update the support of CPT

    Well we know we can set the ‘supports’ args in the register_post_type function, but what if we want to update it after registering the CPT without touching the CPT code?

    here’s how to do that. For this we can use the filter register_post_type_args

    <?php
    function modify_support($args,$post_type){
        if($post_type === 'rt-book'){
            $args['supports'] = array('title','excerpt');
        }
        return $args;
    }
    
    add_filter('register_post_type_args','modify_support');
    
  • day 32

    • Discovery of API
    • Authentication

    Discovery of API

    For the REST client to know about the route and endpoints of WP REST api, we use discovery methods.

    In the site’s html code, a <link> tag with the API url is put so we can get the route of the api

    The client can parse the html and get the href of API route

    Another method is to send HEAD request to the site and a header named Link is sent back. We can get the Route from there and further discover the namespaces.

    Check the last header Link


    Authentication

    The authentication of the WP REST api is something I did not like much, they use cookies for authentication and other method is application passwords.

    The limitation of cookie authentication is we can only use the rest api inside the wordpress.

    The application password authentication requires us to generate a password from admin dashboard and then use it with request.

    Below I have explained the process for basic auth with application passwords.

    The first step is to generate application password, for that from dashboard, edit the user and go to generate application password.

    Click on add new application password, and copy the password shown

    Click on update profile, You can manage the application password set in profile

    Now, for this we are using insomnia to test.

    Open auth window in insomnia and select basic auth

    Input the user id and the password copied earlier

    I have made one post private for demo purpose, when I disable the auth this is response i get

    Now let’s enable the auth and see what happens

    It works! , Please keep your application password safe!

  • wp rest api, continued..

    • Route vs Endpoint
    • HAL standard
    • Global Parameters

    Route vs Endpoint

    Routes are like the urls that we use for accessing stuff. Example would be http://wordpress-dev.local/wp-json/

    The Route when combined with a REST method becomes an endpoint

    The route http://wordpress-dev.local/wp-json/wp/posts has endpoints for GET, PUT and DELETE.

    We communicate with the endpoints using the appropriate methods from out REST client (insomnia in my case). We can also use curl for this.

    To list all the endpoints, we can send request to http://wordpress-dev.local/wp-json/


    HAL (Hypertext Application Language) Standard

    In the response we get we can see the _links key, which has links to stuff our post is connected to.

    the WordPress REST API does not closely follow this standard but the _links is taken from this standard.

    You can check more about this at https://en.wikipedia.org/wiki/Hypertext_Application_Language


    Global Parameters

    I learned about these global paramters that we can set in the request

    • _fileds
    • _embed
    • _method
    • _envelope

    _fields

    If we want only some fields then there is no reason to query for all of them, this parameter helps us do that.

    I wrote this request and added _fields parameter so only id is returned.

    _embed

    We can use this parameters to get the href for embeddable links

    Below the _links, you can see the _embedded. This will ony return if the links have set embeddable as true.


    _envelope

    This is a really cool paramter, using this we can get the headers as a response. Check this


  • day 30

    REST API:-

    • Flexibility to build front-end with different technology and using WordPress as back-end.

    This is just a simple GET request to fetch all posts


    The WP CLI:-
    • Command line interface for wordpress
    • We can manage our site, install plugins and many more from cmd only

    example:-

    Adding sidebar widget

    register_sidebar(
    			array(
    				'name'          => __( 'Primary Sidebar', 'screen-time' ),
    				'id'            => 'sidebar-movie',
    				'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    				'after_widget'  => '</aside>',
    				'before_title'  => '<h3 class="widget-title">',
    				'after_title'   => '</h3>',
    			)
    		);
    

    Using dir attribute to change direction of the page to right-to-left
    <html lang="en" dir="rtl">
    

    We use EasyEngine on remote to host the site. To go into our site shell from easyengine use:

    ee shell example.com

    After this we can use the wp CLI commands for our example.com site

    wp user update admin --user_pass="supersecret#23"
  • End of Week 6

    • Lighthouse CLI
    • Page Tempalate
    • Themese and Multisite
    What is Lighthouse?

    Lighthouse is an open-source, automated tool for improving the quality of web pages. You can run it against any web page, public or requiring authentication. It has audits for performance, accessibility, progressive web apps, SEO, and more.

    Basically, we can use the lighthouse to check how our website is performing against some metrics.
    These metrics are:-

    • First Contentful Paint
    • Speed Index
    • Largest Contentful Paint
    • Cumulative Layout Shift
    • Total Blocking Time

    There are multiple ways to use lighthouse, you can check out here. In this blog I will be talking about the CLI only.

    prerequisites:
    • Node LTS and npm must be installed
    • Google chrome installed

    Install the lighthouse node package from npm

    npm install -g lighthouse

    the -g will install it for global use.

    To run audit on your local wordpress site use below command

    lighthouse http://getit.local --view

    Replace the url with your own site, I have set –view as I want to see the results when it is complete.

    Running this will open the chrome browser, run the audit and create a nice report for your site, it will look something like this,

    Explore it using command

     lighthouse --help

    Creating Page template:

    To create a page template we have to add header comment

    &lt;?php
    /*
    Template Name: Movie Replay
    */
    

    Below Code is for a 404 template, that will echo some output if the curent setup is a multisite.

    <?php
    
    get_header();
    
    if (is_multisite()) {
    	_e('We are in a multisite', 'test');
    }
    
    if (is_main_site()) {
    	_e('This is the main site of the network', 'test');
    }
    ?>
    
    
    <div>
    	<?php _e('not found, maybe try searching?', 'test') ?>
    </div>
    
    <?php get_footer();
    ?>
    

  • day 28

    • Can we load multiple style-sheets using one handle?
    • git add .

    To add any css to our theme we have to enqueue it in the functions.php, for that we can use following code

    wp_enqueue_style( 'style', get_stylesheet_uri() );
    

    This will enqueue the main style.css , you can enqueue other scripts too…

        wp_enqueue_style('test-style',get_stylesheet_directory_uri()  . '/gg.css' ) ;
    
    

    Below given are the arguments for this function :- (got it from the core code)

    function wp_enqueue_style( 
        $handle, 
        $src = '', 
        $deps = array(), 
        $ver = false, 
        $media = 'all' ) 
    
    
    • $handle
      • String unique name for the stylesheet
    • $src
      • The source link for the stylesheet
    • $deps
      • array of other handles on which this depends
    • $ver
      • version for stylesheet, if not added WordPress version is used
    • $media
      • the media for which stylesheet has been defined.

    Is it possible to enqueue multiple scripts using same handle?

    • let’s try

    I have this two css files in my theme and the index.php

    This is my code to enquque the stylesheets

    function enqueue_multi()
    {
        wp_enqueue_style('test-style', 
    get_stylesheet_directory_uri()  . '/gg.css') ;
        wp_enqueue_style('test-style', 
    get_stylesheet_directory_uri()  . '/ff.css') ;
    }
    
    add_action('wp_enqueue_scripts', 'enqueue_multi');
    
    

    This is the output coming:-

    **The script enqueue first is not overwritten by the second one**


    Using “git add .” :-

    It is not a good practise to use git add . when adding the changes to the commit, it will add all the changes at the same time even the ones not intended to be pushed.
    Always add the files one by one


  • day 27

    • Flush rewrite in plugin activation
    • WP_Query and the_wp_query

    Why putting flush_rewrite in plugin activation doesn’t work?

    • We are using init hook to register the CPT
    • But the i nit hook is called at very late in the core load

    Then how to do it?

    • Flush them on init hook ?
      • Not the best way, it will flush it at every load.
    • Register the CPT in activation function also, and then flush
      • Good choice as activation will be called only once!

    WP_Query , how the global query works

    • We rarely have to make a custom WP_Query as the wordpress makes one for us.
    • It parses the request url, and fire the query accordingly.
    • Should we overwrite it ?
      • it is safe to use new WP_Query and the loop to temporarily overwrite the global query
      • use reset_post_data() or reset_query() function to reset it though.
    • Maybe you don’t want to create a new query, in my case I just wanted to limit the number of posts per page on the archive page
    • Is it a good idea to create a custom query for this?
    • No, We can do this using the hook pre_get_posts

    Hers’s how i did it

    public function limit_movies_per_page( $query ) {
    		if ( is_post_type_archive( 'rt-movie' ) && $query->is_main_query() ) {
    			$query->set( 'posts_per_page', $this->movies_per_page );
    		}
    	}
    

    And in the constructor I hooked into the pre_get_posts

    		add_action( 'pre_get_posts', [ $this, 'limit_movies_per_page' ] );
    
    

    $this->movies_per_page is a member of my class that can be set to a different value by calling setter.

    1. Can we create a child theme of the existing child theme?

    • No
    • Well I tried it and it didn’t work.

    I might have done something wrong, please suggest if you see in mistake in code. I am using the rtdating theme as parent for this.