WordPress

Topics related to WordPress:

Getting started with WordPress

enter image description here WordPress is an open source Content Management System (CMS) which is used to build and manage websites. WordPress is the most popular CMS on the internet by a country mile, powering about half of all CMS websites at time of writing and about a quarter of all websites on the internet.

WordPress started life as a platform for blogging but has evolved over the years to be suitable for most types of websites. The interface can be used without coding knowledge making it popular for beginners and developers who want to empower their clients to manage their own website.

Another large factor in the popularity of WordPress is it's flexibility, mostly due to the core's plugin and theming systems. The plugin system makes it easy to extend the core functionality without modifying the core code. In a similar manner, the theming system makes it easy to change the website's layout and aesthetics. There are now thousands of free and premium WordPress plugins and themes available. Many of these are located at the wordpress.org plugin repository and theme repository respectively.

WordPress is developed by it's own community, but is strongly associated with the company Automattic, which employs many of WordPress' core developers.

Code

WordPress is built upon the PHP server scripting language and the MySQL querying language. WordPress uses MySQL as a datastore for user content and configuration. The PHP wrangles the content data into a HTML webpage with all the necessary assets.

wordpress.com vs wordpress.org

You can use WordPress by signing up for Automattic's wordpress.com service and hosting your website on their servers, or you can download the WordPress software from wordpress.org and host your website on a server under your control. The first option is easy but you cannot edit any site code. You can only make changes through the WordPress interface. The second option requires more work but gives you flexibility to do whatever you like with your website code. If you are a StackOverflow user, you probably will be going with the second option.

Open Source

WordPress is open source software meaning it is free to use and anyone can view the source code and contribute to it. Potential contributors can get started by reading the Contribution page of the WordPress codex..

Bugs can be reported by submitting a bug on the WordPress ticket tracker.

Documentation

WordPress is officially documented in the WordPress Codex at WordPress.org. Developers working with WordPress will be particularly interested in the Developer Codex section and Developer Reference section of wordpress.org.

get_bloginfo()

$show

ValuesDescriptionExample
'name' (Default)Site title'Matt Mullenweg'
'description'Site tagline'Just another WordPress site'
'wpurl'URL of the WordPress installation. Same as the site_url() function'http://example.com' , 'http://localhost/wordpress'
'url'URL of the site. Same as the home_url() function'http://example.com' , 'http://localhost/wordpress'
'admin_email'Email address of the main Administrator'[email protected]'
'charset'Character encoding of the pages and feeds'UTF-8'
'version'Current version of the WordPress installation'4.5'
'html_type'content-type value of the HTML'text/html'
'text_direction'Text direction determined by the site’s language'ltr'
'language'ISO 639-1 based language code'en-US'
'stylesheet_url'URL of the stylesheet of the activated theme. Value priority: Child theme » Parent theme.'http://example.com/wp-content/themes/twentysixteen/style.css'
'stylesheet_directory'Resource location of the activated theme. Value priority: Child theme » Parent theme.'http://example.com/wp-content/themes/twentysixteen'
'template_url'URL directory of the activated theme. Value priority: Parent theme » Child theme.'http://example.com/wp-content/themes/twentysixteen'
'template_directory'Same as 'template_url'
'pingback_url'Pingback XML-RPC file'http://example/xmlrpc.php'
'atom_url'Atom feed URL'http://example/feed/atom/'
'rdf_url'RDF/RSS 1.0 feed URL'http://example/feed/rdf/'
'rss_url'RSS 0.92 feed URL'http://example/feed/rss/'
'rss2_url'RSS 2.0 feed URL'http://example/feed/'
'comments_atom_url'Comments Atom feed URL'http://example/comments/feed/atom/'
'siteurl'(deprecated) Use ‘url’ instead
'home'(deprecated) Use ‘url’ instead

$filter

ValuesDescriptionExample
'raw' (Default)No filters will be appliedraw data
'display'Filters will be applied to the return value if $show is neither 'url' , 'directory' , 'home'filtered data

Enqueuing scripts

Making network requests with HTTP API

Returns

(WP_Error | array) The response as an array, or WP_Error on failure.

Enqueuing Styles

home_url()

Custom Post Types

template_include

You must return $template even if not modifying. If this confuses you, look at examples where apply_filter() has been used in code

You should not set up variables here for use later, there are better hooks for this.

A useful program flow for this filter is:

  1. Check $template includes our custom post type name --> template hierarchy!!
  2. if not, search our plugin for suitable files --> Its better to point to specific files rather than searching through folders for files. More efficient. But completely up to the developer.
  3. return the template.

The Loop (main WordPress loop)

AJAX

The $wpdb Object

There are two ways to reference the $wpdb object. The first is to use the PHP keyword global in order to act on the global instance of the object.

global $wpdb;
echo $wpdb->prefix;
// Outputs the prefix for the database

The second way to use the $wpdb object is to reference PHP's $GLOBALS super global variable.

echo $GLOBALS['wpdb']->prefix;
// This will also output the prefix for the database

The second way is discouraged as it may not be considered the best practice.

Actions and Filters

Wordpress Hooks

Something that often confuses developers when starting to work with WordPress are the use of apply_filters() and add_action(). You will often see plugins/themes making use of these in code and if you don't understand the concept, you will find it hard to work with them.

In brief (very brief, look up WordPress load flowchart for process in detail), WordPress loads in the following way:

  1. wp-load.php - functions etc
  2. mu-plugins - any files found in the mu-plugins folder - often used to serve cached objects
  3. Plugins - no particular order, any installed and activated plugins will be loaded
  4. Active child theme / parent theme
  5. init - rest of data
  6. template

If you are a developer and working with a functions file, you can see both are loaded earlier in the process than the files you are working with. Meaning you can't modify processes (note you cannot overwrite functions) or variables that run later or have not been defined yet. Also theme developers may place hooks in their code to allow plugins to hook to or plugins might allow for other plugins to overwrite their variables. Now this may be confusing thus far, but hang in there.

To understand add_filter() and add_action() we need to look at how the hooks are created in the first place.

$arga= 'hello';
do_action('im_a_hook', $arga );

When you encounter the above in WordPress, it will call any functions attached to the hook im_a_hook (look up $wp_filter for information on the process). In your attached function $arga will be available for the attached function to work with.

add_action('im_a_hook', 'attached_function');

function attached_function($arga){
     echo $arga;
}

This opens up powerful new opportunities to modify variables at certain points of the load process. Remember we said earlier that templates are loaded after plugins/ themes? One common plugin is WooCommerce which creates screens later in the process, I'm not going to document how but an example of do_action can be found in the plugin.

do_action( 'woocommerce_after_add_to_cart_button' );

Here we have a hook created that passes no variables back, but we can still have fun with it:

add_action( 'woocommerce_after_add_to_cart_button', 'special_offer');

function special_offer(){
    echo '<h1>Special Offer!</h1>;
}

The above add_action will echo a heading of special offer where do_action('woocommerce_after_add_to_cart_button') is located which is when creating a WooCommerce screen. So we can use this hook to insert html. Other uses might include redirecting to a different screen altogether, etc.

Also multiple variables may be passed to the function. Try this in your themes functions. Note the last parameter we are setting to 3, because we want to work with the 3 available parameters. If we changed this to 2, only 2 would be returned and we would get a undefined error.

add_action('custom_hook', 'attached_function', 10, 3);

function attached_function($a,$b,$c){
    
    var_dump($a);
    var_dump($b);
    var_dump($c);
    
}
    

$arga = 1;
$argb = 2;
$argc = 3;

do_action('custom_hook', $arga, $argb, $argc);
exit;

There is another WP hook type called a filter. A filter is different from an action in its usage, an action can only receive variables, obviously these variables are within the functions scope (you should know what php scope is, if not google). Filters pass back the returned data, so you can use to modify variables.

$filter_me= apply_filters('im_a_filter', $variable_to_filter);

Where you see the above, you can modify the value of $filter_me as any data you return will be the value stored in the variable. So for example (note we are changing $variable_to_filter to $filter_me in the example):

add_filter('im_a_filter', 'attached_function', 100);

function attached_function($filter_me){
    
    $filter_me= 'ray';
    
    return $filter_me;
    
}


$filter_me = 'bob';
$filter_me= apply_filters('im_a_filter', $filter_me);

The $filter_me variable will now contain 'ray' rather than 'bob', we have set a priority of 100 so we are reasonably confident no one is changing the value after use (there can be multiple filters running on the same hook) So we can now change variables used later in the process if apply_filters() is present.

You can also pass multiple parameters, but you can only change the value of one. You must also return a value, or else your variable will contain nothing. If you understand how you use php to assign values/arrays/objects to variables this will be obvious to you, e.g.:

add_filter('im_a_filter', 'attached_function', 100, 3);

function attached_function($filter_me, $arga, $argb){
    
    $filter_me= 'ray'.$arga.$argb;

    $arga= 'you fool';
    
    return $filter_me;
    
}

$filter_me = 'bob';

$arga = ' middlename';
$argb = ' surname';

$filter_me= apply_filters('im_a_filter', $filter_me, $arga, $argb);

The $filter_me variable now contains 'ray middlename surname'. But what about $arga? This still contains 'middlename', changing an $arga to 'you fool' within our function has no effect on the defined value outside of its scope (there are ways, google globals etc.)

add_action($hook_name, $function, $priority, $parameters)

add_filter($hook_name, $function, $priority, $parameters);

wp_get_current_user()

Add/remove contact info for users with user_contactmethods filter hook

Creating a custom template

Customizer Hello World

Customizer Basics (Add Panel, Section, Setting, Control)

The Admin Bar (aka "The Toolbar")

The WordPress Admin Toolbar was added in version 3.1 and contains links to common administrative tasks as well as links to the user's profile and other WordPress information. However, many site owners dislike showing the toolbar by default to all logged-in users and/or want to add their own options to it.

Querying posts

Query arguments are numerous. WP_Query() codex page has a list of parameters. Some of them are

One of the most important thing to have in mind is:

Never use query_posts()

query_posts() overrides the main query, and can cause problems in the rest of your theme. Any time you need to modify the main query (or any query for that matter) is to use pre_get_posts filter. This will allow you to modify the query before it ran.

Also when you are querying posts, you should always reset it using wp_reset_postdata(). This will restore the global $post variable of the main query loop, and you won't have any issues later on (such as categories being excluded, because in your secondary loop you've excluded them and forgot to reset the query).

Alternating main loop (pre_get_posts filter)

If you are using PHP 5.3.0 or above, you can use closures (anonymous functions)

add_action( 'pre_get_posts', function( $query ) {
    if( !$query->is_main_query() || is_admin() ) return;

    // this code will run only if
    // - this query is main query
    // - and this is not admin screen
});

Shortcode

Create a Post Programmatically


Arguments

The next table shows you a list of elements that you can use inside of the first parameter (Array).

ParameterDescription
ID(Int) The post ID. If equal to something other than 0, the post with that ID will be updated. Default 0.
post_author(Int) The ID of the user who added the post. Default is the current user ID.
post_date(String) The date of the post. Default is the current time.
post_date_gmt(String) The date of the post in the GMT timezone. Default is the value of $post_date.
post_content(Mixed) The post content. Default empty.
post_content_filtered(String) The filtered post content. Default empty.
post_title(String) The post title. Default empty.
post_category(Array) Array of post category values.
post_excerpt (String) The post excerpt. Default empty.
post_status(String) The post status. Default draft.
post_type(String) The post type. Default post.
comment_status(String) Whether the post can accept comments. Accepts open or closed. Default is the value of default_comment_status option.
ping_status(String) Whether the post can accept pings. Accepts open or closed. Default is the value of default_ping_status option.
post_password(String) The password to access the post. Default empty.
post_name(String) The post name or slug. Default is the sanitized post title when creating a new post.
to_ping(String) Space or carriage return-separated list of URLs to ping. Default empty.
pinged(String) Space or carriage return-separated list of URLs that have been pinged. Default empty.
post_modified(String) The date when the post was last modified. Default is the current time.
post_modified_gmt(String) The date when the post was last modified in the GMT timezone. Default is the current time.
post_parent(Int) Set this for the post it belongs to, if any. Default 0.
menu_order(Int) The order the post should be displayed in. Default 0.
post_mime_type(String) The mime type of the post. Default empty.
guid(String) Global Unique ID for referencing the post. Default empty.
tax_input(Array) Array of taxonomy terms keyed by their taxonomy name. Default empty.
meta_input(Array) Array of post meta values keyed by their post meta key. Default empty.

Avoid Duplicated Posts

When you execute this function, you could probably get a duplicated post, at least that happened to me. (You can check it into the Post WordPress Section)

I found a solution:

if( !get_page_by_title( $title, 'OBJECT', 'post' ) ){
    $my_post = array('post_title' => $title,
        'post_content' => 'Content',
        'tags_input' => $tags,
        'post_category' => array(2),
        'post_status' => 'publish'
    );

    $result = wp_insert_post( $my_post );
}

Explanation

Before you save a new post, validate if the new post already exists using the post title as a parameter, if there's not a post title, you can save your new post.

Check get_page_by_title's documentation here.

get_template_part()

Taxonomies

get_template_part()

Shortcodes

Post Formats

The following Post Formats are available for users to choose from, if the theme enables support for them.

Note that while the actual post content entry won't change, the theme can use this user choice to display the post differently based on the format chosen. For example, a theme could leave off the display of the title for a "Status" post. How things are displayed is entirely up to the theme, but here are some general guidelines.

  • aside - Typically styled without a title. Similar to a Facebook note update.
  • gallery - A gallery of images. Post will likely contain a gallery shortcode and will have image attachments.
  • link - A link to another site. Themes may wish to use the first tag in the post content as the external link for that post. An alternative approach could be if the post consists only of a URL, then that will be the URL and the title (post_title) will be the name attached to the anchor for it.
  • image - A single image. The first tag in the post could be considered the image. Alternatively, if the post consists only of a URL, that will be the image URL and the title of the post (post_title) will be the title attribute for the image.
  • quote - A quotation. Probably will contain a blockquote holding the quote content. Alternatively, the quote may be just the content, with the source/author being the title.
  • status - A short status update, similar to a Twitter status update.
  • video - A single video or video playlist. The first tag or object/embed in the post content could be considered the video. Alternatively, if the post consists only of a URL, that will be the video URL. May also contain the video as an attachment to the post, if video support is enabled on the blog (like via a plugin). audio - An audio file or playlist. Could be used for Podcasting.
  • chat - A chat transcript

Custom exerpts with excerpt_length and excerpt_more

Plugin development

Security in WordPress - Escaping

Security should be always in mind when developing. Without security an app is open to various attacks such as SQL Injections, XSS, CSRF, RFI etc that can lead to serious problems.

Untrusted data comes from many sources (users, third party sites, your own database!, ...) and all of it needs to be validated both on input and output. (Source: WordPress Codex)

The data should be validated, sanitized or escaped depending the use and the purpose.

To validate is to ensure the data you've requested of the user matches what they've submitted. (Source: WordPress Codex)

Sanitization is a bit more liberal of an approach to accepting user data. We can fall back to using these methods when there's a range of acceptable input. (Source: WordPress Codex)

To escape is to take the data you may already have and help secure it prior to rendering it for the end user. (Source: WordPress Codex)

Template hierarchy

Remove Version from Wordpress and Stylesheets

Intended to improve site speed and safety.

Child Theme Basics

I've been advertising that the use of a child theme is always a good thing but there is always a But ...

In our Template overwriting example let's imagine that the author of a theme is adding his own improvements to the sidebar template and there will be a new one at

/themes/template/sidebar.php

<?php
/**
 * The template for the sidebar containing the main widget area
 *
 * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
 */

if ( is_active_sidebar( 'sidebar-1' )  ) : ?>
    <aside id="secondary" class="sidebar widget-area" role="complementary">
        <?php dynamic_sidebar( 'sidebar-1' ); ?>
    </aside><!-- .sidebar .widget-area -->
<?php endif; ?>

Now our website won't benefit from the new role="complementary" spec because our child theme is still overwriting the template with its own file at /themes/child-theme/sidebar.php

It is our duty as website maintainers to keep a track about what templates do we overwrite and, in the imminent case of an update, look carefully at the changelog so you update the child theme files if necessary.

add_action()

get_template_part()

Shortcode with attribute

Sidebars

Argument options are:

  • name - Sidebar name (default: localized 'Sidebar' and numeric ID).
  • id - Sidebar id - Must be all in lowercase, with no spaces (default: a numeric auto-incremented ID). If you do not set the id argument value, you will get E_USER_NOTICE messages in debug mode, starting with version 4.2.
  • description - Text description of what/where the sidebar is. Shown on widget management screen. (Since 2.9) (default: empty)
  • class - CSS class to assign to the Sidebar in the Appearance -> Widget admin page. This class will only appear in the source of the WordPress Widget admin page. It will not be included in the front end of your website. Note: The value sidebar will be prepended to the class value. For example, a class of tal will result in a class value of sidebar-tal. (default: empty).
  • before_widget - HTML to place before every widget (default: <li id="%1$s" class="widget %2$s">) Note: uses sprintf for variable substitution
  • after_widget - HTML to place after every widget (default: </li>\n).
  • before_title - HTML to place before every title (default: <h2 class="widgettitle">).
  • after_title - HTML to place after every title (default: </h2>\n).

Security in WordPress - Sanitization

Security should be always in mind when developing. Without security an app is open to various attacks such as SQL Injections, XSS, CSRF, RFI etc that can lead to serious problems.

Untrusted data comes from many sources (users, third party sites, your own database!, ...) and all of it needs to be validated both on input and output. (Sourse: WordPress Codex)

The data should be validated, sanitized or escaped depending the use and the purpose.

To validate is to ensure the data you've requested of the user matches what they've submitted. (Sourse: WordPress Codex)

Sanitization is a bit more liberal of an approach to accepting user data. We can fall back to using these methods when there's a range of acceptable input. (Sourse: Wordpress Codex)

To escape is to take the data you may already have and help secure it prior to rendering it for the end user. (Sourse: WordPress Codex)

init

init is an action hook that gets fired after WordPress has finished loading but before any HTTP headers are sent.

Create Template for Custom Post Type

Function: add_action()

The add_action() function creates an Action Hook, associating a PHP function with a particular action "tag" or name. When the action is "triggered" by a call to do_action() (or do_action_ref_array()) with a specific tag, all functions "hooked" to that tag will be executed.

In most cases, this function should be used in a theme's functions.php file or a plugin file - or another source file loaded by either.

This function is a part of the Plugin API

Add Shortcode

  • The shortcode callback will be passed three arguments: the shortcode attributes, the shortcode content (if any), and the name of the shortcode.
  • There can only be one hook for each shortcode. Which means that if another plugin has a similar shortcode, it will override yours or yours will override theirs depending on which order the plugins are included and/or ran.
  • Shortcode attribute names are always converted to lowercase before they are passed into the handler function. Values are untouched.
  • Note that the function called by the shortcode should never produce output of any kind. Shortcode functions should return the text that is to be used to replace the shortcode. Producing the output directly will lead to unexpected results. This is similar to the way filter functions should behave, in that they should not produce expected side effects from the call, since you cannot control when and where they are called from.

How Can I integrate Markdown editor with Advance Custom Field's repeater Add-on.

Installation and Configuration

wp_get_current_user()

WP-Cron

Secure your installation

Options API

The Options API is a simple and standardized way of working with data staored in the options table of MySQL database. The API makes it easy to create, read, update, and delete options.

Function : wp_trim_words()

WP_Query() Loop

Update WordPress Manually

Themes

WP-CLI

Debugging

add_menu_page()

Here is a list of the default positions (for $position)

  • 2 – Dashboard
  • 4 – Separator
  • 5 – Posts
  • 10 – Media
  • 15 – Links
  • 20 – Pages
  • 25 – Comments
  • 59 – Separator
  • 60 – Appearance
  • 65 – Plugins
  • 70 – Users
  • 75 – Tools
  • 80 – Settings
  • 99 – Separator

add_submenu_page()

Here are a list of slugs for $parent_slug

  • Dashboard: ‘index.php’
  • Posts: ‘edit.php’
  • Media: ‘upload.php’
  • Pages: ‘edit.php?post_type=page’
  • Comments: ‘edit-comments.php’
  • Custom Post Types: ‘edit.php?post_type=your_post_type’
  • Appearance: ‘themes.php’
  • Plugins: ‘plugins.php’
  • Users: ‘users.php’
  • Tools: ‘tools.php’
  • Settings: ‘options-general.php’
  • Network Settings: ‘settings.php’

get_option()

List of arguments for $option

  • 'admin_email'
  • 'blogname'
  • 'blogdescription'
  • 'blog_charset'
  • 'date_format'
  • 'default_category'
  • 'home'
  • 'siteurl'
  • 'template'
  • 'start_of_week'
  • 'upload_path'
  • 'users_can_register'
  • 'posts_per_page'
  • 'posts_per_rss'

get_permalink()

For the parameter $leavename, it is false by default.

get_the_category()

Please note that get_the_category() returns an array, which means that you can't directly echo the value returned.

Here is a list of objects of each category that you can print:

  • term_id
  • name
  • slug
  • term_group
  • term_taxonomy_id
  • taxonomy
  • description
  • parent
  • count
  • object_id
  • filter
  • cat_ID
  • category_count
  • category_description
  • cat_name
  • category_nicename
  • category_parent

the_title()

  • For the parameter $echo, use true to display the title and use false to return it for use in PHP
  • Please note that the_title can only be used in loops, if you want to use it outside of loops, please use get_the_title

get_the_title()

If you plan to get the title of a post or page using a post loop, it is suggested to use the_title() instead.

add_editor_style()

add_theme_support()

List of features to be used in $feature:

  • 'post-formats'
  • 'post-thumbnails'
  • 'html5'
  • 'custom-logo'
  • 'custom-header-uploads'
  • 'custom-header'
  • 'custom-background'
  • 'title-tag'
  • 'starter-content'

WordPress Plugin creation

Run WordPress local with XAMPP

Admin Dashboard Widgets

Site Migration

Meta Box

The content inside the render meta box can be anything. Instead of the values being directly integrated, you can also use an include with a PHP template and use set_query_var method to pass data to it. The save would work the same way.

Remove Auto Line Breaks From Content and Excerpt

These must be executed directly in an include file. Whether it is in functions.php or in another include file, these cannot be wrapped in a hook. They won't work on init or any other I have found so far.

They can also be included directly in a template like page.php to execute only for that template.

NOTE: DO NOT INCLUDE THIS IN A DISTRIBUTED THEME OR PLUGIN (unless it is disabled by default, like not including the include file it's in unless the user specifies).

This is bad practice to include in a site you don't control because it can and will break the output of any other themes or plugins.

get_home_path()

Important difference between get_home_path() and ABSTPATH

Please keep in mind the difference between ABSPATH and get_home_path() if you have WordPress installed in a subfolder.

The get_home_path() function will always return a path without the subfolder:

This is how it differs from ABSPATH, which will return different values:

ABSPATH is first defined in wp-load.php which will be located at /var/www/htdocs/example/wp/wp-load.php hence this is where ABSPATH will take its definition from.

get_home_path() checks if the site_url and home_url differ, and removes the substring from the path. Otherwise it returns ABSPATH value:

function get_home_path() {
    $home    = set_url_scheme( get_option( 'home' ), 'http' );
    $siteurl = set_url_scheme( get_option( 'siteurl' ), 'http' );
    if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) {
        $wp_path_rel_to_home = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
        $pos = strripos( str_replace( '\\', '/', $_SERVER['SCRIPT_FILENAME'] ), trailingslashit( $wp_path_rel_to_home ) );
        $home_path = substr( $_SERVER['SCRIPT_FILENAME'], 0, $pos );
        $home_path = trailingslashit( $home_path );
    } else {
        $home_path = ABSPATH;
    }

    return str_replace( '\\', '/', $home_path );
}

Using it in your code

Calling get_home_path() must be done in a context where wp-admin/includes/file.php has already been included.

For example using get_home_path() within the admin_init hook is fine, but using it within the init is not and will result in a PHP fatal error:

Call to undefined function get_home_path()

This file only gets included from within the admin (dashboard) context, if you absolutely need it outside of this context you will need to include the file yourself before calling the function:

require_once(ABSPATH . 'wp-admin/includes/file.php');

Wordpress theme and child-theme development

REST API

To get this WordPress REST API simple example to work for you, you need to learn how it works in more detail. Official documentation recommends learning about:

  1. Routes/Endpoints - which are mappings of individual HTTP methods to routes known as "endpoints" - you do it using register_rest_route() function, and here you can find more about Routes and Endpoints.

  2. Requests - WordPress REST API defines WP_REST_Request class which is used to store and retrieve information for the current request. WP_REST_Request objects are automatically generated for you whenever you make an HTTP request to a registered route. The data specified in the request will determine what response you get back out of the API. Here can learn more about the WP_REST_Request class.

  3. Responses - are the data you get back from the API. The WP_REST_Response provides a way to interact with the response data returned by endpoints. In your endpoint definition you name the callback (response) function to serve your interaction. Here can learn more about the WP_REST_Response class.

  4. Schema - Each endpoint requires and provides slightly different data structures, and those structures are defined in the API Schema. If you want maintainable, discoverable, and easily extensible endpoints it is recommended to use the schema. Here you can learn more about the Schema.

  5. Controller Classes - they bring all elements together in a single place. With a controller class you can manage the registration of routes & endpoints, handle requests, utilize schema, and generate API responses. You have already learned about two controller classes: WP_REST_Request and WP_REST_Response. Here you can learn more about the Controller Classes

Note: Some of this information is taken from the official Wordpress REST APi Handbook