Chuyển HTML sang WordPress: Hướng Dẫn Chi Tiết từ TVD Media

Chào mừng bạn đến với hướng dẫn chi tiết về cách chuyển đổi một giao diện HTML tĩnh thành một theme WordPress động, được cung cấp bởi các chuyên gia tại TVD Media (tvdmedia.vn). Chúng tôi, TVD Media, là đơn vị chuyên cung cấp các dịch vụ thiết kế website, SEO website, chạy quảng cáo Google Ads, Facebook Ads, Tiktok Ads, Zalo Ads, và các dịch vụ marketing online khác. Bài viết này được xây dựng dựa trên kinh nghiệm thực tế và kiến thức chuyên sâu của đội ngũ TVD Media, đảm bảo tính chuyên môn, thẩm quyền và độ tin cậy cao nhất. Nếu bạn cần hỗ trợ, hãy liên hệ với TVD Media qua số điện thoại: +84966779629.

Hướng dẫn chuyển giao diện HTML thành themes WordPress

1) Chuẩn bị

1.1. Chuẩn bị giao diện HTML tĩnh

Trước khi bắt đầu, bạn cần có một giao diện HTML, CSS và JavaScript tĩnh. Nếu bạn chưa có, bạn có thể "clone" giao diện từ một website khác. TVD Media khuyến cáo rằng bạn nên sử dụng giao diện do chính mình tạo ra hoặc có giấy phép sử dụng hợp lệ.

Để "clone" giao diện (chỉ nên dùng cho mục đích học tập và tham khảo), bạn có thể chuột phải vào trang web bạn muốn lấy giao diện, chọn "Save as…" và lưu lại. Bạn sẽ có các file HTML, CSS, JS và hình ảnh.

1.2. Tạo Theme WordPress Mới

TVD Media khuyên bạn nên sử dụng Underscores.me để tạo một theme WordPress "trống" ban đầu. Underscores.me cung cấp một bộ khung theme tối giản, tuân thủ các tiêu chuẩn của WordPress, giúp bạn tiết kiệm thời gian và công sức.

Truy cập Underscores.me, nhập tên theme bạn muốn và nhấn "Generate". Tải theme về máy tính.

Giao diện underscores.me

Cài đặt theme này vào website WordPress của bạn thông qua giao diện quản trị.

Cài đặt theme WordPress

1.3. Chuyển Resources vào Theme

Copy toàn bộ các file CSS, JS, hình ảnh từ thư mục giao diện HTML tĩnh của bạn vào thư mục theme WordPress. Đường dẫn tới thư mục theme WordPress là:

<<folder chứa source code>>/wp-content/themes/<<tên themes>>

1.4. Cấu trúc Theme WordPress Cơ Bản

TVD Media sẽ tập trung vào các thành phần chính để tạo một website tin tức đơn giản. Dưới đây là bảng mô tả các file quan trọng và chức năng của chúng:

STT Thành phần Nội dung File
1 Header Phần đầu của website, chứa menu điều hướng và logo. header.php
2 Footer Phần cuối của website, chứa thông tin liên hệ, bản quyền, v.v. footer.php
3 Pages Các trang tĩnh riêng biệt như "Giới thiệu", "Liên hệ". Tạo file template riêng cho từng trang. [tên-trang].php (ví dụ: about-us.php)
4 Blog (Danh sách Category) Hiển thị danh sách tất cả các category của website. blog.php (tạo từ bản sao của index.php)
5 Category (Single Category) Hiển thị danh sách bài viết thuộc một category cụ thể. archive.php
6 Single Post Hiển thị nội dung chi tiết của một bài viết. single.php

Cấu trúc này chỉ là cơ bản. Để tìm hiểu sâu hơn, bạn nên tham khảo tài liệu chính thức của WordPress. TVD Media sẽ hướng dẫn bạn từng bước để tùy chỉnh các thành phần này.

Cấu trúc themes WordPress

1.5. Plugin Hỗ Trợ

TVD Media đề xuất sử dụng các plugin sau để đơn giản hóa quá trình phát triển theme:

STT Plugin Công dụng Link
1 ACF Advanced Custom Fields Pro Tạo các trường tùy chỉnh (custom fields) để dễ dàng thay đổi nội dung trên các trang và bài viết. Link
2 CPT Custom Post Type UI Tạo các loại bài viết và category tùy chỉnh, tách biệt với các loại bài viết mặc định của WordPress. Link

Thêm đoạn code sau vào cuối file `functions.php` để thêm một tab cài đặt theme (nếu bạn sử dụng plugin Polylang cho website đa ngôn ngữ):

add_action('acf/init', 'my_acf_op_init');function my_acf_op_init(){    // Check function exists.    if (function_exists('acf_add_options_page')) {        // Register options page, each language (polylang) will have one setting tabs.        foreach (pll_languages_list($args) as $lang) {            acf_add_options_page(array(                'page_title'    => "Theme Settings (" . strtoupper($lang) . ")",                'menu_title'    => "Theme Settings (" . strtoupper($lang) . ")",                'menu_slug'     => "theme-${lang}-settings",                'post_id'       => $lang            ));        }    }}
Giao diện ACF Options Page

2) Tích Hợp Giao Diện HTML và Custom Fields

2.1. Header

Copy toàn bộ code HTML của header từ file HTML tĩnh vào file `header.php` của theme WordPress.

Thay đổi đường dẫn tới các file resources (hình ảnh, font, CSS, JS) thành `<?php bloginfo('stylesheet_directory') ?>/[đường dẫn-tới-file]`. Ví dụ:

<link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_directory') ?>/css/style.css">

Ví dụ đầy đủ:

<?php/** * The header for our theme */add_filter('body_class', 'custom_class');?><!doctype html><html <?php language_attributes(); ?>><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">    <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">    <link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_directory') ?>/css/slick-theme.css">    <link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_directory') ?>/css/animate.css">    <link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_directory') ?>/css/bootstrap-select.min.css">    <link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_directory') ?>/css/bootstrap.min.css">    <?php wp_head(); ?></head><?php$menu_name = 'menu-1';$locations = get_nav_menu_locations();$menu = wp_get_nav_menu_object($locations[$menu_name]);$menu_items = wp_get_menu_array($menu);?><body <?php body_class(); ?>>    <?php wp_body_open(); ?>

Giải thích các hàm quan trọng:

STT Hàm Công dụng Vai trò
1 `<?php bloginfo('stylesheet_directory') ?>` Trả về đường dẫn đến thư mục theme hiện tại. Bắt buộc
2 `<?php language_attributes(); ?>` In ra các thuộc tính ngôn ngữ của website. Bắt buộc
3 `<?php wp_head(); ?>` WordPress sẽ tự động thêm các meta tag, link CSS, JS cần thiết vào phần ``. Bắt buộc
4 `<?php body_class(); ?>` Thêm các class vào thẻ ``, giúp bạn tùy chỉnh CSS dễ dàng hơn. Bắt buộc

2.2. Footer

Tương tự như header, copy toàn bộ code HTML của footer từ file HTML tĩnh vào file `footer.php` của theme WordPress.

Đổi link các resources thành `<?php bloginfo('stylesheet_directory') ?>/[đường dẫn-tới-file]`.

Code Footer trong WordPress

Hàm quan trọng:

STT Hàm Công dụng Vai trò
`<?php wp_footer(); ?>` WordPress sẽ chèn thêm các code cần thiết ở cuối trang (script cho FB plugin, Google Tag Manager,...). Bắt buộc

2.3. Menu

Code menu phức tạp hơn một chút. Dưới đây là ví dụ về menu sử dụng Custom Fields và PolyLang:

Custom Menu WordPress Menu WordPress Menu WordPress Custom Field
<header class="header-navbargl">   <nav class="navbar navbar-expand-lg">      <div class="container">         <a class="navbar-brand sticky_logo" href="<?php echo home_url('/'); ?>">         <?php            $logo2 = get_field('logo2', pll_current_language('slug'));            $logo = get_field('logo', pll_current_language('slug'));            $logo2_id = $logo2['ID'];            $logo_id = $logo['ID'];            $size = 'full';            echo wp_get_attachment_image($logo2_id, $size, "", array("class" => "logo2"));            echo wp_get_attachment_image($logo_id, $size, "", array("class" => "logo"));            ?>         </a>         <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">         <span class="menu-toggle"></span>         </button>         <div class="collapse navbar-collapse justify-content-center" id="navbarSupportedContent">            <?php               if (have_rows('btn_order', pll_current_language('slug'))) :                   while (have_rows('btn_order', pll_current_language('slug'))) : the_row();               ?>            <p class="btn-setup">               <a <?php                  $class = 'login_btn_vi';                  if (pll_current_language() == 'vi') :                  ?> class="<?php echo $class; ?>" <?php                  endif;                   ?> href="<?php the_sub_field('link', pll_current_language('slug')); ?>"><?php the_sub_field('text', pll_current_language('slug')); ?>               </a>            </p>            <?php endwhile;               endif; ?>            <ul class="navbar-nav menu-gl">               <?php                  $c = 0;                  $class = '';                  foreach ($menu_items as $item) :                      $c++;                      $class = ($c == 2) ? 'mega-resource news-resources' : '';                      if (property_exists($item, 'children')) {                  ?>               <li class="nav-item sub-item dropdown" onmouseover="navbarHoverIn()" onmouseout="navbarHoverOut()">                  <?php if ($item->url == '#') { ?>                  <a class="nav-link link-excep"><?php echo $item->title; ?></a>                  <?php } else { ?>                  <a class="nav-link" href="<?php echo $item->url; ?>"><?php echo $item->title; ?></a>                  <?php } ?>                  <a class="dropdown-toggle icon-arrow" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fal fa-angle-right"></i></a>                  <div class="dropdown-menu" aria-labelledby="navbarDropdown">                     <ul class="mega-menu d-flex list-unstyled <?php echo $class; ?>">                        <?php                           foreach ($item->children as $item_child) :                               $class = get_field("class_icon", $item_child->ID);                               $icon = get_field("fonts_icon", $item_child->ID);                               $desc = get_field('description', $item_child->ID);                           ?>                        <li class="item1">                           <div class="item-content">                              <h4 class="title-cl t_color2">                                 <span class="<?php echo $class; ?>">                                 <i class="<?php echo $icon; ?>"></i>                                 </span>                                 <?php if ($item_child->url == '#') { ?>                                 <span><?php echo $item_child->title; ?></span>                                 <?php } else { ?>                                 <a href="<?php echo $item_child->url ?>"><?php echo $item_child->title; ?>                                 </a>                                 <?php } ?>                              </h4>                              <p class="des-link"><?php echo $desc; ?></p>                              <?php                                 if (property_exists($item_child, 'children')) :                                     foreach ($item_child->children as $item_grand) :                                 ?>                              <a class="nav-link" href="<?php echo $item_grand->url; ?>"><span class="arrow_carrot-right"></span><span><?php echo $item_grand->title; ?></span></a>                              <?php                                 endforeach;                                 endif;                                 ?>                              <?php                                 $image = get_field('image', $item_child->ID);                                 $image_id = $image['ID'];                                 $size = 'full';                                 ?>                              <?php echo wp_get_attachment_image($image_id, $size, "", array("class" => "float-right")); ?>                           </div>                        </li>                        <?php                           endforeach;                           ?>                     </ul>                  </div>               </li>               <?php                  } else {                  ?>               <li class="nav-item sub-item" onmouseover="navbarHoverIn()" onmouseout="navbarHoverOut()"><a class="nav-link" href="<?php echo $item->url; ?>"><?php echo $item->title; ?></a></li>               <?php                  }                  endforeach;                  ?>            </ul>         </div>         <div class="btn-right<?php $class = ' btngleads-desktop';            if (pll_current_language() == 'vi') : echo $class;            endif; ?>">            <?php               if (have_rows('btn_order', pll_current_language('slug'))) :                   while (have_rows('btn_order', pll_current_language('slug'))) : the_row();               ?>            <a class="login_btn active" href="<?php the_sub_field('link', pll_current_language('slug')); ?>">            <?php the_sub_field('text', pll_current_language('slug')); ?>            </a>            <?php               endwhile;               endif;               ?>         </div>      </div>   </nav></header>

2.4. Trang Home

Copy file `index.php` thành file `home.php` trong thư mục theme.

Tạo trang Home WordPress

Thêm đoạn code sau vào đầu file `home.php` để khai báo đây là template cho trang chủ:

* Template Name: Home Page
Template Name: Home Page

Upload file `home.php` lên server. Trong trang quản trị WordPress, tạo một trang mới và chọn template "Home Page" cho trang đó.

Chọn Template Home Page

Vào phần cài đặt của WordPress và chọn trang vừa tạo làm trang chủ của website.

Cài đặt trang chủ

Copy code HTML của phần nội dung trang home vào file `home.php`, thay đổi đường dẫn resources thành `<?php bloginfo('stylesheet_directory') ?>/[đường dẫn-tới-file]`. Xóa hoặc comment hàm `get_sidebar();` vì phần này chưa dùng đến.

Code trang Home WordPress Code trang Home WordPress

Kết quả là trang home sẽ hiển thị giống như file HTML tĩnh ban đầu.

Giao diện trang Home WordPress
  1. Sử dụng Custom Fields để tùy chỉnh nội dung trang Home

Sau khi cài đặt plugin ACF Pro, tạo một custom field group tên là "home-page". Chọn "Show this field group if" là "Page Template" "is equal to" "Home Page". Điều này có nghĩa là tất cả các trang sử dụng template "Home Page" sẽ hiển thị các trường tùy chỉnh này.

ACF Custom Fields

Các loại custom field chính cần dùng:

STT Loại Công dụng
1 Text Nhập chữ hoặc đoạn văn bản ngắn.
2 Image Upload và chọn hình ảnh.
3 Post Object Chọn một đối tượng từ website (trang, bài viết, custom post).
4 Group Tạo một nhóm các custom field khác.
5 Repeater Tạo một nhóm các custom field có thể lặp lại nhiều lần.