get_template_directory_uri() Retrieves template directory URI for the active theme. Returns the URL of the parent theme directory

get_header($name = null, $args = array()) { } Includes the header template for a theme or if a name is specified then a specialized header will be included. For the parameter, if the file is called “header-special.php” then specify “special”.

get_theme_file_uri('/assets/css/style.css') The URL to a specific file, and it checks Child theme first, Then parent theme (fallback)

esc_url() Checks and cleans a URL.

home_url('/') Retrieves the URL for the current site where the front end is accessible. Param is Path relative to the home URL

wp_login_url() Retrieves the login URL.

admin_url() Retrieves the URL to the admin area for the current site. admin-ajax.php handles AJAX requests for both the WordPress admin and the frontend. When you use admin_url( 'admin-ajax.php' ), you are getting the URL to this built-in file so your JavaScript can send AJAX requests to WordPress. If your AJAX request sends action: 'A', WordPress will look for a function hooked to:

  • wp_ajax_A (for logged-in users)
  • wp_ajax_nopriv_A (for non-logged-in users)
<?php
add_action( 'wp_ajax_A', 'your_function' );
add_action( 'wp_ajax_nopriv_A', 'your_function' );

wp_create_nonce( 'mw_frontend_nonce' ) Creates a cryptographic token tied to a specific action, user, user session, and window of time.


Debounce is a programming technique used to limit how often a function is called. ex - it’s used to delay sending a search request until the user has stopped typing for a certain amount of time (500ms).

Instance of the URLSearchParams object, which is a built-in JavaScript class for working with URL query parameters. You can use it to easily build and encode data for HTTP requests, If you want to add them to the URL, you would do something like:
url + '?' + params.toString()


wp_enqueue_style Enqueues a CSS stylesheet.

<?php  
function wp_enqueue_style(  
$handle,  
$src = '',  
$deps = array(),  
$ver = false,  # if it has one, which is added to the URL as a query string for cache busting purposes.
$media = 'all'  
) { }

is_admin() Determines whether the current request is for an administrative interface page.

$query->is_main_query() Determines whether the query is the main query.

is_post_type_archive( 'rt-person' ) Determines whether the query is for an existing post type archive page.

$query->set( 'posts_per_page', 12 ) Sets the value of a query variable.


check_ajax_referer Verifies the Ajax request to prevent processing requests external of the blog.

<?php
check_ajax_referer( 'mw_frontend_nonce', 'nonce' );
  • It checks that the AJAX request includes a valid nonce (a security token) named 'mw_frontend_nonce' in the 'nonce' POST field.

isset() Determine if a variable is declared and is different than NULL

WP_Query::have_posts Determines whether there are more posts available in the loop.

WP_Query::the_post Sets up the current post. Retrieves the next post, sets up the post, sets the ‘in the loop’ property to true

get_post_meta( $person_id, 'rt-person-meta-basic-birth-date', true ); Retrieves a post meta field for the given post ID. Third param is Whether to return a single value otherwise returns array.

get_the_post_thumbnail_url( $person_id, 'medium' ); Second param is Registered image size to retrieve the source for or a flat array of height and width dimensions. Default is post-thumbnail

get_the_excerpt() Retrieves the post excerpt. of global post

date_i18n( 'd F Y', strtotime( $birth_date ) ); Retrieves the date in localized format, based on a sum of Unix timestamp and timezone offset in seconds.

gmdate( 'Y', strtotime( $release ) ) Returns in GMT/UTC timezone, non localized

strtotime(str) Parse about any English textual datetime description into a Unix timestamp

the_permalink() Displays the permalink for the current post.

the_title() Displays the post title directly in HTML. Used for visible content (e.g., headings).

the_title_attribute() Outputs the post title as a safe, escaped string for use in HTML attributes (like alttitle, etc.).

if ( $query->have_posts() ) {
	while ( $query->have_posts() ) {
		$query->the_post();

wp_reset_postdata() After looping through a separate query, this function restores the $post global to the current post in the main query.

wp_send_json_success() Sends a JSON response back to an Ajax request, indicating success.

ob_start() Turn on output buffering

ob_get_clean() Get current buffer contents and delete current output buffer

<?php comment_class( 'review-card' ); Generates semantic classes for each comment element and adds classes in param too

comment_ID() Displays the comment ID of the current comment.

get_comment_author() returns string

comment_author() displays author

comment_text()

get_comment_date()


$args = array(
	'post_type'      => array( 'rt-movie', 'rt-person' ),
	'posts_per_page' => 8,
	's'              => $search_term,
	'post_status'    => 'publish',
);

$query = new WP_Query( $args );

$slider_query = new WP_Query(
	array(
		'post_type'      => 'rt-movie',
		'posts_per_page' => 4,
		'tax_query'      => array(
			array(
				'taxonomy' => 'rt-movie-label',
				'field'    => 'slug',
				'terms'    => 'slider',
			),
		),
	)
);

// Relation
<?php
'tax_query' => array(
    'relation' => 'OR', // or 'AND'
    array(
        'taxonomy' => 'rt-movie-label',
        'field'    => 'slug',
        'terms'    => 'slider',
    ),
    array(
        'taxonomy' => 'rt-movie-genre',
        'field'    => 'slug',
        'terms'    => 'action',
    ),
)

sprintf( '%dH %dM', $hours, $minutes ); Print formated string

get_the_terms( $movie_id, 'rt-movie-genre' ); Retrieves the terms of the taxonomy that are attached to the post. Returns list of wp_terms object, or false if empty, or WP_Error.

get_the_term_list( $post_id, 'category', '<span>', ', ', '</span>' ); get_the_term_list( $post_id, $taxonomy, $before, $sep, $after )

is_wp_error( $a ) Checks whether the given variable is a WordPress Error.

foreach ( $genres as $genre ) {
	$genre_names[] = $genre->name;
}

function wp_trim_words($text, $num_words = 55, $more = null) Trims text to a certain number of words.

array_slice( $genres, 0, 3 )

get_term_link( $genre ) Generates a permalink for a taxonomy term archive.


  • implode() = array → string implode( ' • ', $genre_names )
  • explode() = string → array

$links = paginate_links(
	array(
		'type'      => 'array',
		'prev_text' => '<span class="arrow">&laquo;</span>',
		'next_text' => '<span class="arrow">&raquo;</span>',
	)
);

if ( $links ) {
    echo '<div class="pagination">';
    foreach ( $links as $pagination_link ) {
        echo wp_kses_post( $pagination_link );
    }
    echo '</div>';
}

kses()

<?php
$allowed_tags = array(
    'a' => array(
        'href' => array(),
        'title' => array()
    ),
    'br' => array(),
    'em' => array(),
    'strong' => array(),
);

$safe_content = wp_kses( $user_content, $allowed_tags );
<?php
$email = "user@example.com<script>";
$clean_email = filter_var($email, FILTER_SANITIZE_EMAIL);
// $clean_email = "user@example.com"

<?php
$email = "user@example.com";
if ( filter_var($email, FILTER_VALIDATE_EMAIL) ) {
    // Valid email
} else {
    // Invalid email
}

single_term_title() Displays or retrieves page title for taxonomy term archive.

global $wp_query;


$json = '{"name":"Ash","age":30}';
$data = json_decode($json, true); // true means retur array, false is for return object
// $data['name'] = "Ash"
// $data['age'] = 30

has_post_thumbnail() Determines whether a post has an image attached.

$actor_post = get_post( $actor_id ); Database call

rawurlencode($text); // John%20Doe%20%26%20Friends

wp_get_attachment_image_src Retrieves an image to represent an attachment. Returns Array of image data, or boolean false if no image is available. function wp_get_attachment_image_src($attachment_id, $size = 'thumbnail', $icon = false) { }

wp_get_attachment_url

Retrieves the URL for an attachment.

function wp_get_attachment_url($attachment_id = 0) { }

if ( post_type_supports( get_post_type(), 'comments' ) ) {
	$movie_comments = get_comments(
		array(
			'post_id' => get_the_ID(),
			'status'  => 'approve',
		)
	);
	if ( comments_open() || $movie_comments ) {
		wp_list_comments(
			array(
				'style'      => 'div',
				'short_ping' => true,
				'callback'   => 'screentime_movie_review_comment',
			),
			array_reverse( $movie_comments )
		);
	}
}
$comments_args = array(
	'title_reply'          => 'Leave a Review',
	'title_reply_before'   => '<h3 class="section-title">',
	'title_reply_after'    => '</h3>',
	'comment_notes_before' => '<p class="section-subtext">Your Email Address will not be published. Required fields are marked * </p>',
	'class_form'           => 'review-form',
	'class_submit'         => 'btn-submit-review',
	'label_submit'         => 'Post Review',
	'comment_field'        => '<div class="form-group"><label for="comment">Comment *</label><textarea id="comment" name="comment" rows="4" required></textarea></div>',
	'fields'               => array(
		'author'  => '<div class="form-row"><div class="form-group half"><label for="author">Name *</label><input type="text" id="author" name="author" required></div>',
		'email'   => '<div class="form-group half"><label for="email">Email *</label><input type="email" id="email" name="email" required></div></div>',
		'url'     => '<div class="form-group"><label for="url">Website</label><input type="url" id="url" name="url"></div>',
		'cookies' => '<div class="form-checkbox"><input type="checkbox" id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" value="yes"><label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time I comment.</label></div>',
	),
	'submit_button'        => '<button name="%1$s" type="submit" id="%2$s" class="%3$s">%4$s</button>',
);
comment_form( $comments_args );

$birth_dt = new DateTime( $birth_date );
$now      = new DateTime();
$age      = $now->diff( $birth_dt )->y;  // returns DateInterval object

$careers = get_the_terms( $person_id, ‘rt-person-career’ );

$career_list = ‘’;

if ( ! empty( $careers ) && ! is_wp_error( $careers ) ) {

$career_names = wp_list_pluck( $careers, ’name’ );

Plucks a certain field out of each object or array in an array. Returns array of found values


The LOOP

The Loop is how WordPress fetches and displays posts from the database.

When WordPress loads a page (home, archive, category, etc.), it builds a query using the WP_Query class.
The Loop is simply the PHP structure that iterates over those results.

<?php if ( have_posts() ) : ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <h2><?php the_title(); ?></h2>
        <div>
            <?php the_content(); ?>
        </div>
    <?php endwhile; ?>
<?php else : ?>
    <p>No posts found.</p>
<?php endif; ?>
<?php
$args = array(
    'post_type' => 'post',
    'posts_per_page' => 3
);
$custom_query = new WP_Query($args);
if ($custom_query->have_posts()) :
    while ($custom_query->have_posts()) : $custom_query->the_post();?>
        <h3><?php the_title(); ?></h3>
	<?php
    endwhile;
    wp_reset_postdata();
endif;
?>

Child theme

A child theme inherits functionality and styling from a parent theme.

You use it when:

  • You want to modify a theme safely

  • You want updates without losing changes

wp-content/
   themes/
      parent-theme/
      parent-theme-child/
          style.css
          functions.php
/*
Theme Name: Parent Theme Child
Template: parent-theme-folder-name
*/
<?php
function child_theme_enqueue_styles() {
    wp_enqueue_style(
        'parent-style',
        get_template_directory_uri() . '/style.css'
    );
}
add_action('wp_enqueue_scripts', 'child_theme_enqueue_styles');

If parent theme has:

single.php

You can copy it into child theme and modify it.

The child theme’s functions.php file is loaded immediately before the parent theme’s functions.php file. For your custom designs to work, the child theme’s style.css must load after the parent theme’s stylesheet so that it can override it.

get_stylesheet_directory_uri(); to get child theme directory

// parent theme
$parent_theme = wp_get_theme( get_template() );
echo $parent_theme->get( 'Name' );
echo $parent_theme->get( 'Version' );

// child theme
$child_theme = wp_get_theme();
echo $child_theme->get( 'Version' );

Lazy loading delays loading of images/videos until they are visible in the viewport.

// auto
<img src="image.jpg" loading="lazy">

// manual
<div class="lazy-bg" data-bg="image.jpg"></div>

document.addEventListener("DOMContentLoaded", function() {
  const lazyElements = document.querySelectorAll(".lazy-bg");

  const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.style.backgroundImage = 
          `url(${entry.target.dataset.bg})`;
        observer.unobserve(entry.target);
      }
    });
  });

  lazyElements.forEach(el => observer.observe(el));
});

const response = await fetch(`/wp-json/wp/v2/posts?per_page=3&page=${currentPage}&_embed`);
const persons = await response.json();
# in here, add custom meta data as output(birthdate)
add_action('rest_api_init', function () {
    register_rest_field('rt_movie', 'birth_date', array(
        'get_callback' => function ($post_array) {
            // Get the metadata from the database
            return get_post_meta($post_array['id'], 'birth_date', true);
        },
        'update_callback' => null,
        'schema'          => null,
    ));
});

get_template_part( 'content', 'single' );

WordPress will search for files in this order:

  1. wp-content/themes/my-child-theme/content-single.php

  2. wp-content/themes/my-parent-theme/content-single.php

  3. wp-content/themes/my-child-theme/content.php

  4. wp-content/themes/my-parent-theme/content.php

add_theme_support('custom-logo', array (height => 23px, widht => 23px))

// Inside the Loop
while ( have_posts() ) : the_post();
    
    // This looks for content-video.php, content-quote.php, etc.
    // If none exists, it falls back to content.php
    get_template_part( 'template-parts/content', get_post_format() );

endwhile;

// register nav menu
function my_theme_setup() {
    // To register a single menu:
    register_nav_menu('header-menu', __( 'Primary Header Menu', 'text-domain' ));
}
add_action( 'after_setup_theme', 'my_theme_setup' );
<nav class="main-navigation">
    <?php
    wp_nav_menu( array(
        'theme_location' => 'header-menu', // Must match the ID used in Step 1
        'container'      => false,         // Removes the default <div> wrapper
        'menu_class'     => 'nav-list',    // Adds a class to the <ul>
    ) );
    ?>
</nav>

function my_theme_setup() {
    // get_template_directory() ensures we look in the right folder
    load_theme_textdomain( 'my-awesome-theme', get_template_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'my_theme_setup' );

add_image_size() set_post_thumbnail_size()


sticky posts

<?php
$args  = array(
	'posts_per_page'      => 1,
	'post__in'            => get_option( 'sticky_posts' ),
	'ignore_sticky_posts' => 1,
);
$query = new WP_Query( $args );

  • Single post: single-{post-type}-{slug}.phpsingle-{post-type}.phpsingle.phpsingular.phpindex.php
  • Pages: custom template filepage-{slug}.phppage-{id}.phppage.phpsingular.phpindex.php
  • Tags: tag-{slug}.phptag-{id}.phptag.phparchive.phpindex.php
  • Front page: front-page.phphome.phppage.phpindex.php
  • Search results: search.phpindex.php

[[Pasted image 20260217134138.png]]


  • wp_head(): Placed just before </head>. It outputs styles, scripts, and meta tags.

  • wp_footer(): Placed just before </body>. Essential for JavaScript and the admin bar.

  • wp_body_open(): Placed immediately after <body>.


function my_theme_scripts() {
    // 1. Enqueue the JS file
    wp_enqueue_script( 'main-js', get_template_directory_uri() . '/js/main.js', array('jquery'), '1.0', true );

    // 2. Pass data to that specific handle
    wp_localize_script( 'main-js', 'siteData', array(
        'ajax_url' => admin_url( 'admin-ajax.php' ),
        'nonce'    => wp_create_nonce( 'my_secret_key' ),
        'loading'  => __( 'Loading posts...', 'text-domain' ) // Localization
    ));
}
add_action( 'wp_enqueue_scripts', 'my_theme_scripts' );


----

jQuery(document).ready(function($) {
    console.log(siteData.ajax_url); // Outputs the full URL to admin-ajax.php
    
    $.ajax({
        url: siteData.ajax_url,
        data: {
            action: 'my_action',
            security: siteData.nonce // Use the nonce for security
        },
        success: function(response) {
            alert(siteData.loading); // Uses the translated string
        }
    });
});
  • lang attribute: Used in the <html> tag to tell browsers and screen readers the language of the current page.

    • Example: <html lang="ja">
  • hreflang attribute: Used in <link> tags in the <head> to tell search engines about alternative versions of the page for different languages/regions.

    • Example: <link rel="alternate" hreflang="ar" href="https://example.com/ar/" />
// Displaying an oEmbed video via code
echo wp_oembed_get( 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' );

CSS

position property: static (default):

  • The element is positioned according to the normal document flow.
  • toprightbottom, and left have no effect.
  • Does not create a positioning context for child elements.

relative:

  • The element stays in the normal flow, but you can move it using toprightbottom, or left (relative to its original position).
  • Creates a positioning context for absolutely positioned child elements.

1. grid.scrollWidth

  • Returns the total width of the grid’s content, including the part not visible due to overflow (i.e., the full scrollable width).

2. grid.clientWidth

  • Returns the visible width of the grid (the width of the element’s content area, excluding scrollbars, borders, and margins).

3. grid.scrollLeft

  • Returns the number of pixeltemplas that the grid’s content is scrolled from its left edge (how far the user has scrolled horizontally).

Flexbox

Flexbox is “content-out.” It calculates the size of the items and fits them along an axis.

  • flex-grow: How much of the “extra” space should this item take? (Proportion)

  • flex-shrink: How much should this item “give up” if the container gets too small? (Priority)

  • flex-basis: What is the “ideal” starting size of this item before growing or shrinking starts? ‘0’ ignore its original width

flex: [flex-grow] [flex-shrink] [flex-basis];

Parent Properties (The Container)

  • display: flex;: Activates the flex context.

  • flex-direction: Defines the main axis.

    • row (default), row-reverse, column, column-reverse.
  • justify-content: Aligns items along the main axis.

    • flex-start, flex-end, center, space-between, space-around, space-evenly.
  • align-items: Aligns items along the cross axis.

    • stretch (default), flex-start, flex-end, center, baseline.
  • flex-wrap: Should items wrap if they run out of space?

    • nowrap (default), wrap, wrap-reverse.

Child Properties (The Items)

  • flex-grow: Ability for an item to grow if necessary (default 0).

  • flex-shrink: Ability for an item to shrink if necessary (default 1).

  • flex-basis: The default size of an element before the remaining space is distributed.

  • align-self: Overrides the align-items value for a specific item.


Grid is “layout-in.” You define the skeleton (columns and rows), and then place items into those “cells.”

Parent Properties (The Container)

  • display: grid;: Activates the grid context.

  • grid-template-columns / grid-template-rows: Defines the track sizes.

    • Example: grid-template-columns: 200px 1fr 2fr; (creates three columns).
  • grid-template-areas: Allows you to name sections of your layout.

  • gap (or grid-gap): Sets the spacing between rows and columns.

  • justify-items: Aligns items inside their cell along the row axis.

  • align-items: Aligns items inside their cell along the column axis.

Child Properties (The Items)

  • grid-column: Shorthand for grid-column-start and grid-column-end.

    • Example: grid-column: 1 / 3; (spans the item across two columns).
  • grid-row: Shorthan for grid-row-start and grid-row-end.

  • grid-area: Either assigns a name to an item or acts as a shorthand for rows/columns.

flex: 1; (The Equalizer)

This is shorthand for flex: 1 1 0;.


Grid

What is fr? It stands for “Fractional Unit.” It represents a fraction of the remaining space in the grid container after the fixed items (the 200px) are accounted for. The fr unit is “gap-aware.” It automatically subtracts any gap before it does the math

grid-template-columns: 1fr 1fr 1fr; (or use the shortcut: repeat(3, 1fr)) grid-template-columns: 150px 1fr 150px; (Two fixed sidebars and a fluid center). grid-template-columns: auto 1fr; (The first column shrinks to fit its smallest text/image, and the second takes the rest).

  • justify-items: Aligns along the Inline (Row) Axis. (Left/Right)

    • start, end, center, stretch (default).
  • align-items: Aligns along the Block (Column) Axis. (Top/Bottom)

    • start, end, center, stretch (default).
/* for child items */
.featured-post {
  grid-column: 1 / 3; /* Starts at line 1, ends at line 3 */
  /* OR */
  grid-column: 1 / span 2; 
}
.container {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: 
    "header header". /* Name your sections */
    "sidebar main"
    "footer footer";
}

.main-sidebar { grid-area: sidebar; }

.featured-image {
  /* row-start / col-start / row-end / col-end */
  grid-area: 1 / 1 / 3 / 3;
  /* occupies two rows two columns*/
}

.sidebar {
  /* Start at row 2, col 1. Span 3 rows down and 1 column wide. */
  grid-area: 2 / 1 / span 3 / span 1;
}
/* minmax( [minimum size], [maximum size] ) */
grid-template-columns: minmax(200px, 1fr);
.container {
  display: grid;
  /* "Create as many columns as fit, but none smaller than 250px" */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

auto-fill (Fill the tracks)

It creates as many “tracks” (columns) as possible, even if they are empty.

  • If you have 1 item in a container that fits 5 columns, it stays in the first column and the other 4 columns sit empty.

auto-fit (Fit the content)

It creates the tracks, but then collapses any empty tracks to 0px.

  • If you have 1 item, that item will stretch to fill the entire width of the container because the empty columns are “fitted” (collapsed) away.

::after

This is a pseudo-element. It instructs the browser to create a “fake” element inside the .person-card, positioned right after the actual content (like the person’s name). You don’t have to write this element in your PHP/HTML; CSS creates it on the fly.

attr(data-birthdate)

This is the “Getter.”

  • It looks at the HTML tag for .person-card.

  • It searches for an attribute named data-birthdate.

The content property defines what the pseudo-element should actually say. By writing "Born: " attr(data-birthdate), you are concatenating (joining) a static string of text with the dynamic value from your HTML.

<div class="person-card" data-birthdate="1995-10-15">
    <h2>Jane Doe</h2>
</div>

What the User Sees on the Screen:

Jane Doe

Born: 1995-10-15


  1. clamp() function
    A mathematical function used for values (like width, font-size, etc.), not for lines of text.
    Syntax:
    clamp(min, preferred, max)
    It restricts a value to be no less than min and no more than max.
    Example:
    font-size: clamp(1rem, 2vw, 2rem);
    This means the font size will never be smaller than 1rem or larger than 2rem, but will scale with 2vw in between.

  2. line-clamp property
    A property (and its vendor-prefixed version -webkit-line-clamp) used to limit the number of lines shown in a block of text.
    Example:
    line-clamp: 3;
    -webkit-line-clamp: 3;
    This will show only 3 lines of text and hide the rest (usually with ellipsis), but it requires additional properties like display: -webkit-box and -webkit-box-orient: vertical.