Hướng dẫn viết Theme WordPress toàn tập phần 2

Ở bài trước chúng ta đã setup mọi thứ và cũng xem qua Design luôn rồi. Hôm nay chúng ta sẽ bắt đầu viết theme WordPress và phần đầu tiên đó chính là Header và Banner của Design.

hướng dẫn viết theme wordpress chi tiết

Các hình ảnh-icons trong Design mình đã lấy toàn bộ và upload lên Drive các bạn có thể nhấn vào đây để tải về để sử dụng trong quá trình viết theme WordPress nhé.

# Setup cơ bản

Trước khi đi vào công việc chính thì các bạn cần cài một số Plugins sau để hỗ trợ cho việc viết theme WordPress nhé. Những plugins đó là Advanced Custom Fields, Custom Post Type UI, SVG Support.

Tiếp theo các bạn mở file style.css lên các bạn xóa hết code đi, chỉ để lại phần ghi chú thôi sau đó vào trang này copy đoạn code reset CSS rồi dán vào file style.css là được. Lúc này file style.css sẽ trông như thế này. Về reset CSS là gì các bạn có thể tìm hiểu nó tại đây nha.

/*!
Theme Name: Maker
Theme URI: http://underscores.me/
Author: Underscores.me
Author URI: http://underscores.me/
Description: Description
Version: 1.0.0
......
*/
/*reset css below*/
reset css paste here

Tiếp theo các bạn mở file functions.php lên và copy các dòng dưới đây dán vào dưới cùng. Những đoạn code này có chức năng cho phép chúng ta thêm class vào vào thẻ li, hay thẻ a trong Menu mà tí nữa chúng ta sẽ làm thông qua hàm wp_nav_menu.

/*Adding class to menu item - li tag */
function add_menu_list_item_class($classes, $item, $args) {
  if($args->list_item_class) {
      $classes[] = $args->list_item_class;
  }
  return $classes;
}
add_filter('nav_menu_css_class', 'add_menu_list_item_class', 1, 3);

/*Adding class to link menu item - a tag */
function add_menu_link_class( $atts, $item, $args ) {
  if($args->link_class) {
    $atts['class'] = $args->link_class;
  }
  return $atts;
}
add_filter( 'nav_menu_link_attributes', 'add_menu_link_class', 1, 3 );

Một lưu ý nữa là sau khi các bạn cài đặt xong các Plugins rồi thì đừng quên vào Admin Dashboard chọn Thư viện sau đó nhấn Tải Lên -> Chọn tập tin -> Chọn hết toàn bộ hình ảnh các bạn đã tải về khi nãy rồi upload lên thôi.

# Header

Như trong Design thì chúng ta thấy có một Logo bên trái và một Menu ở bên phải. Logo mặc định WordPress có cung cấp ở mục Tùy biến(Customize) nhưng làm sao để lấy nó ra và hiển thị ở vị trí mà ta mong muốn thì mình sẽ hướng dẫn sau. Còn Menu thì rất đơn giản, các bạn vào Dashboard -> Giao diện -> Menu

Các bạn sẽ thấy giao diện có một Menu có tên là Menu 1. Các bạn thêm các Item vào Menu này cho nó đủ bộ như Design luôn nhé, chọn Liên kết tự tạo rồi nhấn Thêm vào menu. Đừng quên tích Primary và nhấn Lưu menu nhé

Bây giờ các bạn mở file header.php lên sẽ thấy rất nhiều code phức tạp mà lúc chúng ta tải về nó đã có sẵn, các bạn xóa sạch từ khúc <div id="page" class="site"> trở xuống luôn nha sau đó các bạn dán vào đoạn code của mình dưới đây

<header class="header">
 <div class="container header__container">
  <?php 
    $custom_logo_id = get_theme_mod( 'custom_logo' );
    $image = wp_get_attachment_image_src( $custom_logo_id , 'full' );
  ?>
  <a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="logo">
   <img src="<?php echo $image[0];?>" alt="">
  </a>
 <?php
  wp_nav_menu( array(
   'theme_location'	=> 'menu-1',
   'container'		=> 'nav',
   'container_class'	=> 'menu',
   'menu_class'		=> 'menu__list',
   'link_class'        => 'menu__link',
   'list_item_class'   => 'menu__item'
  ) );
 ?>
 </div>
</header>

Đoạn code $custom_logo_id sẽ lấy ra ID của Logo mặc định của website mà mình đã nói khi nãy. Sau đó mình dùng hàm wp_get_attachment_image_src để lấy ra thông tin của hình logo đó thông qua ID của nó

Và $image sẽ trả về một mảng gồm nhiều thông tin và ở phần tử đầu tiên tức là 0 trong mảng là đường dẫn hình ảnh mà chúng ta cần mình cho nó vào thẻ img.

Đoạn esc_url( home_url( '/' ) ) nó sẽ in ra địa chỉ trang chủ của website chúng ta để khi người ta nhấn vào logo sẽ quay về trang chủ.

Hàm wp_nav_menu các bạn có thể tìm hiểu kỹ hơn tại đây. Chức năng của nó là lấy ra Menu mà chúng ta đã tạo. Khi các bạn tải từ Underscore về mặc định sẽ có một cái Menu tên là Menu 1 và có slug tương ứng là menu-1

Chỗ theme_location sẽ lấy ra menu theo id, slug hoặc tên mà chúng ta muốn, ở đây là Menu có slug là menu-1, container là thẻ nav bọc ngoài Menu, container_class là class của thẻ nav ở đây là menu nghĩa là lúc chạy code nó sẽ sinh ra <nav class="menu"....> như thế này

menu_class là class dành cho thẻ ul bên trong thẻ nav, riêng link_classlist_item_class thì mặc định không có nên chúng ta phải code thêm vào functions.php mà mình đã đề cập ở đoạn mình nói các bạn copy code vào dưới cùng file functions.php đấy.

Lúc này giao diện vẫn chưa có gì ngoài cái Menu gồm các links thô sơ mà chúng ta đã tạo và Logo chưa hiện ra do chúng ta chưa tùy biến. Tiếp theo đây chúng ta sẽ setup và bắt đầu code CSS cho nó đẹp ra nhé.

# style.css

Về phần CSS thì tạm thời mình sẽ dùng biến cho các mã màu để dễ dàng thay đổi và tùy chỉnh về sau. Lưu ý là biến trong CSS không hỗ trợ IE nếu sau này các bạn cần hỗ trợ cho IE thì vào thay thế biến bằng mã màu lại là được rồi.

Đơn vị mình sử dụng sẽ là REM và PX, Font Family của Design này là Lato cho nên mình sẽ lên Google Fonts lấy về rồi chèn vào thẻ head trong file header.php. Mình code chay không dùng thư viện gì cả.

Mình setup một số biến cho mã màu như chủ đạo, màu chữ cũng như là font-family cho website. Và mình thấy nội dung nằm ở giữa có độ rộng là 1185px được dùng đi dùng lại nhiều cho nên mình đặt một class có tên là .container để tái sử dụng.

/*************Main Styles **************/
:root {
 --first: #2583FD;
 --second: #07E1A2;
 --gray: #9299A6;
 --gray-dark: #2C3340;
 --gray-light: #AFB5C2;
}
html {
 font-size: 62.5%;
}
body {
 font-family: "Lato", sans-serif;
}
.container {
 max-width: 1185px;
 margin: 0 auto;
}
.header {
 background-color: white;
 padding-top: 1rem;
 padding-bottom: 1rem;
}
.header__container {
 display: flex;
 align-items: center;
 justify-content: space-between;
}
.menu__list {
 display: flex;
 align-items: center;
 font-size: 1.4rem;
}
.menu__item:not(:last-child) {
 margin-right: 1rem ;
}
.menu__link {
 display: block;
 padding: 1.5rem 2rem;
 color: var(--gray-dark);
 text-decoration: none;
 transition: color .2s linear;
}
.menu__link:hover {
 color: var(--first);
}
.menu__item:last-child .menu__link {
 border: 1px solid var(--gray);
 border-radius: 4px;
}

Tạm thời chúng ta được kết quả như hình

Ây chà chà cái logo vẫn chưa có. Đừng lo lắng, các bạn nhấn vào Giao diện -> Tùy biến -> chọn Nhận dạng Site  -> Chọn logo -> Tải tập tin lên -> Chọn file logo-dark -> Upload lên -> Sau đó nhấn chọn và Bỏ cắt -> Nhấn Đăng là xong.

Các bạn sẽ được kết quả như hình. Thế là chúng ta đã làm xong phần Menu. Tiếp theo dưới đây là phần phức tạp hơn một chút đó là Banner vì có kết hợp với một Plugin mà chúng ta đã cài từ lúc đầu đó chính là Advanced Custom Fields.

# Banner

Giao diện Banner nhìn vào thì dễ dàng ta thấy có những phần linh động thay đổi như một tấm hình bên phải, hình nền dưới lượn sóng dưới cùng, một tiêu đề nhỏ phía trên rồi đến một tiêu đề to, một đoạn text nhỏ dài và một cái hình App store kèm liên kết khi nhấn vào.

Ngoài ra còn có 2 hình tròn mờ nữa nhưng nó có thể làm bằng CSS nên chúng ta không cần phải tạo fields, đơn giản chỉ thêm hai class cho chúng mà thôi.

Như vậy tổng cộng có 7 chỗ có thể dễ dàng thay đổi như vậy chúng ta cần tạo một nhóm Fields dành cho Banner, và để tạo Custom Fields trong WordPress thì plugin hỗ trợ mạnh mẽ nhất đó chính là Advanced Custom Fields.

Trước khi đi vào việc tạo Custom Fields thì việc chúng ta cần làm trước đó là tạo một file tên là content-banner.php trong thư mục gốc để code cho phần Banner. Tiếp đến các bạn tạo một file tên là page-home.php rồi dán code dưới đây vào

<?php
/*
	Template Name: Home Page	
*/
get_header();
?>
<main>
  <?php get_template_part('content','banner'); ?>
</main>
<?php
get_footer();

Sau đó các bạn vào Dashboard chọn Trang -> Thêm trang mới với tên là Home. Ở phần Giao diện các bạn chọn là Home Page -> Đăng.

Rồi các bạn vào Cài đặt chọn Đọc và chỗ Trang chủ các bạn chọn Home(page vừa tạo ở trên) và nhấn Lưu thay đổi

Tiếp đến chúng ta chèn nội dung file content-banner vào file page-home.php bằng hàm get_template_part (đã có ở đoạn code trên). Sau đó các bạn mở file content-banner.php lên và tạm thời code HTML như sau:

<section class="banner">
<div class="container banner__container">
 <div class="banner__content">
  <span class="heading__small">Introducing maker</span>
  <h2 class="heading__">Simple yet powerful webflow template for your startup</h2>
  <p class="desc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium reprehenderit dolorum minus recusandae sapiente provident. Animi quaerat velit, mollitia nisi inventore voluptatum non ullam quibusdam ducimus iusto voluptatem incidunt nulla.</p>
  <a href="#" class="download__app-store">
    <img src="" alt="">
  </a>
 </div>
 <div class="banner__image">
  <img src="" alt="">
 </div>
 </div>
<div class="banner__circle banner__circle--small"></div>
<div class="banner__circle banner__circle--big"></div>
<div class="banner__waves"></div>
</section>

Trên đây chỉ là dữ liệu giả mình nhập sẵn mà thôi, nhưng chúng ta muốn nó linh động có thể dễ dàng thay đổi, cập nhật và lưu ở trong WordPress. Để làm điều đó chúng ta phải tạo Custom Fields.

# ACF

Để tạo Custom Fields các bạn chọn vào phần Custom Fields trong Dashboard sau đó chọn Add new để thêm mới, ở giao diện hiện ra các bạn điền vào tiêu đề Custom Fields ở đây mình để là Banner

Như đã phân tích ở trên tổng cộng chúng ta có 7 Fields bao gồm 4 Fields Text và 3 Fields Image. Để tạo Field Text, các bạn nhấn vào Add Field nó sẽ hiện ra như hình dưới đây. Các bạn điền vào như mình nhé.

Tương tự các bạn tạo thêm ba Fields khác với cấu trúc như hình trên nhưng Field Label khác là được, còn Field Name nó sẽ tự động lấy theo Field Label khi các bạn nhập vào. Các bạn làm giống như mình dưới đây

Còn Fields Image thì khác ở chỗ chúng ta sẽ chọn Field Type là Image và chọn kết quả trả về là Image Array

Tương tự các bạn tạo cho hai Fields cho hình còn lại như mình dưới đây nhé.

Tiếp đến là phần hiển thị những Custom Fields này ở trang nào, tất nhiên là trang Home rồi. Các bạn để ý phần Location, các bạn thiết lập theo như hình dưới đây nhá. Sau đó đừng quên nhấn nút Lưu phía trên bên phải nhé.

Sau đó các bạn quay về trang Home mà các bạn đã tạo khi nãy, các bạn sẽ thấy các Custom Fields nằm trong nhóm Banner mà chúng ta đã tạo như hình.

Thế là xong bước dùng ACF đơn giản, tiếp theo đây là cách làm sao để khi chúng ta cập nhật vào những Fields đó thì nó sẽ lưu lại và hiển thị ra bên ngoài.

# Cách lấy dữ liệu từ ACF

Để lấy dữ liệu từ ACF ra và hiển thị trong code thì chúng ta sẽ gọi chúng ra thông qua hàm get_field("tên field) mà ACF cung cấp, ở đây tên field là cái tên mà lúc chúng ta tạo trong ACF(Field Name chứ không phải Field Label nha các bạn)

Bây giờ mình sẽ áp dụng chúng vào trong file content-banner.php luôn nhé. Các bạn mở file content-banner.php lên và chèn đoạn code dưới đây vào trên cùng.

<?php
$banner_small_title = get_field('banner_small_title');
$banner_big_title = get_field('banner_big_title');
$banner_desc = get_field('banner_desc');
$banner_app_download_link = get_field('banner_app_download_link');
$banner_app_download = get_field('banner_app_download');
$banner_image = get_field('banner_image');
$banner_background_bottom = get_field('banner_background_bottom');
?>

Sau đó chúng ta chỉ việc gọi nó ra mà thôi. Ta có toàn bộ code ở file content-banner.php như sau:

<?php
$banner_small_title = get_field('banner_small_title');
$banner_big_title = get_field('banner_big_title');
$banner_desc = get_field('banner_desc');
$banner_app_download_link = get_field('banner_app_download_link');
$banner_app_download = get_field('banner_app_download');
$banner_image = get_field('banner_image');
$banner_background_bottom = get_field('banner_background_bottom');
?>
<section class="banner">
 <div class="container banner__container">
  <div class="banner__content">
   <span class="heading__small"><?php echo $banner_small_title ;?></span>
   <h2 class="heading__big"><?php echo $banner_big_title ;?></h2>
   <p class="desc"><?php echo $banner_desc ;?></p>
   <a href="<?php echo $banner_app_download_link ;?>" class="download__app-store">
     <img src="<?php echo $banner_app_download['url'] ;?>" alt="<?php echo $banner_app_download['alt'] ;?>">
   </a>
  </div>
  <div class="banner__image">
   <img src="<?php echo $banner_image['url'] ;?>" alt="<?php echo $banner_image['alt'] ;?>">
  </div>
 </div>
 <div class="banner__circle banner__circle--small"></div>
 <div class="banner__circle banner__circle--big"></div>
 <div class="banner__waves" style="background-image:url(<?php echo $banner_background_bottom['url'] ;?>);"></div>
</section>

Hiện tại chưa có gì vì chúng ta chưa thêm gì ở trang Home cả. Giờ mở trang Home lên sau đó tại Banner, các bạn nhập đại các thông tin vào thử xem. Mình nhập vào như này cho giống Design luôn

Tada. Chúng ta được kết quả như mong đợi nhé.

Nhưng mà chưa đẹp cho lắm vì chúng ta chưa CSS cho nó nhỉ. Và đây là đoạn CSS sẽ làm cho nó đẹp lên, các bạn có thể tham khảo của mình hoặc tự code nhé. Làm xong các bạn reload lại xem kết quả có đẹp không nhé.

.banner {
 background-image: linear-gradient(to right bottom, var(--first), var(--second));
 position: relative;
 padding-top: 8rem;
 overflow: hidden;
}

.banner__container {
 display: flex;
 align-items: center;
 justify-content: space-between;
 position: relative;
 z-index: 2;
}

.banner__content {
 max-width: 47rem;
 color: white;
}

.banner__image img {
 max-width: 42rem;
}

.banner__circle {
 position: absolute;
 border-style: solid;
 border-color: white;
 border-radius: 50%;
 opacity: 0.06;
}

.banner__circle--small {
 border-width: 8vh;
 width: 44vh;
 height: 44vh;
 top: 10rem;
 left: 8rem;
}

.banner__circle--big {
 border-width: 14vh;
 width: 110vh;
 height: 110vh;
 bottom: -50%;
 right: -5%;
}

.banner__waves {
 position: absolute;
 left: 0px;
 right: 0px;
 bottom: -1px;
 z-index: 3;
 height: 8vw;
 background-position: 50% 100%;
 background-size: cover;
 background-repeat: no-repeat;
}

.heading__small {
 margin-bottom: 1.5rem;
 font-size: 1.1rem;
 line-height: 1.6;
 font-weight: 700;
 letter-spacing: 2px;
 text-transform: uppercase;
 display: inline-block;
}

.banner__content .heading__small {
 color: rgba(255, 255, 255, 0.6);
}

.heading__big {
 margin-bottom: 1.6rem;
 font-size: 3rem;
 line-height: 1.4;
 font-weight: 700;
}

.banner__content .heading__big {
 font-size: 4.4rem;
}

.desc {
 margin-bottom: 2.5rem;
 font-size: 1.4rem;
 line-height: 1.6;
}

.download__app-store {
 display: inline-block;
 background-color: white;
 border-radius: 4px;
}

# Tạm kết

Phù!!! Thế là xong phần 2. Cũng sắp tết luôn rồi. Hướng dẫn viết Theme cực lắm các bạn ạ, lỡ phóng lao rồi phải theo lao thôi kaka. Code rất nhiều và tùy chỉnh cũng rất nhiều nên nhiều khi không biết viết sao cho các bạn dễ hiểu để làm được.Nhưng thôi cứ cố gắng, hi vọng được các bạn ủng hộ.

Chúc các bạn ăn tết vui vẻ và học tập tốt nhé. Có gì không hiểu hoặc thấy mình làm sai chỗ nào đó hay thắc mắc đừng quên bình luận góp ý giúp mình nha. Ngoài ra mình có upload source code lên Github, các bạn muốn tham khảo đối chiếu thì nhấn vào đây nhé..

Subscribe
Notify of
guest

12 Comments
Inline Feedbacks
View all comments
Nhaan
Nhaan

Đúng là viết theme cực thiệt. Đã viết còn khó rồi mà còn phải nói cho mọi người hiểu nữa !! Cảm ơn anh vì những bài viết ntn ủng hộ anh hoàn thành hết seri này <3 <3

Quan
Quan

Hóng phần kế tiếp, mong bạn sớm hoàn thiện!

Nguyễn Đình Tùng
Nguyễn Đình Tùng

Bạn ơi lâu rồi chưỉa thấy bạn làm tiếp part tiếp theo nhỉ? cố gắng hoàn thành đi. Hóng cả 2 tháng rồi 😀

Nguyễn Đình Tùng
Nguyễn Đình Tùng
Reply to  evondev

Phải nói mới chụi đăng hay sao ý :)) . Mà chủ thớt ở đâu cho thông tin theo sau học hành tí 😀 . Hehe

Phuong Linh
Phuong Linh

Sao mình dùng variable trong file css thì bị lỗi vậy bạn ơi.

Đức
Đức

Viết như này dễ hiểu rồi anh ạ. E code theo thấy oke lắm . Mong anh tiếp tục viết nhé.

Luong
Luong

Anh chưa ra thêm bài viết mới ạ