Cấu trúc website và page template trong PHP

    0

    Khi bắt đầu nghĩ tới việc xây dựng một website “nghiêm túc” hơn một chút, bạn có thể sẽ gặp ngay một loạt vấn đề. Ví dụ như cần tạo những thư mục nào, tạo những file nào, làm sao để thống nhất giao diện giữa các page trong cùng một site. Đây là những vấn đề chung mà người mới học đều gặp phải. Trong bài học này chúng ta sẽ xem xét một số cách đơn giản để giải quyết các vấn đề này.

    Cấu trúc web page

    Trong các bài học trước bạn đã biết cách tạo ra một trang web (web page) bằng PHP. Một trang web chỉ đơn giản là các markup HTML có sẵn kết hợp với nội dung do mã PHP tính ra. Mỗi trang web được truy xuất từ trình duyệt qua một URL xác định.

    Mặc dù người thiết kế và lập trình ra website có thể tùy ý sáng tạo ra các page, thông thường các page nội dung đều có cấu trúc chung gần giống nhau. Người ta cũng gọi sự bố trí các phần trên một page là layout của page đó.

    Hình dưới đây minh họa cấu trúc (layout) thường gặp ở các web page.

    Theo cấu trúc này, một page sẽ được phân chia ra các phần: header, footer, navigation menu, nội dung chính. Phần sidebar có thể nằm bên phải, bên trái, hoặc cả hai bên. Page cũng có thể có thêm menu trước header và dưới footer.

    Cấu trúc chung này giúp người dùng nhanh chóng làm quen và sử dụng được site. Ngoài ra cấu trúc chung này được xây dựng và hoàn thiện từ kinh nghiệm sử dụng. Cũng vì vậy ít site sử dụng những thiết kế quá lạ.

    Để tạo ra cấu trúc này cần sử dụng CSS. Dưới đây là HTML + CSS để tạo ra một khung page cơ bản:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title><?=$title?></title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="css/styles.css">
    </head>
    <body>
    <div class="container">
        <div class="header">
            <p>Header</p>
        </div>
    
        <div class="topnav">
            <a href="#">Home</a>
            <a href="#">About</a>
            <a href="#">Contact</a>
        </div>
    
        <div class="content">
            <!-- Nội dung chính sẽ đặt vào đây -->
        </div>
    
        <div class="footer">
            <p>Footer</p>
        </div>
    </div>
    
    </body>
    </html>
    * {
        box-sizing: border-box;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    body {
        margin: 0;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    .topnav {
        overflow: hidden;
        background-color: #333;
    }
    
    .topnav a {
        float: left;
        display: block;
        color: #f2f2f2;
        text-align: center;
        padding: 14px 16px;
        text-decoration: none;
    }
    
    .topnav a:hover {
        background-color: #ddd;
        color: black;
    }
    
    .content {
        background-color: #ddd;
        padding: 10px;
    }
    
    .header, .footer {
        background-color: #f1f1f1;
        padding: 10px;
    }
    
    .container {
        width: 75%;
        margin: 0 auto;
    }

    Chúng ta sẽ sử dụng template này ở các phần sau của bài học.

    Ngoài ra, trên Internet có thể tìm thấy rất nhiều page template miễn phí như https://templated.co/, https://freewebsitetemplates.com/.

    Cấu trúc website

    Tập hợp của các trang web với cùng một host tạo ra một site (cũng gọi là website hoặc web site). Đôi khi một site cũng nằm gọn trong một sub-directory của một host.

    Để đảm bảo người dùng có thể dễ dàng truy xuất tất cả các page trong site, người ta thưởng tổ chức nội dung của các page theo một logic hoặc cấu trúc nhất định.

    Loại cấu trúc thường gặp là cấu trúc cây.

    What is Website structure? Why structure is important?

    Cấu trúc này tạo ra hệ thống page với xuất phát điểm là một page đặc biệt, gọi là trang chủ (home page). Từ trang chủ sẽ có link đến các page cấp 2. Từ mỗi page cấp 2 có link đến các page cấp 3. Cấu trúc này tạo ra một cây lộn ngược, hoặc cũng có thể nói là một sơ đồ phân nhánh.

    Ví dụ, cấu trúc nội dung của Tự học ICT có thể biểu diễn như sau:

    Ở đây chúng ta cần lưu ý là sự tổ chức này chỉ liên quan đến nội dung – nghĩa là sự liên kết từ trang này tới trang khác thông qua các link tạo bởi thẻ anchor (<a></a>). Cấu trúc website có thể không liên quan đến vị trí vật lý của các page.

    Để tạo đường link bạn chỉ cần sử dụng thẻ <a> với giá trị href là một file php cụ thể:

    <a href="/index.php">Trang chủ</a>
    <a href="/about.php">Giới thiệu</a>
    <a href="/blog/index.php">Blog</a>
    <a href="/tutorials/index.php">Hướng dẫn</a>

    Nhìn chung các đường link từ trang nọ tới trang kia thường được đặt tập trung trong navigation menu ở đầu trang. Trong template ở trên đã xây dựng sẵn class dành cho navigation menu.

    Cấu trúc file/thư mục

    Một site, cũng giống như một phần mềm, sẽ phải bao gồm nhiều file và thư mục. Khác biệt với các phần mềm, các site thường bao gồm thêm một số thư mục và file đặc thù.

    Nhìn chung hầu như site nào cũng cần có các thư mục/file chung sau:

    Thư mục css: chứa các file css (Cascading Style Sheets) dùng trong định dạng các page. Thông thường các style đặc thù của site được đặt trong file css\styles.css. Bạn nên tham chiếu tới file này từ phần header của mỗi page.

    Thư mục js: chứa các file Javascript. Hiện nay hầu như site nào cũng sử dụng Javascript. Những thành phần như navigation menu đều đòi hỏi Javascript để tạo các hiệu ứng động. Ít nhất bạn cũng nên tạo một file js\scripts.js và nhúng vào cuối phần body của các page để dự phòng.

    Thư mục images: chứa các file ảnh sử dụng cho các page. Bạn nên tập trung toàn bộ ảnh vào đây để dễ kiểm soát và sử dụng. Ít nhất mỗi site cũng cần có một file logo để nhận diện.

    File favicon.ico: file biểu tượng của site. File này cần nằm trong thư mục gốc của site. Các trình duyệt thường tự động tìm và tải file này làm biểu tượng trên tab khi mở page của site.

    Thư mục lib hay vendor: chứa các thư viện của các hãng thứ ba. Các thư viện thứ ba hay gặp là Bootstrap (css), JQuery (Javascript). Bạn cũng có thể cài đặt thêm các gói thư viện PHP bằng Composer.

    Bên cạnh các file/thư mục chung trên, tùy vào mỗi ứng dụng bạn có thể tùy ý tạo cấu trúc file/thư mục riêng.

    Ở thư mục gốc của site cần có một file index.php. File index.php có vai trò đặc biệt, gọi là default ducument của thư mục. Nếu trong URL không chỉ định rõ tên file, Apache sẽ tự động hiểu đó là file index.php và sẽ tìm file này.

    Nên phân chia file vào các thư mục theo vai trò của code. Thông thường nhất các site đều chứa code thuộc về các nhóm: giao diện (user interface), quy tắc nghiệp vụ (business logic), truy xuất dữ liệu (data service), thư viện dùng chung.

    Sử dụng chung header và footer

    Qua phân tích cấu trúc web page ở trên và qua kinh nghiệm sử dụng Internet bạn hẳn hình dung ra ngay, hầu như tất cả page trên một site sẽ có cấu trúc và thiết kế thống nhất.

    Nhìn chung, tất cả các page trong cùng một site sẽ thống nhất về header, footer, navigation menu. Một số site sử dụng cả sidebar. Sidebar cũng có thể xuất hiện trên một nhóm trang.

    Như vậy khi sử dụng PHP xây dựng website sẽ phát sinh ngay vấn đề đầu tiên: làm sao để sử dụng chung header/footer/sidebar/v.v. giữa các page?

    Giải pháp đơn giản nhất (và cũng tệ nhất) là copy template cho từng page. Tuy nhiên, hãy nghĩ đến trường hợp bạn thay đổi thiết kế template, và bạn có hàng trăm page! Do vậy, đừng bao giờ nghĩ đến kiểu làm thủ công này.

    Hãy cùng thực hiện một ví dụ sau:

    (1) Tạo một project mới với các file và thư mục như sau:

    Lần lượt viết code cho các file như sau:

    * {
        box-sizing: border-box;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    body {
        margin: 0;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    .topnav {
        overflow: hidden;
        background-color: #333;
    }
    
    .topnav a {
        float: left;
        display: block;
        color: #f2f2f2;
        text-align: center;
        padding: 14px 16px;
        text-decoration: none;
    }
    
    .topnav a:hover {
        background-color: #ddd;
        color: black;
    }
    
    .content {
        background-color: #ddd;
        padding: 10px;
    }
    
    .header, .footer {
        background-color: #f1f1f1;
        padding: 10px;
    }
    
    .container {
        width: 75%;
        margin: 0 auto;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title><?=$title?></title> <!-- biến $title sẽ có giá trị riêng trên từng page -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="css/styles.css">
    </head>
    <body>
    <div class="container">
        <div class="header"><p>Header</p></div>
        <div class="topnav">
            <a href="#">Home</a>
            <a href="#">About</a>
            <a href="#">Contact</a>
        </div>
    
        <div class="content">
    
    </div>
    
    <div class="footer">
        <p>Footer</p>
    </div>
    </div>
    
    </body>
    </html>
    

    Để ý rằng file template cung cấp ban đầu bị tách làm đôi, lấy thẻ <div class=”content”></div> là mốc. Logic rất đơn giản: nếu bạn copy code của header.php + nội dung riêng + code của footer.php dồn lại làm một, bạn thu được một file html hoàn chỉnh.

    Giờ xây dựng trang index.php như sau:

    <?php include 'inc/header.php'; ?>
    
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing
        elit, sed nonummy nibh euismod tincidunt ut laoreet
        dolore magna aliat volutpat. Ut wisi enim ad minim
        veniam, quis nostrud exercita ullamcorper
        suscipit lobortis nisl ut aliquip ex consequat.</p>
    
    <p>Duis autem vel eum iriure dolor in hendrerit in
        vulputate velit molestie consequat, vel illum
        dolore eu feugiat nulla facilisis ats eros et
        accumsan et iusto odio dignissim qui blandit
        prasent up zzril delenit augue duis dolore te
        feugait nulla facilisi. Lorem euismod tincidunt
        erat volutpat.</p>
    
    <p>Libero justo laoreet sit amet cursus sit amet dictum sit.
        Viverra maecenas accumsan lacus vel facilisis volutpat
        est velit egestas. Est placerat in egestas erat imperdiet
        sed euismod. Nisl nunc mi ipsum faucibus vitae aliquet.
        Sit amet nulla facilisi morbi tempus iaculis urna.
        Quis vel eros donec ac odio tempor.</p>
    
    <?php include 'inc/footer.php' ?>
    

    Về sau, khi cần tạo bất kỳ trang nào sử dụng chung mẫu thiết kế, bạn chỉ cần include phần header và footer vào trang.

    Tạo layout chung với output buffer

    Phương pháp tách file ở trên đơn giản cả về cách suy nghĩ và thực hiện. Thực tế là rất nhiều người đã sử dụng cách thức này. Trong PHP có nhiều cách khác để đạt được hiệu quả tương tự. Một trong những cách đơn giản là sử dụng tính năng output buffer của PHP.

    Output buffer là một tính năng đặc biệt của PHP. Bình thường khi thực hiện đến các lệnh in như echo, print, hoặc gặp các đoạn văn bản ngoài khối PHP, PHP sẽ xuất ngay nội dung đó ra nơi sử dụng.
    Tính năng output buffer sẽ ngăn quá trình xuất nội dung này. Thay vào đó, nội dung sẽ được đưa vào một bộ nhớ đệm. Bạn có thể đưa toàn bộ nội dung từ bộ nhớ đệm vào một biến để sử dụng.

    Kỹ thuật này được lợi dụng để tạo ra layout chung cho các trang theo logic sau:

    • Tạo một file layout (template) với các biến có sẵn ở những vị trí cần xuất dữ liệu;
    • Mỗi trang cụ thể sẽ áp dụng kỹ thuật output buffer để xuất dữ liệu vào một biến, thay vì xuất thẳng cho Apache;
    • Include file template vào từng trang và cung cấp biến chứa dữ liệu kết quả.

    Để dễ hiểu, hãy cùng thực hiện một ví dụ.

    (1) Tạo một thư mục mới đặt tên là Template nằm trong htdocs và tạo PhpStorm project từ thư mục này.

    Tạo thêm các file và thư mục trong project như sau:

    Lưu ý: hãy cấu hình PhpStorm theo cách đã trình bày trong bài học trước để PhpStorm hoạt động với XAMPP.

    (2) Lần lượt copy/paste code cho các file như sau:

    * {
        box-sizing: border-box;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    body {
        margin: 0;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    .topnav {
        overflow: hidden;
        background-color: #333;
    }
    
    .topnav a {
        float: left;
        display: block;
        color: #f2f2f2;
        text-align: center;
        padding: 14px 16px;
        text-decoration: none;
    }
    
    .topnav a:hover {
        background-color: #ddd;
        color: black;
    }
    
    .content {
        background-color: #ddd;
        padding: 10px;
    }
    
    .header, .footer {
        background-color: #f1f1f1;
        padding: 10px;
    }
    
    .container {
        width: 75%;
        margin: 0 auto;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title><?=$title?></title> <!-- biến $title sẽ có giá trị riêng trên từng page -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="/template/css/styles.css">
    </head>
    <body>
    <div class="container">
        <div class="header"><p>Header</p></div>
        <div class="topnav">
            <a href="#">Home</a>
            <a href="#">About</a>
            <a href="#">Contact</a>
        </div>
    
        <div class="content">
            <?=$content?> <!-- Lưu ý, ở đâu cần xuất nội dung ra thì bạn đặt dòng lệnh này ở đó -->
        </div>
    
        <div class="footer">
            <p>Footer</p>
        </div>
    </div>
    
    </body>
    </html>
    <?php
    
    $title = 'Page title';
    $layout = 'layout.php';
    
    function start_content($page_title = '', $page_layout = 'layout.php') {
        global $title, $layout;
        $title = $page_title;
        $layout = $page_layout;
        ob_start(); // bắt đầu khởi động chế độ output buffer
    }
    
    function end_content() {
        $content = ob_get_clean(); // dừng chế độ output buffer và lấy nội dung vào biến $content
        global $title, $layout;
        include($layout);
    }
    

    Trong file template.php đặc biệt chú ý đến chỗ sử dụng biến $content. Bạn đặt lệnh <?=$content?> ở nơi mà nội dung chính của page sẽ xuất hiện. Để dễ hiểu hơn, hãy thực hiện tiếp bước 3.

    (3) Viết code cho index.php như sau:

    <?php include 'core/functions.php'; ?>
    
    <?php start_content('Home page'); ?>
    
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing
            elit, sed nonummy nibh euismod tincidunt ut laoreet
            dolore magna aliat volutpat. Ut wisi enim ad minim
            veniam, quis nostrud exercita ullamcorper
            suscipit lobortis nisl ut aliquip ex consequat.</p>
    
        <p>Duis autem vel eum iriure dolor in hendrerit in
            vulputate velit molestie consequat, vel illum
            dolore eu feugiat nulla facilisis ats eros et
            accumsan et iusto odio dignissim qui blandit
            prasent up zzril delenit augue duis dolore te
            feugait nulla facilisi. Lorem euismod tincidunt
            erat volutpat.</p>
    
        <p>Libero justo laoreet sit amet cursus sit amet dictum sit.
            Viverra maecenas accumsan lacus vel facilisis volutpat
            est velit egestas. Est placerat in egestas erat imperdiet
            sed euismod. Nisl nunc mi ipsum faucibus vitae aliquet.
            Sit amet nulla facilisi morbi tempus iaculis urna.
            Quis vel eros donec ac odio tempor.</p>
    
    <?php end_content(); ?>

    Giờ nếu tải trang index.php (localhost/template/index.php) bạn sẽ thu được kết quả như sau:

    Như vậy, khi tải trang index.php, nội dung riêng của index.php được chèn vào đúng vị trí <?=$content?> của template.php. Mã của trang index.php (và bất kỳ trang nào sử dụng chung template này) bắt buộc phải có 3 dòng lệnh sau:

    <?php include 'core/functions.php'; ?>
    <?php start_content('Home page'); ?>
    <!-- Nội dung của trang HTML -->
    <?php end_content(); ?>

    Trong đó, lệnh start_content nhận tham số thứ nhất là tiêu đề của trang, tham số thứ hai là tên file template (trong trường hợp sử dụng template khác ‘layout.php’).

    Bất kỳ trang nào bạn muốn sử dụng lại layout.php thì chỉ cần sử dụng 3 lệnh như trên. Ở giữa bạn có thể để bất kỳ nội dung HTML nào, hoặc kết hợp với lệnh điều khiển + xuất dữ liệu của PHP.

    Từ ví dụ trên bạn có thể tự mình xây dựng một template cho các project php trong tương lai. Bạn cũng có thể tự mình điều chỉnh layout cho phù hợp với yêu cầu riêng, ví dụ như sử dụng Bootstrap và jQuery.

    Để tiện lợi cho bạn trong quá trình học, chúng tôi đã tạo sẵn một mẫu project mà bạn có thể tải từ link sau:
    https://1drv.ms/u/s!Ar_aj4rIJ2qGkvwwcwHs3wUOLHWcrw?e=5GidgF
    Khi sử dụng mẫu project này chú ý:
    (1) thay đổi đường dẫn của hằng APPLICATION_PATH trong file core/config.php cho phù hợp với đường dẫn từ document root.
    (2) thay đổi tên ứng dụng APPLICATION_NAME trong file core/config.php.
    (3) nếu có nhu cầu thay đổi layout, bạn có thể sửa trực tiếp vào file core/layout.php hoặc tạo file layout mới trong thư mục core rồi cập nhật hằng DEFAULT_LAYOUT.
    (4) đây cũng là một project cho PhpStorm. Chúng tôi cũng đã tạo sẵn một template file php (My PHP Template) có sẵn các lệnh cần thiết để sử dụng layout chung.
    (5) mẫu project này đã tích hợp sẵn Bootstrap và jQuery.

    Kết luận

    Trong bài học này chúng ta tìm hiểu về cách tích hợp PHP trong môi trường web ở cấp độ cao hơn, liên quan đến cấu trúc website và cấu trúc web page. Chúng ta cũng tìm hiểu hai kỹ thuật đơn giản để tạo ra cấu trúc thống nhất cho các page trong site.

    Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần Thảo luận cuối trang.
    Nếu cần trao đổi riêng với chúng tôi, hãy gửi email hoặc nhắn tin qua form liên hệ.
    Nếu bài viết hữu ích với bạn, hãy giúp chúng tôi chia sẻ tới mọi người.
    Đăng ký theo dõi trang facebook để nhận thông tin về bài viết mới.
    Tắt Adblocker hoặc whitelist trang để hỗ trợ chúng tôi.
    Cảm ơn bạn!

    * Bản quyền bài viết thuộc về Tự học ICT. Đề nghị tôn trọng bản quyền. DMCA.com Protection Status
    Subscribe
    Notify of
    guest
    0 Thảo luận
    Inline Feedbacks
    View all comments