Pre requirements
- Web Design
- PHP
- OOP
- Mysql
Environment Setup
Part 1: Introduction to WordPress Theme Development
Essential tools: Code editor (VS Code, Sublime), Browser DevTools, etc.
Overview of WordPress theme structure and development workflow.
Setting up the local environment (XAMPP, MAMP, Local by Flywheel).
Basic theme folder
Basic Theme Folder and File Structure
Step 1: Create the Theme Folder
- Navigate to the WordPress installation directory on your local machine:
wp-content/themes/
Create a new folder named OleeHTMLWordPress.
wp-content/themes/OleeHTMLWordPress
Step 2: Create Essential Files
Inside the OleeHTMLWordPress folder, create the following essential theme files:
- style.css
This is the main stylesheet that provides basic information about your theme.
/*
Theme Name: OleeHTMLWordPress
Theme URI: https://example.com/oleehtmlwordpress
Author: Your Name
Author URI: https://example.com
Description: A professional WordPress theme built from scratch.
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: oleehtmlwordpress
Tags: responsive, custom-background, custom-header
*/
index.php
The main template file for displaying content.
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="https://gmpg.org/xfn/11">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<header>
<h1><?php bloginfo( 'name' ); ?></h1>
<p><?php bloginfo( 'description' ); ?></p>
</header>
<div id="content">
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title( '<h2>', '</h2>' );
the_content();
endwhile;
else :
echo '<p>No posts found.</p>';
endif;
?>
</div>
<footer>
<p>© <?php echo date('Y'); ?> <?php bloginfo( 'name' ); ?></p>
</footer>
<?php wp_footer(); ?>
</body>
</html>
functions.php
This file is used to add features and functions to your theme.
<?php
screenshot.png
Add a 1200×900 PNG image to represent your theme in the WordPress dashboard. Save it as screenshot.png.
after setup theme
add_theme_support( 'automatic-feed-links' );//এই ফাংশন টা ব্যবহার করলে আরএসএস ফিড লিনক এইচটিএমএল হেডে টাইটেলটা অটো যোগ হয়ে যাবে
add_theme_support( 'title-tag' );//এই ফাংশন যোগ করলে এইচটিএমএল হেডে টাইটেলটা অটো যোগ হয়ে যাবে
add_theme_support( 'post-thumbnails' );//এই ফাংশনটি যোগ করলে পোস্ট এডিটর পোস্ট থামনীলঅপশন এনাবল হবে
add_theme_support( 'html5', array( 'comment-form', 'comment-list', 'gallery', 'caption', ) );
add_theme_support( 'post-formats', array( 'aside', 'image', 'video', 'quote', 'link', 'gallery', 'audio', ) );//এই ফাংশনটি ব্যবহার মাধ্যমে পোস্ট ভিতরে কি কি ধরনের পোস্ট সাপোর্ট করবে তা দেখাবে
function themename_custom_logo_setup() {
$defaults = array(
'height' => 100,
'width' => 400,
'flex-height' => true,
'flex-width' => true,
'header-text' => array( 'site-title', 'site-description' ),
);
add_theme_support( 'custom-logo', $defaults );
add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'themename_custom_logo_setup' );PHPLink css js
// Enqueue stylesheets
function enqueue_theme_styles() {
// Enqueue Bootstrap CSS
wp_enqueue_style('bootstrap-css', get_template_directory_uri() . '/assets/css/bootstrap.min.css');
// Enqueue style.css
wp_enqueue_style('theme-style', get_stylesheet_uri());
}
// Hook into the 'wp_enqueue_scripts' action
add_action('wp_enqueue_scripts', 'enqueue_theme_styles');
// Enqueue scripts
function enqueue_theme_scripts() {
// Enqueue jQuery
wp_enqueue_script('jquery');
// Enqueue Bootstrap JavaScript
wp_enqueue_script('bootstrap-js', get_template_directory_uri() . '/assets/js/bootstrap.min.js', array('jquery'), null, true);
}
// Hook into the 'wp_enqueue_scripts' action
add_action('wp_enqueue_scripts', 'enqueue_theme_scripts');PHPwp_head(),wp_footer(),
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<!-- Meta -->
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta http-equiv="Content-Type" content="text/html; charset=<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="description" content="">
<meta name="author" content="">
<meta name="keywords" content="MediaCenter, Template, eCommerce">
<meta name="robots" content="all">
<title><?php bloginfo( 'name' ); ?> <?php wp_title( '|', true, 'left' ); ?></title>
<!-- Enqueue the main style.css file -->
<link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_directory_uri() . '/style.css' ); ?>">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_footer() ?>
</body>PHPtemplate break get_header()
<?php get_header( );?>
<?php get_sidebar();?>
<?php get_footer();?>PHPpost loop
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post(); ?>
<article class="flex flex-col shadow my-4">
<!-- Article Image -->
<a href="#" class="hover:opacity-75">
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('full', array('class' => 'object-cover w-full h-64')); ?>
<?php else : ?>
<!-- Default image or placeholder if no thumbnail is set -->
<img src="<?php echo get_template_directory_uri(); ?>/images/default-thumbnail.jpg" alt="Default Thumbnail" class="object-cover w-full h-64">
<?php endif; ?>
</a>
<div class="bg-white flex flex-col justify-start p-6">
<a href="#" class="text-blue-700 text-sm font-bold uppercase pb-4"><?php the_category(',', );?></a>
<a href="<?php the_permalink() ?>" class="text-3xl font-bold hover:text-gray-700 pb-4"><?php the_title() ?></a>
<p href="#" class="text-sm pb-3">
By <a href="#" class="font-semibold hover:text-gray-800"><?php the_author(); ?></a>, Published on <?php the_date(); ?>
</p>
<a href="<?php the_permalink(); ?>" class="pb-6"><?php echo wp_trim_words(get_the_content(), 25); ?></a>
<a href="<?php the_permalink(); ?>" class="uppercase text-gray-800 hover:text-black">Continue Reading <i class="fas fa-arrow-right"></i></a>
</div>
</article>
<?php endwhile;
else :
echo '<p>There are no posts!</p>';
endif;
?>
PHPpagination
<!-- Pagination -->
<div class="flex items-center py-8">
<?php
$pagination_args = array(
'prev_text' => 'Previous',
'next_text' => 'Next ',
'type' => 'array',
);
$pagination_links = paginate_links($pagination_args);
if ($pagination_links) {
foreach ($pagination_links as $link) {
echo '<a class="h-10 w-10 font-semibold text-gray-800 hover:text-gray-900 text-sm flex items-center justify-center"> ' . $link . '</a>';
}
}
?>
</div>PHPsingle page next prev post link with title
<!-- Previous and Next Post Links -->
<div class="w-full flex pt-6">
<?php $prev_post = get_previous_post(); ?>
<?php if ($prev_post) : ?>
<a href="<?php echo get_permalink($prev_post->ID); ?>" class="w-1/2 bg-white shadow hover:shadow-md text-left p-6">
<p class="text-lg text-blue-800 font-bold flex items-center"><i class="fas fa-arrow-left pr-1"></i> Previous</p>
<p class="pt-2"><?php echo esc_html($prev_post->post_title); ?></p>
</a>
<?php endif; ?>
<?php $next_post = get_next_post(); ?>
<?php if ($next_post) : ?>
<a href="<?php echo get_permalink($next_post->ID); ?>" class="w-1/2 bg-white shadow hover:shadow-md text-right p-6">
<p class="text-lg text-blue-800 font-bold flex items-center justify-end">Next <i class="fas fa-arrow-right pl-1"></i></p>
<p class="pt-2"><?php echo esc_html($next_post->post_title); ?></p>
</a>
<?php endif; ?>
</div>PHPpost thumbnail show
<!-- Article Image -->
<a href="#" class="hover:opacity-75">
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('full', array('class' => 'object-cover w-full h-64')); ?>
<?php else : ?>
<!-- Default image or placeholder if no thumbnail is set -->
<img src="<?php echo get_template_directory_uri(); ?>/images/default-thumbnail.jpg" alt="Default Thumbnail" class="object-cover w-full h-64">
<?php endif; ?>
</a>PHPsingle page.php
<?php
get_header(); // Include header.php
if (have_posts()) : // Check if there are posts
while (have_posts()) : the_post(); // Start the loop
// Display post title
the_title('<h1>', '</h1>');
// Display author name
echo '<p>Author: ' . get_the_author() . '</p>';
// Display post category
$categories = get_the_category();
if (!empty($categories)) {
echo '<p>Category: ' . esc_html($categories[0]->name) . '</p>';
}
// Display post tags
$tags = get_the_tags();
if (!empty($tags)) {
echo '<p>Tags: ';
foreach ($tags as $tag) {
echo '<a href="' . esc_url(get_tag_link($tag->term_id)) . '">' . esc_html($tag->name) . '</a> ';
}
echo '</p>';
}
// Display post publish date
echo '<p>Published: ' . get_the_date() . '</p>';
// Display post thumbnail
if (has_post_thumbnail()) {
the_post_thumbnail('full', array('class' => 'post-thumbnail'));
}
// Display post content
the_content();
endwhile; // End the loop
else :
// If no posts are found
echo '<p>No posts found</p>';
endif; // End if have_posts
get_footer(); // Include footer.php
?>
PHPpage.php
<?php
get_header(); // Include header.php
if (have_posts()) : while (have_posts()) : the_post(); // Start the loop
// Display page title
the_title('<h1>', '</h1>');
// Display author name
echo '<p>Author: ' . get_the_author() . '</p>';
// Display page content
the_content();
endwhile; // End the loop
endif; // End if have_posts
get_footer(); // Include footer.php
?>
PHPMenu
Step 1: Register a Menu Location
Open your theme’s functions.php file and register a menu location. Add the following code:
// functions.php
// bootstrap 5 wp_nav_menu walker
class bootstrap_5_wp_nav_menu_walker extends Walker_Nav_menu
{
private $current_item;
private $dropdown_menu_alignment_values = [
'dropdown-menu-start',
'dropdown-menu-end',
'dropdown-menu-sm-start',
'dropdown-menu-sm-end',
'dropdown-menu-md-start',
'dropdown-menu-md-end',
'dropdown-menu-lg-start',
'dropdown-menu-lg-end',
'dropdown-menu-xl-start',
'dropdown-menu-xl-end',
'dropdown-menu-xxl-start',
'dropdown-menu-xxl-end'
];
function start_lvl(&$output, $depth = 0, $args = null)
{
$dropdown_menu_class[] = '';
foreach($this->current_item->classes as $class) {
if(in_array($class, $this->dropdown_menu_alignment_values)) {
$dropdown_menu_class[] = $class;
}
}
$indent = str_repeat("\t", $depth);
$submenu = ($depth > 0) ? ' sub-menu' : '';
$output .= "\n$indent<ul class=\"dropdown-menu$submenu " . esc_attr(implode(" ",$dropdown_menu_class)) . " depth_$depth\">\n";
}
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
{
$this->current_item = $item;
$indent = ($depth) ? str_repeat("\t", $depth) : '';
$li_attributes = '';
$class_names = $value = '';
$classes = empty($item->classes) ? array() : (array) $item->classes;
$classes[] = ($args->walker->has_children) ? 'dropdown' : '';
$classes[] = 'nav-item';
$classes[] = 'nav-item-' . $item->ID;
if ($depth && $args->walker->has_children) {
$classes[] = 'dropdown-menu dropdown-menu-end';
}
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
$class_names = ' class="' . esc_attr($class_names) . '"';
$id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
$id = strlen($id) ? ' id="' . esc_attr($id) . '"' : '';
$output .= $indent . '<li ' . $id . $value . $class_names . $li_attributes . '>';
$attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
$attributes .= !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
$attributes .= !empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : '';
$attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : '';
$active_class = ($item->current || $item->current_item_ancestor || in_array("current_page_parent", $item->classes, true) || in_array("current-post-ancestor", $item->classes, true)) ? 'active' : '';
$nav_link_class = ( $depth > 0 ) ? 'dropdown-item ' : 'nav-link ';
$attributes .= ( $args->walker->has_children ) ? ' class="'. $nav_link_class . $active_class . ' dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"' : ' class="'. $nav_link_class . $active_class . '"';
$item_output = $args->before;
$item_output .= '<a' . $attributes . '>';
$item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
}
// Theme support
function my_theme_setup() {
// Register custom navigation menu
register_nav_menus(array(
'primary' => esc_html__('Primary Menu', 'my-theme'),
));
}
add_action('after_setup_theme', 'my_theme_setup');
PHPThis code registers a menu location named ‘Primary Menu’. You can add more locations as needed.
Step 2: Create a Simple Navigation Menu
Now, let’s create a simple navigation menu and display it in your theme. Open your theme’s template file (e.g., header.php) where you want to display the menu and add the following code:
// header.php
<nav class="navbar navbar-expand-lg navbar-light bg-white px-4 px-lg-5 py-3 py-lg-0">
<a href="index.html" class="navbar-brand p-0">
<h1 class="text-primary m-0"></h1>
<!-- <img src="img/logo.png" alt="Logo"> -->
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse">
<span class="fa fa-bars"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<?php
wp_nav_menu(array(
'theme_location' => 'primary',
'container' => false,
'menu_class' => '',
'fallback_cb' => '__return_false',
'items_wrap' => '<ul id="%1$s" class="navbar-nav me-auto mb-2 mb-md-0 %2$s">%3$s</ul>',
'depth' => 2,
'walker' => new bootstrap_5_wp_nav_menu_walker()
));
?>
</nav>
</div>
HTMLWidget
Step 1: Register a Widget Area in functions.php
Open your theme’s functions.php file and register a widget area. Widget areas are also known as sidebars. Add the following code:
// functions.php
function theme_register_widgets() {
register_sidebar(
array(
'name' => 'Primary Sidebar',
'id' => 'primary-sidebar',
'description' => 'Widgets added here will appear in the primary sidebar.',
'before_widget' => '<div id="%1$s" class="widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
}
add_action('widgets_init', 'theme_register_widgets');
BashThis code registers a widget area named ‘Primary Sidebar’. You can add more widget areas as needed.
Step 2: Display Widget Area in Theme Files
Now, let’s display the registered widget area in your theme files. Open the template file (e.g., sidebar.php or footer.php) where you want to display the widget area and add the following code:
// sidebar.php
<aside id="primary-sidebar" class="widget-area">
<?php dynamic_sidebar('primary-sidebar'); ?>
</aside>
BashThis code uses dynamic_sidebar() to display the widgets added to the ‘Primary Sidebar’ area.
Step 3: Create a Custom Widget
Let’s create a custom widget that displays a list of recent posts. Create a new file named custom-recent-posts-widget.php in your theme directory and add the following code:
// custom-recent-posts-widget.php
class Custom_Recent_Posts_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'custom_recent_posts_widget',
'Custom Recent Posts',
array('description' => 'Displays a list of recent posts.')
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
echo $args['before_title'] . 'Recent Posts' . $args['after_title'];
// Widget content here
$recent_posts = new WP_Query(array('posts_per_page' => 5));
if ($recent_posts->have_posts()) {
echo '<ul>';
while ($recent_posts->have_posts()) {
$recent_posts->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
} else {
echo 'No recent posts.';
}
wp_reset_postdata();
echo $args['after_widget'];
}
}
function register_custom_recent_posts_widget() {
register_widget('Custom_Recent_Posts_Widget');
}
add_action('widgets_init', 'register_custom_recent_posts_widget');
BashThis code creates a custom widget class (Custom_Recent_Posts_Widget) that displays a list of recent posts.
Step 4: Use the Custom Widget in the Admin Panel
Go to your WordPress admin panel, navigate to Appearance > Widgets. You should see your ‘Custom Recent Posts’ widget in the available widgets. Drag it to the ‘Primary Sidebar’ widget area and configure its settings.
Now, your custom widget should appear on the front end in the ‘Primary Sidebar’ area, displaying a list of recent posts.
This tutorial provides a foundation for working with widgets in WordPress, covering registration, display in theme files, and creating a custom widget. Feel free to customize and expand on these examples based on your specific needs.
Custom Post Type (Slider)
Step 1: Register a Custom Post Type
First, make sure you have a custom post type registered. If not, you can register a custom post type, let’s call it slider_item. Open your theme’s functions.php file and add the following code:
// functions.php
function register_slider_post_type() {
$labels = array(
'name' => 'Slider Items',
'singular_name' => 'Slider Item',
'menu_name' => 'Slider',
'add_new' => 'Add New',
'add_new_item' => 'Add New Slider Item',
'edit_item' => 'Edit Slider Item',
'new_item' => 'New Slider Item',
'view_item' => 'View Slider Item',
'search_items' => 'Search Slider Items',
'not_found' => 'No Slider Items found',
'not_found_in_trash' => 'No Slider Items found in Trash',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => false,
'menu_icon' => 'dashicons-images-alt',
'supports' => array('title', 'editor', 'thumbnail', 'page-attributes'),
);
register_post_type('slider_item', $args);
}
add_action('init', 'register_slider_post_type');
BashStep 2: Create Slider Template File
Create a file named slider-template.php in your theme directory. This file will be responsible for displaying the slider. Add the following code:
<?php
$slider_items = new WP_Query(array(
'post_type' => 'slider_item',
'posts_per_page' => -1,
));
if ($slider_items->have_posts()) :
?>
<div class="slider-container">
<div class="slider">
<?php while ($slider_items->have_posts()) : $slider_items->the_post(); ?>
<div class="slide">
<?php the_post_thumbnail('large'); ?>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</div>
<?php endwhile; ?>
</div>
</div>
<?php
wp_reset_postdata();
endif;
?>
BashStep 3: Include Slider in Theme
Now, you can include this slider template in your theme where you want the slider to appear. Open the desired template file (e.g., index.php, header.php, etc.) and add the following code where you want the slider:
<?php get_template_part('slider', 'template'); ?>
BashStep 4: Style Your Slider
Style your slider by adding CSS rules to your theme’s stylesheet (usually style.css). Here’s a simple example:
/* style.css */
.slider-container {
width: 100%;
overflow: hidden;
}
.slider {
display: flex;
transition: transform 0.5s ease-in-out;
}
.slide {
width: 100%;
flex-shrink: 0;
}
.slide img {
width: 100%;
height: auto;
}
BashStep 5: Implement Slider JavaScript
For the slider to work, you may need to include a JavaScript library like Slick or Owl Carousel, or you can use the native JavaScript or jQuery. Add the necessary scripts and initialize the slider in your theme.
For example, using the Slick slider library:
<!-- Add this to your theme's footer or where you load scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<script>
jQuery(document).ready(function ($) {
$('.slider').slick({
// Customize your slick slider options here
autoplay: true,
dots: true,
arrows: false,
});
});
</script>
JavaScriptCustom Post Type
// Enable support for post thumbnails
add_theme_support('post-thumbnails');
// Register Custom Post Type
function custom_post_type() {
$labels = array(
'name' => _x('Custom Post Type', 'Post Type General Name', 'text_domain'),
'singular_name' => _x('Custom Post', 'Post Type Singular Name', 'text_domain'),
'menu_name' => __('Custom Post', 'text_domain'),
'name_admin_bar' => __('Custom Post', 'text_domain'),
'archives' => __('Item Archives', 'text_domain'),
'attributes' => __('Item Attributes', 'text_domain'),
'parent_item_colon' => __('Parent Item:', 'text_domain'),
'all_items' => __('All Items', 'text_domain'),
'add_new_item' => __('Add New Item', 'text_domain'),
'add_new' => __('Add New', 'text_domain'),
'new_item' => __('New Item', 'text_domain'),
'edit_item' => __('Edit Item', 'text_domain'),
'update_item' => __('Update Item', 'text_domain'),
'view_item' => __('View Item', 'text_domain'),
'view_items' => __('View Items', 'text_domain'),
'search_items' => __('Search Item', 'text_domain'),
'not_found' => __('Not found', 'text_domain'),
'not_found_in_trash' => __('Not found in Trash', 'text_domain'),
'featured_image' => __('Featured Image', 'text_domain'),
'set_featured_image' => __('Set featured image', 'text_domain'),
'remove_featured_image' => __('Remove featured image', 'text_domain'),
'use_featured_image' => __('Use as featured image', 'text_domain'),
'insert_into_item' => __('Insert into item', 'text_domain'),
'uploaded_to_this_item' => __('Uploaded to this item', 'text_domain'),
'items_list' => __('Items list', 'text_domain'),
'items_list_navigation' => __('Items list navigation', 'text_domain'),
'filter_items_list' => __('Filter items list', 'text_domain'),
);
$args = array(
'label' => __('Custom Post Type', 'text_domain'),
'description' => __('Custom Post Type Description', 'text_domain'),
'labels' => $labels,
'supports' => array('title', 'editor', 'thumbnail', 'custom-fields'),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
);
register_post_type('custom_post_type', $args);
}
add_action('init', 'custom_post_type', 0);
PHPSilk Slider
// funstions.php
function enqueue_slick_slider() {
// Slick CSS
wp_enqueue_style('slick-css', 'https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css');
// Slick Theme CSS
wp_enqueue_style('slick-theme-css', 'https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick-theme.css');
// jQuery (Slick Slider requires jQuery)
wp_enqueue_script('jquery');
// Slick JS
wp_enqueue_script('slick-js', 'https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js', array('jquery'), null, true);
// Your custom script to initialize the slider
wp_enqueue_script('slick-init', get_template_directory_uri() . '/js/slick-init.js', array('slick-js'), null, true);
}
add_action('wp_enqueue_scripts', 'enqueue_slick_slider');
function create_slider_post_type() {
register_post_type('slider',
array(
'labels' => array(
'name' => __('Sliders'),
'singular_name' => __('Slider')
),
'public' => true,
'has_archive' => false,
'supports' => array( 'title', 'editor', 'thumbnail', 'custom-fields', 'author', 'excerpt', 'comments', 'revisions', 'page-attributes' ),
'rewrite' => array('slug' => 'sliders'),
'show_in_rest' => true // Enable Gutenberg editor and REST API support
)
);
}
add_action('init', 'create_slider_post_type');JavaScriptjQuery(document).ready(function($) {
$('.projects-slider').slick({
dots: true,
infinite: true,
speed: 300,
slidesToShow: 1,
adaptiveHeight: true,
autoplay: true, // Enable autoplay
autoplaySpeed: 2000, // Set the autoplay interval (2000ms = 2s)
});
});
function openTab(evt, tabName) {
var tabcontent, tablinks, targetTabContent;
tabcontent = document.getElementsByClassName("tab-content");
tablinks = document.getElementsByTagName("button");
targetTabContent = document.getElementById(tabName);
// If the tab is already open and is clicked again, hide it.
if (targetTabContent.style.display === "block") {
targetTabContent.style.display = "none";
evt.currentTarget.className = evt.currentTarget.className.replace("text-blue-600 border-blue-600", "text-gray-600 border-transparent");
return;
}
// Hide all other tabs and remove active class
for (let i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
for (let i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace("text-blue-600 border-blue-600", "text-gray-600 border-transparent");
}
// Show the clicked tab and add active class
targetTabContent.style.display = "block";
evt.currentTarget.className += " text-blue-600 border-blue-600";
}
JavaScript<div class="relative">
<?php
$args = array(
'post_type' => 'slider', // Make sure this matches the post type key
'posts_per_page' => -1 // Fetch all posts
);
$projects = new WP_Query($args);
if ($projects->have_posts()) :
?>
<div class="projects-slider">
<?php while ($projects->have_posts()) : $projects->the_post(); ?>
<div>
<?php if (has_post_thumbnail()) : ?>
<img src="<?php the_post_thumbnail_url(); ?>" alt="<?php the_title(); ?>">
<?php endif; ?>
<h2><?php the_title(); ?></h2>
</div>
<?php endwhile; ?>
</div>
<?php
endif;
wp_reset_postdata();
?>
</div>
JavaScriptRedux Framework
Download Plugin and copy theme folder
create a file theme-options.php
<?php
if ( !class_exists( 'Redux' ) ) {
return;
}
// Set the opt_name argument to a unique identifier for your theme options.
$opt_name = "olee";
$theme_options = array(
'opt_name' => $opt_name,
'dev_mode' => false,
'use_cdn' => true,
'display_name' => 'Theme Options',
'display_version' => '1.0.0',
// Add more settings fields as needed
);
Redux::setArgs( $opt_name, $theme_options );
Redux::setSection( $opt_name, array(
'title' => __('Basic Settings', 'your-textdomain'),
'id' => 'basic',
'desc' => __('Basic settings for our theme.', 'your-textdomain'),
'icon' => 'el el-home',
'fields' => array(
array(
'id' => 'text-logo-url',
'type' => 'text',
'title' => __('Site Logo URL', 'your-textdomain'),
'desc' => __('Enter the URL of your site logo.', 'your-textdomain'),
'default' => 'Default Text'
),
array(
'id' => 'media-logo',
'type' => 'media',
'title' => __('Upload Logo', 'your-textdomain'),
'desc' => __('Upload or select a media item to be used as the site logo.', 'your-textdomain'),
'subtitle' => __('Upload using the native media uploader, or define the URL directly', 'your-textdomain'),
'url' => true,
'default' => array(
'url' => 'path_to_your_default_logo_if_any'
)
),
array(
'id' => 'opt-color-primary',
'type' => 'color',
'title' => __('Primary Color', 'your-textdomain'),
'subtitle' => __('Pick a primary color for the theme (default: #3173c7).', 'your-textdomain'),
'default' => '#3173c7',
'transparent' => false,
),
array(
'id' => 'site-description',
'type' => 'textarea',
'title' => __('Site Description', 'your-textdomain'),
'subtitle' => __('Enter a brief description of your site.', 'your-textdomain'),
'desc' => __('This will be used in the meta description tag.', 'your-textdomain'),
'default' => 'This is a description for your site.'
),
array(
'id' => 'background-body',
'type' => 'background',
'title' => __('Body Background', 'your-textdomain'),
'subtitle' => __('Pick a background color or image for the body.', 'your-textdomain'),
'default' => array(
'background-color' => '#FFFFFF',
'background-image' => 'path_to_your_default_background_image_if_any',
'background-position' => 'center center',
'background-size' => 'cover',
'background-repeat' => 'no-repeat'
)
),
// Add more fields as needed
)
));
// Adding Slides Options Section
Redux::setSection( $opt_name, array(
'title' => __('Slides Options', 'your-textdomain'),
'id' => 'slides_options',
'desc' => __('Manage slides for your theme.', 'your-textdomain'),
'icon' => 'el el-picture',
'fields' => array(
array(
'id' => 'opt-slides',
'type' => 'slides',
'title' => esc_html__('Slides Options', 'your-textdomain'),
'subtitle' => esc_html__('Unlimited slides with drag and drop sortings.', 'your-textdomain'),
'desc' => esc_html__('This field will store all slides values into a multidimensional array to use into a foreach loop.', 'your-textdomain'),
'placeholder' => array(
'title' => esc_html__('This is a title', 'your-textdomain'),
'description' => esc_html__('Description Here', 'your-textdomain'),
'url' => esc_html__('Give us a link!', 'your-textdomain'),
)
)
)
));
Redux::setSection($opt_name, array(
'title' => __('Social Media Icons', 'your-textdomain'),
'id' => 'social_media_icons',
'desc' => __('Upload custom social media icons and add their links.', 'your-textdomain'),
'icon' => 'el el-globe',
'fields' => array(
array(
'id' => 'social_icons',
'type' => 'repeater',
'title' => __('Social Icons', 'your-textdomain'),
'bind_title' => 'title', // Bind title to display field
'fields' => array(
array(
'id' => 'title',
'type' => 'text',
'title' => __('Social Network Name', 'your-textdomain'),
'default' => 'Facebook'
),
array(
'id' => 'icon_image',
'type' => 'media',
'title' => __('Social Icon', 'your-textdomain'),
'subtitle' => __('Upload a custom icon.', 'your-textdomain'),
'desc' => __('Recommended size: 32x32 pixels.', 'your-textdomain'),
'default' => array('url' => 'path_to_default_icon_if_any'),
'url' => true
),
array(
'id' => 'link',
'type' => 'text',
'title' => __('Social Link', 'your-textdomain'),
'default' => 'http://'
),
)
),
)
));
// Fetch the Redux options
// $redux_options = get_option('your_theme_options');
// $social_icons = isset($redux_options['social_icons']) ? $redux_options['social_icons'] : [];
// // HTML for displaying custom social icons
// echo '<ul class="custom-social-icons">';
// foreach ($social_icons as $icon) {
// if (!empty($icon['icon_image']['url']) && !empty($icon['link'])) {
// echo '<li><a href="' . esc_url($icon['link']) . '" target="_blank" rel="noopener noreferrer">';
// echo '<img src="' . esc_url($icon['icon_image']['url']) . '" alt="' . esc_attr($icon['title']) . '" style="width: 32px; height: 32px;">';
// echo '</a></li>';
// }
// }
// echo '</ul>';
JavaScriptinclude in functions.php
if ( !class_exists( 'ReduxFramework' ) && file_exists( dirname( __FILE__ ) . '/redux-framework/redux-core/framework.php' ) ) {
require_once( dirname( __FILE__ ) . '/redux-framework/redux-core/framework.php' );
}
include get_template_directory() . '/inc/theme-options.php';JavaScriptHow To get Slider
<?php
$redux_options = get_option('olee'); // Replace 'your_theme_options' with your actual opt_name.
$slides = isset($redux_options['opt-slides']) ? $redux_options['opt-slides'] : [];
if (!empty($slides)) {
echo '<div class="slider">'; // Start of your slider container
foreach ($slides as $slide) {
echo '<div class="slide">'; // Start of a single slide
if (!empty($slide['image'])) {
echo '<img src="' . esc_url($slide['image']) . '" alt="' . esc_attr($slide['title']) . '">'; // Slide image
}
if (!empty($slide['title'])) {
echo '<h3>' . esc_html($slide['title']) . '</h3>'; // Slide title
}
if (!empty($slide['description'])) {
echo '<p>' . esc_html($slide['description']) . '</p>'; // Slide description
}
echo '</div>'; // End of a single slide
}
echo '</div>'; // End of your slider container
}
?>JavaScriptPortfolio Tabs
<div class="p-5">
<ul id="portfolio-tabs" class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="all-tab" data-toggle="tab" href="#all" role="tab" aria-controls="all" aria-selected="true">All</a>
</li>
<?php
$terms = get_terms('portfolio_category');
if ($terms) :
foreach ($terms as $index => $term) :
?>
<li class="nav-item">
<a class="nav-link" id="<?php echo esc_attr($term->slug); ?>-tab" data-toggle="tab" href="#<?php echo esc_attr($term->slug); ?>" role="tab" aria-controls="<?php echo esc_attr($term->slug); ?>" aria-selected="false"><?php echo esc_html($term->name); ?></a>
</li>
<?php
endforeach;
endif;
?>
</ul>
<div class="tab-content mt-3">
<div class="tab-pane fade show active" id="all" role="tabpanel" aria-labelledby="all-tab">
<div class="row">
<?php
$portfolio_query = new WP_Query(array(
'post_type' => 'portfolio',
'posts_per_page' => -1,
));
if ($portfolio_query->have_posts()) :
while ($portfolio_query->have_posts()) :
$portfolio_query->the_post();
?>
<div class="col-lg-4 col-md-6 mb-4">
<div class="portfolio-item">
<?php if (has_post_thumbnail()) : ?>
<div class="portfolio-thumbnail">
<?php the_post_thumbnail('medium', array('class' => 'img-fluid')); ?>
</div>
<?php endif; ?>
<h2><?php the_title(); ?></h2>
<div class="portfolio-content">
<?php the_content(); ?>
</div>
</div>
</div>
<?php
endwhile;
wp_reset_postdata();
else :
echo '<p>No portfolio items found.</p>';
endif;
?>
</div>
</div>
<?php
if ($terms) :
foreach ($terms as $index => $term) :
?>
<div class="tab-pane fade" id="<?php echo esc_attr($term->slug); ?>" role="tabpanel" aria-labelledby="<?php echo esc_attr($term->slug); ?>-tab">
<div class="row">
<?php
$portfolio_query = new WP_Query(array(
'post_type' => 'portfolio',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'portfolio_category',
'field' => 'slug',
'terms' => $term->slug,
),
),
));
if ($portfolio_query->have_posts()) :
while ($portfolio_query->have_posts()) :
$portfolio_query->the_post();
?>
<div class="col-lg-4 col-md-6 mb-4">
<div class="portfolio-item">
<?php if (has_post_thumbnail()) : ?>
<div class="portfolio-thumbnail">
<?php the_post_thumbnail('medium', array('class' => 'img-fluid')); ?>
</div>
<?php endif; ?>
<h2><?php the_title(); ?></h2>
<div class="portfolio-content">
<?php the_content(); ?>
</div>
</div>
</div>
<?php
endwhile;
wp_reset_postdata();
else :
echo '<p>No portfolio items found for this category.</p>';
endif;
?>
</div>
</div>
<?php
endforeach;
endif;
?>
</div>
</div>JavaScriptjQuery(document).ready(function($) {
$('#portfolio-tabs a').click(function() {
// Remove active class from all tabs
$('#portfolio-tabs li').removeClass('active');
// Add active class to the clicked tab
$(this).parent().addClass('active');
// Display corresponding tab content
let currentTab = $(this).attr('href');
$('.tab-content .tab-pane').removeClass('show active');
$(currentTab).addClass('show active');
return false;
});
});
JavaScriptfunction custom_portfolio_post_type() {
$args = array(
'labels' => array(
'name' => __('Portfolio'),
'singular_name' => __('Portfolio Item'),
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'thumbnail', 'custom-fields', 'author', 'excerpt', 'comments', 'revisions', 'page-attributes'),
'show_in_rest' => true, // This enables REST API support
'rest_base' => 'portfolio', // Custom REST API endpoint
);
register_post_type('portfolio', $args);
}
add_action('init', 'custom_portfolio_post_type');
function custom_portfolio_taxonomy() {
$args = array(
'labels' => array(
'name' => __('Portfolio Categories'),
'singular_name' => __('Portfolio Category'),
),
'public' => true,
'hierarchical' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => false,
'show_in_rest' => true, // Enable REST API support
'rest_base' => 'portfolio_categories', // Customize the REST API base
);
register_taxonomy('portfolio_category', 'portfolio', $args);
}
add_action('init', 'custom_portfolio_taxonomy');
function my_flush_rewrite_rules() {
flush_rewrite_rules();
}
add_action('after_switch_theme', 'my_flush_rewrite_rules');JavaScriptcustom login and registration templates
Step 1: Create Template Files
- Create
page-login.phpandpage-register.phpfiles:- In your theme’s directory, create two new files:
page-login.phpandpage-register.php. - These files will contain the HTML and PHP code for the custom login and registration forms.
- In your theme’s directory, create two new files:
- Template for
page-login.php:
<?php
/* Template Name: Custom Login */
get_header(); ?>
<div class="custom-login-form">
<h2>Login</h2>
<form id="loginform" action="<?php echo wp_login_url(); ?>" method="post">
<p>
<label for="user_login">Username or Email</label>
<input type="text" name="log" id="user_login" class="input" value="" size="20" />
</p>
<p>
<label for="user_pass">Password</label>
<input type="password" name="pwd" id="user_pass" class="input" value="" size="20" />
</p>
<p class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary" value="Log In" />
<input type="hidden" name="redirect_to" value="<?php echo home_url(); ?>" />
</p>
</form>
</div>
<?php get_footer(); ?>
PHPTemplate for page-register.php:
<?php
/* Template Name: Custom Register */
get_header(); ?>
<div class="custom-register-form">
<h2>Register</h2>
<form id="registerform" action="<?php echo wp_registration_url(); ?>" method="post">
<p>
<label for="user_login">Username</label>
<input type="text" name="user_login" id="user_login" class="input" value="" size="20" />
</p>
<p>
<label for="user_email">Email</label>
<input type="email" name="user_email" id="user_email" class="input" value="" size="20" />
</p>
<p class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary" value="Register" />
</p>
</form>
</div>
<?php get_footer(); ?>
PHPStep 2: Add Pages in WordPress
- Create Pages for Login and Registration:
- Go to the WordPress dashboard.
- Navigate to Pages > Add New.
- Create a page named “Login” and select the “Custom Login” template from the Page Attributes section.
- Create another page named “Register” and select the “Custom Register” template from the Page Attributes section.
Step 3: Handle Form Submission and User Registration
To handle user registration, we need to add custom code in the functions.php file of your theme.
- Handle User Registration:
function custom_user_registration() {
if (isset($_POST['wp-submit']) && $_POST['wp-submit'] == 'Register') {
$username = sanitize_user($_POST['user_login']);
$email = sanitize_email($_POST['user_email']);
$errors = new WP_Error();
if (username_exists($username)) {
$errors->add('username_exists', 'This username is already taken.');
}
if (!is_email($email)) {
$errors->add('email_invalid', 'Invalid email address.');
}
if (email_exists($email)) {
$errors->add('email_exists', 'This email is already registered.');
}
if (empty($errors->errors)) {
$password = wp_generate_password();
$user_id = wp_create_user($username, $password, $email);
if (!is_wp_error($user_id)) {
wp_new_user_notification($user_id, null, 'user');
wp_redirect(home_url('login?registration=successful'));
exit;
}
} else {
foreach ($errors->get_error_messages() as $error) {
echo '<div class="error">' . $error . '</div>';
}
}
}
}
add_action('template_redirect', 'custom_user_registration');
PHP- Handle User Login:
- The login form already posts to the WordPress login handler (
wp-login.php), so you don’t need additional code for handling login unless you want to customize the behavior further.
- The login form already posts to the WordPress login handler (
Step 4: Enqueue Styles (Optional)
If you want to style your forms, enqueue a custom CSS file in your theme.
- Add Custom Styles:
- Create a CSS file (e.g.,
custom-login.css) in your theme’s directory and add your styles.
- Create a CSS file (e.g.,
- Enqueue the CSS File:
function enqueue_custom_login_styles() {
wp_enqueue_style('custom-login', get_template_directory_uri() . '/custom-login.css');
}
add_action('wp_enqueue_scripts', 'enqueue_custom_login_styles');
PHPStep 5: Customize Messages and Redirection (Optional)
- Custom Login Message:
function custom_login_message() {
if (isset($_GET['registration']) && $_GET['registration'] == 'successful') {
return '<p class="message">Registration successful. Please check your email for the password.</p>';
}
return '';
}
add_filter('login_message', 'custom_login_message');
PHPCustom Redirection After Login:
function custom_login_redirect($redirect_to, $request, $user) {
// Is there a user to check?
if (isset($user->roles) && is_array($user->roles)) {
// Check for admins
if (in_array('administrator', $user->roles)) {
//Redirect them to the default place
return home_url('/wp-admin/');
} else {
return home_url();
}
} else {
return $redirect_to;
}
}
add_filter('login_redirect', 'custom_login_redirect', 10, 3);
PHPContact Form 7
step-by-step guide to installing Contact Form 7 on your WordPress site and using it with the provided structure.
Step 1: Install Contact Form 7
- Log in to your WordPress Admin Dashboard.
- Navigate to Plugins > Add New.
- Search for “Contact Form 7” in the search bar.
- Click the “Install Now” button next to the Contact Form 7 plugin.
- After the installation is complete, click “Activate”.
Step 2: Create a New Contact Form
- Go to Contact > Add New.
- Give your form a title (e.g., “Contact Us”).
- Replace the default form template with your customized form structure:
<div class="form-group">
<label for="your-name">Your name</label>
[text* your-name id:your-name class:form-control autocomplete:name]
</div>
<div class="form-group">
<label for="your-email">Your email</label>
[email* your-email id:your-email class:form-control autocomplete:email]
</div>
<div class="form-group">
<label for="your-subject">Subject</label>
[text* your-subject id:your-subject class:form-control]
</div>
<div class="form-group">
<label for="your-message">Your message (optional)</label>
[textarea your-message id:your-message class:form-control]
</div>
<div class="form-group">
[submit "Submit" class:btn class:btn-primary]
</div>
HTML- Click “Save” to save your form.
Step 3: Embed the Contact Form in a Page or Post
- After saving, you will see a shortcode at the top of the form editor screen. It looks something like this:
[contact-form-7 id="1234" title="Contact Us"]. Copy this shortcode. - Go to Pages > Add New (or Posts > Add New) to create a new page or post, or edit an existing one.
- Paste the shortcode into the content area where you want the form to appear.
- Click “Publish” (or “Update” if editing an existing page/post) to save your changes.
Step 4: Ensure Bootstrap CSS is Loaded
To style your form with Bootstrap, ensure that Bootstrap CSS is included in your WordPress theme. Here’s how to do it:
- Open your theme’s
functions.phpfile. - Add the following code to enqueue Bootstrap CSS:
function enqueue_bootstrap() {
wp_enqueue_style('bootstrap-css', 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css');
}
add_action('wp_enqueue_scripts', 'enqueue_bootstrap');
PHP- Save the
functions.phpfile.
Step 5: Verify the Form
- Visit the page or post where you embedded the contact form.
- Ensure that the form fields and submit button are styled with Bootstrap classes.
Comment form and list